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