Annotation of src/usr.bin/tcfs/tcfs_dbmaint.c, Revision 1.5
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: char *d;
127:
128: va_start (argv, flags);
129:
130: if (flags & F_USR) {
131: d = va_arg (argv, char *);
132: memset (d, 0, UserLen);
133: strcpy (d, t->user);
134: }
135:
136: if (flags & F_PWD) {
137: d = va_arg (argv, char *);
138: memset (d, 0, PassLen);
139: strcpy (d, t->upw);
140: }
141:
142: va_end (argv);
143: return 0;
144: }
145:
146: int
147: tcfsgpwdbr_read (tcfsgpwdb *t, int flags,...)
148: {
149: va_list argv;
150: char *d;
151:
152: va_start (argv, flags);
153:
154: if (flags & F_USR) {
155: d = va_arg (argv, char *);
156: strcpy (d, t->user);
157: }
158:
159: if (flags & F_GKEY) {
160: d = va_arg (argv, char *);
161: strcpy (d, t->gkey);
162: }
163:
164: if (flags & F_GID) {
165: gid_t *d;
166:
167: d = va_arg (argv, gid_t *);
168: memcpy (d, &t->gid, sizeof (gid_t));
169: }
170: /* Incomplete... */
171:
172: va_end (argv);
173: return 0;
174: }
175:
176: void
177: tcfspwdbr_dispose (tcfspwdb *t)
178: {
179: free ((void *)t);
180: }
181:
182: void
183: tcfsgpwdbr_dispose (tcfsgpwdb *t)
184: {
185: free ((void *)t);
186: }
187:
188: tcfspwdb *
189: tcfs_getpwnam (char *user, tcfspwdb **dest)
190: {
191: DB *pdb;
192: DBT srchkey, r;
193:
194: if (!*dest)
195: if (!tcfspwdbr_new (dest))
196: return NULL;
197:
198: pdb = dbopen (TCFSPWDB, O_RDONLY, 0, DB_HASH, NULL);
199: if (!pdb)
200: return NULL;
201:
202: srchkey.data = user;
203: srchkey.size = (int) strlen (user);
204:
205: if (pdb->get(pdb, &srchkey, &r, 0)) {
206: pdb->close(pdb);
207: return 0;
208: }
209:
210: if (r.size != sizeof(tcfspwdb)) {
211: fprintf(stderr, "db: incorrect record size: %d != %d\n",
212: r.size, sizeof(tcfspwdb));
213: pdb->close(pdb);
214: return 0;
215: }
216:
217: memcpy (*dest, r.data, sizeof (tcfspwdb));
218:
219: pdb->close (pdb);
220:
221: return (tcfspwdb *)*dest;
222: }
223:
224: tcfsgpwdb *
225: tcfs_ggetpwnam (char *user, gid_t gid, tcfsgpwdb **dest)
226: {
227: DB *pdb;
228: DBT srchkey, r;
1.5 ! fgsch 229: char *key;
1.3 provos 230: int res;
1.1 provos 231:
232: if (!*dest)
233: if (!tcfsgpwdbr_new (dest))
234: return NULL;
235:
236: pdb = dbopen (TCFSGPWDB, O_RDONLY, 0, DB_HASH, NULL);
237: if (!pdb)
238: return NULL;
239:
240: key = (char*)calloc(strlen(user)+4/*gid lenght*/+1/*null*/,sizeof(char));
241: if (!key)
242: return NULL;
243:
244: sprintf (key, "%s\33%d\0", user, (int)gid);
1.3 provos 245: srchkey.data = key;
246: srchkey.size = (int)strlen (key);
1.1 provos 247:
1.3 provos 248: if ((res = pdb->get(pdb, &srchkey, &r, 0))) {
249: if (res == -1)
250: perror("dbget");
1.1 provos 251: pdb->close (pdb);
252: return (NULL);
253: }
254:
255: memcpy (*dest, r.data, sizeof (tcfsgpwdb));
256:
257: pdb->close (pdb);
258:
259: return (*dest);
260: }
261:
262: int
263: tcfs_putpwnam (char *user, tcfspwdb *src, int flags)
264: {
265: DB *pdb;
266: static DBT srchkey, d;
1.2 provos 267: int open_flag = 0, res;
1.1 provos 268:
269: open_flag = O_RDWR|O_EXCL;
270: if (access (TCFSPWDB, F_OK) < 0)
271: open_flag |= O_CREAT;
272:
273: pdb = dbopen (TCFSPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
274: if (!pdb)
275: return 0;
276:
277: srchkey.data = user;
1.2 provos 278: srchkey.size = (int)strlen (user);
1.1 provos 279:
280: if (flags != U_DEL) {
281: d.data = (char *)src;
282: d.size = (int)sizeof(tcfspwdb);
283:
284: if (pdb->put(pdb, &srchkey, &d, 0) == -1) {
285: fprintf(stderr, "db: put failed\n");
286: pdb->close (pdb);
287: return 0;
288: }
1.2 provos 289: } else if ((res = pdb->del (pdb, &srchkey, 0))) {
290: fprintf(stderr, "db: del failed: %s\n",
291: res == -1 ? "error" : "not found");
1.1 provos 292: pdb->close (pdb);
293: return 0;
294: }
295:
296: pdb->close (pdb);
297: return 1;
298: }
299:
300: int
301: tcfs_gputpwnam (char *user, tcfsgpwdb *src, int flags)
302: {
303: DB *pdb;
304: static DBT srchkey, d;
1.2 provos 305: int open_flag = 0;
1.5 ! fgsch 306: char *key;
1.1 provos 307:
308: open_flag = O_RDWR|O_EXCL;
1.3 provos 309: if (access (TCFSGPWDB, F_OK) < 0)
1.1 provos 310: open_flag |= O_CREAT;
311:
1.3 provos 312: pdb = dbopen (TCFSGPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
313: if (!pdb) {
314: perror("dbopen");
1.1 provos 315: return 0;
1.3 provos 316: }
1.1 provos 317:
318: key = (char *) calloc (strlen(src->user) + 4 + 1, sizeof(char));
319: sprintf (key, "%s\33%d\0", src->user, src->gid);
320:
321: srchkey.data = key;
322: srchkey.size = strlen (key);
323:
324: if (flags != U_DEL) {
325: d.data = (char *)src;
326: d.size = sizeof(tcfsgpwdb);
327:
328: if (pdb->put (pdb, &srchkey, &d, 0) == -1) {
329: fprintf(stderr, "db: put failed\n");
330: pdb->close (pdb);
331: return 0;
332: }
333: } else if (pdb->del (pdb, &srchkey, 0)) {
334: fprintf(stderr, "db: del failed\n");
335: pdb->close (pdb);
336: return 0;
337: }
338:
339: pdb->close (pdb);
340: return 1;
341: }
342:
343: int
344: tcfs_rmgroup (gid_t gid)
345: {
346: DB *gdb;
347: DBT dbkey;
348:
349: gdb = dbopen(TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
350: if (!gdb)
351: return 0;
352:
353: if (gdb->seq(gdb, &dbkey, NULL, R_FIRST))
354: dbkey.data = NULL;
355:
356: while (dbkey.data) {
357: char *tmp;
358:
359: tmp = (char*)calloc(1024, sizeof(char));
360:
361: sprintf(tmp, "\33%d\0", gid);
362: if (strstr (dbkey.data, tmp)) {
363: if (gdb->del(gdb, &dbkey, 0)) {
364: gdb->close (gdb);
365:
366: free (tmp);
367: return 0;
368: }
369: }
370: free (tmp);
371:
372: if (gdb->seq(gdb, &dbkey, NULL, R_NEXT)) {
373: gdb->close(gdb);
374: return (0);
375: }
376: }
377:
378: gdb->close (gdb);
379: return (1);
380: }
381:
382:
383: int
384: tcfs_group_chgpwd (char *user, gid_t gid, char *old, char *new)
385: {
1.5 ! fgsch 386: tcfsgpwdb *group_info = NULL;
1.1 provos 387: unsigned char *key;
388:
1.4 provos 389: key = (unsigned char *)calloc(UUGKEYSIZE + 1, sizeof (char));
1.1 provos 390: if (!key)
391: return 0;
392:
1.4 provos 393: if (!tcfs_decrypt_key (old, group_info->gkey, key, GKEYSIZE))
1.1 provos 394: return 0;
395:
1.4 provos 396: if (!tcfs_encrypt_key (new, key, GKEYSIZE, group_info->gkey,
397: UUGKEYSIZE + 1))
1.1 provos 398: return 0;
399:
400: if (!tcfs_gputpwnam (user, group_info, U_CHG))
401: return 0;
402:
403: free (group_info);
404: free (key);
405:
406: return 1;
407: }
408:
409: int
410: tcfs_chgpwd (char *user, char *old, char *new)
411: {
412: tcfspwdb *user_info=NULL;
413: unsigned char *key;
414:
1.4 provos 415: key = (unsigned char*)calloc(UUKEYSIZE + 1, sizeof(char));
1.1 provos 416:
417: if (!tcfs_getpwnam (user, &user_info))
418: return 0;
419:
1.4 provos 420: if (!tcfs_decrypt_key (old, user_info->upw, key, KEYSIZE))
1.1 provos 421: return 0;
422:
1.4 provos 423: if (!tcfs_encrypt_key (new, key, KEYSIZE, user_info->upw, UUKEYSIZE + 1))
1.1 provos 424: return 0;
425:
426: if (!tcfs_putpwnam (user, user_info, U_CHG))
427: return 0;
428:
429: free (user_info);
430: free (key);
431:
432: return 1;
433: }
434:
435: int
436: tcfs_chgpassword (char *user, char *old, char *new)
437: {
1.5 ! fgsch 438: int error1=0;
1.1 provos 439: DB *gpdb;
440: DBT found, key;
441: unsigned char *ckey;
442:
1.4 provos 443: ckey = (unsigned char*)calloc(UUGKEYSIZE + 1, sizeof(char));
1.1 provos 444: if (!ckey)
445: return 0;
446:
447: gpdb = dbopen (TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
448: if (!gpdb)
449: return 0;
450:
451: error1 = tcfs_chgpwd (user, old, new);
452: if (!error1)
453: return 0;
454:
455: /* Reencrypt group shares */
456: if (gpdb->seq(gpdb, &key, NULL, R_FIRST))
457: key.data = NULL;
458:
459: while (key.data) {
460: if (strncmp (user, key.data, strlen(user))) {
461: if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
462: key.data = NULL;
463: continue;
464: }
465:
466: gpdb->get(gpdb, &key, &found, 0);
467:
1.4 provos 468: if (!tcfs_decrypt_key (old, ((tcfsgpwdb *)found.data)->gkey, ckey, GKEYSIZE))
1.1 provos 469: return 0;
470:
1.4 provos 471: if (!tcfs_encrypt_key (new, ckey, GKEYSIZE, ((tcfsgpwdb *)found.data)->gkey, UUGKEYSIZE + 1))
1.1 provos 472: return 0;
473:
474: if (gpdb->put (gpdb, &key, &found, 0)) {
475: free (ckey);
476:
477: gpdb->close (gpdb);
478: return (0);
479: }
480:
481: free (ckey);
482:
483: if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
484: key.data = NULL;
485: }
486:
487: return 1;
488: }