reindent-20030715
[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
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <string.h>
17 #include <sys/file.h>
18
19 #include <afsconfig.h>
20 #include <afs/param.h>
21
22 RCSID
23     ("$Header$");
24
25 #include <lock.h>
26 #include <netinet/in.h>
27 #define UBIK_INTERNALS
28 #include <ubik.h>
29 #include <rx/xdr.h>
30 #include <rx/rx.h>
31 #include <rx/rxkad.h>
32 #include "kauth.h"
33 #include "kaserver.h"
34 #include "kautils.h"
35
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)))
39
40 extern char *optarg;
41 extern int optind;
42 extern int errno;
43
44 int display_entry();
45
46 static struct kaheader kah;
47 static struct ubik_version uv;
48 struct kadstats dynamic_statistics;
49
50 char buffer[1024];
51 int dbase_fd;
52 FILE *dfp;
53
54 int nflag = 0;
55 int wflag = 0;
56 int flags = 0;
57
58 afs_int32
59 es_Report()
60 {
61 }
62
63 struct afsconf_dir *KA_conf;
64 struct ubik_dbase *KA_dbase;
65 int MinHours = 0;
66 int npwSums = KA_NPWSUMS;
67 afs_int32 verbose_track = 1;
68 afs_int32 myHost = 0;
69
70 main(argc, argv)
71      int argc;
72      char **argv;
73 {
74     register int i;
75     register long code;
76     long cc, upos = 0, gpos;
77     struct ubik_hdr *uh;
78     char *dfile = 0;
79     char *pfile = "/usr/afs/db/kaserver.DB0";
80
81     while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) {
82         switch (cc) {
83         case 'p':
84             pfile = optarg;
85             break;
86         case 'd':
87             dfile = optarg;
88             break;
89         case 'n':
90             nflag++;
91             break;
92         case 'w':
93             wflag++;
94             break;
95         default:
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",
103                   stderr);
104             fputs("    -s  Display only system data\n", stderr);
105             fputs("    -x  Display extra users/groups\n", stderr);
106             exit(1);
107         }
108     }
109     if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY) | O_CREAT, 0600))
110         < 0) {
111         fprintf(stderr, "ka_util: cannot open %s: %s\n", pfile,
112                 strerror(errno));
113         exit(1);
114     }
115     if (read(dbase_fd, buffer, HDRSIZE) < 0) {
116         fprintf(stderr, "ka_util: error reading %s: %s\n", pfile,
117                 strerror(errno));
118         exit(1);
119     }
120
121     if (dfile) {
122         if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) {
123             fprintf(stderr, "ka_util: error opening %s: %s\n", dfile,
124                     strerror(errno));
125             exit(1);
126         }
127     } else
128         dfp = (wflag ? stdin : stdout);
129
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));
142             exit(1);
143         }
144     }
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,
148                 strerror(errno));
149         exit(1);
150     }
151
152     initialize_KA_error_table();
153
154     if (wflag) {
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));
160         header.freePtr = 0;
161         header.eofPtr = htonl(sizeof(header));
162         header.kvnoPtr = 0;
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);
170
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],
176                 rlm[64];
177             afs_int32 maxLifetime;
178
179             sscanf(buffer, "%s %d %d %d %d %d %d %d %s", kaname, &flags, &exp,
180                    &modtime, &modid, &cpwtime, &maxlife, &kvno, key);
181
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);
194
195             tentry.user_expiration = htonl(exp);
196
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);
201
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;
208             else
209                 maxLifetime = 25 * 3600;        /* regular users */
210             if (maxlife)
211                 tentry.max_ticket_lifetime = htonl(maxlife);
212             else
213                 tentry.max_ticket_lifetime = htonl(maxLifetime);
214
215             write(dbase_fd, &tentry, sizeof(tentry));
216         }
217         /*CheckInit(0,0); */
218     } else {
219         while (1) {
220             gpos = display_entry(upos * sizeof(struct kaentry));
221             if (gpos < 0)
222                 break;
223             upos++;
224         }
225     }
226
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,
230                 strerror(errno));
231         exit(1);
232     }
233     uh = (struct ubik_hdr *)buffer;
234     if ((uh->version.epoch != uv.epoch)
235         || (uh->version.counter != uv.counter)) {
236         fprintf(stderr,
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);
240     }
241     close(dbase_fd);
242     exit(0);
243 }
244
245 int
246 display_entry(offset)
247      int offset;
248 {
249     register int i;
250     struct kaentry dbentry;
251     int count;
252     unsigned char x[8];
253     char thiskey[33];
254
255     if (lseek(dbase_fd, offset + HDRSIZE + sizeof(struct kaheader), L_SET) <
256         0)
257         return -1;
258     i = read(dbase_fd, &dbentry, sizeof(struct kaentry));
259     if (i < sizeof(struct kaentry))
260         return -1;
261     if (!strcmp(dbentry.userID.name, ""))
262         return 1;
263     memcpy(x, &dbentry.key, 8);
264
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]);
275     }
276
277     fprintf(dfp, "\n");
278     return 0;
279 }