Annotation of src/usr.bin/tcfs/tcfs_dbmaint.c, Revision 1.4
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;
1.3 provos 232: int res;
1.1 provos 233:
234: if (!*dest)
235: if (!tcfsgpwdbr_new (dest))
236: return NULL;
237:
238: pdb = dbopen (TCFSGPWDB, O_RDONLY, 0, DB_HASH, NULL);
239: if (!pdb)
240: return NULL;
241:
242: key = (char*)calloc(strlen(user)+4/*gid lenght*/+1/*null*/,sizeof(char));
243: if (!key)
244: return NULL;
245:
246: sprintf (key, "%s\33%d\0", user, (int)gid);
1.3 provos 247: srchkey.data = key;
248: srchkey.size = (int)strlen (key);
1.1 provos 249:
1.3 provos 250: if ((res = pdb->get(pdb, &srchkey, &r, 0))) {
251: if (res == -1)
252: perror("dbget");
1.1 provos 253: pdb->close (pdb);
254: return (NULL);
255: }
256:
257: memcpy (*dest, r.data, sizeof (tcfsgpwdb));
258:
259: pdb->close (pdb);
260:
261: return (*dest);
262: }
263:
264: int
265: tcfs_putpwnam (char *user, tcfspwdb *src, int flags)
266: {
267: DB *pdb;
268: static DBT srchkey, d;
1.2 provos 269: int open_flag = 0, res;
1.1 provos 270:
271: open_flag = O_RDWR|O_EXCL;
272: if (access (TCFSPWDB, F_OK) < 0)
273: open_flag |= O_CREAT;
274:
275: pdb = dbopen (TCFSPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
276: if (!pdb)
277: return 0;
278:
279: srchkey.data = user;
1.2 provos 280: srchkey.size = (int)strlen (user);
1.1 provos 281:
282: if (flags != U_DEL) {
283: d.data = (char *)src;
284: d.size = (int)sizeof(tcfspwdb);
285:
286: if (pdb->put(pdb, &srchkey, &d, 0) == -1) {
287: fprintf(stderr, "db: put failed\n");
288: pdb->close (pdb);
289: return 0;
290: }
1.2 provos 291: } else if ((res = pdb->del (pdb, &srchkey, 0))) {
292: fprintf(stderr, "db: del failed: %s\n",
293: res == -1 ? "error" : "not found");
1.1 provos 294: pdb->close (pdb);
295: return 0;
296: }
297:
298: pdb->close (pdb);
299: return 1;
300: }
301:
302: int
303: tcfs_gputpwnam (char *user, tcfsgpwdb *src, int flags)
304: {
305: DB *pdb;
306: static DBT srchkey, d;
1.2 provos 307: int open_flag = 0;
1.1 provos 308: char *key, *buf;
309: char *tmp;
310:
311: open_flag = O_RDWR|O_EXCL;
1.3 provos 312: if (access (TCFSGPWDB, F_OK) < 0)
1.1 provos 313: open_flag |= O_CREAT;
314:
1.3 provos 315: pdb = dbopen (TCFSGPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
316: if (!pdb) {
317: perror("dbopen");
1.1 provos 318: return 0;
1.3 provos 319: }
1.1 provos 320:
321: key = (char *) calloc (strlen(src->user) + 4 + 1, sizeof(char));
322: sprintf (key, "%s\33%d\0", src->user, src->gid);
323:
324: srchkey.data = key;
325: srchkey.size = strlen (key);
326:
327: if (flags != U_DEL) {
328: d.data = (char *)src;
329: d.size = sizeof(tcfsgpwdb);
330:
331: if (pdb->put (pdb, &srchkey, &d, 0) == -1) {
332: fprintf(stderr, "db: put failed\n");
333: pdb->close (pdb);
334: return 0;
335: }
336: } else if (pdb->del (pdb, &srchkey, 0)) {
337: fprintf(stderr, "db: del failed\n");
338: pdb->close (pdb);
339: return 0;
340: }
341:
342: pdb->close (pdb);
343: return 1;
344: }
345:
346: int
347: tcfs_rmgroup (gid_t gid)
348: {
349: DB *gdb;
350: DBT dbkey;
351:
352: gdb = dbopen(TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
353: if (!gdb)
354: return 0;
355:
356: if (gdb->seq(gdb, &dbkey, NULL, R_FIRST))
357: dbkey.data = NULL;
358:
359: while (dbkey.data) {
360: char *tmp;
361:
362: tmp = (char*)calloc(1024, sizeof(char));
363:
364: sprintf(tmp, "\33%d\0", gid);
365: if (strstr (dbkey.data, tmp)) {
366: if (gdb->del(gdb, &dbkey, 0)) {
367: gdb->close (gdb);
368:
369: free (tmp);
370: return 0;
371: }
372: }
373: free (tmp);
374:
375: if (gdb->seq(gdb, &dbkey, NULL, R_NEXT)) {
376: gdb->close(gdb);
377: return (0);
378: }
379: }
380:
381: gdb->close (gdb);
382: return (1);
383: }
384:
385:
386: int
387: tcfs_group_chgpwd (char *user, gid_t gid, char *old, char *new)
388: {
389: tcfsgpwdb *group_info;
390: unsigned char *key;
391:
1.4 ! provos 392: key = (unsigned char *)calloc(UUGKEYSIZE + 1, sizeof (char));
1.1 provos 393: if (!key)
394: return 0;
395:
1.4 ! provos 396: if (!tcfs_decrypt_key (old, group_info->gkey, key, GKEYSIZE))
1.1 provos 397: return 0;
398:
1.4 ! provos 399: if (!tcfs_encrypt_key (new, key, GKEYSIZE, group_info->gkey,
! 400: UUGKEYSIZE + 1))
1.1 provos 401: return 0;
402:
403: if (!tcfs_gputpwnam (user, group_info, U_CHG))
404: return 0;
405:
406: free (group_info);
407: free (key);
408:
409: return 1;
410: }
411:
412: int
413: tcfs_chgpwd (char *user, char *old, char *new)
414: {
415: tcfspwdb *user_info=NULL;
416: unsigned char *key;
417:
1.4 ! provos 418: key = (unsigned char*)calloc(UUKEYSIZE + 1, sizeof(char));
1.1 provos 419:
420: if (!tcfs_getpwnam (user, &user_info))
421: return 0;
422:
1.4 ! provos 423: if (!tcfs_decrypt_key (old, user_info->upw, key, KEYSIZE))
1.1 provos 424: return 0;
425:
1.4 ! provos 426: if (!tcfs_encrypt_key (new, key, KEYSIZE, user_info->upw, UUKEYSIZE + 1))
1.1 provos 427: return 0;
428:
429: if (!tcfs_putpwnam (user, user_info, U_CHG))
430: return 0;
431:
432: free (user_info);
433: free (key);
434:
435: return 1;
436: }
437:
438: int
439: tcfs_chgpassword (char *user, char *old, char *new)
440: {
441: int error1=0, error2=0;
442: DB *gpdb;
443: DBT found, key;
444: unsigned char *ckey;
445:
1.4 ! provos 446: ckey = (unsigned char*)calloc(UUGKEYSIZE + 1, sizeof(char));
1.1 provos 447: if (!ckey)
448: return 0;
449:
450: gpdb = dbopen (TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
451: if (!gpdb)
452: return 0;
453:
454: error1 = tcfs_chgpwd (user, old, new);
455: if (!error1)
456: return 0;
457:
458: /* Reencrypt group shares */
459: if (gpdb->seq(gpdb, &key, NULL, R_FIRST))
460: key.data = NULL;
461:
462: while (key.data) {
463: if (strncmp (user, key.data, strlen(user))) {
464: if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
465: key.data = NULL;
466: continue;
467: }
468:
469: gpdb->get(gpdb, &key, &found, 0);
470:
1.4 ! provos 471: if (!tcfs_decrypt_key (old, ((tcfsgpwdb *)found.data)->gkey, ckey, GKEYSIZE))
1.1 provos 472: return 0;
473:
1.4 ! provos 474: if (!tcfs_encrypt_key (new, ckey, GKEYSIZE, ((tcfsgpwdb *)found.data)->gkey, UUGKEYSIZE + 1))
1.1 provos 475: return 0;
476:
477: if (gpdb->put (gpdb, &key, &found, 0)) {
478: free (ckey);
479:
480: gpdb->close (gpdb);
481: return (0);
482: }
483:
484: free (ckey);
485:
486: if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
487: key.data = NULL;
488: }
489:
490: return 1;
491: }