]> andersk Git - moira.git/blob - afssync/pt_util.c
Attempt to preserve hidden status on all groups (not just those created)
[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         struct usr_list *u;
189
190         while(fgets(buffer, sizeof(buffer), dfp)) {
191             int id, oid, cid, flags, quota, uid;
192             char name[PR_MAXNAMELEN], mem[PR_MAXNAMELEN];
193
194             if (isspace(*buffer)) {
195                 sscanf(buffer, "%s %d", mem, &uid);
196                 for (u=usr_head; u; u=u->next)
197                     if (u->uid && u->uid==uid) break;
198                 if (u) {
199                     i = PR_INewEntry(u->cid, u->name, u->uid, u->oid);
200                     u->uid = 0;
201                     if (i) {
202                         fprintf(stderr, "Error while creating %s: %s\n",
203                                 name, error_message(i));
204                         continue;
205                     }
206                     i = PR_SetFieldsEntry(NULL, id,
207                                           ((flags&PRQUOTA)?PR_SF_NGROUPS:0)|
208                                           ((flags&PRACCESS)?PR_SF_ALLBITS:0),
209                                           flags >> PRIVATE_SHIFT,
210                                           quota, 0, 0, 0);
211                     if (i)
212                         fprintf(stderr, "Error while setting flags on %s\n",
213                                 name);
214                 }
215                 i = PR_AddToGroup(NULL,uid,id);
216                 if (i==0 || i==PRIDEXIST) continue;
217                 fprintf(stderr, "Error while adding %s to %s: %s\n",
218                         mem, name, error_message(i));
219             } else {
220                 sscanf(buffer, "%s %d/%d %d %d %d",
221                        name, &flags, &quota, &id, &oid, &cid);
222                 i = PR_INewEntry(cid, name, id, oid);
223                 if (i == PRBADNAM) {
224                     u = (struct usr_list *)malloc(sizeof(struct usr_list));
225                     u->next = usr_head;
226                     u->uid = id;
227                     u->oid = oid;
228                     u->cid = cid;
229                     u->flags = flags;
230                     u->quota = quota;
231                     strcpy(u->name, name);
232                     usr_head = u;
233                     continue;
234                 }
235                 if (i && i != PRIDEXIST) {
236                     fprintf(stderr, "Error while creating %s: %s\n",
237                             name, error_message(i));
238                     continue;
239                 }
240                 i = PR_SetFieldsEntry(NULL, id,
241                                       ((flags&PRQUOTA) ? PR_SF_NGROUPS : 0)|
242                                       ((flags&PRACCESS) ? PR_SF_ALLBITS : 0),
243                                       flags >> PRIVATE_SHIFT,
244                                       quota, 0, 0, 0);
245                 if (i)
246                     fprintf(stderr, "Error while setting flags on %s: %s\n",
247                             name, error_message(i));
248             }
249         }
250         for (u=usr_head; u; u=u->next)
251             if (u->uid)
252                 fprintf(stderr, "Error while creating %s: %s\n",
253                         u->name, error_message(PRBADNAM));
254     } else {
255         for (i = 0; i < HASHSIZE; i++) {
256             offset = nflag ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]);
257             while (offset)
258                 offset = display_entry(offset);
259         }
260         if (flags & DO_GRP)
261             display_groups();
262     }
263
264     lseek (dbase_fd, 0, L_SET);         /* rewind to beginning of file */
265     if (read(dbase_fd, buffer, HDRSIZE) < 0) {
266         fprintf(stderr, "ptdump: error reading %s: %s\n",
267                 pfile, sys_errlist[errno]);
268         exit (1);
269     }
270     uh = (struct ubik_hdr *)buffer;
271     if ((uh->version.epoch != uv.epoch) ||
272         (uh->version.counter != uv.counter)) {
273         fprintf(stderr, "ptdump: Ubik Version number changed during execution.\n");
274         fprintf(stderr, "Old Version = %d.%d, new version = %d.%d\n",
275                 uv.epoch, uv.counter, uh->version.epoch,
276                 uh->version.counter);
277     }
278     close (dbase_fd);
279     exit (0);
280 }
281
282 int display_entry (offset)
283 int offset;
284 {
285     register int i;
286
287     lseek (dbase_fd, offset+HDRSIZE, L_SET);
288     read(dbase_fd, &pre, sizeof(struct prentry));
289
290     fix_pre(&pre);
291
292     if ((pre.flags & PRFREE) == 0) {
293         if (pre.flags & PRGRP) {
294             if (flags & DO_GRP)
295                 add_group(pre.id);
296         } else {
297             if (print_id(pre.id) && (flags&DO_USR))
298                 fprintf(dfp, FMT_BASE,
299                         pre.name, pre.flags, pre.ngroups,
300                         pre.id, pre.owner, pre.creator);
301             checkin(&pre);
302         }
303     }
304     return(nflag ? pre.nextName: pre.nextID);
305 }
306
307 void add_group(id)
308     long id;
309 {
310     struct grp_list *g;
311     register long i;
312
313     i = grp_count++ % 1024;
314     if (i == 0) {
315         g = (struct grp_list *)malloc(sizeof(struct grp_list));
316         g->next = grp_head;
317         grp_head = g;
318     }
319     g = grp_head;
320     g->groups[i] = id;
321 }
322
323 void display_groups()
324 {
325     register int i, id;
326     struct grp_list *g;
327
328     g = grp_head;
329     while (grp_count--) {
330         i = grp_count%1024;
331         id = g->groups[i];
332         display_group(id);
333         if (i==0) {
334             grp_head = g->next;
335             free(g);
336             g = grp_head;
337         }
338     }
339 }
340
341 void display_group(id)
342     int id;
343 {
344     register int i, offset;
345     int print_grp = 0;
346
347     offset = ntohl(prh.idHash[IDHash(id)]);
348     while (offset) {
349         lseek(dbase_fd, offset+HDRSIZE, L_SET);
350         if (read(dbase_fd, &pre, sizeof(struct prentry)) < 0) {
351             fprintf(stderr, "ptdump: read i/o error: %s\n",
352                     strerror(errno));
353             exit (1);
354         }
355         fix_pre(&pre);
356         if (pre.id == id)
357             break;
358         offset = pre.nextID;
359     }
360
361     if (print_id(id)) {
362         fprintf(dfp, FMT_BASE,
363                 pre.name, pre.flags, pre.ngroups,
364                 pre.id, pre.owner, pre.creator);
365         print_grp = 1;
366     }
367
368     if ((flags&DO_MEM) == 0)
369         return;
370
371     for (i=0; i<PRSIZE; i++) {
372         if ((id=pre.entries[i]) == 0)
373             break;
374         if (id==PRBADID) continue;
375         if (print_id(id) || print_grp==1) {
376             if (print_grp==0) {
377                 fprintf(dfp, FMT_BASE,
378                         pre.name, pre.flags, pre.ngroups,
379                         pre.id, pre.owner, pre.creator);
380                 print_grp = 2;
381             }
382             fprintf(dfp, FMT_MEM, id_to_name(id), id);
383         }
384     }
385     if (i == PRSIZE) {
386         offset = pre.next;
387         while (offset) {
388             lseek(dbase_fd, offset+HDRSIZE, L_SET);
389             read(dbase_fd, &prco, sizeof(struct contentry));
390             prco.next = ntohl(prco.next);
391             for (i = 0; i < COSIZE; i++) {
392                 prco.entries[i] = ntohl(prco.entries[i]);
393                 if ((id=prco.entries[i]) == 0)
394                     break;
395                 if (id==PRBADID) continue;
396                 if (print_id(id) || print_grp==1) {
397                     if (print_grp==0) {
398                         fprintf(dfp, FMT_BASE,
399                                 pre.name, pre.flags, pre.ngroups,
400                                 pre.id, pre.owner, pre.creator);
401                         print_grp = 2;
402                     }
403                     fprintf(dfp, FMT_MEM, id_to_name(id), id);
404                 }
405             }
406             if ((i == COSIZE) && prco.next)
407                 offset = prco.next;
408             else offset = 0;
409         }
410     }
411 }
412
413 void fix_pre(pre)
414     struct prentry *pre;
415 {
416     register int i;
417     
418     pre->flags = ntohl(pre->flags);
419     pre->id = ntohl(pre->id);
420     pre->cellid = ntohl(pre->cellid);
421     pre->next = ntohl(pre->next);
422     pre->nextID = ntohl(pre->nextID);
423     pre->nextName = ntohl(pre->nextName);
424     pre->owner = ntohl(pre->owner);
425     pre->creator = ntohl(pre->creator);
426     pre->ngroups = ntohl(pre->ngroups);
427     pre->nusers = ntohl(pre->nusers);
428     pre->count = ntohl(pre->count);
429     pre->instance = ntohl(pre->instance);
430     pre->owned = ntohl(pre->owned);
431     pre->nextOwned = ntohl(pre->nextOwned);
432     pre->parent = ntohl(pre->parent);
433     pre->sibling = ntohl(pre->sibling);
434     pre->child = ntohl(pre->child);
435     for (i = 0; i < PRSIZE; i++) {
436         pre->entries[i] = ntohl(pre->entries[i]);
437     }
438 }
439
440 char *id_to_name(id)
441 int id;
442 {
443     register int offset;
444     static struct prentry pre;
445     char *name;
446
447     name = check_core(id);
448     if (name) return(name);
449     offset = ntohl(prh.idHash[IDHash(id)]);
450     while (offset) {
451         lseek(dbase_fd, offset+HDRSIZE, L_SET);
452         if (read(dbase_fd, &pre, sizeof(struct prentry)) < 0) {
453             fprintf(stderr, "ptdump: read i/o error: %s\n",
454                     sys_errlist[errno]);
455             exit (1);
456         }
457         pre.id = ntohl(pre.id);
458         if (pre.id == id) {
459             name = checkin(&pre);
460             return(name);
461         }
462         offset = ntohl(pre.nextID);
463     }
464     return 0;
465 }
466
467 char *checkin(pre)
468 struct prentry *pre;
469 {
470     struct hash_entry *he, *last;
471     register int id;
472
473     id = pre->id;
474     last = (struct hash_entry *)0;
475     he = hat[IDHash(id)];
476     while (he) {
477         if (id == he->h_id) return(he->h_name);
478         last = he;
479         he = he->next;
480     }
481     he = (struct hash_entry *)malloc(sizeof(struct hash_entry));
482     if (he == 0) {
483         fprintf(stderr, "ptdump: No Memory for internal hash table.\n");
484         exit (1);
485     }
486     he->h_id = id;
487     he->next = (struct hash_entry *)0;
488     strncpy(he->h_name, pre->name, PR_MAXNAMELEN);
489     if (last == (struct hash_entry *)0) hat[IDHash(id)] = he;
490     else last->next = he;
491     return(he->h_name);
492 }
493
494 char *check_core(id)
495 register int id;
496 {
497     struct hash_entry *he;
498     he = hat[IDHash(id)];
499     while (he) {
500         if (id == he->h_id) return(he->h_name);
501         he = he->next;
502     }
503     return 0;
504 }
This page took 0.096608 seconds and 5 git commands to generate.