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