]>
Commit | Line | Data |
---|---|---|
96786087 | 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> | |
b4cd3401 | 16 | #include <string.h> |
96786087 | 17 | #include <sys/file.h> |
18 | #include <lock.h> | |
19 | #include <netinet/in.h> | |
20 | #define UBIK_INTERNALS | |
21 | #include <ubik.h> | |
22 | #include <rx/xdr.h> | |
23 | #include <rx/rx.h> | |
24 | #include <afs/ptint.h> | |
25 | #include <afs/ptserver.h> | |
26 | extern char *optarg; | |
27 | extern int optind; | |
28 | extern int errno; | |
29 | extern char *sys_errlist[]; | |
30 | struct prheader prh; | |
31 | struct prentry pre; | |
32 | struct ubik_version uv; | |
33 | char buffer[1024]; | |
34 | int grpflag, nmflg, cflag; | |
35 | ||
36 | main(argc, argv) | |
37 | int argc; | |
38 | char **argv; | |
39 | { | |
40 | int cc; | |
41 | int fd, offset; | |
42 | register int i; | |
43 | char file[512]; | |
44 | register struct ubik_hdr *uh; | |
45 | int didit; | |
c7e4633e | 46 | setvbuf(stdout, NULL, _IOLBF, BUFSIZ); |
96786087 | 47 | strcpy(file, "/usr/afs/db/prdb.DB0"); |
48 | while ((cc = getopt(argc, argv, "f:gnc")) != EOF) { | |
49 | switch (cc) { | |
50 | case 'f': | |
51 | strncpy (file, optarg, sizeof(file)); | |
52 | break; | |
53 | case 'g': | |
54 | grpflag++; | |
55 | break; | |
56 | case 'c': | |
57 | cflag++; | |
58 | break; | |
59 | case 'n': | |
60 | nmflg++; /* Use the Name hash chain */ | |
61 | break; | |
62 | default: | |
63 | fprintf(stderr, "ptdump: -%c: unknown option\n", cc); | |
64 | break; | |
65 | } | |
66 | } | |
67 | if (cflag && !grpflag) { | |
68 | fprintf(stderr, "ptdump: -c requires -g flag.\n"); | |
69 | exit (1); | |
70 | } | |
71 | if ((fd = open(file, O_RDONLY, 0600)) < 0) { | |
72 | fprintf(stderr, "ptdump: cannot open %s: %s\n", | |
73 | file, sys_errlist[errno]); | |
74 | exit (1); | |
75 | } | |
76 | if (read(fd, buffer, HDRSIZE) < 0) { | |
77 | fprintf(stderr, "ptdump: error reading %s: %s\n", | |
78 | file, sys_errlist[errno]); | |
79 | exit (1); | |
80 | } | |
81 | uh = (struct ubik_hdr *)buffer; | |
82 | if (ntohl(uh->magic) != UBIK_MAGIC) | |
83 | fprintf(stderr, "ptdump: %s: Bad UBIK_MAGIC. Is %x should be %x\n", | |
84 | file, ntohl(uh->magic), UBIK_MAGIC); | |
c7e4633e | 85 | memcpy(&uv, &uh->version, sizeof(struct ubik_version)); |
96786087 | 86 | fprintf(stderr, "Ubik Version is: %D.%d\n", |
87 | uv.epoch, uv.counter); | |
88 | if (read(fd, &prh, sizeof(struct prheader)) < 0) { | |
89 | fprintf(stderr, "ptdump: error reading %s: %s\n", | |
90 | file, sys_errlist[errno]); | |
91 | exit (1); | |
92 | } | |
93 | for (i = 0; i < HASHSIZE; i++) { | |
94 | offset = nmflg ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]); | |
95 | didit = 0; | |
96 | while (offset) | |
97 | offset = display_entry(offset, fd, &didit); | |
98 | } | |
99 | lseek (fd, 0, L_SET); /* rewind to beginning of file */ | |
100 | if (read(fd, buffer, HDRSIZE) < 0) { | |
101 | fprintf(stderr, "ptdump: error reading %s: %s\n", | |
102 | file, sys_errlist[errno]); | |
103 | exit (1); | |
104 | } | |
105 | uh = (struct ubik_hdr *)buffer; | |
106 | if ((uh->version.epoch != uv.epoch) || | |
107 | (uh->version.counter != uv.counter)) { | |
108 | fprintf(stderr, "ptdump: Ubik Version number changed during execution.\n"); | |
109 | fprintf(stderr, "Old Version = %D.%d, new version = %D.%d\n", | |
110 | uv.epoch, uv.counter, uh->version.epoch, | |
111 | uh->version.counter); | |
112 | } | |
113 | close (fd); | |
114 | exit (0); | |
115 | } | |
116 | int display_entry (offset, fd, didit) | |
117 | int offset, fd; | |
118 | int *didit; | |
119 | { | |
120 | void display_useful_groups(); | |
121 | char *checkin(); | |
122 | register int i; | |
123 | lseek (fd, offset+HDRSIZE, L_SET); | |
124 | read(fd, &pre, sizeof(struct prentry)); | |
125 | pre.flags = ntohl(pre.flags); | |
126 | pre.id = ntohl(pre.id); | |
127 | pre.cellid = ntohl(pre.cellid); | |
128 | pre.next = ntohl(pre.next); | |
129 | pre.nextID = ntohl(pre.nextID); | |
130 | pre.nextName = ntohl(pre.nextName); | |
131 | pre.owner = ntohl(pre.owner); | |
132 | pre.creator = ntohl(pre.creator); | |
133 | pre.ngroups = ntohl(pre.ngroups); | |
134 | pre.nusers = ntohl(pre.nusers); | |
135 | pre.count = ntohl(pre.count); | |
136 | pre.instance = ntohl(pre.instance); | |
137 | pre.owned = ntohl(pre.owned); | |
138 | pre.nextOwned = ntohl(pre.nextOwned); | |
139 | pre.parent = ntohl(pre.parent); | |
140 | pre.sibling = ntohl(pre.sibling); | |
141 | pre.child = ntohl(pre.child); | |
142 | for (i = 0; i < PRSIZE; i++) { | |
143 | pre.entries[i] = ntohl(pre.entries[i]); | |
144 | } | |
145 | if ((pre.flags & PRFREE) == 0) { /* A normal user */ | |
146 | if (cflag) (void) checkin(&pre); | |
147 | if (((pre.flags & PRGRP) && grpflag) || | |
148 | (((pre.flags & PRGRP) == 0) && !grpflag)) { | |
149 | if (!*didit && !cflag) { | |
150 | *didit = 1; | |
151 | printf("==========\n"); | |
152 | } | |
153 | if (!cflag) | |
154 | printf("Name: %s ID: %D\n", pre.name, pre.id); | |
155 | else display_useful_groups(&pre, fd); | |
156 | } | |
157 | } | |
158 | return(nmflg ? pre.nextName : pre.nextID); | |
159 | } | |
160 | static struct contentry prco; | |
161 | void display_useful_groups(pre, fd) | |
162 | register struct prentry *pre; | |
163 | int fd; | |
164 | { | |
165 | register int i; | |
166 | register int offset; | |
167 | char *id_to_name(); | |
168 | if (pre->entries[0] == 0) return; | |
169 | printf("Group: %s\n", pre->name); | |
170 | for (i = 0; i < PRSIZE; i++) { | |
171 | if (pre->entries[i] == 0) break; | |
8ca5eb7c | 172 | if (pre->entries[i] == PRBADID) continue; |
96786087 | 173 | printf(" Member: %s\n", id_to_name(pre->entries[i], fd)); |
174 | } | |
175 | if (i == PRSIZE) { | |
176 | offset = pre->next; | |
177 | while (offset) { | |
178 | lseek(fd, offset+HDRSIZE, L_SET); | |
179 | read(fd, &prco, sizeof(struct contentry)); | |
180 | prco.next = ntohl(prco.next); | |
181 | for (i = 0; i < COSIZE; i++) { | |
182 | prco.entries[i] = ntohl(prco.entries[i]); | |
183 | if (prco.entries[i] == 0) break; | |
8ca5eb7c | 184 | if (prco.entries[i] == PRBADID) continue; |
96786087 | 185 | printf(" Member(co): %s\n", id_to_name(prco.entries[i], fd)); |
186 | } | |
187 | if ((i == COSIZE) && prco.next) | |
188 | offset = prco.next; | |
189 | else offset = 0; | |
190 | } | |
191 | } | |
192 | } | |
193 | char *id_to_name(id, fd) | |
194 | int id; | |
195 | int fd; | |
196 | { | |
197 | register int offset; | |
198 | struct prentry pre; | |
199 | char *name; | |
200 | char *check_core(); | |
201 | char *checkin(); | |
202 | long IDHash(); | |
203 | name = check_core(id); | |
204 | if (name != NULL) return(name); | |
205 | offset = ntohl(prh.idHash[IDHash(id)]); | |
206 | if (offset == NULL) return("NOT FOUND"); | |
207 | while (offset) { | |
208 | lseek(fd, offset+HDRSIZE, L_SET); | |
209 | if (read(fd, &pre, sizeof(struct prentry)) < 0) { | |
210 | fprintf(stderr, "ptdump: read i/o error: %s\n", | |
211 | sys_errlist[errno]); | |
212 | exit (1); | |
213 | } | |
214 | pre.id = ntohl(pre.id); | |
215 | if (pre.id == id) { | |
216 | name = checkin(&pre); | |
217 | return(name); | |
218 | } | |
219 | offset = ntohl(pre.nextID); | |
220 | } | |
221 | return("NOT FOUND"); | |
222 | } | |
223 | struct hash_entry { | |
224 | char h_name[PR_MAXNAMELEN]; | |
225 | int h_id; | |
226 | struct hash_entry *next; | |
227 | }; | |
228 | struct hash_entry *hat[HASHSIZE]; | |
229 | char *checkin(pre) | |
230 | struct prentry *pre; | |
231 | { | |
232 | struct hash_entry *he, *last; | |
233 | register int id; | |
234 | long IDHash(); | |
235 | id = pre->id; | |
236 | last = (struct hash_entry *)0; | |
237 | he = hat[IDHash(id)]; | |
238 | while (he) { | |
239 | if (id == he->h_id) return(he->h_name); | |
240 | last = he; | |
241 | he = he->next; | |
242 | } | |
243 | he = (struct hash_entry *)malloc(sizeof(struct hash_entry)); | |
244 | if (he == NULL) { | |
245 | fprintf(stderr, "ptdump: No Memory for internal hash table.\n"); | |
246 | exit (1); | |
247 | } | |
248 | he->h_id = id; | |
249 | he->next = (struct hash_entry *)0; | |
250 | strncpy(he->h_name, pre->name, PR_MAXNAMELEN); | |
251 | if (last == (struct hash_entry *)0) hat[IDHash(id)] = he; | |
252 | else last->next = he; | |
253 | return(he->h_name); | |
254 | } | |
255 | char *check_core(id) | |
256 | register int id; | |
257 | { | |
258 | struct hash_entry *he; | |
259 | long IDHash(); | |
260 | he = hat[IDHash(id)]; | |
261 | while (he) { | |
262 | if (id == he->h_id) return(he->h_name); | |
263 | he = he->next; | |
264 | } | |
265 | return(NULL); | |
266 | } | |
267 | ||
268 | long IDHash(x) | |
269 | long x; | |
270 | { | |
271 | /* returns hash bucket for x */ | |
272 | return ((abs(x)) % HASHSIZE); | |
273 | } |