17c478bd9Sstevel@tonic-gate 
27c478bd9Sstevel@tonic-gate /*
3*55fea89dSDan Cross  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
67c478bd9Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
77c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
87c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
97c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
127c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
137c478bd9Sstevel@tonic-gate  *	copyright.
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
167c478bd9Sstevel@tonic-gate  *
177c478bd9Sstevel@tonic-gate  */
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /*
217c478bd9Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
227c478bd9Sstevel@tonic-gate  *
23159d09a2SMark Phalan  * $Header$
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
27159d09a2SMark Phalan static char *rcsid = "$Header$";
287c478bd9Sstevel@tonic-gate #endif
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include	<sys/file.h>
317c478bd9Sstevel@tonic-gate #include	<fcntl.h>
3254925bf6Swillf #include	"policy_db.h"
337c478bd9Sstevel@tonic-gate #include	<stdlib.h>
347c478bd9Sstevel@tonic-gate #include	<string.h>
3556a424ccSmp #include <errno.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate extern	caddr_t xdralloc_getdata(XDR *xdrs);
387c478bd9Sstevel@tonic-gate extern	void xdralloc_create(XDR *xdrs, enum xdr_op op);
3956a424ccSmp 
407c478bd9Sstevel@tonic-gate #define OPENLOCK(db, mode) \
417c478bd9Sstevel@tonic-gate { \
4256a424ccSmp        int olret; \
437c478bd9Sstevel@tonic-gate 	    if (db == NULL) \
447c478bd9Sstevel@tonic-gate 		 return EINVAL; \
457c478bd9Sstevel@tonic-gate 	    else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \
467c478bd9Sstevel@tonic-gate 		 return OSA_ADB_DBINIT; \
4756a424ccSmp 	    else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \
4856a424ccSmp 		 return olret; \
497c478bd9Sstevel@tonic-gate 	    }
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #define CLOSELOCK(db) \
527c478bd9Sstevel@tonic-gate { \
5356a424ccSmp      int cl_ret; \
5456a424ccSmp      if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \
5556a424ccSmp 	  return cl_ret; \
567c478bd9Sstevel@tonic-gate }
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /*
607c478bd9Sstevel@tonic-gate  * Function: osa_adb_create_policy
61*55fea89dSDan Cross  *
627c478bd9Sstevel@tonic-gate  * Purpose: create a policy entry in the policy db.
637c478bd9Sstevel@tonic-gate  *
647c478bd9Sstevel@tonic-gate  * Arguments:
657c478bd9Sstevel@tonic-gate  *	entry		(input) pointer to the entry to be added
6656a424ccSmp  * 	<return value>	OSA_ADB_OK on success, else error code.
677c478bd9Sstevel@tonic-gate  *
687c478bd9Sstevel@tonic-gate  * Requires:
697c478bd9Sstevel@tonic-gate  *	entry have a valid name.
70*55fea89dSDan Cross  *
717c478bd9Sstevel@tonic-gate  * Effects:
727c478bd9Sstevel@tonic-gate  *	creates the entry in the db
737c478bd9Sstevel@tonic-gate  *
747c478bd9Sstevel@tonic-gate  * Modifies:
757c478bd9Sstevel@tonic-gate  *	the policy db.
76*55fea89dSDan Cross  *
777c478bd9Sstevel@tonic-gate  */
7854925bf6Swillf krb5_error_code
osa_adb_create_policy(osa_adb_policy_t db,osa_policy_ent_t entry)797c478bd9Sstevel@tonic-gate osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
807c478bd9Sstevel@tonic-gate {
817c478bd9Sstevel@tonic-gate     DBT			dbkey;
827c478bd9Sstevel@tonic-gate     DBT			dbdata;
837c478bd9Sstevel@tonic-gate     XDR			xdrs;
847c478bd9Sstevel@tonic-gate     int			ret;
857c478bd9Sstevel@tonic-gate 
8654925bf6Swillf     OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate     if(entry->name == NULL) {
897c478bd9Sstevel@tonic-gate 	 ret = EINVAL;
907c478bd9Sstevel@tonic-gate 	 goto error;
917c478bd9Sstevel@tonic-gate     }
927c478bd9Sstevel@tonic-gate     dbkey.data = entry->name;
937c478bd9Sstevel@tonic-gate     dbkey.size = (strlen(entry->name) + 1);
94*55fea89dSDan Cross 
957c478bd9Sstevel@tonic-gate     switch(db->db->get(db->db, &dbkey, &dbdata, 0)) {
967c478bd9Sstevel@tonic-gate     case 0:
977c478bd9Sstevel@tonic-gate 	 ret = OSA_ADB_DUP;
987c478bd9Sstevel@tonic-gate 	 goto error;
997c478bd9Sstevel@tonic-gate     case 1:
1007c478bd9Sstevel@tonic-gate 	break;
1017c478bd9Sstevel@tonic-gate     default:
1027c478bd9Sstevel@tonic-gate 	 ret = errno;
1037c478bd9Sstevel@tonic-gate 	 goto error;
1047c478bd9Sstevel@tonic-gate     }
1057c478bd9Sstevel@tonic-gate     xdralloc_create(&xdrs, XDR_ENCODE);
1067c478bd9Sstevel@tonic-gate     if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
1077c478bd9Sstevel@tonic-gate 	xdr_destroy(&xdrs);
1087c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_XDR_FAILURE;
1097c478bd9Sstevel@tonic-gate 	goto error;
1107c478bd9Sstevel@tonic-gate     }
1117c478bd9Sstevel@tonic-gate     dbdata.data = xdralloc_getdata(&xdrs);
1127c478bd9Sstevel@tonic-gate     dbdata.size = xdr_getpos(&xdrs);
1137c478bd9Sstevel@tonic-gate     switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) {
1147c478bd9Sstevel@tonic-gate     case 0:
1157c478bd9Sstevel@tonic-gate 	if((db->db->sync(db->db, 0)) == -1)
1167c478bd9Sstevel@tonic-gate 	    ret = OSA_ADB_FAILURE;
1177c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_OK;
1187c478bd9Sstevel@tonic-gate 	break;
1197c478bd9Sstevel@tonic-gate     case 1:
1207c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_DUP;
1217c478bd9Sstevel@tonic-gate 	break;
1227c478bd9Sstevel@tonic-gate     default:
1237c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_FAILURE;
1247c478bd9Sstevel@tonic-gate 	break;
1257c478bd9Sstevel@tonic-gate     }
1267c478bd9Sstevel@tonic-gate     xdr_destroy(&xdrs);
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate error:
1297c478bd9Sstevel@tonic-gate     CLOSELOCK(db);
1307c478bd9Sstevel@tonic-gate     return ret;
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate /*
1347c478bd9Sstevel@tonic-gate  * Function: osa_adb_destroy_policy
135*55fea89dSDan Cross  *
1367c478bd9Sstevel@tonic-gate  * Purpose: destroy a policy entry
1377c478bd9Sstevel@tonic-gate  *
1387c478bd9Sstevel@tonic-gate  * Arguments:
1397c478bd9Sstevel@tonic-gate  *	db		(input) database handle
1407c478bd9Sstevel@tonic-gate  *	name		(input) name of policy
14156a424ccSmp  * 	<return value>	OSA_ADB_OK on success, or error code.
1427c478bd9Sstevel@tonic-gate  *
1437c478bd9Sstevel@tonic-gate  * Requires:
1447c478bd9Sstevel@tonic-gate  *	db being valid.
1457c478bd9Sstevel@tonic-gate  *	name being non-null.
1467c478bd9Sstevel@tonic-gate  * Effects:
1477c478bd9Sstevel@tonic-gate  *	deletes policy from db.
1487c478bd9Sstevel@tonic-gate  *
1497c478bd9Sstevel@tonic-gate  * Modifies:
1507c478bd9Sstevel@tonic-gate  *	policy db.
151*55fea89dSDan Cross  *
1527c478bd9Sstevel@tonic-gate  */
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)
1557c478bd9Sstevel@tonic-gate {
1567c478bd9Sstevel@tonic-gate     DBT	    dbkey;
1577c478bd9Sstevel@tonic-gate     int	    status, ret;
1587c478bd9Sstevel@tonic-gate 
15954925bf6Swillf     OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
160*55fea89dSDan Cross 
1617c478bd9Sstevel@tonic-gate     if(name == NULL) {
1627c478bd9Sstevel@tonic-gate 	 ret = EINVAL;
1637c478bd9Sstevel@tonic-gate 	 goto error;
1647c478bd9Sstevel@tonic-gate     }
1657c478bd9Sstevel@tonic-gate     dbkey.data = name;
1667c478bd9Sstevel@tonic-gate     dbkey.size = (strlen(name) + 1);
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate     status = db->db->del(db->db, &dbkey, 0);
1697c478bd9Sstevel@tonic-gate     switch(status) {
1707c478bd9Sstevel@tonic-gate     case 1:
1717c478bd9Sstevel@tonic-gate 	 ret = OSA_ADB_NOENT;
1727c478bd9Sstevel@tonic-gate 	 goto error;
1737c478bd9Sstevel@tonic-gate     case 0:
1747c478bd9Sstevel@tonic-gate 	 if ((db->db->sync(db->db, 0)) == -1) {
1757c478bd9Sstevel@tonic-gate 	      ret = OSA_ADB_FAILURE;
1767c478bd9Sstevel@tonic-gate 	      goto error;
1777c478bd9Sstevel@tonic-gate 	 }
1787c478bd9Sstevel@tonic-gate 	 ret = OSA_ADB_OK;
1797c478bd9Sstevel@tonic-gate 	 break;
1807c478bd9Sstevel@tonic-gate     default:
1817c478bd9Sstevel@tonic-gate 	 ret = OSA_ADB_FAILURE;
1827c478bd9Sstevel@tonic-gate 	 goto error;
1837c478bd9Sstevel@tonic-gate     }
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate error:
1867c478bd9Sstevel@tonic-gate     CLOSELOCK(db);
1877c478bd9Sstevel@tonic-gate     return ret;
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate  * Function: osa_adb_get_policy
192*55fea89dSDan Cross  *
1937c478bd9Sstevel@tonic-gate  * Purpose: retrieve policy
1947c478bd9Sstevel@tonic-gate  *
1957c478bd9Sstevel@tonic-gate  * Arguments:
1967c478bd9Sstevel@tonic-gate  *	db		(input) db handle
1977c478bd9Sstevel@tonic-gate  *	name		(input) name of policy
1987c478bd9Sstevel@tonic-gate  *	entry		(output) policy entry
19954925bf6Swillf  *      cnt             (inout) Number of entries
20056a424ccSmp  * 	<return value>	0 on success, error code on failure.
2017c478bd9Sstevel@tonic-gate  *
2027c478bd9Sstevel@tonic-gate  * Requires:
2037c478bd9Sstevel@tonic-gate  * Effects:
2047c478bd9Sstevel@tonic-gate  * Modifies:
2057c478bd9Sstevel@tonic-gate  */
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)
2097c478bd9Sstevel@tonic-gate {
2107c478bd9Sstevel@tonic-gate     DBT			dbkey;
2117c478bd9Sstevel@tonic-gate     DBT			dbdata;
2127c478bd9Sstevel@tonic-gate     XDR			xdrs;
2137c478bd9Sstevel@tonic-gate     int			ret;
2147c478bd9Sstevel@tonic-gate     char		*aligned_data;
2157c478bd9Sstevel@tonic-gate 
21654925bf6Swillf     OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED);
21754925bf6Swillf 
21854925bf6Swillf     *cnt = 1;
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate     if(name == NULL) {
2217c478bd9Sstevel@tonic-gate 	 ret = EINVAL;
2227c478bd9Sstevel@tonic-gate 	 goto error;
2237c478bd9Sstevel@tonic-gate     }
2247c478bd9Sstevel@tonic-gate     dbkey.data = name;
2257c478bd9Sstevel@tonic-gate     dbkey.size = (strlen(dbkey.data) + 1);
2267c478bd9Sstevel@tonic-gate     dbdata.data = NULL;
2277c478bd9Sstevel@tonic-gate     dbdata.size = 0;
2287c478bd9Sstevel@tonic-gate     switch((db->db->get(db->db, &dbkey, &dbdata, 0))) {
2297c478bd9Sstevel@tonic-gate     case 1:
23054925bf6Swillf 	 ret = OSA_ADB_OK;
23154925bf6Swillf 	 *cnt = 0;
2327c478bd9Sstevel@tonic-gate 	 goto error;
2337c478bd9Sstevel@tonic-gate     case 0:
2347c478bd9Sstevel@tonic-gate 	break;
2357c478bd9Sstevel@tonic-gate     default:
2367c478bd9Sstevel@tonic-gate 	 ret = OSA_ADB_FAILURE;
2377c478bd9Sstevel@tonic-gate 	 goto error;
2387c478bd9Sstevel@tonic-gate     }
2397c478bd9Sstevel@tonic-gate     if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) {
2407c478bd9Sstevel@tonic-gate 	 ret = ENOMEM;
2417c478bd9Sstevel@tonic-gate 	 goto error;
2427c478bd9Sstevel@tonic-gate     }
2437c478bd9Sstevel@tonic-gate     if (!(aligned_data = (char *) malloc(dbdata.size))) {
2447c478bd9Sstevel@tonic-gate 	 ret = ENOMEM;
2457c478bd9Sstevel@tonic-gate 	 goto error;
2467c478bd9Sstevel@tonic-gate     }
247*55fea89dSDan Cross     memcpy(aligned_data, dbdata.data, dbdata.size);
2487c478bd9Sstevel@tonic-gate     memset(*entry, 0, sizeof(osa_policy_ent_rec));
2497c478bd9Sstevel@tonic-gate     xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
250*55fea89dSDan Cross     if (!xdr_osa_policy_ent_rec(&xdrs, *entry))
2517c478bd9Sstevel@tonic-gate 	ret =  OSA_ADB_FAILURE;
2527c478bd9Sstevel@tonic-gate     else ret = OSA_ADB_OK;
2537c478bd9Sstevel@tonic-gate     xdr_destroy(&xdrs);
2547c478bd9Sstevel@tonic-gate     free(aligned_data);
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate error:
2577c478bd9Sstevel@tonic-gate     CLOSELOCK(db);
2587c478bd9Sstevel@tonic-gate     return ret;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate /*
2627c478bd9Sstevel@tonic-gate  * Function: osa_adb_put_policy
263*55fea89dSDan Cross  *
2647c478bd9Sstevel@tonic-gate  * Purpose: update a policy in the dababase
2657c478bd9Sstevel@tonic-gate  *
2667c478bd9Sstevel@tonic-gate  * Arguments:
2677c478bd9Sstevel@tonic-gate  *	db		(input) db handle
2687c478bd9Sstevel@tonic-gate  *	entry		(input) policy entry
26956a424ccSmp  * 	<return value>	0 on success error code on failure.
2707c478bd9Sstevel@tonic-gate  *
2717c478bd9Sstevel@tonic-gate  * Requires:
2727c478bd9Sstevel@tonic-gate  *	[requires]
273*55fea89dSDan Cross  *
2747c478bd9Sstevel@tonic-gate  * Effects:
2757c478bd9Sstevel@tonic-gate  *	[effects]
2767c478bd9Sstevel@tonic-gate  *
2777c478bd9Sstevel@tonic-gate  * Modifies:
2787c478bd9Sstevel@tonic-gate  *	[modifies]
279*55fea89dSDan Cross  *
2807c478bd9Sstevel@tonic-gate  */
28154925bf6Swillf krb5_error_code
osa_adb_put_policy(osa_adb_policy_t db,osa_policy_ent_t entry)2827c478bd9Sstevel@tonic-gate osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate     DBT			dbkey;
2857c478bd9Sstevel@tonic-gate     DBT			dbdata;
2867c478bd9Sstevel@tonic-gate     DBT			tmpdb;
2877c478bd9Sstevel@tonic-gate     XDR			xdrs;
2887c478bd9Sstevel@tonic-gate     int			ret;
2897c478bd9Sstevel@tonic-gate 
29054925bf6Swillf     OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE);
291*55fea89dSDan Cross 
2927c478bd9Sstevel@tonic-gate     if(entry->name == NULL) {
2937c478bd9Sstevel@tonic-gate 	 ret = EINVAL;
2947c478bd9Sstevel@tonic-gate 	 goto error;
2957c478bd9Sstevel@tonic-gate     }
2967c478bd9Sstevel@tonic-gate     dbkey.data = entry->name;
2977c478bd9Sstevel@tonic-gate     dbkey.size = (strlen(entry->name) + 1);
2987c478bd9Sstevel@tonic-gate     switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) {
2997c478bd9Sstevel@tonic-gate     case 0:
3007c478bd9Sstevel@tonic-gate 	break;
3017c478bd9Sstevel@tonic-gate     case 1:
3027c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_NOENT;
3037c478bd9Sstevel@tonic-gate 	goto error;
3047c478bd9Sstevel@tonic-gate     default:
3057c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_FAILURE;
3067c478bd9Sstevel@tonic-gate 	goto error;
3077c478bd9Sstevel@tonic-gate     }
3087c478bd9Sstevel@tonic-gate     xdralloc_create(&xdrs, XDR_ENCODE);
3097c478bd9Sstevel@tonic-gate     if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
3107c478bd9Sstevel@tonic-gate 	xdr_destroy(&xdrs);
3117c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_XDR_FAILURE;
3127c478bd9Sstevel@tonic-gate 	goto error;
3137c478bd9Sstevel@tonic-gate     }
3147c478bd9Sstevel@tonic-gate     dbdata.data = xdralloc_getdata(&xdrs);
3157c478bd9Sstevel@tonic-gate     dbdata.size = xdr_getpos(&xdrs);
3167c478bd9Sstevel@tonic-gate     switch(db->db->put(db->db, &dbkey, &dbdata, 0)) {
3177c478bd9Sstevel@tonic-gate     case 0:
3187c478bd9Sstevel@tonic-gate 	if((db->db->sync(db->db, 0)) == -1)
3197c478bd9Sstevel@tonic-gate 	    ret = OSA_ADB_FAILURE;
3207c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_OK;
3217c478bd9Sstevel@tonic-gate 	break;
3227c478bd9Sstevel@tonic-gate     default:
3237c478bd9Sstevel@tonic-gate 	ret = OSA_ADB_FAILURE;
3247c478bd9Sstevel@tonic-gate 	break;
3257c478bd9Sstevel@tonic-gate     }
3267c478bd9Sstevel@tonic-gate     xdr_destroy(&xdrs);
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate error:
3297c478bd9Sstevel@tonic-gate     CLOSELOCK(db);
3307c478bd9Sstevel@tonic-gate     return ret;
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate /*
3347c478bd9Sstevel@tonic-gate  * Function: osa_adb_iter_policy
335*55fea89dSDan Cross  *
3367c478bd9Sstevel@tonic-gate  * Purpose: iterate over the policy database.
3377c478bd9Sstevel@tonic-gate  *
3387c478bd9Sstevel@tonic-gate  * Arguments:
3397c478bd9Sstevel@tonic-gate  *	db		(input) db handle
3407c478bd9Sstevel@tonic-gate  *	func		(input) fucntion pointer to call
3417c478bd9Sstevel@tonic-gate  *	data		opaque data type
34256a424ccSmp  * 	<return value>	0 on success error code on failure
3437c478bd9Sstevel@tonic-gate  *
3447c478bd9Sstevel@tonic-gate  * Requires:
3457c478bd9Sstevel@tonic-gate  * Effects:
3467c478bd9Sstevel@tonic-gate  * Modifies:
3477c478bd9Sstevel@tonic-gate  */
34854925bf6Swillf krb5_error_code
osa_adb_iter_policy(osa_adb_policy_t db,osa_adb_iter_policy_func func,void * data)3497c478bd9Sstevel@tonic-gate osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func,
3507c478bd9Sstevel@tonic-gate 		    void *data)
3517c478bd9Sstevel@tonic-gate {
3527c478bd9Sstevel@tonic-gate     DBT			    dbkey,
3537c478bd9Sstevel@tonic-gate 			    dbdata;
3547c478bd9Sstevel@tonic-gate     XDR			    xdrs;
3557c478bd9Sstevel@tonic-gate     int			    ret;
3567c478bd9Sstevel@tonic-gate     osa_policy_ent_t	    entry;
3577c478bd9Sstevel@tonic-gate     char		    *aligned_data;
3587c478bd9Sstevel@tonic-gate 
35954925bf6Swillf     OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate     if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) {
3627c478bd9Sstevel@tonic-gate 	 ret = errno;
3637c478bd9Sstevel@tonic-gate 	 goto error;
3647c478bd9Sstevel@tonic-gate     }
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate     while (ret == 0) {
3677c478bd9Sstevel@tonic-gate 	if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) {
3687c478bd9Sstevel@tonic-gate 	     ret = ENOMEM;
3697c478bd9Sstevel@tonic-gate 	     goto error;
3707c478bd9Sstevel@tonic-gate 	}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	if(!(aligned_data = (char *) malloc(dbdata.size))) {
3737c478bd9Sstevel@tonic-gate 	     ret = ENOMEM;
3747c478bd9Sstevel@tonic-gate 	     goto error;
3757c478bd9Sstevel@tonic-gate 	}
3767c478bd9Sstevel@tonic-gate 	memcpy(aligned_data, dbdata.data, dbdata.size);
377*55fea89dSDan Cross 
3787c478bd9Sstevel@tonic-gate 	memset(entry, 0, sizeof(osa_policy_ent_rec));
3797c478bd9Sstevel@tonic-gate 	xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE);
3807c478bd9Sstevel@tonic-gate 	if(!xdr_osa_policy_ent_rec(&xdrs, entry)) {
3817c478bd9Sstevel@tonic-gate 	    xdr_destroy(&xdrs);
3827c478bd9Sstevel@tonic-gate 	    free(aligned_data);
3837c478bd9Sstevel@tonic-gate 	    ret = OSA_ADB_FAILURE;
3847c478bd9Sstevel@tonic-gate 	    goto error;
3857c478bd9Sstevel@tonic-gate 	}
3867c478bd9Sstevel@tonic-gate 	(*func)(data, entry);
3877c478bd9Sstevel@tonic-gate 	xdr_destroy(&xdrs);
388*55fea89dSDan Cross 	free(aligned_data);
3897c478bd9Sstevel@tonic-gate 	osa_free_policy_ent(entry);
3907c478bd9Sstevel@tonic-gate 	ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT);
3917c478bd9Sstevel@tonic-gate     }
3927c478bd9Sstevel@tonic-gate     if(ret == -1)
3937c478bd9Sstevel@tonic-gate 	 ret = errno;
3947c478bd9Sstevel@tonic-gate     else ret = OSA_ADB_OK;
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate error:
3977c478bd9Sstevel@tonic-gate     CLOSELOCK(db);
3987c478bd9Sstevel@tonic-gate     return ret;
3997c478bd9Sstevel@tonic-gate }
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