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