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