Annotation of src/usr.bin/tcfs/tcfs_dbmaint.c, Revision 1.2
1.1 provos 1: /*
2: * Transparent Cryptographic File System (TCFS) for NetBSD
3: * Author and mantainer: Luigi Catuogno [luicat@tcfs.unisa.it]
4: *
5: * references: http://tcfs.dia.unisa.it
6: * tcfs-bsd@tcfs.unisa.it
7: */
8:
9: /*
10: * Base utility set v0.1
11: */
12:
13: #include <stdio.h>
14: #include <stdlib.h>
15: #include <unistd.h>
16: #include <stdarg.h>
17: #include <string.h>
18: #include <db.h>
19: #include <syslog.h>
20: #include <sys/types.h>
21: #include <sys/stat.h>
22: #include <fcntl.h>
23:
24: #include <miscfs/tcfs/tcfs.h>
25: #include "tcfslib.h"
26: #include "tcfspwdb.h"
27:
28: #define PERM_SECURE (S_IRUSR|S_IWUSR)
29:
30: int
31: tcfspwdbr_new (tcfspwdb **new)
32: {
33: *new = (tcfspwdb *)calloc(1, sizeof(tcfspwdb));
34:
35: if (!*new)
36: return (0);
37:
38: return (1);
39: }
40:
41: int
42: tcfsgpwdbr_new (tcfsgpwdb **new)
43: {
44: *new = (tcfsgpwdb *)calloc(1, sizeof(tcfsgpwdb));
45:
46: if (!*new)
47: return (0);
48:
49: return (1);
50: }
51:
52: int
53: tcfspwdbr_edit (tcfspwdb **tmp, int flags,...)
54: {
55: va_list argv;
56: char *d;
57:
58: if (!*tmp)
59: if (!tcfspwdbr_new (tmp))
60: return 0;
61:
62: va_start (argv, flags);
63:
64: if (flags & F_USR) {
65: d = va_arg (argv, char *);
66: strcpy ((*tmp)->user, d);
67: }
68:
69: if (flags & F_PWD) {
70: d = va_arg (argv, char *);
71: strcpy ((*tmp)->upw, d);
72: }
73:
74: va_end (argv);
75: return 1;
76: }
77:
78: int
79: tcfsgpwdbr_edit (tcfsgpwdb **tmp, int flags,...)
80: {
81: va_list argv;
82: char *d;
83:
84: if (!*tmp)
85: if (!tcfsgpwdbr_new (tmp))
86: return 0;
87:
88: va_start (argv, flags);
89:
90: if (flags & F_USR) {
91: d = va_arg (argv, char *);
92: strcpy ((*tmp)->user, d);
93: }
94:
95: if (flags & F_GKEY) {
96: d = va_arg (argv, char *);
97: strcpy ((*tmp)->gkey, d);
98: }
99:
100: if (flags & F_GID) {
101: gid_t d;
102: d = va_arg (argv, gid_t);
103: (*tmp)->gid = d;
104: }
105:
106: if (flags & F_MEMBERS) {
107: int d;
108: d = va_arg (argv, int);
109: (*tmp)->n = d;
110: }
111:
112: if (flags & F_THRESHOLD) {
113: int d;
114: d = va_arg (argv, int);
115: (*tmp)->soglia = d;
116: }
117:
118: va_end (argv);
119: return (1);
120: }
121:
122: int
123: tcfspwdbr_read (tcfspwdb *t, int flags,...)
124: {
125: va_list argv;
126: int r;
127: char *d;
128:
129: va_start (argv, flags);
130:
131: if (flags & F_USR) {
132: d = va_arg (argv, char *);
133: memset (d, 0, UserLen);
134: strcpy (d, t->user);
135: }
136:
137: if (flags & F_PWD) {
138: d = va_arg (argv, char *);
139: memset (d, 0, PassLen);
140: strcpy (d, t->upw);
141: }
142:
143: va_end (argv);
144: return 0;
145: }
146:
147: int
148: tcfsgpwdbr_read (tcfsgpwdb *t, int flags,...)
149: {
150: va_list argv;
151: int r;
152: char *d;
153:
154: va_start (argv, flags);
155:
156: if (flags & F_USR) {
157: d = va_arg (argv, char *);
158: strcpy (d, t->user);
159: }
160:
161: if (flags & F_GKEY) {
162: d = va_arg (argv, char *);
163: strcpy (d, t->gkey);
164: }
165:
166: if (flags & F_GID) {
167: gid_t *d;
168:
169: d = va_arg (argv, gid_t *);
170: memcpy (d, &t->gid, sizeof (gid_t));
171: }
172: /* Incomplete... */
173:
174: va_end (argv);
175: return 0;
176: }
177:
178: void
179: tcfspwdbr_dispose (tcfspwdb *t)
180: {
181: free ((void *)t);
182: }
183:
184: void
185: tcfsgpwdbr_dispose (tcfsgpwdb *t)
186: {
187: free ((void *)t);
188: }
189:
190: tcfspwdb *
191: tcfs_getpwnam (char *user, tcfspwdb **dest)
192: {
193: DB *pdb;
194: DBT srchkey, r;
195:
196: if (!*dest)
197: if (!tcfspwdbr_new (dest))
198: return NULL;
199:
200: pdb = dbopen (TCFSPWDB, O_RDONLY, 0, DB_HASH, NULL);
201: if (!pdb)
202: return NULL;
203:
204: srchkey.data = user;
205: srchkey.size = (int) strlen (user);
206:
207: if (pdb->get(pdb, &srchkey, &r, 0)) {
208: pdb->close(pdb);
209: return 0;
210: }
211:
212: if (r.size != sizeof(tcfspwdb)) {
213: fprintf(stderr, "db: incorrect record size: %d != %d\n",
214: r.size, sizeof(tcfspwdb));
215: pdb->close(pdb);
216: return 0;
217: }
218:
219: memcpy (*dest, r.data, sizeof (tcfspwdb));
220:
221: pdb->close (pdb);
222:
223: return (tcfspwdb *)*dest;
224: }
225:
226: tcfsgpwdb *
227: tcfs_ggetpwnam (char *user, gid_t gid, tcfsgpwdb **dest)
228: {
229: DB *pdb;
230: DBT srchkey, r;
231: char *key, *buf;
232:
233: if (!*dest)
234: if (!tcfsgpwdbr_new (dest))
235: return NULL;
236:
237: pdb = dbopen (TCFSGPWDB, O_RDONLY, 0, DB_HASH, NULL);
238: if (!pdb)
239: return NULL;
240:
241: key = (char*)calloc(strlen(user)+4/*gid lenght*/+1/*null*/,sizeof(char));
242: if (!key)
243: return NULL;
244:
245: sprintf (key, "%s\33%d\0", user, (int)gid);
246: srchkey.data=key;
247: srchkey.size=(int)strlen (key);
248:
249: if (pdb->get(pdb, &srchkey, &r, 0)) {
250: pdb->close (pdb);
251: return (NULL);
252: }
253:
254: memcpy (*dest, r.data, sizeof (tcfsgpwdb));
255:
256: pdb->close (pdb);
257:
258: return (*dest);
259: }
260:
261: int
262: tcfs_putpwnam (char *user, tcfspwdb *src, int flags)
263: {
264: DB *pdb;
265: static DBT srchkey, d;
1.2 ! provos 266: int open_flag = 0, res;
1.1 provos 267:
268: open_flag = O_RDWR|O_EXCL;
269: if (access (TCFSPWDB, F_OK) < 0)
270: open_flag |= O_CREAT;
271:
272: pdb = dbopen (TCFSPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
273: if (!pdb)
274: return 0;
275:
276: srchkey.data = user;
1.2 ! provos 277: srchkey.size = (int)strlen (user);
1.1 provos 278:
279: if (flags != U_DEL) {
280: d.data = (char *)src;
281: d.size = (int)sizeof(tcfspwdb);
282:
283: if (pdb->put(pdb, &srchkey, &d, 0) == -1) {
284: fprintf(stderr, "db: put failed\n");
285: pdb->close (pdb);
286: return 0;
287: }
1.2 ! provos 288: } else if ((res = pdb->del (pdb, &srchkey, 0))) {
! 289: fprintf(stderr, "db: del failed: %s\n",
! 290: res == -1 ? "error" : "not found");
1.1 provos 291: pdb->close (pdb);
292: return 0;
293: }
294:
295: pdb->close (pdb);
296: return 1;
297: }
298:
299: int
300: tcfs_gputpwnam (char *user, tcfsgpwdb *src, int flags)
301: {
302: DB *pdb;
303: static DBT srchkey, d;
1.2 ! provos 304: int open_flag = 0;
1.1 provos 305: char *key, *buf;
306: char *tmp;
307:
308: open_flag = O_RDWR|O_EXCL;
309: if (access (TCFSPWDB, F_OK) < 0)
310: open_flag |= O_CREAT;
311:
312: pdb = dbopen (TCFSPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
313: if (!pdb)
314: return 0;
315:
316: key = (char *) calloc (strlen(src->user) + 4 + 1, sizeof(char));
317: sprintf (key, "%s\33%d\0", src->user, src->gid);
318:
319: srchkey.data = key;
320: srchkey.size = strlen (key);
321:
322: if (flags != U_DEL) {
323: d.data = (char *)src;
324: d.size = sizeof(tcfsgpwdb);
325:
326: if (pdb->put (pdb, &srchkey, &d, 0) == -1) {
327: fprintf(stderr, "db: put failed\n");
328: pdb->close (pdb);
329: return 0;
330: }
331: } else if (pdb->del (pdb, &srchkey, 0)) {
332: fprintf(stderr, "db: del failed\n");
333: pdb->close (pdb);
334: return 0;
335: }
336:
337: pdb->close (pdb);
338: return 1;
339: }
340:
341: int
342: tcfs_rmgroup (gid_t gid)
343: {
344: DB *gdb;
345: DBT dbkey;
346:
347: gdb = dbopen(TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
348: if (!gdb)
349: return 0;
350:
351: if (gdb->seq(gdb, &dbkey, NULL, R_FIRST))
352: dbkey.data = NULL;
353:
354: while (dbkey.data) {
355: char *tmp;
356:
357: tmp = (char*)calloc(1024, sizeof(char));
358:
359: sprintf(tmp, "\33%d\0", gid);
360: if (strstr (dbkey.data, tmp)) {
361: if (gdb->del(gdb, &dbkey, 0)) {
362: gdb->close (gdb);
363:
364: free (tmp);
365: return 0;
366: }
367: }
368: free (tmp);
369:
370: if (gdb->seq(gdb, &dbkey, NULL, R_NEXT)) {
371: gdb->close(gdb);
372: return (0);
373: }
374: }
375:
376: gdb->close (gdb);
377: return (1);
378: }
379:
380:
381: int
382: tcfs_group_chgpwd (char *user, gid_t gid, char *old, char *new)
383: {
384: tcfsgpwdb *group_info;
385: unsigned char *key;
386:
387: key=(unsigned char *)calloc(UUKEYSIZE, sizeof (char));
388: if (!key)
389: return 0;
390:
391: if (!tcfs_decrypt_key (user, old, (unsigned char*)group_info->gkey, key, GROUPKEY))
392: return 0;
393:
394: if (!tcfs_encrypt_key (user, new, key, (unsigned char *)group_info->gkey, GROUPKEY))
395: return 0;
396:
397: if (!tcfs_gputpwnam (user, group_info, U_CHG))
398: return 0;
399:
400: free (group_info);
401: free (key);
402:
403: return 1;
404: }
405:
406: int
407: tcfs_chgpwd (char *user, char *old, char *new)
408: {
409: tcfspwdb *user_info=NULL;
410: unsigned char *key;
411:
412: key = (unsigned char*)calloc(UUKEYSIZE, sizeof(char));
413:
414: if (!tcfs_getpwnam (user, &user_info))
415: return 0;
416:
417: if (!tcfs_decrypt_key (user, old, (unsigned char *)user_info->upw, key, USERKEY))
418: return 0;
419:
420: if (!tcfs_encrypt_key (user, new, key, (unsigned char *)user_info->upw, USERKEY))
421: return 0;
422:
423: if (!tcfs_putpwnam (user, user_info, U_CHG))
424: return 0;
425:
426: free (user_info);
427: free (key);
428:
429: return 1;
430: }
431:
432: int
433: tcfs_chgpassword (char *user, char *old, char *new)
434: {
435: int error1=0, error2=0;
436: DB *gpdb;
437: DBT found, key;
438: unsigned char *ckey;
439:
440: ckey = (unsigned char*)calloc(UUKEYSIZE, sizeof(char));
441: if (!ckey)
442: return 0;
443:
444: gpdb = dbopen (TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
445: if (!gpdb)
446: return 0;
447:
448: error1 = tcfs_chgpwd (user, old, new);
449: if (!error1)
450: return 0;
451:
452: /* Reencrypt group shares */
453: if (gpdb->seq(gpdb, &key, NULL, R_FIRST))
454: key.data = NULL;
455:
456: while (key.data) {
457: if (strncmp (user, key.data, strlen(user))) {
458: if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
459: key.data = NULL;
460: continue;
461: }
462:
463: gpdb->get(gpdb, &key, &found, 0);
464:
465: if (!tcfs_decrypt_key (user, old, (unsigned char *)((tcfsgpwdb *)found.data)->gkey, ckey, USERKEY))
466: return 0;
467:
468: if (!tcfs_encrypt_key (user, new, ckey, (unsigned char *)((tcfsgpwdb *)found.data)->gkey, USERKEY))
469: return 0;
470:
471: if (gpdb->put (gpdb, &key, &found, 0)) {
472: free (ckey);
473:
474: gpdb->close (gpdb);
475: return (0);
476: }
477:
478: free (ckey);
479:
480: if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
481: key.data = NULL;
482: }
483:
484: return 1;
485: }