xref: /illumos-gate/usr/src/lib/krb5/plugins/kdb/db2/adb_policy.c (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
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