1
2 /*
3 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
4 *
5 * Openvision retains the copyright to derivative works of
6 * this source code. Do *NOT* create a derivative of this
7 * source code before consulting with your legal department.
8 * Do *NOT* integrate *ANY* of this source code into another
9 * product before consulting with your legal department.
10 *
11 * For further information, read the top-level Openvision
12 * copyright which is contained in the top-level MIT Kerberos
13 * copyright.
14 *
15 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
16 *
17 */
18
19
20 /*
21 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
22 *
23 * $Header$
24 */
25
26 #if !defined(lint) && !defined(__CODECENTER__)
27 static char *rcsid = "$Header$";
28 #endif
29
30 #include <sys/file.h>
31 #include <fcntl.h>
32 #include "policy_db.h"
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36
37 extern caddr_t xdralloc_getdata(XDR *xdrs);
38 extern void xdralloc_create(XDR *xdrs, enum xdr_op op);
39
40 #define OPENLOCK(db, mode) \
41 { \
42 int olret; \
43 if (db == NULL) \
44 return EINVAL; \
45 else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \
46 return OSA_ADB_DBINIT; \
47 else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \
48 return olret; \
49 }
50
51 #define CLOSELOCK(db) \
52 { \
53 int cl_ret; \
54 if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \
55 return cl_ret; \
56 }
57
58
59 /*
60 * Function: osa_adb_create_policy
61 *
62 * Purpose: create a policy entry in the policy db.
63 *
64 * Arguments:
65 * entry (input) pointer to the entry to be added
66 * <return value> OSA_ADB_OK on success, else error code.
67 *
68 * Requires:
69 * entry have a valid name.
70 *
71 * Effects:
72 * creates the entry in the db
73 *
74 * Modifies:
75 * the policy db.
76 *
77 */
78 krb5_error_code
osa_adb_create_policy(osa_adb_policy_t db,osa_policy_ent_t entry)79 osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
80 {
81 DBT dbkey;
82 DBT dbdata;
83 XDR xdrs;
84 int ret;
85
86 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
87
88 if(entry->name == NULL) {
89 ret = EINVAL;
90 goto error;
91 }
92 dbkey.data = entry->name;
93 dbkey.size = (strlen(entry->name) + 1);
94
95 switch(db->db->get(db->db, &dbkey, &dbdata, 0)) {
96 case 0:
97 ret = OSA_ADB_DUP;
98 goto error;
99 case 1:
100 break;
101 default:
102 ret = errno;
103 goto error;
104 }
105 xdralloc_create(&xdrs, XDR_ENCODE);
106 if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
107 xdr_destroy(&xdrs);
108 ret = OSA_ADB_XDR_FAILURE;
109 goto error;
110 }
111 dbdata.data = xdralloc_getdata(&xdrs);
112 dbdata.size = xdr_getpos(&xdrs);
113 switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) {
114 case 0:
115 if((db->db->sync(db->db, 0)) == -1)
116 ret = OSA_ADB_FAILURE;
117 ret = OSA_ADB_OK;
118 break;
119 case 1:
120 ret = OSA_ADB_DUP;
121 break;
122 default:
123 ret = OSA_ADB_FAILURE;
124 break;
125 }
126 xdr_destroy(&xdrs);
127
128 error:
129 CLOSELOCK(db);
130 return ret;
131 }
132
133 /*
134 * Function: osa_adb_destroy_policy
135 *
136 * Purpose: destroy a policy entry
137 *
138 * Arguments:
139 * db (input) database handle
140 * name (input) name of policy
141 * <return value> OSA_ADB_OK on success, or error code.
142 *
143 * Requires:
144 * db being valid.
145 * name being non-null.
146 * Effects:
147 * deletes policy from db.
148 *
149 * Modifies:
150 * policy db.
151 *
152 */
153 krb5_error_code
osa_adb_destroy_policy(osa_adb_policy_t db,char * name)154 osa_adb_destroy_policy(osa_adb_policy_t db, char *name)
155 {
156 DBT dbkey;
157 int status, ret;
158
159 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
160
161 if(name == NULL) {
162 ret = EINVAL;
163 goto error;
164 }
165 dbkey.data = name;
166 dbkey.size = (strlen(name) + 1);
167
168 status = db->db->del(db->db, &dbkey, 0);
169 switch(status) {
170 case 1:
171 ret = OSA_ADB_NOENT;
172 goto error;
173 case 0:
174 if ((db->db->sync(db->db, 0)) == -1) {
175 ret = OSA_ADB_FAILURE;
176 goto error;
177 }
178 ret = OSA_ADB_OK;
179 break;
180 default:
181 ret = OSA_ADB_FAILURE;
182 goto error;
183 }
184
185 error:
186 CLOSELOCK(db);
187 return ret;
188 }
189
190 /*
191 * Function: osa_adb_get_policy
192 *
193 * Purpose: retrieve policy
194 *
195 * Arguments:
196 * db (input) db handle
197 * name (input) name of policy
198 * entry (output) policy entry
199 * cnt (inout) Number of entries
200 * <return value> 0 on success, error code on failure.
201 *
202 * Requires:
203 * Effects:
204 * Modifies:
205 */
206 krb5_error_code
osa_adb_get_policy(osa_adb_policy_t db,char * name,osa_policy_ent_t * entry,int * cnt)207 osa_adb_get_policy(osa_adb_policy_t db, char *name,
208 osa_policy_ent_t *entry, int *cnt)
209 {
210 DBT dbkey;
211 DBT dbdata;
212 XDR xdrs;
213 int ret;
214 char *aligned_data;
215
216 OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED);
217
218 *cnt = 1;
219
220 if(name == NULL) {
221 ret = EINVAL;
222 goto error;
223 }
224 dbkey.data = name;
225 dbkey.size = (strlen(dbkey.data) + 1);
226 dbdata.data = NULL;
227 dbdata.size = 0;
228 switch((db->db->get(db->db, &dbkey, &dbdata, 0))) {
229 case 1:
230 ret = OSA_ADB_OK;
231 *cnt = 0;
232 goto error;
233 case 0:
234 break;
235 default:
236 ret = OSA_ADB_FAILURE;
237 goto error;
238 }
239 if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) {
240 ret = ENOMEM;
241 goto error;
242 }
243 if (!(aligned_data = (char *) malloc(dbdata.size))) {
244 ret = ENOMEM;
245 goto error;
246 }
247 memcpy(aligned_data, dbdata.data, dbdata.size);
248 memset(*entry, 0, sizeof(osa_policy_ent_rec));
249 xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
250 if (!xdr_osa_policy_ent_rec(&xdrs, *entry))
251 ret = OSA_ADB_FAILURE;
252 else ret = OSA_ADB_OK;
253 xdr_destroy(&xdrs);
254 free(aligned_data);
255
256 error:
257 CLOSELOCK(db);
258 return ret;
259 }
260
261 /*
262 * Function: osa_adb_put_policy
263 *
264 * Purpose: update a policy in the dababase
265 *
266 * Arguments:
267 * db (input) db handle
268 * entry (input) policy entry
269 * <return value> 0 on success error code on failure.
270 *
271 * Requires:
272 * [requires]
273 *
274 * Effects:
275 * [effects]
276 *
277 * Modifies:
278 * [modifies]
279 *
280 */
281 krb5_error_code
osa_adb_put_policy(osa_adb_policy_t db,osa_policy_ent_t entry)282 osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
283 {
284 DBT dbkey;
285 DBT dbdata;
286 DBT tmpdb;
287 XDR xdrs;
288 int ret;
289
290 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
291
292 if(entry->name == NULL) {
293 ret = EINVAL;
294 goto error;
295 }
296 dbkey.data = entry->name;
297 dbkey.size = (strlen(entry->name) + 1);
298 switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) {
299 case 0:
300 break;
301 case 1:
302 ret = OSA_ADB_NOENT;
303 goto error;
304 default:
305 ret = OSA_ADB_FAILURE;
306 goto error;
307 }
308 xdralloc_create(&xdrs, XDR_ENCODE);
309 if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
310 xdr_destroy(&xdrs);
311 ret = OSA_ADB_XDR_FAILURE;
312 goto error;
313 }
314 dbdata.data = xdralloc_getdata(&xdrs);
315 dbdata.size = xdr_getpos(&xdrs);
316 switch(db->db->put(db->db, &dbkey, &dbdata, 0)) {
317 case 0:
318 if((db->db->sync(db->db, 0)) == -1)
319 ret = OSA_ADB_FAILURE;
320 ret = OSA_ADB_OK;
321 break;
322 default:
323 ret = OSA_ADB_FAILURE;
324 break;
325 }
326 xdr_destroy(&xdrs);
327
328 error:
329 CLOSELOCK(db);
330 return ret;
331 }
332
333 /*
334 * Function: osa_adb_iter_policy
335 *
336 * Purpose: iterate over the policy database.
337 *
338 * Arguments:
339 * db (input) db handle
340 * func (input) fucntion pointer to call
341 * data opaque data type
342 * <return value> 0 on success error code on failure
343 *
344 * Requires:
345 * Effects:
346 * Modifies:
347 */
348 krb5_error_code
osa_adb_iter_policy(osa_adb_policy_t db,osa_adb_iter_policy_func func,void * data)349 osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func,
350 void *data)
351 {
352 DBT dbkey,
353 dbdata;
354 XDR xdrs;
355 int ret;
356 osa_policy_ent_t entry;
357 char *aligned_data;
358
359 OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */
360
361 if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) {
362 ret = errno;
363 goto error;
364 }
365
366 while (ret == 0) {
367 if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) {
368 ret = ENOMEM;
369 goto error;
370 }
371
372 if(!(aligned_data = (char *) malloc(dbdata.size))) {
373 ret = ENOMEM;
374 goto error;
375 }
376 memcpy(aligned_data, dbdata.data, dbdata.size);
377
378 memset(entry, 0, sizeof(osa_policy_ent_rec));
379 xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
380 if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
381 xdr_destroy(&xdrs);
382 free(aligned_data);
383 ret = OSA_ADB_FAILURE;
384 goto error;
385 }
386 (*func)(data, entry);
387 xdr_destroy(&xdrs);
388 free(aligned_data);
389 osa_free_policy_ent(entry);
390 ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT);
391 }
392 if(ret == -1)
393 ret = errno;
394 else ret = OSA_ADB_OK;
395
396 error:
397 CLOSELOCK(db);
398 return ret;
399 }
400
401 void
osa_free_policy_ent(osa_policy_ent_t val)402 osa_free_policy_ent(osa_policy_ent_t val)
403 {
404 XDR xdrs;
405
406 xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
407
408 xdr_osa_policy_ent_rec(&xdrs, val);
409
410 free(val);
411 }
412