Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | #include <afsconfig.h> | |
11 | #include <afs/param.h> | |
12 | ||
13 | #include <roken.h> | |
14 | ||
15 | #include <afs/afs_consts.h> | |
16 | #include <afs/vice.h> | |
17 | #include <afs/afsint.h> | |
18 | #include <afs/venus.h> | |
19 | #include <rx/xdr.h> | |
20 | ||
21 | #include "rmtsys.h" | |
22 | ||
23 | ||
24 | /* | |
25 | * We deal with converting pioctl parameters between host and network order. | |
26 | * Painful but somebody has to do this and pioctl is the best place rather than | |
27 | * leaving it to the calling application programs! | |
28 | */ | |
29 | ||
30 | #define MAXNAME 100 | |
31 | #define MAXGCSIZE 16 | |
32 | ||
33 | struct Acl { | |
34 | int nplus; | |
35 | int nminus; | |
36 | struct AclEntry *pluslist; | |
37 | struct AclEntry *minuslist; | |
38 | }; | |
39 | ||
40 | struct AclEntry { | |
41 | struct AclEntry *next; | |
42 | char name[MAXNAME]; | |
43 | afs_int32 rights; | |
44 | }; | |
45 | ||
46 | struct ClearToken { | |
47 | afs_int32 AuthHandle; | |
48 | char HandShakeKey[8]; | |
49 | afs_int32 ViceId; | |
50 | afs_int32 BeginTimestamp; | |
51 | afs_int32 EndTimestamp; | |
52 | }; | |
53 | ||
54 | char * | |
55 | RSkipLine(char *astr) | |
56 | { | |
57 | while (*astr != '\n') | |
58 | astr++; | |
59 | astr++; | |
60 | return astr; | |
61 | } | |
62 | ||
63 | ||
64 | struct Acl * | |
65 | RParseAcl(char *astr) | |
66 | { | |
67 | int nplus, nminus, i, trights; | |
68 | char tname[MAXNAME]; | |
69 | struct AclEntry *first, *last, *tl; | |
70 | struct Acl *ta; | |
71 | sscanf(astr, "%d", &nplus); | |
72 | astr = RSkipLine(astr); | |
73 | sscanf(astr, "%d", &nminus); | |
74 | astr = RSkipLine(astr); | |
75 | ||
76 | ta = malloc(sizeof(struct Acl)); | |
77 | ta->nplus = nplus; | |
78 | ta->nminus = nminus; | |
79 | ||
80 | last = 0; | |
81 | first = 0; | |
82 | for (i = 0; i < nplus; i++) { | |
83 | sscanf(astr, "%100s %d", tname, &trights); | |
84 | astr = RSkipLine(astr); | |
85 | tl = malloc(sizeof(struct AclEntry)); | |
86 | if (!first) | |
87 | first = tl; | |
88 | strcpy(tl->name, tname); | |
89 | tl->rights = trights; | |
90 | tl->next = 0; | |
91 | if (last) | |
92 | last->next = tl; | |
93 | last = tl; | |
94 | } | |
95 | ta->pluslist = first; | |
96 | ||
97 | last = 0; | |
98 | first = 0; | |
99 | for (i = 0; i < nminus; i++) { | |
100 | sscanf(astr, "%100s %d", tname, &trights); | |
101 | astr = RSkipLine(astr); | |
102 | tl = malloc(sizeof(struct AclEntry)); | |
103 | if (!first) | |
104 | first = tl; | |
105 | strcpy(tl->name, tname); | |
106 | tl->rights = trights; | |
107 | tl->next = 0; | |
108 | if (last) | |
109 | last->next = tl; | |
110 | last = tl; | |
111 | } | |
112 | ta->minuslist = first; | |
113 | ||
114 | return ta; | |
115 | } | |
116 | ||
117 | ||
118 | void | |
119 | RAclToString(struct Acl *acl, char *mydata, int ntoh_conv) | |
120 | { | |
121 | char tstring[AFS_PIOCTL_MAXSIZE]; | |
122 | struct AclEntry *tp; | |
123 | ||
124 | /* No conversion needed since they're in network order in the first place */ | |
125 | sprintf(mydata, "%d\n%d\n", acl->nplus, acl->nminus); | |
126 | for (tp = acl->pluslist; tp; tp = tp->next) { | |
127 | sprintf(tstring, "%s %d\n", tp->name, tp->rights); | |
128 | strcat(mydata, tstring); | |
129 | } | |
130 | for (tp = acl->minuslist; tp; tp = tp->next) { | |
131 | sprintf(tstring, "%s %d\n", tp->name, tp->rights); | |
132 | strcat(mydata, tstring); | |
133 | } | |
134 | } | |
135 | ||
136 | ||
137 | /* Free all malloced stuff */ | |
138 | void | |
139 | RCleanAcl(struct Acl *aa) | |
140 | { | |
141 | struct AclEntry *te, *ne; | |
142 | ||
143 | for (te = aa->pluslist; te; te = ne) { | |
144 | ne = te->next; | |
145 | free(te); | |
146 | } | |
147 | for (te = aa->minuslist; te; te = ne) { | |
148 | ne = te->next; | |
149 | free(te); | |
150 | } | |
151 | free(aa); | |
152 | } | |
153 | ||
154 | ||
155 | void | |
156 | RFetchVolumeStatus_conversion(char *data, int ntoh_conv) | |
157 | { | |
158 | struct AFSFetchVolumeStatus *status = (AFSFetchVolumeStatus *) data; | |
159 | ||
160 | if (ntoh_conv) { /* Network -> Host */ | |
161 | status->Vid = ntohl(status->Vid); | |
162 | status->ParentId = ntohl(status->ParentId); | |
163 | #ifdef notdef | |
164 | /* save cycles */ | |
165 | status->OnLine = status->OnLine; | |
166 | status->InService = status->InService; | |
167 | status->Blessed = status->Blessed; | |
168 | status->NeedsSalvage = status->NeedsSalvage; | |
169 | #endif | |
170 | status->Type = ntohl(status->Type); | |
171 | status->MinQuota = ntohl(status->MinQuota); | |
172 | status->MaxQuota = ntohl(status->MaxQuota); | |
173 | status->BlocksInUse = ntohl(status->BlocksInUse); | |
174 | status->PartBlocksAvail = ntohl(status->PartBlocksAvail); | |
175 | status->PartMaxBlocks = ntohl(status->PartMaxBlocks); | |
176 | } else { /* Host -> Network */ | |
177 | status->Vid = htonl(status->Vid); | |
178 | status->ParentId = htonl(status->ParentId); | |
179 | #ifdef notdef | |
180 | /* save cycles */ | |
181 | status->OnLine = status->OnLine; | |
182 | status->InService = status->InService; | |
183 | status->Blessed = status->Blessed; | |
184 | status->NeedsSalvage = status->NeedsSalvage; | |
185 | #endif | |
186 | status->Type = htonl(status->Type); | |
187 | status->MinQuota = htonl(status->MinQuota); | |
188 | status->MaxQuota = htonl(status->MaxQuota); | |
189 | status->BlocksInUse = htonl(status->BlocksInUse); | |
190 | status->PartBlocksAvail = htonl(status->PartBlocksAvail); | |
191 | status->PartMaxBlocks = htonl(status->PartMaxBlocks); | |
192 | } | |
193 | } | |
194 | ||
195 | void | |
196 | RClearToken_convert(char *ptr, int ntoh_conv) | |
197 | { | |
198 | struct ClearToken *ticket = (struct ClearToken *)ptr; | |
199 | ||
200 | if (ntoh_conv) { /* Network -> host */ | |
201 | ticket->AuthHandle = ntohl(ticket->AuthHandle); | |
202 | ticket->ViceId = ntohl(ticket->ViceId); | |
203 | ticket->BeginTimestamp = ntohl(ticket->BeginTimestamp); | |
204 | ticket->EndTimestamp = ntohl(ticket->EndTimestamp); | |
205 | } else { /* Host -> Network */ | |
206 | ticket->AuthHandle = htonl(ticket->AuthHandle); | |
207 | ticket->ViceId = htonl(ticket->ViceId); | |
208 | ticket->BeginTimestamp = htonl(ticket->BeginTimestamp); | |
209 | ticket->EndTimestamp = htonl(ticket->EndTimestamp); | |
210 | } | |
211 | } | |
212 | ||
213 | void | |
214 | inparam_conversion(afs_int32 cmd, char *buffer, afs_int32 ntoh_conv) | |
215 | { | |
216 | struct Acl *acl; | |
217 | afs_int32 *lptr, i; | |
218 | char *ptr; | |
219 | ||
220 | switch (cmd & 0xffff) { | |
221 | case VIOCSETAL & 0xffff: | |
222 | acl = RParseAcl(buffer); | |
223 | RAclToString(acl, buffer, ntoh_conv); | |
224 | RCleanAcl(acl); | |
225 | break; | |
226 | case VIOCSETTOK & 0xffff: | |
227 | lptr = (afs_int32 *) buffer; | |
228 | /* i is sizeof of the secret ticket */ | |
229 | if (ntoh_conv) { | |
230 | i = ntohl(*lptr); | |
231 | *lptr = i; | |
232 | } else { | |
233 | i = *lptr; | |
234 | *lptr = htonl(i); | |
235 | } | |
236 | lptr++; | |
237 | ptr = (char *)lptr; | |
238 | ptr += i; /* skip over the ticket */ | |
239 | lptr = (afs_int32 *) ptr; | |
240 | /* i is now size of the clear token */ | |
241 | if (ntoh_conv) { | |
242 | i = ntohl(*lptr); | |
243 | *lptr = i; | |
244 | } else { | |
245 | i = *lptr; | |
246 | *lptr = htonl(i); | |
247 | } | |
248 | lptr++; | |
249 | ptr = (char *)lptr; | |
250 | RClearToken_convert(ptr, ntoh_conv); | |
251 | ptr += i; /* sizeof(struct ClearToken) */ | |
252 | lptr = (afs_int32 *) ptr; | |
253 | if (ntoh_conv) | |
254 | *lptr = ntohl(*lptr); | |
255 | else | |
256 | *lptr = htonl(*lptr); | |
257 | lptr++; /* primary flag */ | |
258 | break; | |
259 | case VIOCSETVOLSTAT & 0xffff: | |
260 | RFetchVolumeStatus_conversion(buffer, ntoh_conv); | |
261 | break; | |
262 | case VIOCGETTOK & 0xffff: | |
263 | case VIOCCKSERV & 0xffff: | |
264 | case VIOCACCESS & 0xffff: | |
265 | case VIOCSETCACHESIZE & 0xffff: | |
266 | case VIOCGETCELL & 0xffff: | |
267 | case VIOC_AFS_MARINER_HOST & 0xffff: | |
268 | case VIOC_VENUSLOG & 0xffff: | |
269 | case VIOC_AFS_SYSNAME & 0xffff: | |
270 | case VIOC_EXPORTAFS & 0xffff: | |
271 | lptr = (afs_int32 *) buffer; | |
272 | if (ntoh_conv) | |
273 | *lptr = ntohl(*lptr); | |
274 | else | |
275 | *lptr = htonl(*lptr); | |
276 | break; | |
277 | case VIOC_SETCELLSTATUS & 0xffff: | |
278 | lptr = (afs_int32 *) buffer; | |
279 | if (ntoh_conv) | |
280 | *lptr = ntohl(*lptr); | |
281 | else | |
282 | *lptr = htonl(*lptr); | |
283 | lptr++; | |
284 | if (ntoh_conv) | |
285 | *lptr = ntohl(*lptr); | |
286 | else | |
287 | *lptr = htonl(*lptr); | |
288 | break; | |
289 | case VIOCGETAL & 0xffff: | |
290 | case VIOCGETVOLSTAT & 0xffff: | |
291 | case VIOCGETCACHEPARMS & 0xffff: | |
292 | case VIOCFLUSH & 0xffff: | |
293 | case VIOCSTAT & 0xffff: | |
294 | case VIOCUNLOG & 0xffff: | |
295 | case VIOCCKBACK & 0xffff: | |
296 | case VIOCCKCONN & 0xffff: | |
297 | case VIOCGETTIME & 0xffff: /* Obsolete */ | |
298 | case VIOCWHEREIS & 0xffff: | |
299 | case VIOCPREFETCH & 0xffff: | |
300 | case VIOCNOP & 0xffff: /* Obsolete */ | |
301 | case VIOCENGROUP & 0xffff: /* Obsolete */ | |
302 | case VIOCDISGROUP & 0xffff: /* Obsolete */ | |
303 | case VIOCLISTGROUPS & 0xffff: /* Obsolete */ | |
304 | case VIOCUNPAG & 0xffff: | |
305 | case VIOCWAITFOREVER & 0xffff: /* Obsolete */ | |
306 | case VIOCFLUSHCB & 0xffff: | |
307 | case VIOCNEWCELL & 0xffff: | |
308 | case VIOC_AFS_DELETE_MT_PT & 0xffff: | |
309 | case VIOC_AFS_STAT_MT_PT & 0xffff: | |
310 | case VIOC_FILE_CELL_NAME & 0xffff: | |
311 | case VIOC_GET_WS_CELL & 0xffff: | |
312 | case VIOC_GET_PRIMARY_CELL & 0xffff: | |
313 | case VIOC_GETCELLSTATUS & 0xffff: | |
314 | case VIOC_FLUSHVOLUME & 0xffff: | |
315 | case VIOCGETFID & 0xffff: /* nothing yet */ | |
316 | break; | |
317 | default: | |
318 | /* Note that new pioctls are supposed to be in network order! */ | |
319 | break; | |
320 | } | |
321 | } | |
322 | ||
323 | ||
324 | void | |
325 | outparam_conversion(afs_int32 cmd, char *buffer, afs_int32 ntoh_conv) | |
326 | { | |
327 | struct Acl *acl; | |
328 | afs_int32 *lptr, i; | |
329 | char *ptr; | |
330 | ||
331 | switch (cmd & 0xffff) { | |
332 | case VIOCGETAL & 0xffff: | |
333 | acl = RParseAcl(buffer); | |
334 | RAclToString(acl, buffer, ntoh_conv); | |
335 | RCleanAcl(acl); | |
336 | break; | |
337 | case VIOCGETVOLSTAT & 0xffff: | |
338 | RFetchVolumeStatus_conversion(buffer, ntoh_conv); | |
339 | break; | |
340 | case VIOCSETVOLSTAT & 0xffff: | |
341 | RFetchVolumeStatus_conversion(buffer, ntoh_conv); | |
342 | break; | |
343 | case VIOCGETTOK & 0xffff: | |
344 | lptr = (afs_int32 *) buffer; | |
345 | /* i is set to sizeof secret ticket */ | |
346 | if (ntoh_conv) { | |
347 | i = ntohl(*lptr); | |
348 | *lptr = i; | |
349 | } else { | |
350 | i = *lptr; | |
351 | *lptr = htonl(i); | |
352 | } | |
353 | lptr++; | |
354 | ptr = (char *)lptr; | |
355 | ptr += i; /* skip over the ticket */ | |
356 | lptr = (afs_int32 *) ptr; | |
357 | /* i is set to sizeof clear ticket */ | |
358 | if (ntoh_conv) { | |
359 | i = ntohl(*lptr); | |
360 | *lptr = i; | |
361 | } else { | |
362 | i = *lptr; | |
363 | *lptr = htonl(i); | |
364 | } | |
365 | lptr++; | |
366 | ptr = (char *)lptr; | |
367 | RClearToken_convert(ptr, ntoh_conv); | |
368 | ptr += i; /* sizeof(struct ClearToken) */ | |
369 | lptr = (afs_int32 *) ptr; | |
370 | if (ntoh_conv) | |
371 | *lptr = ntohl(*lptr); | |
372 | else | |
373 | *lptr = htonl(*lptr); | |
374 | lptr++; /* primary flag */ | |
375 | break; | |
376 | case VIOCCKCONN & 0xffff: | |
377 | case VIOC_AFS_MARINER_HOST & 0xffff: | |
378 | case VIOC_VENUSLOG & 0xffff: | |
379 | case VIOC_GETCELLSTATUS & 0xffff: | |
380 | case VIOC_AFS_SYSNAME & 0xffff: | |
381 | case VIOC_EXPORTAFS & 0xffff: | |
382 | lptr = (afs_int32 *) buffer; | |
383 | if (ntoh_conv) | |
384 | *lptr = ntohl(*lptr); | |
385 | else | |
386 | *lptr = htonl(*lptr); | |
387 | break; | |
388 | case VIOCGETCACHEPARMS & 0xffff: | |
389 | lptr = (afs_int32 *) buffer; | |
390 | for (i = 0; i < MAXGCSIZE; i++, lptr++) { | |
391 | if (ntoh_conv) | |
392 | *lptr = ntohl(*lptr); | |
393 | else | |
394 | *lptr = htonl(*lptr); | |
395 | } | |
396 | break; | |
397 | case VIOCUNLOG & 0xffff: | |
398 | case VIOCCKSERV & 0xffff: /* Already in network order */ | |
399 | case VIOCCKBACK & 0xffff: | |
400 | case VIOCGETTIME & 0xffff: /* Obsolete */ | |
401 | case VIOCWHEREIS & 0xffff: /* Already in network order */ | |
402 | case VIOCPREFETCH & 0xffff: | |
403 | case VIOCNOP & 0xffff: /* Obsolete */ | |
404 | case VIOCENGROUP & 0xffff: /* Obsolete */ | |
405 | case VIOCDISGROUP & 0xffff: /* Obsolete */ | |
406 | case VIOCLISTGROUPS & 0xffff: /* Obsolete */ | |
407 | case VIOCACCESS & 0xffff: | |
408 | case VIOCUNPAG & 0xffff: | |
409 | case VIOCWAITFOREVER & 0xffff: /* Obsolete */ | |
410 | case VIOCSETCACHESIZE & 0xffff: | |
411 | case VIOCFLUSHCB & 0xffff: | |
412 | case VIOCNEWCELL & 0xffff: | |
413 | case VIOCGETCELL & 0xffff: /* Already in network order */ | |
414 | case VIOC_AFS_DELETE_MT_PT & 0xffff: | |
415 | case VIOC_AFS_STAT_MT_PT & 0xffff: | |
416 | case VIOC_FILE_CELL_NAME & 0xffff: /* no need to convert */ | |
417 | case VIOC_GET_WS_CELL & 0xffff: /* no need to convert */ | |
418 | case VIOCGETFID & 0xffff: /* nothing yet */ | |
419 | case VIOCSETAL & 0xffff: | |
420 | case VIOCFLUSH & 0xffff: | |
421 | case VIOCSTAT & 0xffff: | |
422 | case VIOCSETTOK & 0xffff: | |
423 | case VIOC_GET_PRIMARY_CELL & 0xffff: /* The cell is returned here */ | |
424 | case VIOC_SETCELLSTATUS & 0xffff: | |
425 | case VIOC_FLUSHVOLUME & 0xffff: | |
426 | break; | |
427 | default: | |
428 | /* Note that new pioctls are supposed to be in network order! */ | |
429 | break; | |
430 | } | |
431 | } |