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