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
11 #include <afsconfig.h>
12 #include <afs/param.h>
27 osi_rwlock_t cm_userLock;
29 cm_user_t *cm_rootUserp;
31 void cm_InitUser(void)
33 static osi_once_t once;
35 if (osi_Once(&once)) {
36 lock_InitializeRWLock(&cm_userLock, "cm_userLock", LOCK_HIERARCHY_USER_GLOBAL);
40 cm_rootUserp = cm_NewUser();
43 cm_user_t *cm_NewUser(void)
47 userp = malloc(sizeof(*userp));
48 memset(userp, 0, sizeof(*userp));
49 InterlockedIncrement( &userp->refCount);
50 lock_InitializeMutex(&userp->mx, "cm_user_t", LOCK_HIERARCHY_USER);
54 /* must be called with locked userp */
55 cm_ucell_t *cm_GetUCell(cm_user_t *userp, cm_cell_t *cellp)
59 lock_AssertMutex(&userp->mx);
60 for (ucp = userp->cellInfop; ucp; ucp=ucp->nextp) {
61 if (ucp->cellp == cellp)
66 ucp = malloc(sizeof(*ucp));
67 memset(ucp, 0, sizeof(*ucp));
68 ucp->nextp = userp->cellInfop;
70 ucp->iterator = userp->cellInfop->iterator + 1;
73 userp->cellInfop = ucp;
75 if (userp == cm_rootUserp)
76 ucp->flags |= CM_UCELLFLAG_ROOTUSER;
82 cm_ucell_t *cm_FindUCell(cm_user_t *userp, int iterator)
88 lock_AssertMutex(&userp->mx);
89 for (ucp = userp->cellInfop; ucp; ucp = ucp->nextp) {
90 if (ucp->iterator >= iterator)
98 void cm_HoldUser(cm_user_t *up)
102 lock_ObtainWrite(&cm_userLock);
103 lcount = InterlockedIncrement( &up->refCount);
104 osi_assertx(lcount > 0, "user refcount error");
105 lock_ReleaseWrite(&cm_userLock);
108 void cm_ReleaseUser(cm_user_t *userp)
117 lock_ObtainWrite(&cm_userLock);
118 lcount = InterlockedDecrement(&userp->refCount);
119 osi_assertx(lcount >= 0, "cm_user_t refCount < 0");
121 lock_FinalizeMutex(&userp->mx);
122 for (ucp = userp->cellInfop; ucp; ucp = ncp) {
130 lock_ReleaseWrite(&cm_userLock);
134 void cm_HoldUserVCRef(cm_user_t *userp)
136 lock_ObtainMutex(&userp->mx);
137 InterlockedIncrement(&userp->vcRefs);
138 lock_ReleaseMutex(&userp->mx);
141 /* release the count of the # of connections that use this user structure.
142 * When this hits zero, we know we won't be getting any new requests from
143 * this user, and thus we can start GC'ing connections. Ref count on user
144 * won't hit zero until all cm_conn_t's have been GC'd, since they hold
145 * refCount references to userp.
147 void cm_ReleaseUserVCRef(cm_user_t *userp)
151 lock_ObtainMutex(&userp->mx);
152 lcount = InterlockedDecrement(&userp->vcRefs);
153 osi_assertx(lcount >= 0, "cm_user vcRefs refCount < 0");
154 lock_ReleaseMutex(&userp->mx);
159 * Check if any users' tokens have expired and if they have then do the
160 * equivalent of unlogging the user for that particular cell for which
161 * the tokens have expired.
162 * ref. cm_IoctlDelToken() in cm_ioctl.c
163 * This routine is called by the cm_Daemon() ie. the periodic daemon.
164 * every cm_daemonTokenCheckInterval seconds
166 void cm_CheckTokenCache(time_t now)
168 extern smb_vc_t *smb_allVCsp; /* global vcp list */
171 cm_user_t *userp = NULL;
176 * For every vcp, get the user and check his tokens
178 lock_ObtainRead(&smb_rctLock);
179 for (vcp=smb_allVCsp; vcp; vcp=vcp->nextp) {
180 for (usersp=vcp->usersp; usersp; usersp=usersp->nextp) {
182 if ((userp=usersp->unp->userp)==0)
186 lock_ObtainMutex(&userp->mx);
187 for (ucellp=userp->cellInfop; ucellp; ucellp=ucellp->nextp) {
188 if (ucellp->flags & CM_UCELLFLAG_RXKAD) {
189 if (ucellp->expirationTime < now) {
190 /* this guy's tokens have expired */
191 osi_Log3(afsd_logp, "cm_CheckTokens: Tokens for user:%s have expired expiration time:0x%x ucellp:%x",
192 ucellp->userName, ucellp->expirationTime, ucellp);
193 if (ucellp->ticketp) {
194 free(ucellp->ticketp);
195 ucellp->ticketp = NULL;
197 _InterlockedAnd(&ucellp->flags, ~CM_UCELLFLAG_RXKAD);
199 lock_ReleaseMutex(&userp->mx);
200 cm_ResetACLCache(ucellp->cellp, userp);
201 lock_ObtainMutex(&userp->mx);
205 lock_ReleaseMutex(&userp->mx);
208 lock_ReleaseRead(&smb_rctLock);
211 #ifdef USE_ROOT_TOKENS
213 * Service/Parameters/RootTokens/<cellname>/
215 * -> Keytab (required if UseLSA is 0)
216 * -> Principal (required if there is more than one principal in the keytab)
217 * -> Realm (required if realm is not upper-case of <cellname>
218 * -> RequireEncryption
222 cm_RefreshRootTokens(void)