--- /dev/null
+/*
+ *
+ * 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 <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/file.h>
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+RCSID("$Header$");
+
+#include <lock.h>
+#include <netinet/in.h>
+#define UBIK_INTERNALS
+#include <ubik.h>
+#include <rx/xdr.h>
+#include <rx/rx.h>
+#include <rx/rxkad.h>
+#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_int32 myHost = 0;
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ register int i;
+ register long code;
+ long cc, upos=0, gpos;
+ struct ubik_hdr *uh;
+ struct timeval time;
+ 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);
+ }
+
+ init_kaprocs(pfile,9);
+ initialize_KA_error_table();
+
+ if (wflag) {
+ 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];
+ afs_int32 maxLifetime;
+
+ sscanf(buffer, "%s %d %d %d %d %d %d %d %s",
+ kaname, &flags, &exp, &modtime, &modid, &cpwtime,
+ &maxlife, &kvno, key);
+
+ 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));
+ }
+ } 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;
+{
+ register 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;
+}
+