introduce-ka-util-20020116
[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("$Header$");
23
24 #include <lock.h>
25 #include <netinet/in.h>
26 #define UBIK_INTERNALS
27 #include <ubik.h>
28 #include <rx/xdr.h>
29 #include <rx/rx.h>
30 #include <rx/rxkad.h>
31 #include "kauth.h"
32 #include "kaserver.h"
33 #include "kautils.h"
34
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)))
38
39 extern char *optarg;
40 extern int optind;
41 extern int errno;
42
43 int display_entry();
44
45 static struct kaheader kah;
46 static struct ubik_version uv;
47 struct kadstats dynamic_statistics;
48
49 char buffer[1024];
50 int dbase_fd;
51 FILE *dfp;
52
53 int nflag = 0;
54 int wflag = 0;
55 int flags = 0;
56
57 afs_int32 es_Report(){}
58
59 struct afsconf_dir *KA_conf;
60 struct ubik_dbase *KA_dbase;
61 int MinHours = 0;
62 int npwSums = KA_NPWSUMS;
63 afs_int32 verbose_track = 1;
64 afs_int32 myHost = 0;
65
66 main(argc, argv)
67 int argc;
68 char **argv;
69 {
70     register int i;
71     register long code;
72     long cc, upos=0, gpos;
73     struct ubik_hdr *uh;
74     struct timeval time;
75     char *dfile = 0;
76     char *pfile = "/usr/afs/db/kaserver.DB0";
77     
78     while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) {
79         switch (cc) {
80         case 'p':
81             pfile = optarg;
82             break;
83         case 'd':
84             dfile = optarg;
85             break;
86         case 'n':
87             nflag++;
88             break;
89         case 'w':
90             wflag++;
91             break;
92         default:
93             fprintf(stderr,
94                     "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", stderr);
101             fputs("    -s  Display only system data\n", stderr);
102             fputs("    -x  Display extra users/groups\n", stderr);
103             exit(1);
104         }
105     }
106     if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY)|O_CREAT, 0600)) 
107         < 0) {
108         fprintf(stderr, "ka_util: cannot open %s: %s\n",
109                 pfile, strerror(errno));
110         exit (1);
111     }
112     if (read(dbase_fd, buffer, HDRSIZE) < 0) {
113         fprintf(stderr, "ka_util: error reading %s: %s\n",
114                 pfile, strerror(errno));
115         exit (1);
116     }
117
118     if (dfile) {
119         if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) {
120             fprintf(stderr, "ka_util: error opening %s: %s\n",
121                     dfile, strerror(errno));
122             exit(1);
123         }
124     } else
125         dfp = (wflag ? stdin : stdout);
126
127     uh = (struct ubik_hdr *)buffer;
128     if (ntohl(uh->magic) != UBIK_MAGIC)
129         fprintf(stderr, "ka_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
130                 pfile, ntohl(uh->magic), UBIK_MAGIC);
131     memcpy(&uv, &uh->version, sizeof(struct ubik_version));
132     if (wflag && uv.epoch==0 && uv.counter==0) {
133         uv.epoch=2; /* a ubik version of 0 or 1 has special meaning */
134         memcpy(&uh->version, &uv, sizeof(struct ubik_version));
135         lseek(dbase_fd, 0, SEEK_SET);
136         if (write(dbase_fd, buffer, HDRSIZE) < 0) {
137             fprintf(stderr, "ka_util: error writing ubik version to %s: %s\n",
138                     pfile, strerror(errno));
139             exit (1);
140         }
141     }
142     fprintf(stderr, "Ubik Version is: %d.%d\n",
143             uv.epoch, uv.counter);
144     if (read(dbase_fd, &kah, sizeof(struct kaheader)) < 0) {
145         fprintf(stderr, "ka_util: error reading %s: %s\n",
146                 pfile, strerror(errno));
147         exit (1);
148     }
149
150     init_kaprocs(pfile,9);
151     initialize_KA_error_table();
152
153     if (wflag) {
154         while(fgets(buffer, sizeof(buffer), dfp)) {
155           struct kaentry tentry;
156           int flags, exp, modtime, modid, cpwtime, maxlife, kvno;
157           char kaname[64+64+2], key[33], name[64], instance[64];
158           afs_int32 maxLifetime;
159
160           sscanf(buffer, "%s %d %d %d %d %d %d %d %s",
161                  kaname, &flags, &exp, &modtime, &modid, &cpwtime, 
162                  &maxlife, &kvno, key);
163           
164           strncpy(tentry.userID.name, name, sizeof(tentry.userID.name));
165           strncpy(tentry.userID.instance, instance, sizeof(tentry.userID.instance));
166           tentry.flags = htonl(flags);
167           memcpy(&tentry.key, key, sizeof(tentry.key));
168           tentry.key_version = htonl(kvno);
169
170           tentry.user_expiration = htonl(exp);
171
172           /* time and addr of entry for guy changing this entry */
173           tentry.modification_time = htonl(modtime);
174           tentry.modification_id = htonl(modid);
175           tentry.change_password_time = htonl(cpwtime);
176
177           if (strcmp (name, KA_TGS_NAME) == 0) maxLifetime = MAXKTCTICKETLIFETIME;
178           else if (strcmp (name, KA_ADMIN_NAME) == 0) maxLifetime = 10*3600;
179           else if (strcmp (name, AUTH_SUPERUSER) == 0) maxLifetime = 100*3600;
180           else maxLifetime = 25*3600;         /* regular users */
181           if (maxlife) 
182             tentry.max_ticket_lifetime = htonl(maxlife);
183           else
184             tentry.max_ticket_lifetime = htonl(maxLifetime);
185
186           write(dbase_fd, &tentry, sizeof(&tentry));
187         }
188     } else {
189         while (1) {
190             gpos = display_entry(upos*sizeof(struct kaentry));
191             if (gpos < 0)
192                 break;
193             upos++;
194         }
195     }
196
197     lseek (dbase_fd, 0, L_SET);         /* rewind to beginning of file */
198     if (read(dbase_fd, buffer, HDRSIZE) < 0) {
199         fprintf(stderr, "ka_util: error reading %s: %s\n",
200                 pfile, strerror(errno));
201         exit (1);
202     }
203     uh = (struct ubik_hdr *)buffer;
204     if ((uh->version.epoch != uv.epoch) ||
205         (uh->version.counter != uv.counter)) {
206         fprintf(stderr, "ka_util: Ubik Version number changed during execution.\n");
207         fprintf(stderr, "Old Version = %d.%d, new version = %d.%d\n",
208                 uv.epoch, uv.counter, uh->version.epoch,
209                 uh->version.counter);
210     }
211     close (dbase_fd);
212     exit (0);
213 }
214
215 int display_entry (offset)
216 int offset;
217 {
218     register int i;
219     struct kaentry dbentry;
220     int count;
221     unsigned char x[8];
222     char thiskey[33];
223
224     if (lseek (dbase_fd, offset+HDRSIZE+sizeof(struct kaheader), L_SET) < 0)
225       return -1;
226     i = read(dbase_fd, &dbentry, sizeof(struct kaentry));
227     if (i<sizeof(struct kaentry)) 
228       return -1;
229     if(!strcmp(dbentry.userID.name, ""))
230       return 1;
231     memcpy(x, &dbentry.key, 8);
232
233     fprintf(dfp, "%s%s%s %d %d %d %d %d %d %d ",
234             dbentry.userID.name,
235             ((dbentry.userID.instance && strcmp(dbentry.userID.instance,"")) 
236              ? "." : ""),
237             ((dbentry.userID.instance && strcmp(dbentry.userID.instance,""))
238              ? dbentry.userID.instance : ""), dbentry.flags, 
239             dbentry.user_expiration, dbentry.modification_time,
240             dbentry.modification_id, dbentry.change_password_time,
241             dbentry.max_ticket_lifetime, dbentry.key_version);
242     for(count=0;count<8;count++)
243     {
244         fprintf(dfp, "\\%03o",(unsigned char *)x[count]);
245     }
246
247     fprintf(dfp, "\n");
248     return 0;
249 }
250