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>
25 #include <netinet/in.h>
26 #define UBIK_INTERNALS
35 #define IDHash(x) (abs(x) % HASHSIZE)
36 #define print_id(x) ( ((flags&DO_SYS)==0 && (x<-32767 || x>97536)) || \
37 ((flags&DO_OTR)==0 && (x>-32768 && x<97537)))
45 static struct kaheader kah;
46 static struct ubik_version uv;
47 struct kadstats dynamic_statistics;
57 afs_int32 es_Report(){}
59 struct afsconf_dir *KA_conf;
60 struct ubik_dbase *KA_dbase;
62 int npwSums = KA_NPWSUMS;
63 afs_int32 verbose_track = 1;
72 long cc, upos=0, gpos;
75 char *pfile = "/usr/afs/db/kaserver.DB0";
77 while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) {
93 "Usage: ka_util [options] [-d data] [-p prdb]\n");
94 fputs(" Options:\n", stderr);
95 fputs(" -w Update prdb with contents of data file\n", stderr);
96 fputs(" -u Display users\n", stderr);
97 fputs(" -g Display groups\n", stderr);
98 fputs(" -m Display group members\n", stderr);
99 fputs(" -n Follow name hash chains (not id hashes)\n", stderr);
100 fputs(" -s Display only system data\n", stderr);
101 fputs(" -x Display extra users/groups\n", stderr);
105 if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY)|O_CREAT, 0600))
107 fprintf(stderr, "ka_util: cannot open %s: %s\n",
108 pfile, strerror(errno));
111 if (read(dbase_fd, buffer, HDRSIZE) < 0) {
112 fprintf(stderr, "ka_util: error reading %s: %s\n",
113 pfile, strerror(errno));
118 if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) {
119 fprintf(stderr, "ka_util: error opening %s: %s\n",
120 dfile, strerror(errno));
124 dfp = (wflag ? stdin : stdout);
126 uh = (struct ubik_hdr *)buffer;
127 if (ntohl(uh->magic) != UBIK_MAGIC)
128 fprintf(stderr, "ka_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
129 pfile, ntohl(uh->magic), UBIK_MAGIC);
130 memcpy(&uv, &uh->version, sizeof(struct ubik_version));
131 if (wflag && uv.epoch==0 && uv.counter==0) {
132 uv.epoch=2; /* a ubik version of 0 or 1 has special meaning */
133 memcpy(&uh->version, &uv, sizeof(struct ubik_version));
134 lseek(dbase_fd, 0, SEEK_SET);
135 if (write(dbase_fd, buffer, HDRSIZE) < 0) {
136 fprintf(stderr, "ka_util: error writing ubik version to %s: %s\n",
137 pfile, strerror(errno));
141 fprintf(stderr, "Ubik Version is: %d.%d\n",
142 uv.epoch, uv.counter);
143 if (read(dbase_fd, &kah, sizeof(struct kaheader)) < 0) {
144 fprintf(stderr, "ka_util: error reading %s: %s\n",
145 pfile, strerror(errno));
149 initialize_KA_error_table();
152 struct kaheader header;
153 afs_int32 ltime=time(0);
154 memset(&header, 0, sizeof(header));
155 header.version = htonl(KADBVERSION);
156 header.headerSize = htonl(sizeof(header));
158 header.eofPtr = htonl(sizeof(header));
160 header.stats.allocs = 0;
161 header.stats.frees = 0;
162 header.stats.cpws = 0;
163 header.admin_accounts = 0;
164 header.specialKeysVersion = htonl(ltime);
165 header.hashsize = htonl(HASHSIZE);
166 header.checkVersion = htonl(KADBVERSION);
168 write(dbase_fd, &header, sizeof(header));
169 while(fgets(buffer, sizeof(buffer), dfp)) {
170 struct kaentry tentry;
171 int flags, exp, modtime, modid, cpwtime, maxlife, kvno;
172 char kaname[64+64+2], key[33], name[64], instance[64], rlm[64];
173 afs_int32 maxLifetime;
175 sscanf(buffer, "%s %d %d %d %d %d %d %d %s",
176 kaname, &flags, &exp, &modtime, &modid, &cpwtime,
177 &maxlife, &kvno, key);
179 printf("%s %d %d %d %d %d %d %d %s", kaname, flags, exp, modtime,
180 modid, cpwtime, maxlife, kvno, key);
181 memset(name,0,sizeof(name));
182 memset(instance,0,sizeof(instance));
183 ka_ParseLoginName(&kaname, &name, &instance, &rlm);
184 printf("%s %s %s\n", kaname, name, instance);
185 strncpy(tentry.userID.name, name, sizeof(tentry.userID.name));
186 strncpy(tentry.userID.instance, instance, sizeof(tentry.userID.instance));
187 tentry.flags = htonl(flags);
188 memcpy(&tentry.key, key, sizeof(tentry.key));
189 tentry.key_version = htonl(kvno);
191 tentry.user_expiration = htonl(exp);
193 /* time and addr of entry for guy changing this entry */
194 tentry.modification_time = htonl(modtime);
195 tentry.modification_id = htonl(modid);
196 tentry.change_password_time = htonl(cpwtime);
198 if (strcmp (name, KA_TGS_NAME) == 0) maxLifetime = MAXKTCTICKETLIFETIME;
199 else if (strcmp (name, KA_ADMIN_NAME) == 0) maxLifetime = 10*3600;
200 else if (strcmp (name, AUTH_SUPERUSER) == 0) maxLifetime = 100*3600;
201 else maxLifetime = 25*3600; /* regular users */
203 tentry.max_ticket_lifetime = htonl(maxlife);
205 tentry.max_ticket_lifetime = htonl(maxLifetime);
207 write(dbase_fd, &tentry, sizeof(tentry));
212 gpos = display_entry(upos*sizeof(struct kaentry));
219 lseek (dbase_fd, 0, L_SET); /* rewind to beginning of file */
220 if (read(dbase_fd, buffer, HDRSIZE) < 0) {
221 fprintf(stderr, "ka_util: error reading %s: %s\n",
222 pfile, strerror(errno));
225 uh = (struct ubik_hdr *)buffer;
226 if ((uh->version.epoch != uv.epoch) ||
227 (uh->version.counter != uv.counter)) {
228 fprintf(stderr, "ka_util: Ubik Version number changed during execution.\n");
229 fprintf(stderr, "Old Version = %d.%d, new version = %d.%d\n",
230 uv.epoch, uv.counter, uh->version.epoch,
231 uh->version.counter);
237 int display_entry (offset)
241 struct kaentry dbentry;
246 if (lseek (dbase_fd, offset+HDRSIZE+sizeof(struct kaheader), L_SET) < 0)
248 i = read(dbase_fd, &dbentry, sizeof(struct kaentry));
249 if (i<sizeof(struct kaentry))
251 if(!strcmp(dbentry.userID.name, ""))
253 memcpy(x, &dbentry.key, 8);
255 fprintf(dfp, "%s%s%s %d %d %d %d %d %d %d ",
257 ((dbentry.userID.instance && strcmp(dbentry.userID.instance,""))
259 ((dbentry.userID.instance && strcmp(dbentry.userID.instance,""))
260 ? dbentry.userID.instance : ""), dbentry.flags,
261 dbentry.user_expiration, dbentry.modification_time,
262 dbentry.modification_id, dbentry.change_password_time,
263 dbentry.max_ticket_lifetime, dbentry.key_version);
264 for(count=0;count<8;count++)
266 fprintf(dfp, "\\%03o",(unsigned char *)x[count]);