14960Swillf
24960Swillf /*
34960Swillf * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
44960Swillf *
54960Swillf * Openvision retains the copyright to derivative works of
64960Swillf * this source code. Do *NOT* create a derivative of this
74960Swillf * source code before consulting with your legal department.
84960Swillf * Do *NOT* integrate *ANY* of this source code into another
94960Swillf * product before consulting with your legal department.
104960Swillf *
114960Swillf * For further information, read the top-level Openvision
124960Swillf * copyright which is contained in the top-level MIT Kerberos
134960Swillf * copyright.
144960Swillf *
154960Swillf * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
164960Swillf *
174960Swillf */
184960Swillf
194960Swillf
204960Swillf /*
214960Swillf * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
224960Swillf *
23*7934SMark.Phalan@Sun.COM * $Header$
244960Swillf */
254960Swillf
264960Swillf #if !defined(lint) && !defined(__CODECENTER__)
27*7934SMark.Phalan@Sun.COM static char *rcsid = "$Header$";
284960Swillf #endif
294960Swillf
304960Swillf #include <sys/file.h>
314960Swillf #include <fcntl.h>
324960Swillf #include "policy_db.h"
334960Swillf #include <stdlib.h>
344960Swillf #include <string.h>
354960Swillf #include <errno.h>
364960Swillf
374960Swillf extern caddr_t xdralloc_getdata(XDR *xdrs);
384960Swillf extern void xdralloc_create(XDR *xdrs, enum xdr_op op);
394960Swillf
404960Swillf #define OPENLOCK(db, mode) \
414960Swillf { \
424960Swillf int olret; \
434960Swillf if (db == NULL) \
444960Swillf return EINVAL; \
454960Swillf else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \
464960Swillf return OSA_ADB_DBINIT; \
474960Swillf else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \
484960Swillf return olret; \
494960Swillf }
504960Swillf
514960Swillf #define CLOSELOCK(db) \
524960Swillf { \
534960Swillf int cl_ret; \
544960Swillf if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \
554960Swillf return cl_ret; \
564960Swillf }
574960Swillf
584960Swillf
594960Swillf /*
604960Swillf * Function: osa_adb_create_policy
614960Swillf *
624960Swillf * Purpose: create a policy entry in the policy db.
634960Swillf *
644960Swillf * Arguments:
654960Swillf * entry (input) pointer to the entry to be added
664960Swillf * <return value> OSA_ADB_OK on success, else error code.
674960Swillf *
684960Swillf * Requires:
694960Swillf * entry have a valid name.
704960Swillf *
714960Swillf * Effects:
724960Swillf * creates the entry in the db
734960Swillf *
744960Swillf * Modifies:
754960Swillf * the policy db.
764960Swillf *
774960Swillf */
784960Swillf krb5_error_code
osa_adb_create_policy(osa_adb_policy_t db,osa_policy_ent_t entry)794960Swillf osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
804960Swillf {
814960Swillf DBT dbkey;
824960Swillf DBT dbdata;
834960Swillf XDR xdrs;
844960Swillf int ret;
854960Swillf
864960Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
874960Swillf
884960Swillf if(entry->name == NULL) {
894960Swillf ret = EINVAL;
904960Swillf goto error;
914960Swillf }
924960Swillf dbkey.data = entry->name;
934960Swillf dbkey.size = (strlen(entry->name) + 1);
944960Swillf
954960Swillf switch(db->db->get(db->db, &dbkey, &dbdata, 0)) {
964960Swillf case 0:
974960Swillf ret = OSA_ADB_DUP;
984960Swillf goto error;
994960Swillf case 1:
1004960Swillf break;
1014960Swillf default:
1024960Swillf ret = errno;
1034960Swillf goto error;
1044960Swillf }
1054960Swillf xdralloc_create(&xdrs, XDR_ENCODE);
1064960Swillf if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
1074960Swillf xdr_destroy(&xdrs);
1084960Swillf ret = OSA_ADB_XDR_FAILURE;
1094960Swillf goto error;
1104960Swillf }
1114960Swillf dbdata.data = xdralloc_getdata(&xdrs);
1124960Swillf dbdata.size = xdr_getpos(&xdrs);
1134960Swillf switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) {
1144960Swillf case 0:
1154960Swillf if((db->db->sync(db->db, 0)) == -1)
1164960Swillf ret = OSA_ADB_FAILURE;
1174960Swillf ret = OSA_ADB_OK;
1184960Swillf break;
1194960Swillf case 1:
1204960Swillf ret = OSA_ADB_DUP;
1214960Swillf break;
1224960Swillf default:
1234960Swillf ret = OSA_ADB_FAILURE;
1244960Swillf break;
1254960Swillf }
1264960Swillf xdr_destroy(&xdrs);
1274960Swillf
1284960Swillf error:
1294960Swillf CLOSELOCK(db);
1304960Swillf return ret;
1314960Swillf }
1324960Swillf
1334960Swillf /*
1344960Swillf * Function: osa_adb_destroy_policy
1354960Swillf *
1364960Swillf * Purpose: destroy a policy entry
1374960Swillf *
1384960Swillf * Arguments:
1394960Swillf * db (input) database handle
1404960Swillf * name (input) name of policy
1414960Swillf * <return value> OSA_ADB_OK on success, or error code.
1424960Swillf *
1434960Swillf * Requires:
1444960Swillf * db being valid.
1454960Swillf * name being non-null.
1464960Swillf * Effects:
1474960Swillf * deletes policy from db.
1484960Swillf *
1494960Swillf * Modifies:
1504960Swillf * policy db.
1514960Swillf *
1524960Swillf */
1534960Swillf krb5_error_code
osa_adb_destroy_policy(osa_adb_policy_t db,char * name)1544960Swillf osa_adb_destroy_policy(osa_adb_policy_t db, char *name)
1554960Swillf {
1564960Swillf DBT dbkey;
1574960Swillf int status, ret;
1584960Swillf
1594960Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
1604960Swillf
1614960Swillf if(name == NULL) {
1624960Swillf ret = EINVAL;
1634960Swillf goto error;
1644960Swillf }
1654960Swillf dbkey.data = name;
1664960Swillf dbkey.size = (strlen(name) + 1);
1674960Swillf
1684960Swillf status = db->db->del(db->db, &dbkey, 0);
1694960Swillf switch(status) {
1704960Swillf case 1:
1714960Swillf ret = OSA_ADB_NOENT;
1724960Swillf goto error;
1734960Swillf case 0:
1744960Swillf if ((db->db->sync(db->db, 0)) == -1) {
1754960Swillf ret = OSA_ADB_FAILURE;
1764960Swillf goto error;
1774960Swillf }
1784960Swillf ret = OSA_ADB_OK;
1794960Swillf break;
1804960Swillf default:
1814960Swillf ret = OSA_ADB_FAILURE;
1824960Swillf goto error;
1834960Swillf }
1844960Swillf
1854960Swillf error:
1864960Swillf CLOSELOCK(db);
1874960Swillf return ret;
1884960Swillf }
1894960Swillf
1904960Swillf /*
1914960Swillf * Function: osa_adb_get_policy
1924960Swillf *
1934960Swillf * Purpose: retrieve policy
1944960Swillf *
1954960Swillf * Arguments:
1964960Swillf * db (input) db handle
1974960Swillf * name (input) name of policy
1984960Swillf * entry (output) policy entry
1994960Swillf * cnt (inout) Number of entries
2004960Swillf * <return value> 0 on success, error code on failure.
2014960Swillf *
2024960Swillf * Requires:
2034960Swillf * Effects:
2044960Swillf * Modifies:
2054960Swillf */
2064960Swillf krb5_error_code
osa_adb_get_policy(osa_adb_policy_t db,char * name,osa_policy_ent_t * entry,int * cnt)2074960Swillf osa_adb_get_policy(osa_adb_policy_t db, char *name,
2084960Swillf osa_policy_ent_t *entry, int *cnt)
2094960Swillf {
2104960Swillf DBT dbkey;
2114960Swillf DBT dbdata;
2124960Swillf XDR xdrs;
2134960Swillf int ret;
2144960Swillf char *aligned_data;
2154960Swillf
2164960Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED);
2174960Swillf
2184960Swillf *cnt = 1;
2194960Swillf
2204960Swillf if(name == NULL) {
2214960Swillf ret = EINVAL;
2224960Swillf goto error;
2234960Swillf }
2244960Swillf dbkey.data = name;
2254960Swillf dbkey.size = (strlen(dbkey.data) + 1);
2264960Swillf dbdata.data = NULL;
2274960Swillf dbdata.size = 0;
2284960Swillf switch((db->db->get(db->db, &dbkey, &dbdata, 0))) {
2294960Swillf case 1:
2304960Swillf ret = OSA_ADB_OK;
2314960Swillf *cnt = 0;
2324960Swillf goto error;
2334960Swillf case 0:
2344960Swillf break;
2354960Swillf default:
2364960Swillf ret = OSA_ADB_FAILURE;
2374960Swillf goto error;
2384960Swillf }
2394960Swillf if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) {
2404960Swillf ret = ENOMEM;
2414960Swillf goto error;
2424960Swillf }
2434960Swillf if (!(aligned_data = (char *) malloc(dbdata.size))) {
2444960Swillf ret = ENOMEM;
2454960Swillf goto error;
2464960Swillf }
2474960Swillf memcpy(aligned_data, dbdata.data, dbdata.size);
2484960Swillf memset(*entry, 0, sizeof(osa_policy_ent_rec));
2494960Swillf xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
2504960Swillf if (!xdr_osa_policy_ent_rec(&xdrs, *entry))
2514960Swillf ret = OSA_ADB_FAILURE;
2524960Swillf else ret = OSA_ADB_OK;
2534960Swillf xdr_destroy(&xdrs);
2544960Swillf free(aligned_data);
2554960Swillf
2564960Swillf error:
2574960Swillf CLOSELOCK(db);
2584960Swillf return ret;
2594960Swillf }
2604960Swillf
2614960Swillf /*
2624960Swillf * Function: osa_adb_put_policy
2634960Swillf *
2644960Swillf * Purpose: update a policy in the dababase
2654960Swillf *
2664960Swillf * Arguments:
2674960Swillf * db (input) db handle
2684960Swillf * entry (input) policy entry
2694960Swillf * <return value> 0 on success error code on failure.
2704960Swillf *
2714960Swillf * Requires:
2724960Swillf * [requires]
2734960Swillf *
2744960Swillf * Effects:
2754960Swillf * [effects]
2764960Swillf *
2774960Swillf * Modifies:
2784960Swillf * [modifies]
2794960Swillf *
2804960Swillf */
2814960Swillf krb5_error_code
osa_adb_put_policy(osa_adb_policy_t db,osa_policy_ent_t entry)2824960Swillf osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
2834960Swillf {
2844960Swillf DBT dbkey;
2854960Swillf DBT dbdata;
2864960Swillf DBT tmpdb;
2874960Swillf XDR xdrs;
2884960Swillf int ret;
2894960Swillf
2904960Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
2914960Swillf
2924960Swillf if(entry->name == NULL) {
2934960Swillf ret = EINVAL;
2944960Swillf goto error;
2954960Swillf }
2964960Swillf dbkey.data = entry->name;
2974960Swillf dbkey.size = (strlen(entry->name) + 1);
2984960Swillf switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) {
2994960Swillf case 0:
3004960Swillf break;
3014960Swillf case 1:
3024960Swillf ret = OSA_ADB_NOENT;
3034960Swillf goto error;
3044960Swillf default:
3054960Swillf ret = OSA_ADB_FAILURE;
3064960Swillf goto error;
3074960Swillf }
3084960Swillf xdralloc_create(&xdrs, XDR_ENCODE);
3094960Swillf if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
3104960Swillf xdr_destroy(&xdrs);
3114960Swillf ret = OSA_ADB_XDR_FAILURE;
3124960Swillf goto error;
3134960Swillf }
3144960Swillf dbdata.data = xdralloc_getdata(&xdrs);
3154960Swillf dbdata.size = xdr_getpos(&xdrs);
3164960Swillf switch(db->db->put(db->db, &dbkey, &dbdata, 0)) {
3174960Swillf case 0:
3184960Swillf if((db->db->sync(db->db, 0)) == -1)
3194960Swillf ret = OSA_ADB_FAILURE;
3204960Swillf ret = OSA_ADB_OK;
3214960Swillf break;
3224960Swillf default:
3234960Swillf ret = OSA_ADB_FAILURE;
3244960Swillf break;
3254960Swillf }
3264960Swillf xdr_destroy(&xdrs);
3274960Swillf
3284960Swillf error:
3294960Swillf CLOSELOCK(db);
3304960Swillf return ret;
3314960Swillf }
3324960Swillf
3334960Swillf /*
3344960Swillf * Function: osa_adb_iter_policy
3354960Swillf *
3364960Swillf * Purpose: iterate over the policy database.
3374960Swillf *
3384960Swillf * Arguments:
3394960Swillf * db (input) db handle
3404960Swillf * func (input) fucntion pointer to call
3414960Swillf * data opaque data type
3424960Swillf * <return value> 0 on success error code on failure
3434960Swillf *
3444960Swillf * Requires:
3454960Swillf * Effects:
3464960Swillf * Modifies:
3474960Swillf */
3484960Swillf krb5_error_code
osa_adb_iter_policy(osa_adb_policy_t db,osa_adb_iter_policy_func func,void * data)3494960Swillf osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func,
3504960Swillf void *data)
3514960Swillf {
3524960Swillf DBT dbkey,
3534960Swillf dbdata;
3544960Swillf XDR xdrs;
3554960Swillf int ret;
3564960Swillf osa_policy_ent_t entry;
3574960Swillf char *aligned_data;
3584960Swillf
3594960Swillf OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */
3604960Swillf
3614960Swillf if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) {
3624960Swillf ret = errno;
3634960Swillf goto error;
3644960Swillf }
3654960Swillf
3664960Swillf while (ret == 0) {
3674960Swillf if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) {
3684960Swillf ret = ENOMEM;
3694960Swillf goto error;
3704960Swillf }
3714960Swillf
3724960Swillf if(!(aligned_data = (char *) malloc(dbdata.size))) {
3734960Swillf ret = ENOMEM;
3744960Swillf goto error;
3754960Swillf }
3764960Swillf memcpy(aligned_data, dbdata.data, dbdata.size);
3774960Swillf
3784960Swillf memset(entry, 0, sizeof(osa_policy_ent_rec));
3794960Swillf xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
3804960Swillf if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
3814960Swillf xdr_destroy(&xdrs);
3824960Swillf free(aligned_data);
3834960Swillf ret = OSA_ADB_FAILURE;
3844960Swillf goto error;
3854960Swillf }
3864960Swillf (*func)(data, entry);
3874960Swillf xdr_destroy(&xdrs);
3884960Swillf free(aligned_data);
3894960Swillf osa_free_policy_ent(entry);
3904960Swillf ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT);
3914960Swillf }
3924960Swillf if(ret == -1)
3934960Swillf ret = errno;
3944960Swillf else ret = OSA_ADB_OK;
3954960Swillf
3964960Swillf error:
3974960Swillf CLOSELOCK(db);
3984960Swillf return ret;
3994960Swillf }
4004960Swillf
4014960Swillf void
osa_free_policy_ent(osa_policy_ent_t val)4024960Swillf osa_free_policy_ent(osa_policy_ent_t val)
4034960Swillf {
4044960Swillf XDR xdrs;
4054960Swillf
4064960Swillf xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
4074960Swillf
4084960Swillf xdr_osa_policy_ent_rec(&xdrs, val);
4094960Swillf
4104960Swillf free(val);
4114960Swillf }
412