2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h"
17 #include "afs/unified_afs.h"
18 #include "rx/rx_globals.h"
23 struct afspag_cell *next;
28 afs_rwlock_t afs_xpagcell;
29 afs_rwlock_t afs_xpagsys;
30 static int lastcell = 0;
31 static struct afspag_cell *cells = 0;
32 static struct afspag_cell *primary_cell = 0;
35 struct afspag_cell *afspag_GetCell(char *acell)
37 struct afspag_cell *tcell;
39 ObtainWriteLock(&afs_xpagcell, 820);
41 for (tcell = cells; tcell; tcell = tcell->next) {
42 if (!strcmp(acell, tcell->cellname))
47 tcell = (struct afspag_cell *)afs_osi_Alloc(sizeof(struct afspag_cell));
50 tcell->cellname = (char *)afs_osi_Alloc(strlen(acell) + 1);
51 if (!tcell->cellname) {
52 afs_osi_Free(tcell, sizeof(struct afspag_cell));
56 strcpy(tcell->cellname, acell);
57 tcell->cellnum = ++lastcell;
60 if (!primary_cell) primary_cell = tcell;
64 ReleaseWriteLock(&afs_xpagcell);
69 struct afspag_cell *afspag_GetPrimaryCell()
71 struct afspag_cell *tcell;
73 ObtainWriteLock(&afs_xpagcell, 821);
75 ReleaseWriteLock(&afs_xpagcell);
80 void afspag_SetPrimaryCell(char *acell)
82 struct afspag_cell *tcell;
84 tcell = afspag_GetCell(acell);
85 ObtainWriteLock(&afs_xpagcell, 822);
87 ReleaseWriteLock(&afs_xpagcell);
91 int afspag_PUnlog(char *ain, afs_int32 ainSize, afs_ucred_t **acred)
94 register struct unixuser *tu;
98 if (!afs_resourceinit_flag) /* afs daemons haven't started yet */
99 return EIO; /* Inappropriate ioctl for device */
101 pag = PagInCred(*acred);
102 uid = (pag == NOPAG) ? (*acred)->cr_uid : pag;
104 ObtainWriteLock(&afs_xuser, 823);
105 for (tu = afs_users[i]; tu; tu = tu->next) {
106 if (tu->uid == uid) {
108 tu->states &= ~UHasTokens;
109 /* security is not having to say you're sorry */
110 memset((char *)&tu->ct, 0, sizeof(struct ClearToken));
112 /* set the expire times to 0, causes
113 * afs_GCUserData to remove this entry
115 tu->ct.EndTimestamp = 0;
120 ReleaseWriteLock(&afs_xuser);
125 int afspag_PSetTokens(char *ain, afs_int32 ainSize, afs_ucred_t **acred)
128 register struct unixuser *tu;
129 struct afspag_cell *tcell;
130 struct ClearToken clear;
133 afs_int32 flag, set_parent_pag = 0;
136 AFS_STATCNT(PSetTokens);
137 if (!afs_resourceinit_flag) {
140 memcpy((char *)&i, ain, sizeof(afs_int32));
141 ain += sizeof(afs_int32);
142 stp = ain; /* remember where the ticket is */
143 if (i < 0 || i > MAXKTCTICKETLEN)
144 return EINVAL; /* malloc may fail */
146 ain += i; /* skip over ticket */
147 memcpy((char *)&i, ain, sizeof(afs_int32));
148 ain += sizeof(afs_int32);
149 if (i != sizeof(struct ClearToken)) {
152 memcpy((char *)&clear, ain, sizeof(struct ClearToken));
153 if (clear.AuthHandle == -1)
154 clear.AuthHandle = 999; /* more rxvab compat stuff */
155 ain += sizeof(struct ClearToken);
156 if (ainSize != 2 * sizeof(afs_int32) + stLen + sizeof(struct ClearToken)) {
157 /* still stuff left? we've got primary flag and cell name. Set these */
158 memcpy((char *)&flag, ain, sizeof(afs_int32)); /* primary id flag */
159 ain += sizeof(afs_int32); /* skip id field */
160 /* rest is cell name, look it up */
161 /* some versions of gcc appear to need != 0 in order to get this right */
162 if ((flag & 0x8000) != 0) { /* XXX Use Constant XXX */
166 tcell = afspag_GetCell(ain);
168 /* default to primary cell, primary id */
169 flag = 1; /* primary id */
170 tcell = afspag_GetPrimaryCell();
172 if (!tcell) return ESRCH;
173 if (set_parent_pag) {
174 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
175 #if defined(AFS_DARWIN_ENV)
176 afs_proc_t *p = current_proc(); /* XXX */
178 afs_proc_t *p = curproc; /* XXX */
180 #ifndef AFS_DARWIN80_ENV
181 uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
182 p->p_pid, p->p_comm);
184 setpag(p, acred, -1, &pag, 1);
187 setpag(u.u_procp, acred, -1, &pag, 1); /* XXX u.u_procp is a no-op XXX */
189 setpag(acred, -1, &pag, 1);
193 pag = PagInCred(*acred);
194 uid = (pag == NOPAG) ? (*acred)->cr_uid : pag;
195 /* now we just set the tokens */
196 tu = afs_GetUser(uid, tcell->cellnum, WRITE_LOCK);
198 tu->cellinfo = (void *)tcell;
199 tu->vid = clear.ViceId;
200 if (tu->stp != NULL) {
201 afs_osi_Free(tu->stp, tu->stLen);
203 tu->stp = (char *)afs_osi_Alloc(stLen);
205 memcpy(tu->stp, stp, stLen);
208 afs_stats_cmfullperf.authent.TicketUpdates++;
209 afs_ComputePAGStats();
210 #endif /* AFS_NOSTATS */
211 tu->states |= UHasTokens;
212 tu->states &= ~UTokensBad;
213 afs_SetPrimary(tu, flag);
214 tu->tokenTime = osi_Time();
215 afs_PutUser(tu, WRITE_LOCK);
222 SPAGCB_GetCreds(struct rx_call *a_call, afs_int32 a_uid,
227 int bucket, count, i = 0, clen;
232 memset(a_creds, 0, sizeof(struct CredInfos));
233 if ((rx_HostOf(rx_PeerOf(rx_ConnectionOf(a_call))) != afs_nfs_server_addr
234 || rx_PortOf(rx_PeerOf(rx_ConnectionOf(a_call))) != htons(7001))
235 #if 0 /* for debugging ONLY! */
236 && rx_PortOf(rx_PeerOf(rx_ConnectionOf(a_call))) != htons(7901)
243 ObtainWriteLock(&afs_xuser, 823);
245 /* count them first */
246 bucket = UHash(a_uid);
247 for (count = 0, tu = afs_users[bucket]; tu; tu = tu->next) {
248 if (tu->uid == a_uid) count++;
252 ReleaseWriteLock(&afs_xuser);
257 a_creds->CredInfos_val =
258 (CredInfo *)afs_osi_Alloc(count * sizeof(CredInfo));
259 if (!a_creds->CredInfos_val)
261 a_creds->CredInfos_len = count;
262 memset(a_creds->CredInfos_val, 0, count * sizeof(CredInfo));
264 for (i = 0, tu = afs_users[bucket]; tu; tu = tu->next, i++) {
265 if (tu->uid == a_uid && tu->cellinfo &&
266 (tu->states & UHasTokens) && !(tu->states & UTokensBad)) {
268 tci = &a_creds->CredInfos_val[i];
270 tci->ct.AuthHandle = tu->ct.AuthHandle;
271 memcpy(tci->ct.HandShakeKey, tu->ct.HandShakeKey, 8);
272 tci->ct.ViceId = tu->ct.ViceId;
273 tci->ct.BeginTimestamp = tu->ct.BeginTimestamp;
274 tci->ct.EndTimestamp = tu->ct.EndTimestamp;
276 cellname = ((struct afspag_cell *)(tu->cellinfo))->cellname;
277 clen = strlen(cellname) + 1;
278 tci->cellname = afs_osi_Alloc(clen);
281 memcpy(tci->cellname, cellname, clen);
283 tci->st.st_len = tu->stLen;
284 tci->st.st_val = afs_osi_Alloc(tu->stLen);
285 if (!tci->st.st_val) {
286 afs_osi_Free(tci->cellname, clen);
289 memcpy(tci->st.st_val, tu->stp, tu->stLen);
290 if (tu->states & UPrimary)
291 tci->states |= UPrimary;
295 ReleaseWriteLock(&afs_xuser);
300 if (a_creds->CredInfos_val) {
302 afs_osi_Free(a_creds->CredInfos_val[i].st.st_val,
303 a_creds->CredInfos_val[i].st.st_len);
304 afs_osi_Free(a_creds->CredInfos_val[i].cellname,
305 strlen(a_creds->CredInfos_val[i].cellname) + 1);
307 afs_osi_Free(a_creds->CredInfos_val, count * sizeof(CredInfo));
310 ReleaseWriteLock(&afs_xuser);
316 int afspag_PSetSysName(char *ain, afs_int32 ainSize, afs_ucred_t **acred)
318 int setsysname, count, t;
322 memcpy((char *)&setsysname, ain, sizeof(afs_int32));
323 ain += sizeof(afs_int32);
325 return 0; /* nothing to do locally */
328 if (setsysname < 0 || setsysname > MAXNUMSYSNAMES)
330 if (!afs_osi_suser(*acred))
332 for (cp = ain, count = 0; count < setsysname; count++) {
333 /* won't go past end of ain since maxsysname*num < ain length */
335 if (t >= MAXSYSNAME || t <= 0)
337 /* check for names that can shoot us in the foot */
338 if (*cp == '.' && (cp[1] == 0 || (cp[1] == '.' && cp[2] == 0)))
343 ObtainWriteLock(&afs_xpagsys, 824);
344 for (cp = ain, count = 0; count < setsysname; count++) {
346 memcpy(afs_sysnamelist[count], cp, t + 1);
349 afs_sysnamecount = setsysname;
351 ReleaseWriteLock(&afs_xpagsys);
353 /* Change the arguments so we pass the allpags flag to the server */
354 setsysname |= 0x8000;
355 memcpy(setp, (char *)&setsysname, sizeof(afs_int32));
361 SPAGCB_GetSysName(struct rx_call *a_call, afs_int32 a_uid,
362 SysNameList *a_sysnames)
368 ObtainReadLock(&afs_xpagsys);
369 memset(a_sysnames, 0, sizeof(struct SysNameList));
371 a_sysnames->SysNameList_len = afs_sysnamecount;
372 a_sysnames->SysNameList_val =
373 afs_osi_Alloc(afs_sysnamecount * sizeof(SysNameEnt));
374 if (!a_sysnames->SysNameList_val)
377 for (i = 0; i < afs_sysnamecount; i++) {
378 a_sysnames->SysNameList_val[i].sysname =
379 afs_osi_Alloc(strlen(afs_sysnamelist[i]) + 1);
380 if (!a_sysnames->SysNameList_val[i].sysname)
382 strcpy(a_sysnames->SysNameList_val[i].sysname, afs_sysnamelist[i]);
385 ReleaseReadLock(&afs_xpagsys);
390 if (a_sysnames->SysNameList_val) {
392 afs_osi_Free(a_sysnames->SysNameList_val[i].sysname,
393 strlen(a_sysnames->SysNameList_val[i].sysname) + 1);
395 afs_osi_Free(a_sysnames->SysNameList_val,
396 afs_sysnamecount * sizeof(SysNameEnt));
399 ReleaseWriteLock(&afs_xpagsys);