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