convert-from-bsd-to-posix-string-and-memory-functions-20010807
[openafs.git] / src / afsweb / apache_afs_utils.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 /*
11  * This file contains routines common to both the client and the server-
12  * primarily an interface routine to the pioctl call
13  * and a routine for setting the primary flag in the token structure in
14  * order to create a new PAG while doing the SET TOKEN. In addition there are
15  * debugging routines of interest to both the client and server processes
16  */
17
18 #include "apache_afs_utils.h"
19 #include "apache_afs_utils.h"
20
21 /* 
22  * do_pioctl does the actual call to pioctl (or equivalent for that platform)
23  * sets up the ViceIoctl buffer with all the parameters required
24  * NOTE: in_buffer and out_buffer may point to the same memory buffer
25  */
26 int do_pioctl(char *in_buffer, int in_size, 
27               char *out_buffer, int out_size, 
28               int opcode, char *path, int followSymLinks)
29 {
30   struct ViceIoctl iob;
31   iob.in = in_buffer;
32   iob.in_size = in_size;
33   iob.out = out_buffer;
34   iob.out_size = out_size;
35   
36 #ifdef AFS_USR_SUN5_ENV
37   return syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, _VICEIOCTL(opcode), &iob, 
38                  followSymLinks);
39 #else /* AFS_USR_SUN5_ENV */
40   return lpioctl(path, _VICEIOCTL(opcode), &iob, followSymLinks);
41 #endif /* AFS_USR_SUN5_ENV */
42 }
43
44 int do_setpag()
45 {
46   return lsetpag();
47 }
48
49 /*
50  * Return 1 if we have a token, 0 if we don't
51  */
52 int haveToken()
53 {
54   char temp[1024]; 
55   afs_int32 i = 0;
56   int code;
57
58   memcpy((void *)temp, (void *)&i, sizeof(afs_int32));
59   code = do_pioctl(temp, sizeof(afs_int32), temp, sizeof(temp),VIOCGETTOK, NULL,0);
60   if (code) 
61     return 0;
62   else
63     return 1;
64 }
65
66
67 /* 
68  * flipPrimary sets the primary cell longword - 
69  * enabling a SETPAG if the same buffer is used with VICESETTOK 
70  */
71 flipPrimary(char *tokenBuf)
72 {
73   afs_int32 i;
74   char * temp = tokenBuf;
75
76   /* skip over the secret token */
77   memcpy(&i, temp, sizeof(afs_int32));
78   temp += (i + sizeof(afs_int32));
79
80   /* skip over the clear token */
81   memcpy(&i, temp, sizeof(afs_int32));
82   temp += (i + sizeof(afs_int32));
83   
84   /* set the primary flag */
85   memcpy(&i, temp, sizeof(afs_int32)); 
86   i |= 0x8000;
87   memcpy(temp, &i, sizeof(afs_int32));
88   temp += sizeof(afs_int32);
89   return 0;
90 }
91
92 /* get the current AFS pag for the calling process */ 
93 static afs_int32 curpag()
94 {
95   gid_t groups[30];
96   afs_uint32 g0, g1;
97   afs_uint32 h, l, ret;
98   
99   if (getgroups(sizeof groups/sizeof groups[0], groups) < 2) return 0;
100   
101   g0 = groups[0]  & 0xffff;
102   g1 = groups[1]  & 0xffff;
103   g0 -= 0x3f00;
104   g1 -= 0x3f00;
105   if (g0 < 0xc000 && g1 < 0xc000) {
106     l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
107     h = (g0 >> 14);
108     h = (g1 >> 14) + h + h + h;
109     ret = ((h << 28) | l);
110     /* Additional testing */
111     if (((ret >> 24) & 0xff) == 'A')
112       return ret;
113     else
114       return -1;
115   }
116   return -1;
117 }
118
119 /* Returns the AFS pag number, if any, otherwise return -1 */
120 afs_int32 getPAG()
121 {
122   afs_int32 pag;
123
124   assert(sizeof(afs_uint32) == 4);
125   assert(sizeof(afs_int32) == 4);
126
127   pag = curpag();
128   if (pag == 0 || pag == -1)
129     return -1;
130
131   /* high order byte is always 'A'; actual pag value is low 24 bits */
132   return (pag & 0xFFFFFF);
133 }
134
135 /*
136  * Write out the formatted string to the error log if the specified level
137  * is greater than or equal to the global afsDebugLevel which is set by
138  * the directive SetAFSDebugLevel in the httpd.conf file
139  */
140 /* VARARGS1 */
141 void afsLogError (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
142 char    * a;
143 char    * b;
144 char    * c;
145 char    * d;
146 char    * e;
147 char    * f;
148 char    * g;
149 char    * h;
150 char    * i;
151 char    * j;
152 char    * k;
153 char    * l;
154 char    * m;
155 char    * n;
156 {
157   char reason[1024];
158   
159   sprintf (reason, a,b,c,d,e,f,g,h,i,j,k,l,m,n);
160   /*  LOG_REASON(reason,r->uri,r); */
161   strcat(reason,"\n");
162   fprintf(stderr, reason);
163 }
164     
165
166 /* the following are debug utilities */
167
168 void hexDump(char *tbuffer, int len)
169 {
170   int i;
171   int byte;
172   char *temp = tbuffer;
173
174   fprintf(stderr, "HEXDUMP:\n");
175   for (i=0; i < len; i++) {
176     byte = *temp;
177     temp++;
178     fprintf(stderr, "%x",byte);
179   }
180   fprintf(stderr, "\n");
181 }
182
183 /* 
184  * debugging utility to see if the group id changes - if SETPAG worked 
185  * call this before and after the routine to dosetpag and verify results 
186  */
187
188 int printGroups()
189 {
190   int numGroups,i;
191   gid_t grouplist[NGROUPS_MAX];
192
193   numGroups = getgroups(NGROUPS_MAX, &grouplist[0]);
194   if (numGroups == -1) {
195     perror("getgroups:");
196     return -1;
197   }
198   for (i=0; i<numGroups; i++) {
199     fprintf(stderr, "grouplist[%d]=%d\n",i,grouplist[i]);
200   }
201   return 0;
202 }
203
204 /* 
205  * prints clear token fields, cell name and primary flag to stdout 
206  */
207
208 void parseToken(char *buf)
209 {
210   afs_int32 len=0;
211   char cellName[64];
212   register char *tp;
213
214   struct ClearToken {
215     afs_int32 AuthHandle;
216     char HandShakeKey[8];
217     afs_int32 ViceId;
218     afs_int32 BeginTimestamp;
219     afs_int32 EndTimestamp;
220   } clearToken;
221   
222   assert ( buf != NULL );
223
224   tp = buf;
225   memcpy(&len, tp, sizeof(afs_int32));    /* get size of secret token */
226   tp += (sizeof(afs_int32)+ len);        /* skip secret token */
227
228   memcpy(&len, tp, sizeof(afs_int32));    /* get size of clear token */
229   if (len != sizeof(struct ClearToken)) {
230     fprintf(stderr, "weblog:parseToken: error getting length of ClearToken\n");
231     return;
232   }
233   
234   tp += sizeof(afs_int32);                  /* skip length of cleartoken */
235   memcpy(&clearToken, tp, sizeof(struct ClearToken)); /* copy cleartoken */
236   
237   tp += len;                        /* skip clear token itself */
238
239   memcpy(&len, tp, sizeof(afs_int32));   /* copy the primary flag */
240   tp += sizeof(afs_int32);                  /* skip primary flag */
241
242   /* tp now points to the cell name */
243   strcpy(cellName, tp);
244
245   fprintf(stderr, "CellName:%s\n", cellName);
246   fprintf(stderr, "Primary Flag (Hex):%x\n", len);
247   fprintf(stderr, "ClearToken Fields:-\nAuthHandle=%d\n"
248           "ViceId=%d\nBeginTimestamp=%d\nEndTimestamp=%d\n",
249           clearToken.AuthHandle, clearToken.ViceId,
250           clearToken.BeginTimestamp,clearToken.EndTimestamp);
251 }