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