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.
11 #include <afsconfig.h>
12 #include <afs/param.h>
19 #define UBIK_INTERNALS
29 #define IDHash(x) (abs(x) % HASHSIZE)
30 #define print_id(x) ( ((flags&DO_SYS)==0 && (x<-32767 || x>97536)) || \
31 ((flags&DO_OTR)==0 && (x>-32768 && x<97537)))
39 static struct kaheader kah
;
40 static struct ubik_version uv
;
41 struct kadstats dynamic_statistics
;
56 struct afsconf_dir
*KA_conf
;
57 struct ubik_dbase
*KA_dbase
;
59 int npwSums
= KA_NPWSUMS
;
60 afs_int32 verbose_track
= 1;
61 afs_uint32 myHost
= 0;
69 long cc
, upos
= 0, gpos
;
72 char *pfile
= "/usr/afs/db/kaserver.DB0";
74 while ((cc
= getopt(argc
, argv
, "wugmxsnp:d:")) != EOF
) {
89 fprintf(stderr
, "Usage: ka_util [options] [-d data] [-p prdb]\n");
90 fputs(" Options:\n", stderr
);
91 fputs(" -w Update prdb with contents of data file\n", stderr
);
92 fputs(" -u Display users\n", stderr
);
93 fputs(" -g Display groups\n", stderr
);
94 fputs(" -m Display group members\n", stderr
);
95 fputs(" -n Follow name hash chains (not id hashes)\n",
97 fputs(" -s Display only system data\n", stderr
);
98 fputs(" -x Display extra users/groups\n", stderr
);
102 if ((dbase_fd
= open(pfile
, (wflag
? O_RDWR
: O_RDONLY
) | O_CREAT
, 0600))
104 fprintf(stderr
, "ka_util: cannot open %s: %s\n", pfile
,
108 if (read(dbase_fd
, buffer
, HDRSIZE
) < 0) {
109 fprintf(stderr
, "ka_util: error reading %s: %s\n", pfile
,
115 if ((dfp
= fopen(dfile
, wflag
? "r" : "w")) == 0) {
116 fprintf(stderr
, "ka_util: error opening %s: %s\n", dfile
,
121 dfp
= (wflag
? stdin
: stdout
);
123 uh
= (struct ubik_hdr
*)buffer
;
124 if (ntohl(uh
->magic
) != UBIK_MAGIC
)
125 fprintf(stderr
, "ka_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
126 pfile
, ntohl(uh
->magic
), UBIK_MAGIC
);
127 memcpy(&uv
, &uh
->version
, sizeof(struct ubik_version
));
128 if (wflag
&& uv
.epoch
== 0 && uv
.counter
== 0) {
129 uv
.epoch
= 2; /* a ubik version of 0 or 1 has special meaning */
130 memcpy(&uh
->version
, &uv
, sizeof(struct ubik_version
));
131 lseek(dbase_fd
, 0, SEEK_SET
);
132 if (write(dbase_fd
, buffer
, HDRSIZE
) < 0) {
133 fprintf(stderr
, "ka_util: error writing ubik version to %s: %s\n",
134 pfile
, strerror(errno
));
138 fprintf(stderr
, "Ubik Version is: %d.%d\n", uv
.epoch
, uv
.counter
);
139 if (read(dbase_fd
, &kah
, sizeof(struct kaheader
)) < 0) {
140 fprintf(stderr
, "ka_util: error reading %s: %s\n", pfile
,
145 initialize_KA_error_table();
148 struct kaheader header
;
149 afs_int32 ltime
= time(0);
150 memset(&header
, 0, sizeof(header
));
151 header
.version
= htonl(KADBVERSION
);
152 header
.headerSize
= htonl(sizeof(header
));
154 header
.eofPtr
= htonl(sizeof(header
));
156 header
.stats
.allocs
= 0;
157 header
.stats
.frees
= 0;
158 header
.stats
.cpws
= 0;
159 header
.admin_accounts
= 0;
160 header
.specialKeysVersion
= htonl(ltime
);
161 header
.hashsize
= htonl(HASHSIZE
);
162 header
.checkVersion
= htonl(KADBVERSION
);
164 write(dbase_fd
, &header
, sizeof(header
));
165 while (fgets(buffer
, sizeof(buffer
), dfp
)) {
166 struct kaentry tentry
;
167 int flags
, exp
, modtime
, modid
, cpwtime
, maxlife
, kvno
;
168 char kaname
[64 + 64 + 2], key
[33], name
[64], instance
[64],
170 afs_int32 maxLifetime
;
172 sscanf(buffer
, "%s %d %d %d %d %d %d %d %s", kaname
, &flags
, &exp
,
173 &modtime
, &modid
, &cpwtime
, &maxlife
, &kvno
, key
);
175 printf("%s %d %d %d %d %d %d %d %s", kaname
, flags
, exp
, modtime
,
176 modid
, cpwtime
, maxlife
, kvno
, key
);
177 memset(name
, 0, sizeof(name
));
178 memset(instance
, 0, sizeof(instance
));
179 ka_ParseLoginName(&kaname
, &name
, &instance
, &rlm
);
180 printf("%s %s %s\n", kaname
, name
, instance
);
181 strncpy(tentry
.userID
.name
, name
, sizeof(tentry
.userID
.name
));
182 strncpy(tentry
.userID
.instance
, instance
,
183 sizeof(tentry
.userID
.instance
));
184 tentry
.flags
= htonl(flags
);
185 memcpy(&tentry
.key
, key
, sizeof(tentry
.key
));
186 tentry
.key_version
= htonl(kvno
);
188 tentry
.user_expiration
= htonl(exp
);
190 /* time and addr of entry for guy changing this entry */
191 tentry
.modification_time
= htonl(modtime
);
192 tentry
.modification_id
= htonl(modid
);
193 tentry
.change_password_time
= htonl(cpwtime
);
195 if (strcmp(name
, KA_TGS_NAME
) == 0)
196 maxLifetime
= MAXKTCTICKETLIFETIME
;
197 else if (strcmp(name
, KA_ADMIN_NAME
) == 0)
198 maxLifetime
= 10 * 3600;
199 else if (strcmp(name
, AUTH_SUPERUSER
) == 0)
200 maxLifetime
= 100 * 3600;
202 maxLifetime
= 25 * 3600; /* regular users */
204 tentry
.max_ticket_lifetime
= htonl(maxlife
);
206 tentry
.max_ticket_lifetime
= htonl(maxLifetime
);
208 write(dbase_fd
, &tentry
, sizeof(tentry
));
213 gpos
= display_entry(upos
* sizeof(struct kaentry
));
220 lseek(dbase_fd
, 0, L_SET
); /* rewind to beginning of file */
221 if (read(dbase_fd
, buffer
, HDRSIZE
) < 0) {
222 fprintf(stderr
, "ka_util: error reading %s: %s\n", pfile
,
226 uh
= (struct ubik_hdr
*)buffer
;
227 if ((uh
->version
.epoch
!= uv
.epoch
)
228 || (uh
->version
.counter
!= uv
.counter
)) {
230 "ka_util: Ubik Version number changed during execution.\n");
231 fprintf(stderr
, "Old Version = %d.%d, new version = %d.%d\n",
232 uv
.epoch
, uv
.counter
, uh
->version
.epoch
, uh
->version
.counter
);
239 display_entry(offset
)
243 struct kaentry dbentry
;
248 if (lseek(dbase_fd
, offset
+ HDRSIZE
+ sizeof(struct kaheader
), L_SET
) <
251 i
= read(dbase_fd
, &dbentry
, sizeof(struct kaentry
));
252 if (i
< sizeof(struct kaentry
))
254 if (!strcmp(dbentry
.userID
.name
, ""))
256 memcpy(x
, &dbentry
.key
, 8);
258 fprintf(dfp
, "%s%s%s %d %d %d %d %d %d %d ", dbentry
.userID
.name
,
259 ((dbentry
.userID
.instance
&& strcmp(dbentry
.userID
.instance
, ""))
260 ? "." : ""), ((dbentry
.userID
.instance
261 && strcmp(dbentry
.userID
.instance
, ""))
262 ? dbentry
.userID
.instance
: ""), dbentry
.flags
,
263 dbentry
.user_expiration
, dbentry
.modification_time
,
264 dbentry
.modification_id
, dbentry
.change_password_time
,
265 dbentry
.max_ticket_lifetime
, dbentry
.key_version
);
266 for (count
= 0; count
< 8; count
++) {
267 fprintf(dfp
, "\\%03o", (unsigned char *)x
[count
]);