Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / kauth / ka_util.c
1 /*
2 *
3 * ka_util: Program to dump the AFS authentication server database
4 * into an ascii file.
5 *
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.
10 */
11 #include <afsconfig.h>
12 #include <afs/param.h>
13
14 #include <roken.h>
15
16 #include <ctype.h>
17
18 #include <lock.h>
19 #define UBIK_INTERNALS
20 #include <ubik.h>
21 #include <rx/xdr.h>
22 #include <rx/rx.h>
23 #include <rx/rxkad.h>
24
25 #include "kauth.h"
26 #include "kaserver.h"
27 #include "kautils.h"
28
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)))
32
33 extern char *optarg;
34 extern int optind;
35 extern int errno;
36
37 int display_entry();
38
39 static struct kaheader kah;
40 static struct ubik_version uv;
41 struct kadstats dynamic_statistics;
42
43 char buffer[1024];
44 int dbase_fd;
45 FILE *dfp;
46
47 int nflag = 0;
48 int wflag = 0;
49 int flags = 0;
50
51 afs_int32
52 es_Report()
53 {
54 }
55
56 struct afsconf_dir *KA_conf;
57 struct ubik_dbase *KA_dbase;
58 int MinHours = 0;
59 int npwSums = KA_NPWSUMS;
60 afs_int32 verbose_track = 1;
61 afs_uint32 myHost = 0;
62
63 main(argc, argv)
64 int argc;
65 char **argv;
66 {
67 int i;
68 long code;
69 long cc, upos = 0, gpos;
70 struct ubik_hdr *uh;
71 char *dfile = 0;
72 char *pfile = "/usr/afs/db/kaserver.DB0";
73
74 while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) {
75 switch (cc) {
76 case 'p':
77 pfile = optarg;
78 break;
79 case 'd':
80 dfile = optarg;
81 break;
82 case 'n':
83 nflag++;
84 break;
85 case 'w':
86 wflag++;
87 break;
88 default:
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",
96 stderr);
97 fputs(" -s Display only system data\n", stderr);
98 fputs(" -x Display extra users/groups\n", stderr);
99 exit(1);
100 }
101 }
102 if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY) | O_CREAT, 0600))
103 < 0) {
104 fprintf(stderr, "ka_util: cannot open %s: %s\n", pfile,
105 strerror(errno));
106 exit(1);
107 }
108 if (read(dbase_fd, buffer, HDRSIZE) < 0) {
109 fprintf(stderr, "ka_util: error reading %s: %s\n", pfile,
110 strerror(errno));
111 exit(1);
112 }
113
114 if (dfile) {
115 if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) {
116 fprintf(stderr, "ka_util: error opening %s: %s\n", dfile,
117 strerror(errno));
118 exit(1);
119 }
120 } else
121 dfp = (wflag ? stdin : stdout);
122
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));
135 exit(1);
136 }
137 }
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,
141 strerror(errno));
142 exit(1);
143 }
144
145 initialize_KA_error_table();
146
147 if (wflag) {
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));
153 header.freePtr = 0;
154 header.eofPtr = htonl(sizeof(header));
155 header.kvnoPtr = 0;
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);
163
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],
169 rlm[64];
170 afs_int32 maxLifetime;
171
172 sscanf(buffer, "%s %d %d %d %d %d %d %d %s", kaname, &flags, &exp,
173 &modtime, &modid, &cpwtime, &maxlife, &kvno, key);
174
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);
187
188 tentry.user_expiration = htonl(exp);
189
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);
194
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;
201 else
202 maxLifetime = 25 * 3600; /* regular users */
203 if (maxlife)
204 tentry.max_ticket_lifetime = htonl(maxlife);
205 else
206 tentry.max_ticket_lifetime = htonl(maxLifetime);
207
208 write(dbase_fd, &tentry, sizeof(tentry));
209 }
210 /*CheckInit(0,0); */
211 } else {
212 while (1) {
213 gpos = display_entry(upos * sizeof(struct kaentry));
214 if (gpos < 0)
215 break;
216 upos++;
217 }
218 }
219
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,
223 strerror(errno));
224 exit(1);
225 }
226 uh = (struct ubik_hdr *)buffer;
227 if ((uh->version.epoch != uv.epoch)
228 || (uh->version.counter != uv.counter)) {
229 fprintf(stderr,
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);
233 }
234 close(dbase_fd);
235 exit(0);
236 }
237
238 int
239 display_entry(offset)
240 int offset;
241 {
242 int i;
243 struct kaentry dbentry;
244 int count;
245 unsigned char x[8];
246 char thiskey[33];
247
248 if (lseek(dbase_fd, offset + HDRSIZE + sizeof(struct kaheader), L_SET) <
249 0)
250 return -1;
251 i = read(dbase_fd, &dbentry, sizeof(struct kaentry));
252 if (i < sizeof(struct kaentry))
253 return -1;
254 if (!strcmp(dbentry.userID.name, ""))
255 return 1;
256 memcpy(x, &dbentry.key, 8);
257
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]);
268 }
269
270 fprintf(dfp, "\n");
271 return 0;
272 }