2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2N/A/*
2N/A * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
2N/A *
2N/A * $Header$
2N/A */
2N/A
2N/A/*
2N/A * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
2N/A *
2N/A * Openvision retains the copyright to derivative works of
2N/A * this source code. Do *NOT* create a derivative of this
2N/A * source code before consulting with your legal department.
2N/A * Do *NOT* integrate *ANY* of this source code into another
2N/A * product before consulting with your legal department.
2N/A *
2N/A * For further information, read the top-level Openvision
2N/A * copyright which is contained in the top-level MIT Kerberos
2N/A * copyright.
2N/A *
2N/A * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
2N/A *
2N/A */
2N/A
2N/A#if !defined(lint) && !defined(__CODECENTER__)
2N/Astatic char *rcsid = "$Header$";
2N/A#endif
2N/A
2N/A#include <sys/file.h>
2N/A#include <fcntl.h>
2N/A#include "policy_db.h"
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <errno.h>
2N/A
2N/A#define OPENLOCK(db, mode) \
2N/A { \
2N/A int olret; \
2N/A if (db == NULL) \
2N/A return EINVAL; \
2N/A else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \
2N/A return OSA_ADB_DBINIT; \
2N/A else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \
2N/A return olret; \
2N/A }
2N/A
2N/A#define CLOSELOCK(db) \
2N/A { \
2N/A int cl_ret; \
2N/A if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \
2N/A return cl_ret; \
2N/A }
2N/A
2N/A
2N/A/*
2N/A * Function: osa_adb_create_policy
2N/A *
2N/A * Purpose: create a policy entry in the policy db.
2N/A *
2N/A * Arguments:
2N/A * entry (input) pointer to the entry to be added
2N/A * <return value> OSA_ADB_OK on success, else error code.
2N/A *
2N/A * Requires:
2N/A * entry have a valid name.
2N/A *
2N/A * Effects:
2N/A * creates the entry in the db
2N/A *
2N/A * Modifies:
2N/A * the policy db.
2N/A *
2N/A */
2N/Akrb5_error_code
2N/Aosa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
2N/A{
2N/A DBT dbkey;
2N/A DBT dbdata;
2N/A XDR xdrs;
2N/A int ret;
2N/A
2N/A OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
2N/A
2N/A if(entry->name == NULL) {
2N/A ret = EINVAL;
2N/A goto error;
2N/A }
2N/A dbkey.data = entry->name;
2N/A dbkey.size = (strlen(entry->name) + 1);
2N/A
2N/A switch(db->db->get(db->db, &dbkey, &dbdata, 0)) {
2N/A case 0:
2N/A ret = OSA_ADB_DUP;
2N/A goto error;
2N/A case 1:
2N/A break;
2N/A default:
2N/A ret = errno;
2N/A goto error;
2N/A }
2N/A xdralloc_create(&xdrs, XDR_ENCODE);
2N/A if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
2N/A xdr_destroy(&xdrs);
2N/A ret = OSA_ADB_XDR_FAILURE;
2N/A goto error;
2N/A }
2N/A dbdata.data = xdralloc_getdata(&xdrs);
2N/A dbdata.size = xdr_getpos(&xdrs);
2N/A switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) {
2N/A case 0:
2N/A if((db->db->sync(db->db, 0)) == -1)
2N/A ret = OSA_ADB_FAILURE;
2N/A ret = OSA_ADB_OK;
2N/A break;
2N/A case 1:
2N/A ret = OSA_ADB_DUP;
2N/A break;
2N/A default:
2N/A ret = OSA_ADB_FAILURE;
2N/A break;
2N/A }
2N/A xdr_destroy(&xdrs);
2N/A
2N/Aerror:
2N/A CLOSELOCK(db);
2N/A return ret;
2N/A}
2N/A
2N/A/*
2N/A * Function: osa_adb_destroy_policy
2N/A *
2N/A * Purpose: destroy a policy entry
2N/A *
2N/A * Arguments:
2N/A * db (input) database handle
2N/A * name (input) name of policy
2N/A * <return value> OSA_ADB_OK on success, or error code.
2N/A *
2N/A * Requires:
2N/A * db being valid.
2N/A * name being non-null.
2N/A * Effects:
2N/A * deletes policy from db.
2N/A *
2N/A * Modifies:
2N/A * policy db.
2N/A *
2N/A */
2N/Akrb5_error_code
2N/Aosa_adb_destroy_policy(osa_adb_policy_t db, char *name)
2N/A{
2N/A DBT dbkey;
2N/A int status, ret;
2N/A
2N/A OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
2N/A
2N/A if(name == NULL) {
2N/A ret = EINVAL;
2N/A goto error;
2N/A }
2N/A dbkey.data = name;
2N/A dbkey.size = (strlen(name) + 1);
2N/A
2N/A status = db->db->del(db->db, &dbkey, 0);
2N/A switch(status) {
2N/A case 1:
2N/A ret = OSA_ADB_NOENT;
2N/A goto error;
2N/A case 0:
2N/A if ((db->db->sync(db->db, 0)) == -1) {
2N/A ret = OSA_ADB_FAILURE;
2N/A goto error;
2N/A }
2N/A ret = OSA_ADB_OK;
2N/A break;
2N/A default:
2N/A ret = OSA_ADB_FAILURE;
2N/A goto error;
2N/A }
2N/A
2N/Aerror:
2N/A CLOSELOCK(db);
2N/A return ret;
2N/A}
2N/A
2N/A/*
2N/A * Function: osa_adb_get_policy
2N/A *
2N/A * Purpose: retrieve policy
2N/A *
2N/A * Arguments:
2N/A * db (input) db handle
2N/A * name (input) name of policy
2N/A * entry (output) policy entry
2N/A * cnt (inout) Number of entries
2N/A * <return value> 0 on success, error code on failure.
2N/A *
2N/A * Requires:
2N/A * Effects:
2N/A * Modifies:
2N/A */
2N/Akrb5_error_code
2N/Aosa_adb_get_policy(osa_adb_policy_t db, char *name,
2N/A osa_policy_ent_t *entry, int *cnt)
2N/A{
2N/A DBT dbkey;
2N/A DBT dbdata;
2N/A XDR xdrs;
2N/A int ret;
2N/A char *aligned_data;
2N/A
2N/A OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED);
2N/A
2N/A *cnt = 1;
2N/A
2N/A if(name == NULL) {
2N/A ret = EINVAL;
2N/A goto error;
2N/A }
2N/A dbkey.data = name;
2N/A dbkey.size = (strlen(dbkey.data) + 1);
2N/A dbdata.data = NULL;
2N/A dbdata.size = 0;
2N/A switch((db->db->get(db->db, &dbkey, &dbdata, 0))) {
2N/A case 1:
2N/A ret = 0;
2N/A *cnt = 0;
2N/A goto error;
2N/A case 0:
2N/A break;
2N/A default:
2N/A ret = OSA_ADB_FAILURE;
2N/A goto error;
2N/A }
2N/A if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) {
2N/A ret = ENOMEM;
2N/A goto error;
2N/A }
2N/A if (!(aligned_data = (char *) malloc(dbdata.size))) {
2N/A ret = ENOMEM;
2N/A goto error;
2N/A }
2N/A memcpy(aligned_data, dbdata.data, dbdata.size);
2N/A memset(*entry, 0, sizeof(osa_policy_ent_rec));
2N/A xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
2N/A if (!xdr_osa_policy_ent_rec(&xdrs, *entry))
2N/A ret = OSA_ADB_FAILURE;
2N/A else ret = OSA_ADB_OK;
2N/A xdr_destroy(&xdrs);
2N/A free(aligned_data);
2N/A
2N/Aerror:
2N/A CLOSELOCK(db);
2N/A return ret;
2N/A}
2N/A
2N/A/*
2N/A * Function: osa_adb_put_policy
2N/A *
2N/A * Purpose: update a policy in the dababase
2N/A *
2N/A * Arguments:
2N/A * db (input) db handle
2N/A * entry (input) policy entry
2N/A * <return value> 0 on success error code on failure.
2N/A *
2N/A * Requires:
2N/A * [requires]
2N/A *
2N/A * Effects:
2N/A * [effects]
2N/A *
2N/A * Modifies:
2N/A * [modifies]
2N/A *
2N/A */
2N/Akrb5_error_code
2N/Aosa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
2N/A{
2N/A DBT dbkey;
2N/A DBT dbdata;
2N/A DBT tmpdb;
2N/A XDR xdrs;
2N/A int ret;
2N/A
2N/A OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
2N/A
2N/A if(entry->name == NULL) {
2N/A ret = EINVAL;
2N/A goto error;
2N/A }
2N/A dbkey.data = entry->name;
2N/A dbkey.size = (strlen(entry->name) + 1);
2N/A switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) {
2N/A case 0:
2N/A break;
2N/A case 1:
2N/A ret = OSA_ADB_NOENT;
2N/A goto error;
2N/A default:
2N/A ret = OSA_ADB_FAILURE;
2N/A goto error;
2N/A }
2N/A xdralloc_create(&xdrs, XDR_ENCODE);
2N/A if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
2N/A xdr_destroy(&xdrs);
2N/A ret = OSA_ADB_XDR_FAILURE;
2N/A goto error;
2N/A }
2N/A dbdata.data = xdralloc_getdata(&xdrs);
2N/A dbdata.size = xdr_getpos(&xdrs);
2N/A switch(db->db->put(db->db, &dbkey, &dbdata, 0)) {
2N/A case 0:
2N/A if((db->db->sync(db->db, 0)) == -1)
2N/A ret = OSA_ADB_FAILURE;
2N/A ret = OSA_ADB_OK;
2N/A break;
2N/A default:
2N/A ret = OSA_ADB_FAILURE;
2N/A break;
2N/A }
2N/A xdr_destroy(&xdrs);
2N/A
2N/Aerror:
2N/A CLOSELOCK(db);
2N/A return ret;
2N/A}
2N/A
2N/A/*
2N/A * Function: osa_adb_iter_policy
2N/A *
2N/A * Purpose: iterate over the policy database.
2N/A *
2N/A * Arguments:
2N/A * db (input) db handle
2N/A * func (input) fucntion pointer to call
2N/A * data opaque data type
2N/A * <return value> 0 on success error code on failure
2N/A *
2N/A * Requires:
2N/A * Effects:
2N/A * Modifies:
2N/A */
2N/Akrb5_error_code
2N/Aosa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func,
2N/A void *data)
2N/A{
2N/A DBT dbkey,
2N/A dbdata;
2N/A XDR xdrs;
2N/A int ret;
2N/A osa_policy_ent_t entry;
2N/A char *aligned_data;
2N/A
2N/A OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */
2N/A
2N/A if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) {
2N/A ret = errno;
2N/A goto error;
2N/A }
2N/A
2N/A while (ret == 0) {
2N/A if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) {
2N/A ret = ENOMEM;
2N/A goto error;
2N/A }
2N/A
2N/A if(!(aligned_data = (char *) malloc(dbdata.size))) {
2N/A ret = ENOMEM;
2N/A /* Solaris Kerberos */
2N/A free(entry);
2N/A goto error;
2N/A }
2N/A memcpy(aligned_data, dbdata.data, dbdata.size);
2N/A
2N/A memset(entry, 0, sizeof(osa_policy_ent_rec));
2N/A xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
2N/A if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
2N/A xdr_destroy(&xdrs);
2N/A free(aligned_data);
2N/A osa_free_policy_ent(entry);
2N/A ret = OSA_ADB_FAILURE;
2N/A goto error;
2N/A }
2N/A (*func)(data, entry);
2N/A xdr_destroy(&xdrs);
2N/A free(aligned_data);
2N/A osa_free_policy_ent(entry);
2N/A ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT);
2N/A }
2N/A if(ret == -1)
2N/A ret = errno;
2N/A else ret = OSA_ADB_OK;
2N/A
2N/Aerror:
2N/A CLOSELOCK(db);
2N/A return ret;
2N/A}
2N/A
2N/Avoid
2N/Aosa_free_policy_ent(osa_policy_ent_t val)
2N/A{
2N/A XDR xdrs;
2N/A
2N/A xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
2N/A
2N/A xdr_osa_policy_ent_rec(&xdrs, val);
2N/A
2N/A free(val);
2N/A}