freelance-updates-20011031
[openafs.git] / src / WINNT / afsd / cm_user.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 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #ifndef DJGPP
14 #include <windows.h>
15 #endif /* !DJGPP */
16 #include <malloc.h>
17 #include <string.h>
18
19 #include <osi.h>
20 #include <rx/rx.h>
21
22 #include "afsd.h"
23
24 osi_rwlock_t cm_userLock;
25
26 cm_user_t *cm_rootUserp;
27
28 void cm_InitUser(void)
29 {
30         static osi_once_t once;
31         
32         if (osi_Once(&once)) {
33                 lock_InitializeRWLock(&cm_userLock, "cm_userLock");
34                 osi_EndOnce(&once);
35         }
36         
37         cm_rootUserp = cm_NewUser();
38 }
39
40 cm_user_t *cm_NewUser(void)
41 {
42         cm_user_t *up;
43         
44         up = malloc(sizeof(*up));
45         memset(up, 0, sizeof(*up));
46         up->refCount = 1;
47         up->vcRefs = 1;         /* from caller */
48         lock_InitializeMutex(&up->mx, "cm_user_t");
49         return up;
50 }
51
52 /* must be called with locked userp */
53 cm_ucell_t *cm_GetUCell(cm_user_t *userp, cm_cell_t *cellp)
54 {
55         cm_ucell_t *ucp;
56         
57         lock_AssertMutex(&userp->mx);
58         for(ucp = userp->cellInfop; ucp; ucp=ucp->nextp) {
59                 if (ucp->cellp == cellp) break;
60         }
61         
62         if (!ucp) {
63                 ucp = malloc(sizeof(*ucp));
64                 memset(ucp, 0, sizeof(*ucp));
65                 ucp->nextp = userp->cellInfop;
66                 if (userp->cellInfop)
67                         ucp->iterator = userp->cellInfop->iterator + 1;
68                 else
69                         ucp->iterator = 1;
70                 userp->cellInfop = ucp;
71                 ucp->cellp = cellp;
72         }
73         
74         return ucp;
75 }
76
77 cm_ucell_t *cm_FindUCell(cm_user_t *userp, int iterator)
78 {
79         cm_ucell_t *ucp;
80         cm_ucell_t *best;
81
82         best = NULL;
83         lock_AssertMutex(&userp->mx);
84         for (ucp = userp->cellInfop; ucp; ucp = ucp->nextp) {
85                 if (ucp->iterator >= iterator)
86                         best = ucp;
87                 else
88                         break;
89         }
90         return best;
91 }
92
93 void cm_HoldUser(cm_user_t *up)
94 {
95         lock_ObtainWrite(&cm_userLock);
96         up->refCount++;
97         lock_ReleaseWrite(&cm_userLock);
98 }
99
100 void cm_ReleaseUser(cm_user_t *up)
101 {
102         cm_ucell_t *ucp;
103         cm_ucell_t *ncp;
104
105         if (up == NULL) return;
106
107         lock_ObtainWrite(&cm_userLock);
108         osi_assert(up->refCount-- > 0);
109         if (up->refCount == 0) {
110                 lock_FinalizeMutex(&up->mx);
111                 for(ucp = up->cellInfop; ucp; ucp = ncp) {
112                         ncp = ucp->nextp;
113                         if (ucp->ticketp) free(ucp->ticketp);
114                         free(ucp);
115                 }
116                 free(up);
117         }
118         lock_ReleaseWrite(&cm_userLock);
119 }
120
121 /* release the count of the # of connections that use this user structure.
122  * When this hits zero, we know we won't be getting an new requests from
123  * this user, and thus we can start GC'ing connections.  Ref count on user
124  * won't hit zero until all cm_conn_t's have been GC'd, since they hold
125  * refCount references to userp.
126  */
127 void cm_ReleaseUserVCRef(cm_user_t *userp)
128 {
129         lock_ObtainMutex(&userp->mx);
130         osi_assert(userp->vcRefs-- > 0);
131         lock_ReleaseMutex(&userp->mx);
132 }
133
134
135 /*
136  * Check if any users' tokens have expired and if they have then do the 
137  * equivalent of unlogging the user for that particular cell for which 
138  * the tokens have expired.
139  * ref. cm_IoctlDelToken() in cm_ioctl.c 
140  * This routine is called by the cm_Daemon() ie. the periodic daemon.
141  * every cm_daemonTokenCheckInterval seconds 
142  */
143 void cm_CheckTokenCache(long now)
144 {
145         extern smb_vc_t *smb_allVCsp; /* global vcp list */
146         smb_vc_t   *vcp;
147         smb_user_t *usersp;
148         cm_user_t  *userp = NULL;
149         cm_ucell_t *ucellp;
150         BOOL bExpired=FALSE;
151   
152         /* 
153          * For every vcp, get the user and check his tokens 
154          */
155         lock_ObtainWrite(&smb_rctLock);
156         for(vcp=smb_allVCsp; vcp; vcp=vcp->nextp) {
157                 for(usersp=vcp->usersp; usersp; usersp=usersp->nextp) {\r
158                                 if (usersp->unp) {
159                            if ((userp=usersp->unp->userp)==0)\r
160                                            continue;\r
161                                 } else\r
162                                         continue;\r
163                         lock_ObtainMutex(&userp->mx);
164                         for(ucellp=userp->cellInfop; ucellp; ucellp=ucellp->nextp) {
165                           if(ucellp->flags & CM_UCELLFLAG_RXKAD) {
166                             if(ucellp->expirationTime < now) {
167                                   /* this guy's tokens have expired */
168                                   osi_Log3(afsd_logp, "cm_CheckTokens: Tokens for user:%s have expired expiration time:0x%x ucellp:%x", ucellp->userName, ucellp->expirationTime, ucellp);
169                                   if (ucellp->ticketp) {
170                                           free(ucellp->ticketp);
171                                           ucellp->ticketp = NULL;
172                                   }
173                                   ucellp->flags &= ~CM_UCELLFLAG_RXKAD;
174                                   ucellp->gen++;
175                                   bExpired=TRUE;
176                             }
177                           } 
178                         }
179                         lock_ReleaseMutex(&userp->mx);
180                         if(bExpired) {
181                                 bExpired=FALSE;
182                                 cm_ResetACLCache(userp);
183                         }
184                 }
185         }
186         lock_ReleaseWrite(&smb_rctLock);
187 }