154925bf6Swillf
254925bf6Swillf /*
354925bf6Swillf * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
454925bf6Swillf *
554925bf6Swillf * Openvision retains the copyright to derivative works of
654925bf6Swillf * this source code. Do *NOT* create a derivative of this
754925bf6Swillf * source code before consulting with your legal department.
854925bf6Swillf * Do *NOT* integrate *ANY* of this source code into another
954925bf6Swillf * product before consulting with your legal department.
1054925bf6Swillf *
1154925bf6Swillf * For further information, read the top-level Openvision
1254925bf6Swillf * copyright which is contained in the top-level MIT Kerberos
1354925bf6Swillf * copyright.
1454925bf6Swillf *
1554925bf6Swillf * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
1654925bf6Swillf *
1754925bf6Swillf */
1854925bf6Swillf
1954925bf6Swillf
2054925bf6Swillf /*
2154925bf6Swillf * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
2254925bf6Swillf *
23*159d09a2SMark Phalan * $Header$
2454925bf6Swillf */
2554925bf6Swillf
2654925bf6Swillf #if !defined(lint) && !defined(__CODECENTER__)
27*159d09a2SMark Phalan static char *rcsid = "$Header$";
2854925bf6Swillf #endif
2954925bf6Swillf
3054925bf6Swillf #include <sys/file.h>
3154925bf6Swillf #include <fcntl.h>
3254925bf6Swillf #include "policy_db.h"
3354925bf6Swillf #include <stdlib.h>
3454925bf6Swillf #include <string.h>
3554925bf6Swillf #include <errno.h>
3654925bf6Swillf
3754925bf6Swillf extern caddr_t xdralloc_getdata(XDR *xdrs);
3854925bf6Swillf extern void xdralloc_create(XDR *xdrs, enum xdr_op op);
3954925bf6Swillf
4054925bf6Swillf #define OPENLOCK(db, mode) \
4154925bf6Swillf { \
4254925bf6Swillf int olret; \
4354925bf6Swillf if (db == NULL) \
4454925bf6Swillf return EINVAL; \
4554925bf6Swillf else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \
4654925bf6Swillf return OSA_ADB_DBINIT; \
4754925bf6Swillf else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \
4854925bf6Swillf return olret; \
4954925bf6Swillf }
5054925bf6Swillf
5154925bf6Swillf #define CLOSELOCK(db) \
5254925bf6Swillf { \
5354925bf6Swillf int cl_ret; \
5454925bf6Swillf if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \
5554925bf6Swillf return cl_ret; \
5654925bf6Swillf }
5754925bf6Swillf
5854925bf6Swillf
5954925bf6Swillf /*
6054925bf6Swillf * Function: osa_adb_create_policy
6154925bf6Swillf *
6254925bf6Swillf * Purpose: create a policy entry in the policy db.
6354925bf6Swillf *
6454925bf6Swillf * Arguments:
6554925bf6Swillf * entry (input) pointer to the entry to be added
6654925bf6Swillf * <return value> OSA_ADB_OK on success, else error code.
6754925bf6Swillf *
6854925bf6Swillf * Requires:
6954925bf6Swillf * entry have a valid name.
7054925bf6Swillf *
7154925bf6Swillf * Effects:
7254925bf6Swillf * creates the entry in the db
7354925bf6Swillf *
7454925bf6Swillf * Modifies:
7554925bf6Swillf * the policy db.
7654925bf6Swillf *
7754925bf6Swillf */
7854925bf6Swillf krb5_error_code
osa_adb_create_policy(osa_adb_policy_t db,osa_policy_ent_t entry)7954925bf6Swillf osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
8054925bf6Swillf {
8154925bf6Swillf DBT dbkey;
8254925bf6Swillf DBT dbdata;
8354925bf6Swillf XDR xdrs;
8454925bf6Swillf int ret;
8554925bf6Swillf
8654925bf6Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
8754925bf6Swillf
8854925bf6Swillf if(entry->name == NULL) {
8954925bf6Swillf ret = EINVAL;
9054925bf6Swillf goto error;
9154925bf6Swillf }
9254925bf6Swillf dbkey.data = entry->name;
9354925bf6Swillf dbkey.size = (strlen(entry->name) + 1);
9454925bf6Swillf
9554925bf6Swillf switch(db->db->get(db->db, &dbkey, &dbdata, 0)) {
9654925bf6Swillf case 0:
9754925bf6Swillf ret = OSA_ADB_DUP;
9854925bf6Swillf goto error;
9954925bf6Swillf case 1:
10054925bf6Swillf break;
10154925bf6Swillf default:
10254925bf6Swillf ret = errno;
10354925bf6Swillf goto error;
10454925bf6Swillf }
10554925bf6Swillf xdralloc_create(&xdrs, XDR_ENCODE);
10654925bf6Swillf if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
10754925bf6Swillf xdr_destroy(&xdrs);
10854925bf6Swillf ret = OSA_ADB_XDR_FAILURE;
10954925bf6Swillf goto error;
11054925bf6Swillf }
11154925bf6Swillf dbdata.data = xdralloc_getdata(&xdrs);
11254925bf6Swillf dbdata.size = xdr_getpos(&xdrs);
11354925bf6Swillf switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) {
11454925bf6Swillf case 0:
11554925bf6Swillf if((db->db->sync(db->db, 0)) == -1)
11654925bf6Swillf ret = OSA_ADB_FAILURE;
11754925bf6Swillf ret = OSA_ADB_OK;
11854925bf6Swillf break;
11954925bf6Swillf case 1:
12054925bf6Swillf ret = OSA_ADB_DUP;
12154925bf6Swillf break;
12254925bf6Swillf default:
12354925bf6Swillf ret = OSA_ADB_FAILURE;
12454925bf6Swillf break;
12554925bf6Swillf }
12654925bf6Swillf xdr_destroy(&xdrs);
12754925bf6Swillf
12854925bf6Swillf error:
12954925bf6Swillf CLOSELOCK(db);
13054925bf6Swillf return ret;
13154925bf6Swillf }
13254925bf6Swillf
13354925bf6Swillf /*
13454925bf6Swillf * Function: osa_adb_destroy_policy
13554925bf6Swillf *
13654925bf6Swillf * Purpose: destroy a policy entry
13754925bf6Swillf *
13854925bf6Swillf * Arguments:
13954925bf6Swillf * db (input) database handle
14054925bf6Swillf * name (input) name of policy
14154925bf6Swillf * <return value> OSA_ADB_OK on success, or error code.
14254925bf6Swillf *
14354925bf6Swillf * Requires:
14454925bf6Swillf * db being valid.
14554925bf6Swillf * name being non-null.
14654925bf6Swillf * Effects:
14754925bf6Swillf * deletes policy from db.
14854925bf6Swillf *
14954925bf6Swillf * Modifies:
15054925bf6Swillf * policy db.
15154925bf6Swillf *
15254925bf6Swillf */
15354925bf6Swillf krb5_error_code
osa_adb_destroy_policy(osa_adb_policy_t db,char * name)15454925bf6Swillf osa_adb_destroy_policy(osa_adb_policy_t db, char *name)
15554925bf6Swillf {
15654925bf6Swillf DBT dbkey;
15754925bf6Swillf int status, ret;
15854925bf6Swillf
15954925bf6Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
16054925bf6Swillf
16154925bf6Swillf if(name == NULL) {
16254925bf6Swillf ret = EINVAL;
16354925bf6Swillf goto error;
16454925bf6Swillf }
16554925bf6Swillf dbkey.data = name;
16654925bf6Swillf dbkey.size = (strlen(name) + 1);
16754925bf6Swillf
16854925bf6Swillf status = db->db->del(db->db, &dbkey, 0);
16954925bf6Swillf switch(status) {
17054925bf6Swillf case 1:
17154925bf6Swillf ret = OSA_ADB_NOENT;
17254925bf6Swillf goto error;
17354925bf6Swillf case 0:
17454925bf6Swillf if ((db->db->sync(db->db, 0)) == -1) {
17554925bf6Swillf ret = OSA_ADB_FAILURE;
17654925bf6Swillf goto error;
17754925bf6Swillf }
17854925bf6Swillf ret = OSA_ADB_OK;
17954925bf6Swillf break;
18054925bf6Swillf default:
18154925bf6Swillf ret = OSA_ADB_FAILURE;
18254925bf6Swillf goto error;
18354925bf6Swillf }
18454925bf6Swillf
18554925bf6Swillf error:
18654925bf6Swillf CLOSELOCK(db);
18754925bf6Swillf return ret;
18854925bf6Swillf }
18954925bf6Swillf
19054925bf6Swillf /*
19154925bf6Swillf * Function: osa_adb_get_policy
19254925bf6Swillf *
19354925bf6Swillf * Purpose: retrieve policy
19454925bf6Swillf *
19554925bf6Swillf * Arguments:
19654925bf6Swillf * db (input) db handle
19754925bf6Swillf * name (input) name of policy
19854925bf6Swillf * entry (output) policy entry
19954925bf6Swillf * cnt (inout) Number of entries
20054925bf6Swillf * <return value> 0 on success, error code on failure.
20154925bf6Swillf *
20254925bf6Swillf * Requires:
20354925bf6Swillf * Effects:
20454925bf6Swillf * Modifies:
20554925bf6Swillf */
20654925bf6Swillf krb5_error_code
osa_adb_get_policy(osa_adb_policy_t db,char * name,osa_policy_ent_t * entry,int * cnt)20754925bf6Swillf osa_adb_get_policy(osa_adb_policy_t db, char *name,
20854925bf6Swillf osa_policy_ent_t *entry, int *cnt)
20954925bf6Swillf {
21054925bf6Swillf DBT dbkey;
21154925bf6Swillf DBT dbdata;
21254925bf6Swillf XDR xdrs;
21354925bf6Swillf int ret;
21454925bf6Swillf char *aligned_data;
21554925bf6Swillf
21654925bf6Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED);
21754925bf6Swillf
21854925bf6Swillf *cnt = 1;
21954925bf6Swillf
22054925bf6Swillf if(name == NULL) {
22154925bf6Swillf ret = EINVAL;
22254925bf6Swillf goto error;
22354925bf6Swillf }
22454925bf6Swillf dbkey.data = name;
22554925bf6Swillf dbkey.size = (strlen(dbkey.data) + 1);
22654925bf6Swillf dbdata.data = NULL;
22754925bf6Swillf dbdata.size = 0;
22854925bf6Swillf switch((db->db->get(db->db, &dbkey, &dbdata, 0))) {
22954925bf6Swillf case 1:
23054925bf6Swillf ret = OSA_ADB_OK;
23154925bf6Swillf *cnt = 0;
23254925bf6Swillf goto error;
23354925bf6Swillf case 0:
23454925bf6Swillf break;
23554925bf6Swillf default:
23654925bf6Swillf ret = OSA_ADB_FAILURE;
23754925bf6Swillf goto error;
23854925bf6Swillf }
23954925bf6Swillf if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) {
24054925bf6Swillf ret = ENOMEM;
24154925bf6Swillf goto error;
24254925bf6Swillf }
24354925bf6Swillf if (!(aligned_data = (char *) malloc(dbdata.size))) {
24454925bf6Swillf ret = ENOMEM;
24554925bf6Swillf goto error;
24654925bf6Swillf }
24754925bf6Swillf memcpy(aligned_data, dbdata.data, dbdata.size);
24854925bf6Swillf memset(*entry, 0, sizeof(osa_policy_ent_rec));
24954925bf6Swillf xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
25054925bf6Swillf if (!xdr_osa_policy_ent_rec(&xdrs, *entry))
25154925bf6Swillf ret = OSA_ADB_FAILURE;
25254925bf6Swillf else ret = OSA_ADB_OK;
25354925bf6Swillf xdr_destroy(&xdrs);
25454925bf6Swillf free(aligned_data);
25554925bf6Swillf
25654925bf6Swillf error:
25754925bf6Swillf CLOSELOCK(db);
25854925bf6Swillf return ret;
25954925bf6Swillf }
26054925bf6Swillf
26154925bf6Swillf /*
26254925bf6Swillf * Function: osa_adb_put_policy
26354925bf6Swillf *
26454925bf6Swillf * Purpose: update a policy in the dababase
26554925bf6Swillf *
26654925bf6Swillf * Arguments:
26754925bf6Swillf * db (input) db handle
26854925bf6Swillf * entry (input) policy entry
26954925bf6Swillf * <return value> 0 on success error code on failure.
27054925bf6Swillf *
27154925bf6Swillf * Requires:
27254925bf6Swillf * [requires]
27354925bf6Swillf *
27454925bf6Swillf * Effects:
27554925bf6Swillf * [effects]
27654925bf6Swillf *
27754925bf6Swillf * Modifies:
27854925bf6Swillf * [modifies]
27954925bf6Swillf *
28054925bf6Swillf */
28154925bf6Swillf krb5_error_code
osa_adb_put_policy(osa_adb_policy_t db,osa_policy_ent_t entry)28254925bf6Swillf osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
28354925bf6Swillf {
28454925bf6Swillf DBT dbkey;
28554925bf6Swillf DBT dbdata;
28654925bf6Swillf DBT tmpdb;
28754925bf6Swillf XDR xdrs;
28854925bf6Swillf int ret;
28954925bf6Swillf
29054925bf6Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
29154925bf6Swillf
29254925bf6Swillf if(entry->name == NULL) {
29354925bf6Swillf ret = EINVAL;
29454925bf6Swillf goto error;
29554925bf6Swillf }
29654925bf6Swillf dbkey.data = entry->name;
29754925bf6Swillf dbkey.size = (strlen(entry->name) + 1);
29854925bf6Swillf switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) {
29954925bf6Swillf case 0:
30054925bf6Swillf break;
30154925bf6Swillf case 1:
30254925bf6Swillf ret = OSA_ADB_NOENT;
30354925bf6Swillf goto error;
30454925bf6Swillf default:
30554925bf6Swillf ret = OSA_ADB_FAILURE;
30654925bf6Swillf goto error;
30754925bf6Swillf }
30854925bf6Swillf xdralloc_create(&xdrs, XDR_ENCODE);
30954925bf6Swillf if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
31054925bf6Swillf xdr_destroy(&xdrs);
31154925bf6Swillf ret = OSA_ADB_XDR_FAILURE;
31254925bf6Swillf goto error;
31354925bf6Swillf }
31454925bf6Swillf dbdata.data = xdralloc_getdata(&xdrs);
31554925bf6Swillf dbdata.size = xdr_getpos(&xdrs);
31654925bf6Swillf switch(db->db->put(db->db, &dbkey, &dbdata, 0)) {
31754925bf6Swillf case 0:
31854925bf6Swillf if((db->db->sync(db->db, 0)) == -1)
31954925bf6Swillf ret = OSA_ADB_FAILURE;
32054925bf6Swillf ret = OSA_ADB_OK;
32154925bf6Swillf break;
32254925bf6Swillf default:
32354925bf6Swillf ret = OSA_ADB_FAILURE;
32454925bf6Swillf break;
32554925bf6Swillf }
32654925bf6Swillf xdr_destroy(&xdrs);
32754925bf6Swillf
32854925bf6Swillf error:
32954925bf6Swillf CLOSELOCK(db);
33054925bf6Swillf return ret;
33154925bf6Swillf }
33254925bf6Swillf
33354925bf6Swillf /*
33454925bf6Swillf * Function: osa_adb_iter_policy
33554925bf6Swillf *
33654925bf6Swillf * Purpose: iterate over the policy database.
33754925bf6Swillf *
33854925bf6Swillf * Arguments:
33954925bf6Swillf * db (input) db handle
34054925bf6Swillf * func (input) fucntion pointer to call
34154925bf6Swillf * data opaque data type
34254925bf6Swillf * <return value> 0 on success error code on failure
34354925bf6Swillf *
34454925bf6Swillf * Requires:
34554925bf6Swillf * Effects:
34654925bf6Swillf * Modifies:
34754925bf6Swillf */
34854925bf6Swillf krb5_error_code
osa_adb_iter_policy(osa_adb_policy_t db,osa_adb_iter_policy_func func,void * data)34954925bf6Swillf osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func,
35054925bf6Swillf void *data)
35154925bf6Swillf {
35254925bf6Swillf DBT dbkey,
35354925bf6Swillf dbdata;
35454925bf6Swillf XDR xdrs;
35554925bf6Swillf int ret;
35654925bf6Swillf osa_policy_ent_t entry;
35754925bf6Swillf char *aligned_data;
35854925bf6Swillf
35954925bf6Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */
36054925bf6Swillf
36154925bf6Swillf if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) {
36254925bf6Swillf ret = errno;
36354925bf6Swillf goto error;
36454925bf6Swillf }
36554925bf6Swillf
36654925bf6Swillf while (ret == 0) {
36754925bf6Swillf if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) {
36854925bf6Swillf ret = ENOMEM;
36954925bf6Swillf goto error;
37054925bf6Swillf }
37154925bf6Swillf
37254925bf6Swillf if(!(aligned_data = (char *) malloc(dbdata.size))) {
37354925bf6Swillf ret = ENOMEM;
37454925bf6Swillf goto error;
37554925bf6Swillf }
37654925bf6Swillf memcpy(aligned_data, dbdata.data, dbdata.size);
37754925bf6Swillf
37854925bf6Swillf memset(entry, 0, sizeof(osa_policy_ent_rec));
37954925bf6Swillf xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
38054925bf6Swillf if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
38154925bf6Swillf xdr_destroy(&xdrs);
38254925bf6Swillf free(aligned_data);
38354925bf6Swillf ret = OSA_ADB_FAILURE;
38454925bf6Swillf goto error;
38554925bf6Swillf }
38654925bf6Swillf (*func)(data, entry);
38754925bf6Swillf xdr_destroy(&xdrs);
38854925bf6Swillf free(aligned_data);
38954925bf6Swillf osa_free_policy_ent(entry);
39054925bf6Swillf ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT);
39154925bf6Swillf }
39254925bf6Swillf if(ret == -1)
39354925bf6Swillf ret = errno;
39454925bf6Swillf else ret = OSA_ADB_OK;
39554925bf6Swillf
39654925bf6Swillf error:
39754925bf6Swillf CLOSELOCK(db);
39854925bf6Swillf return ret;
39954925bf6Swillf }
40054925bf6Swillf
40154925bf6Swillf void
osa_free_policy_ent(osa_policy_ent_t val)40254925bf6Swillf osa_free_policy_ent(osa_policy_ent_t val)
40354925bf6Swillf {
40454925bf6Swillf XDR xdrs;
40554925bf6Swillf
40654925bf6Swillf xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
40754925bf6Swillf
40854925bf6Swillf xdr_osa_policy_ent_rec(&xdrs, val);
40954925bf6Swillf
41054925bf6Swillf free(val);
41154925bf6Swillf }
412