/* * * ka_util: Program to dump the AFS authentication server database * into an ascii file. * * Assumptions: We *cheat* here and read the datafile directly, ie. * not going through the ubik distributed data manager. * therefore the database must be quiescent for the * output of this program to be valid. */ #include #include #include #include #include #define UBIK_INTERNALS #include #include #include #include #include "kauth.h" #include "kaserver.h" #include "kautils.h" #define IDHash(x) (abs(x) % HASHSIZE) #define print_id(x) ( ((flags&DO_SYS)==0 && (x<-32767 || x>97536)) || \ ((flags&DO_OTR)==0 && (x>-32768 && x<97537))) extern char *optarg; extern int optind; extern int errno; int display_entry(); static struct kaheader kah; static struct ubik_version uv; struct kadstats dynamic_statistics; char buffer[1024]; int dbase_fd; FILE *dfp; int nflag = 0; int wflag = 0; int flags = 0; afs_int32 es_Report() { } struct afsconf_dir *KA_conf; struct ubik_dbase *KA_dbase; int MinHours = 0; int npwSums = KA_NPWSUMS; afs_int32 verbose_track = 1; afs_uint32 myHost = 0; main(argc, argv) int argc; char **argv; { int i; long code; long cc, upos = 0, gpos; struct ubik_hdr *uh; char *dfile = 0; char *pfile = "/usr/afs/db/kaserver.DB0"; while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) { switch (cc) { case 'p': pfile = optarg; break; case 'd': dfile = optarg; break; case 'n': nflag++; break; case 'w': wflag++; break; default: fprintf(stderr, "Usage: ka_util [options] [-d data] [-p prdb]\n"); fputs(" Options:\n", stderr); fputs(" -w Update prdb with contents of data file\n", stderr); fputs(" -u Display users\n", stderr); fputs(" -g Display groups\n", stderr); fputs(" -m Display group members\n", stderr); fputs(" -n Follow name hash chains (not id hashes)\n", stderr); fputs(" -s Display only system data\n", stderr); fputs(" -x Display extra users/groups\n", stderr); exit(1); } } if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY) | O_CREAT, 0600)) < 0) { fprintf(stderr, "ka_util: cannot open %s: %s\n", pfile, strerror(errno)); exit(1); } if (read(dbase_fd, buffer, HDRSIZE) < 0) { fprintf(stderr, "ka_util: error reading %s: %s\n", pfile, strerror(errno)); exit(1); } if (dfile) { if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) { fprintf(stderr, "ka_util: error opening %s: %s\n", dfile, strerror(errno)); exit(1); } } else dfp = (wflag ? stdin : stdout); uh = (struct ubik_hdr *)buffer; if (ntohl(uh->magic) != UBIK_MAGIC) fprintf(stderr, "ka_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n", pfile, ntohl(uh->magic), UBIK_MAGIC); memcpy(&uv, &uh->version, sizeof(struct ubik_version)); if (wflag && uv.epoch == 0 && uv.counter == 0) { uv.epoch = 2; /* a ubik version of 0 or 1 has special meaning */ memcpy(&uh->version, &uv, sizeof(struct ubik_version)); lseek(dbase_fd, 0, SEEK_SET); if (write(dbase_fd, buffer, HDRSIZE) < 0) { fprintf(stderr, "ka_util: error writing ubik version to %s: %s\n", pfile, strerror(errno)); exit(1); } } fprintf(stderr, "Ubik Version is: %d.%d\n", uv.epoch, uv.counter); if (read(dbase_fd, &kah, sizeof(struct kaheader)) < 0) { fprintf(stderr, "ka_util: error reading %s: %s\n", pfile, strerror(errno)); exit(1); } initialize_KA_error_table(); if (wflag) { struct kaheader header; afs_int32 ltime = time(0); memset(&header, 0, sizeof(header)); header.version = htonl(KADBVERSION); header.headerSize = htonl(sizeof(header)); header.freePtr = 0; header.eofPtr = htonl(sizeof(header)); header.kvnoPtr = 0; header.stats.allocs = 0; header.stats.frees = 0; header.stats.cpws = 0; header.admin_accounts = 0; header.specialKeysVersion = htonl(ltime); header.hashsize = htonl(HASHSIZE); header.checkVersion = htonl(KADBVERSION); write(dbase_fd, &header, sizeof(header)); while (fgets(buffer, sizeof(buffer), dfp)) { struct kaentry tentry; int flags, exp, modtime, modid, cpwtime, maxlife, kvno; char kaname[64 + 64 + 2], key[33], name[64], instance[64], rlm[64]; afs_int32 maxLifetime; sscanf(buffer, "%s %d %d %d %d %d %d %d %s", kaname, &flags, &exp, &modtime, &modid, &cpwtime, &maxlife, &kvno, key); printf("%s %d %d %d %d %d %d %d %s", kaname, flags, exp, modtime, modid, cpwtime, maxlife, kvno, key); memset(name, 0, sizeof(name)); memset(instance, 0, sizeof(instance)); ka_ParseLoginName(&kaname, &name, &instance, &rlm); printf("%s %s %s\n", kaname, name, instance); strncpy(tentry.userID.name, name, sizeof(tentry.userID.name)); strncpy(tentry.userID.instance, instance, sizeof(tentry.userID.instance)); tentry.flags = htonl(flags); memcpy(&tentry.key, key, sizeof(tentry.key)); tentry.key_version = htonl(kvno); tentry.user_expiration = htonl(exp); /* time and addr of entry for guy changing this entry */ tentry.modification_time = htonl(modtime); tentry.modification_id = htonl(modid); tentry.change_password_time = htonl(cpwtime); if (strcmp(name, KA_TGS_NAME) == 0) maxLifetime = MAXKTCTICKETLIFETIME; else if (strcmp(name, KA_ADMIN_NAME) == 0) maxLifetime = 10 * 3600; else if (strcmp(name, AUTH_SUPERUSER) == 0) maxLifetime = 100 * 3600; else maxLifetime = 25 * 3600; /* regular users */ if (maxlife) tentry.max_ticket_lifetime = htonl(maxlife); else tentry.max_ticket_lifetime = htonl(maxLifetime); write(dbase_fd, &tentry, sizeof(tentry)); } /*CheckInit(0,0); */ } else { while (1) { gpos = display_entry(upos * sizeof(struct kaentry)); if (gpos < 0) break; upos++; } } lseek(dbase_fd, 0, L_SET); /* rewind to beginning of file */ if (read(dbase_fd, buffer, HDRSIZE) < 0) { fprintf(stderr, "ka_util: error reading %s: %s\n", pfile, strerror(errno)); exit(1); } uh = (struct ubik_hdr *)buffer; if ((uh->version.epoch != uv.epoch) || (uh->version.counter != uv.counter)) { fprintf(stderr, "ka_util: Ubik Version number changed during execution.\n"); fprintf(stderr, "Old Version = %d.%d, new version = %d.%d\n", uv.epoch, uv.counter, uh->version.epoch, uh->version.counter); } close(dbase_fd); exit(0); } int display_entry(offset) int offset; { int i; struct kaentry dbentry; int count; unsigned char x[8]; char thiskey[33]; if (lseek(dbase_fd, offset + HDRSIZE + sizeof(struct kaheader), L_SET) < 0) return -1; i = read(dbase_fd, &dbentry, sizeof(struct kaentry)); if (i < sizeof(struct kaentry)) return -1; if (!strcmp(dbentry.userID.name, "")) return 1; memcpy(x, &dbentry.key, 8); fprintf(dfp, "%s%s%s %d %d %d %d %d %d %d ", dbentry.userID.name, ((dbentry.userID.instance && strcmp(dbentry.userID.instance, "")) ? "." : ""), ((dbentry.userID.instance && strcmp(dbentry.userID.instance, "")) ? dbentry.userID.instance : ""), dbentry.flags, dbentry.user_expiration, dbentry.modification_time, dbentry.modification_id, dbentry.change_password_time, dbentry.max_ticket_lifetime, dbentry.key_version); for (count = 0; count < 8; count++) { fprintf(dfp, "\\%03o", (unsigned char *)x[count]); } fprintf(dfp, "\n"); return 0; }