3 * ka_util: Program to dump the AFS authentication server database
6 * Assumptions: We *cheat* here and read the datafile directly, ie.
7 * not going through the ubik distributed data manager.
8 * therefore the database must be quiescent for the
9 * output of this program to be valid.
12 #include <sys/types.h>
19 #include <afsconfig.h>
20 #include <afs/param.h>
26 #include <netinet/in.h>
27 #define UBIK_INTERNALS
36 #define IDHash(x) (abs(x) % HASHSIZE)
37 #define print_id(x) ( ((flags&DO_SYS)==0 && (x<-32767 || x>97536)) || \
38 ((flags&DO_OTR)==0 && (x>-32768 && x<97537)))
46 static struct kaheader kah;
47 static struct ubik_version uv;
48 struct kadstats dynamic_statistics;
63 struct afsconf_dir *KA_conf;
64 struct ubik_dbase *KA_dbase;
66 int npwSums = KA_NPWSUMS;
67 afs_int32 verbose_track = 1;
76 long cc, upos = 0, gpos;
79 char *pfile = "/usr/afs/db/kaserver.DB0";
81 while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) {
96 fprintf(stderr, "Usage: ka_util [options] [-d data] [-p prdb]\n");
97 fputs(" Options:\n", stderr);
98 fputs(" -w Update prdb with contents of data file\n", stderr);
99 fputs(" -u Display users\n", stderr);
100 fputs(" -g Display groups\n", stderr);
101 fputs(" -m Display group members\n", stderr);
102 fputs(" -n Follow name hash chains (not id hashes)\n",
104 fputs(" -s Display only system data\n", stderr);
105 fputs(" -x Display extra users/groups\n", stderr);
109 if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY) | O_CREAT, 0600))
111 fprintf(stderr, "ka_util: cannot open %s: %s\n", pfile,
115 if (read(dbase_fd, buffer, HDRSIZE) < 0) {
116 fprintf(stderr, "ka_util: error reading %s: %s\n", pfile,
122 if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) {
123 fprintf(stderr, "ka_util: error opening %s: %s\n", dfile,
128 dfp = (wflag ? stdin : stdout);
130 uh = (struct ubik_hdr *)buffer;
131 if (ntohl(uh->magic) != UBIK_MAGIC)
132 fprintf(stderr, "ka_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
133 pfile, ntohl(uh->magic), UBIK_MAGIC);
134 memcpy(&uv, &uh->version, sizeof(struct ubik_version));
135 if (wflag && uv.epoch == 0 && uv.counter == 0) {
136 uv.epoch = 2; /* a ubik version of 0 or 1 has special meaning */
137 memcpy(&uh->version, &uv, sizeof(struct ubik_version));
138 lseek(dbase_fd, 0, SEEK_SET);
139 if (write(dbase_fd, buffer, HDRSIZE) < 0) {
140 fprintf(stderr, "ka_util: error writing ubik version to %s: %s\n",
141 pfile, strerror(errno));
145 fprintf(stderr, "Ubik Version is: %d.%d\n", uv.epoch, uv.counter);
146 if (read(dbase_fd, &kah, sizeof(struct kaheader)) < 0) {
147 fprintf(stderr, "ka_util: error reading %s: %s\n", pfile,
152 initialize_KA_error_table();
155 struct kaheader header;
156 afs_int32 ltime = time(0);
157 memset(&header, 0, sizeof(header));
158 header.version = htonl(KADBVERSION);
159 header.headerSize = htonl(sizeof(header));
161 header.eofPtr = htonl(sizeof(header));
163 header.stats.allocs = 0;
164 header.stats.frees = 0;
165 header.stats.cpws = 0;
166 header.admin_accounts = 0;
167 header.specialKeysVersion = htonl(ltime);
168 header.hashsize = htonl(HASHSIZE);
169 header.checkVersion = htonl(KADBVERSION);
171 write(dbase_fd, &header, sizeof(header));
172 while (fgets(buffer, sizeof(buffer), dfp)) {
173 struct kaentry tentry;
174 int flags, exp, modtime, modid, cpwtime, maxlife, kvno;
175 char kaname[64 + 64 + 2], key[33], name[64], instance[64],
177 afs_int32 maxLifetime;
179 sscanf(buffer, "%s %d %d %d %d %d %d %d %s", kaname, &flags, &exp,
180 &modtime, &modid, &cpwtime, &maxlife, &kvno, key);
182 printf("%s %d %d %d %d %d %d %d %s", kaname, flags, exp, modtime,
183 modid, cpwtime, maxlife, kvno, key);
184 memset(name, 0, sizeof(name));
185 memset(instance, 0, sizeof(instance));
186 ka_ParseLoginName(&kaname, &name, &instance, &rlm);
187 printf("%s %s %s\n", kaname, name, instance);
188 strncpy(tentry.userID.name, name, sizeof(tentry.userID.name));
189 strncpy(tentry.userID.instance, instance,
190 sizeof(tentry.userID.instance));
191 tentry.flags = htonl(flags);
192 memcpy(&tentry.key, key, sizeof(tentry.key));
193 tentry.key_version = htonl(kvno);
195 tentry.user_expiration = htonl(exp);
197 /* time and addr of entry for guy changing this entry */
198 tentry.modification_time = htonl(modtime);
199 tentry.modification_id = htonl(modid);
200 tentry.change_password_time = htonl(cpwtime);
202 if (strcmp(name, KA_TGS_NAME) == 0)
203 maxLifetime = MAXKTCTICKETLIFETIME;
204 else if (strcmp(name, KA_ADMIN_NAME) == 0)
205 maxLifetime = 10 * 3600;
206 else if (strcmp(name, AUTH_SUPERUSER) == 0)
207 maxLifetime = 100 * 3600;
209 maxLifetime = 25 * 3600; /* regular users */
211 tentry.max_ticket_lifetime = htonl(maxlife);
213 tentry.max_ticket_lifetime = htonl(maxLifetime);
215 write(dbase_fd, &tentry, sizeof(tentry));
220 gpos = display_entry(upos * sizeof(struct kaentry));
227 lseek(dbase_fd, 0, L_SET); /* rewind to beginning of file */
228 if (read(dbase_fd, buffer, HDRSIZE) < 0) {
229 fprintf(stderr, "ka_util: error reading %s: %s\n", pfile,
233 uh = (struct ubik_hdr *)buffer;
234 if ((uh->version.epoch != uv.epoch)
235 || (uh->version.counter != uv.counter)) {
237 "ka_util: Ubik Version number changed during execution.\n");
238 fprintf(stderr, "Old Version = %d.%d, new version = %d.%d\n",
239 uv.epoch, uv.counter, uh->version.epoch, uh->version.counter);
246 display_entry(offset)
250 struct kaentry dbentry;
255 if (lseek(dbase_fd, offset + HDRSIZE + sizeof(struct kaheader), L_SET) <
258 i = read(dbase_fd, &dbentry, sizeof(struct kaentry));
259 if (i < sizeof(struct kaentry))
261 if (!strcmp(dbentry.userID.name, ""))
263 memcpy(x, &dbentry.key, 8);
265 fprintf(dfp, "%s%s%s %d %d %d %d %d %d %d ", dbentry.userID.name,
266 ((dbentry.userID.instance && strcmp(dbentry.userID.instance, ""))
267 ? "." : ""), ((dbentry.userID.instance
268 && strcmp(dbentry.userID.instance, ""))
269 ? dbentry.userID.instance : ""), dbentry.flags,
270 dbentry.user_expiration, dbentry.modification_time,
271 dbentry.modification_id, dbentry.change_password_time,
272 dbentry.max_ticket_lifetime, dbentry.key_version);
273 for (count = 0; count < 8; count++) {
274 fprintf(dfp, "\\%03o", (unsigned char *)x[count]);