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;
36 afspag_GetCell(char *acell
)
38 struct afspag_cell
*tcell
;
40 ObtainWriteLock(&afs_xpagcell
, 820);
42 for (tcell
= cells
; tcell
; tcell
= tcell
->next
) {
43 if (!strcmp(acell
, tcell
->cellname
))
48 tcell
= afs_osi_Alloc(sizeof(struct afspag_cell
));
51 tcell
->cellname
= afs_osi_Alloc(strlen(acell
) + 1);
52 if (!tcell
->cellname
) {
53 afs_osi_Free(tcell
, sizeof(struct afspag_cell
));
57 strcpy(tcell
->cellname
, acell
);
58 tcell
->cellnum
= ++lastcell
;
61 if (!primary_cell
) primary_cell
= tcell
;
65 ReleaseWriteLock(&afs_xpagcell
);
71 afspag_GetPrimaryCell(void)
73 struct afspag_cell
*tcell
;
75 ObtainWriteLock(&afs_xpagcell
, 821);
77 ReleaseWriteLock(&afs_xpagcell
);
83 afspag_SetPrimaryCell(char *acell
)
85 struct afspag_cell
*tcell
;
87 tcell
= afspag_GetCell(acell
);
88 ObtainWriteLock(&afs_xpagcell
, 822);
90 ReleaseWriteLock(&afs_xpagcell
);
95 afspag_PUnlog(char *ain
, afs_int32 ainSize
, afs_ucred_t
**acred
)
102 if (!afs_resourceinit_flag
) /* afs daemons haven't started yet */
103 return EIO
; /* Inappropriate ioctl for device */
105 pag
= PagInCred(*acred
);
106 uid
= (pag
== NOPAG
) ? afs_cr_uid(*acred
) : pag
;
108 ObtainWriteLock(&afs_xuser
, 823);
109 for (tu
= afs_users
[i
]; tu
; tu
= tu
->next
) {
110 if (tu
->uid
== uid
) {
112 ReleaseWriteLock(&afs_xuser
);
114 afs_LockUser(tu
, WRITE_LOCK
, 368);
116 tu
->states
&= ~UHasTokens
;
117 tu
->viceId
= UNDEFVID
;
118 afs_FreeTokens(&tu
->tokens
);
120 /* set the expire times to 0, causes
121 * afs_GCUserData to remove this entry
126 afs_PutUser(tu
, WRITE_LOCK
);
128 ObtainWriteLock(&afs_xuser
, 369);
131 ReleaseWriteLock(&afs_xuser
);
137 afspag_PSetTokens(char *ain
, afs_int32 ainSize
, afs_ucred_t
**acred
)
141 struct afspag_cell
*tcell
;
142 struct ClearToken clear
;
145 afs_int32 flag
, set_parent_pag
= 0;
148 AFS_STATCNT(PSetTokens
);
149 if (!afs_resourceinit_flag
) {
152 memcpy((char *)&i
, ain
, sizeof(afs_int32
));
153 ain
+= sizeof(afs_int32
);
154 stp
= ain
; /* remember where the ticket is */
155 if (i
< 0 || i
> MAXKTCTICKETLEN
)
156 return EINVAL
; /* malloc may fail */
158 ain
+= i
; /* skip over ticket */
159 memcpy((char *)&i
, ain
, sizeof(afs_int32
));
160 ain
+= sizeof(afs_int32
);
161 if (i
!= sizeof(struct ClearToken
)) {
164 memcpy((char *)&clear
, ain
, sizeof(struct ClearToken
));
165 if (clear
.AuthHandle
== -1)
166 clear
.AuthHandle
= 999; /* more rxvab compat stuff */
167 ain
+= sizeof(struct ClearToken
);
168 if (ainSize
!= 2 * sizeof(afs_int32
) + stLen
+ sizeof(struct ClearToken
)) {
169 /* still stuff left? we've got primary flag and cell name. Set these */
170 memcpy((char *)&flag
, ain
, sizeof(afs_int32
)); /* primary id flag */
171 ain
+= sizeof(afs_int32
); /* skip id field */
172 /* rest is cell name, look it up */
173 /* some versions of gcc appear to need != 0 in order to get this right */
174 if ((flag
& 0x8000) != 0) { /* XXX Use Constant XXX */
178 tcell
= afspag_GetCell(ain
);
180 /* default to primary cell, primary id */
181 flag
= 1; /* primary id */
182 tcell
= afspag_GetPrimaryCell();
184 if (!tcell
) return ESRCH
;
185 if (set_parent_pag
) {
186 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
188 osi_procname(procname
, 256);
190 afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
191 MyPidxx2Pid(MyPidxx
), procname
);
192 setpag(osi_curproc(), acred
, -1, &pag
, 1);
194 setpag(acred
, -1, &pag
, 1);
197 pag
= PagInCred(*acred
);
198 uid
= (pag
== NOPAG
) ? afs_cr_uid(*acred
) : pag
;
199 /* now we just set the tokens */
200 tu
= afs_GetUser(uid
, tcell
->cellnum
, WRITE_LOCK
);
202 tu
->cellinfo
= (void *)tcell
;
203 afs_FreeTokens(&tu
->tokens
);
204 afs_AddRxkadToken(&tu
->tokens
, stp
, stLen
, &clear
);
206 afs_stats_cmfullperf
.authent
.TicketUpdates
++;
207 afs_ComputePAGStats();
208 #endif /* AFS_NOSTATS */
209 tu
->states
|= UHasTokens
;
210 tu
->states
&= ~UTokensBad
;
211 afs_SetPrimary(tu
, flag
);
212 tu
->tokenTime
= osi_Time();
213 afs_PutUser(tu
, WRITE_LOCK
);
220 SPAGCB_GetCreds(struct rx_call
*a_call
, afs_int32 a_uid
,
224 union tokenUnion
*token
;
226 int bucket
, count
, i
= 0, clen
;
231 memset(a_creds
, 0, sizeof(struct CredInfos
));
232 if ((rx_HostOf(rx_PeerOf(rx_ConnectionOf(a_call
))) != afs_nfs_server_addr
233 || rx_PortOf(rx_PeerOf(rx_ConnectionOf(a_call
))) != htons(7001))
234 #if 0 /* for debugging ONLY! */
235 && rx_PortOf(rx_PeerOf(rx_ConnectionOf(a_call
))) != htons(7901)
242 ObtainWriteLock(&afs_xuser
, 823);
244 /* count them first */
245 bucket
= UHash(a_uid
);
246 for (count
= 0, tu
= afs_users
[bucket
]; tu
; tu
= tu
->next
) {
247 if (tu
->uid
== a_uid
) count
++;
251 ReleaseWriteLock(&afs_xuser
);
256 a_creds
->CredInfos_val
= afs_osi_Alloc(count
* sizeof(CredInfo
));
257 if (!a_creds
->CredInfos_val
)
259 a_creds
->CredInfos_len
= count
;
260 memset(a_creds
->CredInfos_val
, 0, count
* sizeof(CredInfo
));
262 for (i
= 0, tu
= afs_users
[bucket
]; tu
; tu
= tu
->next
, i
++) {
263 if (tu
->uid
== a_uid
&& tu
->cellinfo
&&
264 (tu
->states
& UHasTokens
) && !(tu
->states
& UTokensBad
)) {
267 ReleaseWriteLock(&afs_xuser
);
269 afs_LockUser(tu
, READ_LOCK
, 0);
271 token
= afs_FindToken(tu
->tokens
, RX_SECIDX_KAD
);
273 tci
= &a_creds
->CredInfos_val
[i
];
274 tci
->vid
= token
->rxkad
.clearToken
.ViceId
;
275 tci
->ct
.AuthHandle
= token
->rxkad
.clearToken
.AuthHandle
;
276 memcpy(tci
->ct
.HandShakeKey
,
277 token
->rxkad
.clearToken
.HandShakeKey
, 8);
278 tci
->ct
.ViceId
= token
->rxkad
.clearToken
.ViceId
;
279 tci
->ct
.BeginTimestamp
= token
->rxkad
.clearToken
.BeginTimestamp
;
280 tci
->ct
.EndTimestamp
= token
->rxkad
.clearToken
.EndTimestamp
;
282 cellname
= ((struct afspag_cell
*)(tu
->cellinfo
))->cellname
;
283 clen
= strlen(cellname
) + 1;
284 tci
->cellname
= afs_osi_Alloc(clen
);
285 if (!tci
->cellname
) {
286 afs_PutUser(tu
, READ_LOCK
);
287 ObtainWriteLock(&afs_xuser
, 370);
290 memcpy(tci
->cellname
, cellname
, clen
);
292 tci
->st
.st_len
= token
->rxkad
.ticketLen
;
293 tci
->st
.st_val
= afs_osi_Alloc(token
->rxkad
.ticketLen
);
294 if (!tci
->st
.st_val
) {
295 afs_PutUser(tu
, READ_LOCK
);
296 afs_osi_Free(tci
->cellname
, clen
);
297 ObtainWriteLock(&afs_xuser
, 371);
300 memcpy(tci
->st
.st_val
,
301 token
->rxkad
.ticket
, token
->rxkad
.ticketLen
);
302 if (tu
->states
& UPrimary
)
303 tci
->states
|= UPrimary
;
305 afs_PutUser(tu
, READ_LOCK
);
306 ObtainWriteLock(&afs_xuser
, 372);
310 ReleaseWriteLock(&afs_xuser
);
315 if (a_creds
->CredInfos_val
) {
317 afs_osi_Free(a_creds
->CredInfos_val
[i
].st
.st_val
,
318 a_creds
->CredInfos_val
[i
].st
.st_len
);
319 afs_osi_Free(a_creds
->CredInfos_val
[i
].cellname
,
320 strlen(a_creds
->CredInfos_val
[i
].cellname
) + 1);
322 afs_osi_Free(a_creds
->CredInfos_val
, count
* sizeof(CredInfo
));
325 ReleaseWriteLock(&afs_xuser
);
332 afspag_PSetSysName(char *ain
, afs_int32 ainSize
, afs_ucred_t
**acred
)
334 int setsysname
, count
, t
;
338 memcpy((char *)&setsysname
, ain
, sizeof(afs_int32
));
339 ain
+= sizeof(afs_int32
);
341 return 0; /* nothing to do locally */
344 if (setsysname
< 0 || setsysname
> MAXNUMSYSNAMES
)
346 if (!afs_osi_suser(*acred
))
348 for (cp
= ain
, count
= 0; count
< setsysname
; count
++) {
349 /* won't go past end of ain since maxsysname*num < ain length */
351 if (t
>= MAXSYSNAME
|| t
<= 0)
353 /* check for names that can shoot us in the foot */
354 if (*cp
== '.' && (cp
[1] == 0 || (cp
[1] == '.' && cp
[2] == 0)))
359 ObtainWriteLock(&afs_xpagsys
, 824);
360 for (cp
= ain
, count
= 0; count
< setsysname
; count
++) {
362 memcpy(afs_sysnamelist
[count
], cp
, t
+ 1);
365 afs_sysnamecount
= setsysname
;
367 ReleaseWriteLock(&afs_xpagsys
);
369 /* Change the arguments so we pass the allpags flag to the server */
370 setsysname
|= 0x8000;
371 memcpy(setp
, (char *)&setsysname
, sizeof(afs_int32
));
377 SPAGCB_GetSysName(struct rx_call
*a_call
, afs_int32 a_uid
,
378 SysNameList
*a_sysnames
)
384 ObtainReadLock(&afs_xpagsys
);
385 memset(a_sysnames
, 0, sizeof(struct SysNameList
));
387 a_sysnames
->SysNameList_len
= afs_sysnamecount
;
388 a_sysnames
->SysNameList_val
=
389 afs_osi_Alloc(afs_sysnamecount
* sizeof(SysNameEnt
));
390 if (!a_sysnames
->SysNameList_val
)
393 for (i
= 0; i
< afs_sysnamecount
; i
++) {
394 a_sysnames
->SysNameList_val
[i
].sysname
=
395 afs_osi_Alloc(strlen(afs_sysnamelist
[i
]) + 1);
396 if (!a_sysnames
->SysNameList_val
[i
].sysname
)
398 strcpy(a_sysnames
->SysNameList_val
[i
].sysname
, afs_sysnamelist
[i
]);
401 ReleaseReadLock(&afs_xpagsys
);
406 if (a_sysnames
->SysNameList_val
) {
408 afs_osi_Free(a_sysnames
->SysNameList_val
[i
].sysname
,
409 strlen(a_sysnames
->SysNameList_val
[i
].sysname
) + 1);
411 afs_osi_Free(a_sysnames
->SysNameList_val
,
412 afs_sysnamecount
* sizeof(SysNameEnt
));
415 ReleaseWriteLock(&afs_xpagsys
);