]> andersk Git - moira.git/blob - afssync/pt_util.c
Initial revision
[moira.git] / afssync / pt_util.c
1 /*
2  *
3  * ptdump: Program to dump the AFS protection 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 <strings.h>
17 #include <sys/file.h>
18
19 #include <afs/param.h>
20 #include <lock.h>
21 #include <netinet/in.h>
22 #define UBIK_INTERNALS
23 #include <ubik.h>
24 #include <rx/xdr.h>
25 #include <rx/rx.h>
26 #include "ptint.h"
27 #include "ptserver.h"
28 #include "pterror.h"
29
30 #define IDHash(x) (abs(x) % HASHSIZE)
31 #define print_id(x) ( ((flags&DO_SYS)==0 && (abs(x)>32767)) || \
32                       ((flags&DO_OTR)==0 && (abs(x)<32768)))
33
34 extern char *optarg;
35 extern int optind;
36 extern int errno;
37 extern char *sys_errlist[];
38 #define strerror(a) sys_errlist[a]
39
40 int display_entry();
41 void add_group();
42 void display_groups();
43 void display_group();
44 void fix_pre();
45 char *checkin();
46 char *check_core();
47 char *id_to_name();
48
49 struct hash_entry {
50     char h_name[PR_MAXNAMELEN];
51     int h_id;
52     struct hash_entry *next;
53 };
54 struct hash_entry *hat[HASHSIZE];
55
56 static struct contentry prco;
57 static struct prentry pre;
58 static struct prheader prh;
59 static struct ubik_version uv;
60
61 struct grp_list {
62     struct grp_list     *next;
63     long                groups[1024];
64 };
65 static struct grp_list *grp_head=0;
66 static long grp_count=0;
67
68 struct usr_list {
69     struct usr_list *next;
70     char name[PR_MAXNAMELEN];
71     long uid;
72     long oid;
73     long cid;
74     long flags;
75     int quota;
76 };
77 static struct usr_list *usr_head=0;
78
79 char buffer[1024];
80 int dbase_fd;
81 FILE *dfp;
82
83 #define FMT_BASE "%-10s %d/%d %d %d %d\n"
84 #define FMT_MEM  "   %-8s %d\n"
85
86 #define DO_USR 1
87 #define DO_GRP 2
88 #define DO_MEM 4
89 #define DO_SYS 8
90 #define DO_OTR 16
91
92 int nflag = 0;
93 int wflag = 0;
94 int flags = 0;
95
96 main(argc, argv)
97 int argc;
98 char **argv;
99 {
100     int cc;
101     int offset;
102     register int i;
103     register struct ubik_hdr *uh;
104     char *pfile = "/usr/afs/db/prdb.DB0";
105     char *dfile = 0;
106     
107     while ((cc = getopt(argc, argv, "wugmxsnp:d:")) != EOF) {
108         switch (cc) {
109         case 'p':
110             pfile = optarg;
111             break;
112         case 'd':
113             dfile = optarg;
114             break;
115         case 'n':
116             nflag++;
117             break;
118         case 'w':
119             wflag++;
120             break;
121         case 'u':
122             flags |= DO_USR;
123             break;
124         case 'm':
125             flags |= (DO_GRP|DO_MEM);
126             break;
127         case 'g':
128             flags |= DO_GRP;
129             break;
130         case 's':
131             flags |= DO_SYS;
132             break;
133         case 'x':
134             flags |= DO_OTR;
135             break;
136         default:
137             fprintf(stderr,
138                     "Usage: ptdump [options] [-d data] [-p prdb]\n");
139             fputs("  Options:\n", stderr);
140             fputs("    -w  Update prdb with contents of data file\n", stderr);
141             fputs("    -u  Display users\n", stderr);
142             fputs("    -g  Display groups\n", stderr);
143             fputs("    -m  Display group members\n", stderr);
144             fputs("    -n  Follow name hash chains (not id hashes)\n", stderr);
145             fputs("    -s  Display only system (Moira) data\n", stderr);
146             fputs("    -x  Display extra users/groups\n", stderr);
147             exit(1);
148         }
149     }
150     if ((dbase_fd = open(pfile, wflag ? O_RDWR : O_RDONLY, 0600)) < 0) {
151         fprintf(stderr, "ptdump: cannot open %s: %s\n",
152                 pfile, sys_errlist[errno]);
153         exit (1);
154     }
155     if (read(dbase_fd, buffer, HDRSIZE) < 0) {
156         fprintf(stderr, "ptdump: error reading %s: %s\n",
157                 pfile, sys_errlist[errno]);
158         exit (1);
159     }
160
161     if (dfile) {
162         if ((dfp = fopen(dfile, wflag ? "r" : "w")) == 0) {
163             fprintf(stderr, "ptdump: error opening %s: %s\n",
164                     dfile, sys_errlist[errno]);
165             exit(1);
166         }
167     } else
168         dfp = (wflag ? stdin : stdout);
169
170     uh = (struct ubik_hdr *)buffer;
171     if (ntohl(uh->magic) != UBIK_MAGIC)
172         fprintf(stderr, "ptdump: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
173                 pfile, ntohl(uh->magic), UBIK_MAGIC);
174     bcopy(&uh->version, &uv, sizeof(struct ubik_version));
175     fprintf(stderr, "Ubik Version is: %d.%d\n",
176             uv.epoch, uv.counter);
177     if (read(dbase_fd, &prh, sizeof(struct prheader)) < 0) {
178         fprintf(stderr, "ptdump: error reading %s: %s\n",
179                 pfile, sys_errlist[errno]);
180         exit (1);
181     }
182
183     initialize_pt_error_table();
184     initialize_rxk_error_table();
185     initialize_acfg_error_table();
186
187     if (wflag) {
188         while(fgets(buffer, sizeof(buffer), dfp)) {
189             struct usr_list *u;
190             int id, oid, cid, flags, quota, uid;
191             char name[PR_MAXNAMELEN], mem[PR_MAXNAMELEN];
192
193             if (isspace(*buffer)) {
194                 sscanf(buffer, "%s %d", mem, &uid);
195                 for (u=usr_head; u; u=u->next)
196                     if (u->uid && u->uid==uid) break;
197                 if (u) {
198                     i = PR_INewEntry(u->cid, u->name, u->uid, u->oid);
199                     u->uid = 0;
200                     if (i && i!=PRIDEXIST) {
201                         fprintf(stderr, "Error while creating %s: %s\n",
202                                 name, error_message(i));
203                         continue;
204                     }
205                     i = PR_SetFieldsEntry(NULL, id,
206                                           ((flags&PRQUOTA)?PR_SF_NGROUPS:0)|
207                                           ((flags&PRACCESS)?PR_SF_ALLBITS:0),
208                                           flags >> PRIVATE_SHIFT,
209                                           quota, 0, 0, 0);
210                     if (i)
211                         fprintf(stderr, "Error while setting flags on %s\n",
212                                 name);
213                 }
214                 i = PR_AddToGroup(NULL,uid,id);
215                 if (i==0 || i==PRIDEXIST) continue;
216                 fprintf(stderr, "Error while adding %s to %s\n", mem, name);
217             } else {
218                 sscanf(buffer, "%s %d/%d %d %d %d",
219                        name, &flags, &quota, &id, &oid, &cid);
220                 i = PR_INewEntry(cid, name, id, oid);
221                 if (i == PRBADNAM) {
222                     u = (struct usr_list *)malloc(sizeof(struct usr_list));
223                     u->next = usr_head;
224                     u->uid = id;
225                     u->oid = oid;
226                     u->cid = cid;
227                     u->flags = flags;
228                     u->quota = quota;
229                     strcpy(u->name, name);
230                     usr_head = u;
231                     continue;
232                 }
233                 if (i && i != PRIDEXIST) {
234                     fprintf(stderr, "Error while creating %s: %s\n",
235                             name, error_message(i));
236                     continue;
237                 }
238                 i = PR_SetFieldsEntry(NULL, id,
239                                       ((flags&PRQUOTA) ? PR_SF_NGROUPS : 0)|
240                                       ((flags&PRACCESS) ? PR_SF_ALLBITS : 0),
241                                       flags >> PRIVATE_SHIFT,
242                                       quota, 0, 0, 0);
243                 if (i)
244                     fprintf(stderr, "Error while setting flags on %s\n", name);
245             }
246         }
247     } else {
248         for (i = 0; i < HASHSIZE; i++) {
249             offset = nflag ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]);
250             while (offset)
251                 offset = display_entry(offset);
252         }
253         if (flags & DO_GRP)
254             display_groups();
255     }
256
257     lseek (dbase_fd, 0, L_SET);         /* rewind to beginning of file */
258     if (read(dbase_fd, buffer, HDRSIZE) < 0) {
259         fprintf(stderr, "ptdump: error reading %s: %s\n",
260                 pfile, sys_errlist[errno]);
261         exit (1);
262     }
263     uh = (struct ubik_hdr *)buffer;
264     if ((uh->version.epoch != uv.epoch) ||
265         (uh->version.counter != uv.counter)) {
266         fprintf(stderr, "ptdump: Ubik Version number changed during execution.\n");
267         fprintf(stderr, "Old Version = %d.%d, new version = %d.%d\n",
268                 uv.epoch, uv.counter, uh->version.epoch,
269                 uh->version.counter);
270     }
271     close (dbase_fd);
272     exit (0);
273 }
274
275 int display_entry (offset)
276 int offset;
277 {
278     register int i;
279
280     lseek (dbase_fd, offset+HDRSIZE, L_SET);
281     read(dbase_fd, &pre, sizeof(struct prentry));
282
283     fix_pre(&pre);
284
285     if ((pre.flags & PRFREE) == 0) {
286         if (pre.flags & PRGRP) {
287             if (flags & DO_GRP)
288                 add_group(pre.id);
289         } else {
290             if (print_id(pre.id) && (flags&DO_USR))
291                 fprintf(dfp, FMT_BASE,
292                         pre.name, pre.flags, pre.ngroups,
293                         pre.id, pre.owner, pre.creator);
294             checkin(&pre);
295         }
296     }
297     return(nflag ? pre.nextName: pre.nextID);
298 }
299
300 void add_group(id)
301     long id;
302 {
303     struct grp_list *g;
304     register long i;
305
306     i = grp_count++ % 1024;
307     if (i == 0) {
308         g = (struct grp_list *)malloc(sizeof(struct grp_list));
309         g->next = grp_head;
310         grp_head = g;
311     }
312     g = grp_head;
313     g->groups[i] = id;
314 }
315
316 void display_groups()
317 {
318     register int i, id;
319     struct grp_list *g;
320
321     g = grp_head;
322     while (grp_count--) {
323         i = grp_count%1024;
324         id = g->groups[i];
325         display_group(id);
326         if (i==0) {
327             grp_head = g->next;
328             free(g);
329             g = grp_head;
330         }
331     }
332 }
333
334 void display_group(id)
335     int id;
336 {
337     register int i, offset;
338     int print_grp = 0;
339
340     offset = ntohl(prh.idHash[IDHash(id)]);
341     while (offset) {
342         lseek(dbase_fd, offset+HDRSIZE, L_SET);
343         if (read(dbase_fd, &pre, sizeof(struct prentry)) < 0) {
344             fprintf(stderr, "ptdump: read i/o error: %s\n",
345                     strerror(errno));
346             exit (1);
347         }
348         fix_pre(&pre);
349         if (pre.id == id)
350             break;
351         offset = pre.nextID;
352     }
353
354     if (print_id(id)) {
355         fprintf(dfp, FMT_BASE,
356                 pre.name, pre.flags, pre.ngroups,
357                 pre.id, pre.owner, pre.creator);
358         print_grp = 1;
359     }
360
361     if ((flags&DO_MEM) == 0)
362         return;
363
364     for (i=0; i<PRSIZE; i++) {
365         if ((id=pre.entries[i]) == 0)
366             break;
367         if (id==PRBADID) continue;
368         if (print_id(id) || print_grp==1) {
369             if (print_grp==0) {
370                 fprintf(dfp, FMT_BASE,
371                         pre.name, pre.flags, pre.ngroups,
372                         pre.id, pre.owner, pre.creator);
373                 print_grp = 2;
374             }
375             fprintf(dfp, FMT_MEM, id_to_name(id), id);
376         }
377     }
378     if (i == PRSIZE) {
379         offset = pre.next;
380         while (offset) {
381             lseek(dbase_fd, offset+HDRSIZE, L_SET);
382             read(dbase_fd, &prco, sizeof(struct contentry));
383             prco.next = ntohl(prco.next);
384             for (i = 0; i < COSIZE; i++) {
385                 prco.entries[i] = ntohl(prco.entries[i]);
386                 if ((id=prco.entries[i]) == 0)
387                     break;
388                 if (id==PRBADID) continue;
389                 if (print_id(id) || print_grp==1) {
390                     if (print_grp==0) {
391                         fprintf(dfp, FMT_BASE,
392                                 pre.name, pre.flags, pre.ngroups,
393                                 pre.id, pre.owner, pre.creator);
394                         print_grp = 2;
395                     }
396                     fprintf(dfp, FMT_MEM, id_to_name(id), id);
397                 }
398             }
399             if ((i == COSIZE) && prco.next)
400                 offset = prco.next;
401             else offset = 0;
402         }
403     }
404 }
405
406 void fix_pre(pre)
407     struct prentry *pre;
408 {
409     register int i;
410     
411     pre->flags = ntohl(pre->flags);
412     pre->id = ntohl(pre->id);
413     pre->cellid = ntohl(pre->cellid);
414     pre->next = ntohl(pre->next);
415     pre->nextID = ntohl(pre->nextID);
416     pre->nextName = ntohl(pre->nextName);
417     pre->owner = ntohl(pre->owner);
418     pre->creator = ntohl(pre->creator);
419     pre->ngroups = ntohl(pre->ngroups);
420     pre->nusers = ntohl(pre->nusers);
421     pre->count = ntohl(pre->count);
422     pre->instance = ntohl(pre->instance);
423     pre->owned = ntohl(pre->owned);
424     pre->nextOwned = ntohl(pre->nextOwned);
425     pre->parent = ntohl(pre->parent);
426     pre->sibling = ntohl(pre->sibling);
427     pre->child = ntohl(pre->child);
428     for (i = 0; i < PRSIZE; i++) {
429         pre->entries[i] = ntohl(pre->entries[i]);
430     }
431 }
432
433 char *id_to_name(id)
434 int id;
435 {
436     register int offset;
437     static struct prentry pre;
438     char *name;
439
440     name = check_core(id);
441     if (name) return(name);
442     offset = ntohl(prh.idHash[IDHash(id)]);
443     while (offset) {
444         lseek(dbase_fd, offset+HDRSIZE, L_SET);
445         if (read(dbase_fd, &pre, sizeof(struct prentry)) < 0) {
446             fprintf(stderr, "ptdump: read i/o error: %s\n",
447                     sys_errlist[errno]);
448             exit (1);
449         }
450         pre.id = ntohl(pre.id);
451         if (pre.id == id) {
452             name = checkin(&pre);
453             return(name);
454         }
455         offset = ntohl(pre.nextID);
456     }
457     return 0;
458 }
459
460 char *checkin(pre)
461 struct prentry *pre;
462 {
463     struct hash_entry *he, *last;
464     register int id;
465
466     id = pre->id;
467     last = (struct hash_entry *)0;
468     he = hat[IDHash(id)];
469     while (he) {
470         if (id == he->h_id) return(he->h_name);
471         last = he;
472         he = he->next;
473     }
474     he = (struct hash_entry *)malloc(sizeof(struct hash_entry));
475     if (he == 0) {
476         fprintf(stderr, "ptdump: No Memory for internal hash table.\n");
477         exit (1);
478     }
479     he->h_id = id;
480     he->next = (struct hash_entry *)0;
481     strncpy(he->h_name, pre->name, PR_MAXNAMELEN);
482     if (last == (struct hash_entry *)0) hat[IDHash(id)] = he;
483     else last->next = he;
484     return(he->h_name);
485 }
486
487 char *check_core(id)
488 register int id;
489 {
490     struct hash_entry *he;
491     he = hat[IDHash(id)];
492     while (he) {
493         if (id == he->h_id) return(he->h_name);
494         he = he->next;
495     }
496     return 0;
497 }
This page took 0.135081 seconds and 5 git commands to generate.