kauth: Don't overflow cell string
[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 }