audit: remove static local realms
[openafs.git] / src / budb / db_lock.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 <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #include <ubik.h>
16 #include <afs/afsutil.h>
17 #include <afs/audit.h>
18 #include <afs/bubasics.h>
19
20 #include "budb_errs.h"
21 #include "database.h"
22 #include "budb_internal.h"
23 #include "error_macros.h"
24
25 #define DBH_POS(ptr)            ( (char *) (ptr) - (char *) &db.h )
26
27 afs_int32 FreeAllLocks(struct rx_call *, afs_uint32);
28 afs_int32 FreeLock(struct rx_call *, afs_uint32);
29 afs_int32 GetInstanceId(struct rx_call *, afs_uint32 *);
30 afs_int32 GetLock(struct rx_call *, afs_uint32, afs_int32, afs_int32,
31                   afs_uint32 *);
32
33 afs_int32
34 SBUDB_FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
35 {
36     afs_int32 code;
37
38     code = FreeAllLocks(call, instanceId);
39     osi_auditU(call, BUDB_FrALckEvent, code, AUD_END);
40     return code;
41 }
42
43 afs_int32
44 FreeAllLocks(struct rx_call *call, afs_uint32 instanceId)
45 {
46     db_lockP startPtr, endPtr;
47     struct ubik_trans *ut;
48     afs_int32 code;
49
50     if (callPermitted(call) == 0)
51         return (BUDB_NOTPERMITTED);
52
53     code = InitRPC(&ut, LOCKWRITE, 1);
54     if (code)
55         return (code);
56
57     startPtr = &db.h.textLocks[0];
58     endPtr = &db.h.textLocks[TB_NUM - 1];
59     while (startPtr <= endPtr) {
60         if ((ntohl(startPtr->lockState) == 1)
61             && (ntohl(startPtr->instanceId) == instanceId)
62             ) {
63             /* release the lock */
64             startPtr->lockState = 0;    /* unlock it */
65             startPtr->lockTime = 0;
66             startPtr->expires = 0;
67             startPtr->instanceId = 0;
68             dbwrite(ut, DBH_POS(startPtr), (char *)startPtr,
69                     sizeof(db_lockT));
70         }
71         startPtr++;
72     }
73     code = ubik_EndTrans(ut);
74     return (code);
75 }
76
77 afs_int32
78 SBUDB_FreeLock(struct rx_call *call, afs_uint32 lockHandle)
79 {
80     afs_int32 code;
81
82     code = FreeLock(call, lockHandle);
83     osi_auditU(call, BUDB_FreLckEvent, code, AUD_END);
84     return code;
85 }
86
87 afs_int32
88 FreeLock(struct rx_call *call, afs_uint32 lockHandle)
89 {
90     db_lockP lockPtr = 0;
91     struct ubik_trans *ut;
92     afs_int32 code;
93
94     if (callPermitted(call) == 0)
95         return (BUDB_NOTPERMITTED);
96
97     code = InitRPC(&ut, LOCKWRITE, 1);
98     if (code)
99         return (code);
100
101     if (checkLockHandle(ut, lockHandle) == 0)
102         ABORT(BUDB_BADARGUMENT);
103
104     lockPtr = &db.h.textLocks[lockHandle - 1];
105
106     lockPtr->lockState = 0;     /* unlock it */
107     lockPtr->lockTime = 0;
108     lockPtr->expires = 0;
109     lockPtr->instanceId = 0;
110     dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
111
112     code = ubik_EndTrans(ut);
113     return (code);
114
115   abort_exit:
116     ubik_AbortTrans(ut);
117     return (code);
118 }
119
120 afs_int32
121 SBUDB_GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
122 {
123     afs_int32 code;
124
125     code = GetInstanceId(call, instanceId);
126     osi_auditU(call, BUDB_GetIIdEvent, code, AUD_END);
127     return code;
128 }
129
130 afs_int32
131 GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
132 {
133     struct ubik_trans *ut;
134     afs_int32 code;
135     afs_int32 instanceValue;
136
137     LogDebug(4, "GetInstanceId:\n");
138
139     /* *** Allow anyone to get the instance id ***
140      * if ( callPermitted(call) == 0 )
141      *    return(BUDB_NOTPERMITTED);
142      */
143
144     code = InitRPC(&ut, LOCKWRITE, 1);
145     if (code)
146         return (code);
147
148     instanceValue = ntohl(db.h.lastInstanceId) + 1;
149
150     set_header_word(ut, lastInstanceId, htonl(instanceValue));
151
152     code = ubik_EndTrans(ut);
153     return (code);
154 }
155
156
157 afs_int32
158 SBUDB_GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
159               afs_int32 expiration, afs_uint32 *lockHandle)
160 {
161     afs_int32 code;
162
163     code = GetLock(call, instanceId, lockName, expiration, lockHandle);
164     osi_auditU(call, BUDB_GetLckEvent, code, AUD_END);
165     return code;
166 }
167
168 afs_int32
169 GetLock(struct rx_call *call, afs_uint32 instanceId, afs_int32 lockName,
170         afs_int32 expiration, afs_uint32 *lockHandle)
171 {
172     struct timeval tv;
173     db_lockP lockPtr;
174     struct ubik_trans *ut;
175
176     afs_int32 code;
177
178     if (callPermitted(call) == 0)
179         return (BUDB_NOTPERMITTED);
180
181     if ((lockName < 0) || (lockName >= TB_NUM))
182         return (BUDB_BADARGUMENT);
183
184     /* get the current time */
185     gettimeofday(&tv, 0);
186
187     code = InitRPC(&ut, LOCKWRITE, 1);
188     if (code)
189         return (code);
190
191     lockPtr = &db.h.textLocks[lockName];
192
193     if ((ntohl(lockPtr->lockState) != 0)        /* lock set */
194         &&(ntohl(lockPtr->expires) > tv.tv_sec) /* not expired */
195         ) {
196         if (ntohl(lockPtr->instanceId) == instanceId)
197             code = BUDB_SELFLOCKED;
198         else
199             code = BUDB_LOCKED;
200         goto abort_exit;
201     }
202
203     lockPtr->lockState = htonl(1);      /* lock it */
204     lockPtr->lockTime = htonl(tv.tv_sec);       /* when locked */
205     lockPtr->expires = htonl(tv.tv_sec + expiration);
206     lockPtr->instanceId = htonl(instanceId);
207     code = dbwrite(ut, DBH_POS(lockPtr), (char *)lockPtr, sizeof(db_lockT));
208     if (code)
209         ABORT(code);
210
211     *lockHandle = (afs_uint32) (lockName + 1);
212     code = ubik_EndTrans(ut);
213     return (code);
214
215   abort_exit:
216     ubik_AbortTrans(ut);
217     return (code);
218 }
219
220
221 /* checkLockHandle
222  * exit:
223  *      0 - if invalid handle
224  *      1 - if handle is valid
225  */
226 int
227 checkLockHandle(struct ubik_trans *ut, afs_uint32 lockHandle)
228 {
229     return (((lockHandle > 0) && (lockHandle <= TB_NUM)) ? 1 : 0);
230 }