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 <afsconfig.h>
13 #include <afs/param.h>
15 #include <sys/types.h>
24 #include <netinet/in.h>
25 #define UBIK_INTERNALS
34 #define IDHash(x) (abs(x) % HASHSIZE)
35 #define print_id(x) ( ((flags&DO_SYS)==0 && (x<-32767 || x>97536)) || \
36 ((flags&DO_OTR)==0 && (x>-32768 && x<97537)))
44 static struct kaheader kah
;
45 static struct ubik_version uv
;
46 struct kadstats dynamic_statistics
;
61 struct afsconf_dir
*KA_conf
;
62 struct ubik_dbase
*KA_dbase
;
64 int npwSums
= KA_NPWSUMS
;
65 afs_int32 verbose_track
= 1;
66 afs_uint32 myHost
= 0;
74 long cc
, upos
= 0, gpos
;
77 char *pfile
= "/usr/afs/db/kaserver.DB0";
79 while ((cc
= getopt(argc
, argv
, "wugmxsnp:d:")) != EOF
) {
94 fprintf(stderr
, "Usage: ka_util [options] [-d data] [-p prdb]\n");
95 fputs(" Options:\n", stderr
);
96 fputs(" -w Update prdb with contents of data file\n", stderr
);
97 fputs(" -u Display users\n", stderr
);
98 fputs(" -g Display groups\n", stderr
);
99 fputs(" -m Display group members\n", stderr
);
100 fputs(" -n Follow name hash chains (not id hashes)\n",
102 fputs(" -s Display only system data\n", stderr
);
103 fputs(" -x Display extra users/groups\n", stderr
);
107 if ((dbase_fd
= open(pfile
, (wflag
? O_RDWR
: O_RDONLY
) | O_CREAT
, 0600))
109 fprintf(stderr
, "ka_util: cannot open %s: %s\n", pfile
,
113 if (read(dbase_fd
, buffer
, HDRSIZE
) < 0) {
114 fprintf(stderr
, "ka_util: error reading %s: %s\n", pfile
,
120 if ((dfp
= fopen(dfile
, wflag
? "r" : "w")) == 0) {
121 fprintf(stderr
, "ka_util: error opening %s: %s\n", dfile
,
126 dfp
= (wflag
? stdin
: stdout
);
128 uh
= (struct ubik_hdr
*)buffer
;
129 if (ntohl(uh
->magic
) != UBIK_MAGIC
)
130 fprintf(stderr
, "ka_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
131 pfile
, ntohl(uh
->magic
), UBIK_MAGIC
);
132 memcpy(&uv
, &uh
->version
, sizeof(struct ubik_version
));
133 if (wflag
&& uv
.epoch
== 0 && uv
.counter
== 0) {
134 uv
.epoch
= 2; /* a ubik version of 0 or 1 has special meaning */
135 memcpy(&uh
->version
, &uv
, sizeof(struct ubik_version
));
136 lseek(dbase_fd
, 0, SEEK_SET
);
137 if (write(dbase_fd
, buffer
, HDRSIZE
) < 0) {
138 fprintf(stderr
, "ka_util: error writing ubik version to %s: %s\n",
139 pfile
, strerror(errno
));
143 fprintf(stderr
, "Ubik Version is: %d.%d\n", uv
.epoch
, uv
.counter
);
144 if (read(dbase_fd
, &kah
, sizeof(struct kaheader
)) < 0) {
145 fprintf(stderr
, "ka_util: error reading %s: %s\n", pfile
,
150 initialize_KA_error_table();
153 struct kaheader header
;
154 afs_int32 ltime
= time(0);
155 memset(&header
, 0, sizeof(header
));
156 header
.version
= htonl(KADBVERSION
);
157 header
.headerSize
= htonl(sizeof(header
));
159 header
.eofPtr
= htonl(sizeof(header
));
161 header
.stats
.allocs
= 0;
162 header
.stats
.frees
= 0;
163 header
.stats
.cpws
= 0;
164 header
.admin_accounts
= 0;
165 header
.specialKeysVersion
= htonl(ltime
);
166 header
.hashsize
= htonl(HASHSIZE
);
167 header
.checkVersion
= htonl(KADBVERSION
);
169 write(dbase_fd
, &header
, sizeof(header
));
170 while (fgets(buffer
, sizeof(buffer
), dfp
)) {
171 struct kaentry tentry
;
172 int flags
, exp
, modtime
, modid
, cpwtime
, maxlife
, kvno
;
173 char kaname
[64 + 64 + 2], key
[33], name
[64], instance
[64],
175 afs_int32 maxLifetime
;
177 sscanf(buffer
, "%s %d %d %d %d %d %d %d %s", kaname
, &flags
, &exp
,
178 &modtime
, &modid
, &cpwtime
, &maxlife
, &kvno
, key
);
180 printf("%s %d %d %d %d %d %d %d %s", kaname
, flags
, exp
, modtime
,
181 modid
, cpwtime
, maxlife
, kvno
, key
);
182 memset(name
, 0, sizeof(name
));
183 memset(instance
, 0, sizeof(instance
));
184 ka_ParseLoginName(&kaname
, &name
, &instance
, &rlm
);
185 printf("%s %s %s\n", kaname
, name
, instance
);
186 strncpy(tentry
.userID
.name
, name
, sizeof(tentry
.userID
.name
));
187 strncpy(tentry
.userID
.instance
, instance
,
188 sizeof(tentry
.userID
.instance
));
189 tentry
.flags
= htonl(flags
);
190 memcpy(&tentry
.key
, key
, sizeof(tentry
.key
));
191 tentry
.key_version
= htonl(kvno
);
193 tentry
.user_expiration
= htonl(exp
);
195 /* time and addr of entry for guy changing this entry */
196 tentry
.modification_time
= htonl(modtime
);
197 tentry
.modification_id
= htonl(modid
);
198 tentry
.change_password_time
= htonl(cpwtime
);
200 if (strcmp(name
, KA_TGS_NAME
) == 0)
201 maxLifetime
= MAXKTCTICKETLIFETIME
;
202 else if (strcmp(name
, KA_ADMIN_NAME
) == 0)
203 maxLifetime
= 10 * 3600;
204 else if (strcmp(name
, AUTH_SUPERUSER
) == 0)
205 maxLifetime
= 100 * 3600;
207 maxLifetime
= 25 * 3600; /* regular users */
209 tentry
.max_ticket_lifetime
= htonl(maxlife
);
211 tentry
.max_ticket_lifetime
= htonl(maxLifetime
);
213 write(dbase_fd
, &tentry
, sizeof(tentry
));
218 gpos
= display_entry(upos
* sizeof(struct kaentry
));
225 lseek(dbase_fd
, 0, L_SET
); /* rewind to beginning of file */
226 if (read(dbase_fd
, buffer
, HDRSIZE
) < 0) {
227 fprintf(stderr
, "ka_util: error reading %s: %s\n", pfile
,
231 uh
= (struct ubik_hdr
*)buffer
;
232 if ((uh
->version
.epoch
!= uv
.epoch
)
233 || (uh
->version
.counter
!= uv
.counter
)) {
235 "ka_util: Ubik Version number changed during execution.\n");
236 fprintf(stderr
, "Old Version = %d.%d, new version = %d.%d\n",
237 uv
.epoch
, uv
.counter
, uh
->version
.epoch
, uh
->version
.counter
);
244 display_entry(offset
)
248 struct kaentry dbentry
;
253 if (lseek(dbase_fd
, offset
+ HDRSIZE
+ sizeof(struct kaheader
), L_SET
) <
256 i
= read(dbase_fd
, &dbentry
, sizeof(struct kaentry
));
257 if (i
< sizeof(struct kaentry
))
259 if (!strcmp(dbentry
.userID
.name
, ""))
261 memcpy(x
, &dbentry
.key
, 8);
263 fprintf(dfp
, "%s%s%s %d %d %d %d %d %d %d ", dbentry
.userID
.name
,
264 ((dbentry
.userID
.instance
&& strcmp(dbentry
.userID
.instance
, ""))
265 ? "." : ""), ((dbentry
.userID
.instance
266 && strcmp(dbentry
.userID
.instance
, ""))
267 ? dbentry
.userID
.instance
: ""), dbentry
.flags
,
268 dbentry
.user_expiration
, dbentry
.modification_time
,
269 dbentry
.modification_id
, dbentry
.change_password_time
,
270 dbentry
.max_ticket_lifetime
, dbentry
.key_version
);
271 for (count
= 0; count
< 8; count
++) {
272 fprintf(dfp
, "\\%03o", (unsigned char *)x
[count
]);