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