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