xref: /onnv-gate/usr/src/lib/krb5/kadm5/srv/server_kdb.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
25916Swillf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
100Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
110Sstevel@tonic-gate  *	source code before consulting with your legal department.
120Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
130Sstevel@tonic-gate  *	product before consulting with your legal department.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  *	For further information, read the top-level Openvision
160Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
170Sstevel@tonic-gate  *	copyright.
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
200Sstevel@tonic-gate  *
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate 
230Sstevel@tonic-gate 
240Sstevel@tonic-gate /*
250Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
260Sstevel@tonic-gate  *
27*7934SMark.Phalan@Sun.COM  * $Header$
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
31*7934SMark.Phalan@Sun.COM static char *rcsid = "$Header$";
320Sstevel@tonic-gate #endif
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #include <stdio.h>
350Sstevel@tonic-gate #include <stdlib.h>
364960Swillf #include "k5-int.h"
370Sstevel@tonic-gate #include <kadm5/admin.h>
380Sstevel@tonic-gate #include "server_internal.h"
390Sstevel@tonic-gate 
400Sstevel@tonic-gate extern caddr_t xdralloc_getdata(XDR *xdrs);
410Sstevel@tonic-gate extern void xdralloc_create(XDR *xdrs, enum xdr_op op);
420Sstevel@tonic-gate 
430Sstevel@tonic-gate krb5_principal	    master_princ;
440Sstevel@tonic-gate krb5_db_entry	    master_db;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate krb5_principal	    hist_princ;
470Sstevel@tonic-gate krb5_keyblock	    hist_key;
480Sstevel@tonic-gate krb5_db_entry	    hist_db;
490Sstevel@tonic-gate krb5_kvno	    hist_kvno;
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /* much of this code is stolen from the kdc.  there should be some
520Sstevel@tonic-gate    library code to deal with this. */
530Sstevel@tonic-gate 
kdb_init_master(kadm5_server_handle_t handle,char * r,int from_keyboard)540Sstevel@tonic-gate krb5_error_code kdb_init_master(kadm5_server_handle_t handle,
550Sstevel@tonic-gate 				char *r, int from_keyboard)
560Sstevel@tonic-gate {
570Sstevel@tonic-gate     int		   ret = 0;
580Sstevel@tonic-gate     char	   *realm;
592881Smp153739     krb5_boolean   from_kbd = FALSE;
602881Smp153739 
612881Smp153739     if (from_keyboard)
622881Smp153739       from_kbd = TRUE;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate     if (r == NULL)  {
650Sstevel@tonic-gate 	if ((ret = krb5_get_default_realm(handle->context, &realm)))
660Sstevel@tonic-gate 	    return ret;
670Sstevel@tonic-gate     } else {
680Sstevel@tonic-gate 	realm = r;
690Sstevel@tonic-gate     }
704960Swillf 
710Sstevel@tonic-gate     if ((ret = krb5_db_setup_mkey_name(handle->context,
720Sstevel@tonic-gate 				       handle->params.mkey_name,
730Sstevel@tonic-gate 				       realm, NULL, &master_princ)))
740Sstevel@tonic-gate 	goto done;
75*7934SMark.Phalan@Sun.COM /* Solaris Kerberos */
76*7934SMark.Phalan@Sun.COM #if 0
77*7934SMark.Phalan@Sun.COM     master_keyblock.enctype = handle->params.enctype;
78*7934SMark.Phalan@Sun.COM #endif
790Sstevel@tonic-gate 
80*7934SMark.Phalan@Sun.COM     /* Solaris Kerberos */
812881Smp153739     ret = krb5_db_fetch_mkey(handle->context, master_princ,
822881Smp153739 			     handle->params.enctype, from_kbd,
832881Smp153739 			     FALSE /* only prompt once */,
842881Smp153739 			     handle->params.stash_file,
852881Smp153739 			     NULL /* I'm not sure about this,
862881Smp153739 				     but it's what the kdc does --marc */,
872881Smp153739 			     &handle->master_keyblock);
882881Smp153739     if (ret)
890Sstevel@tonic-gate 	goto done;
900Sstevel@tonic-gate 
91*7934SMark.Phalan@Sun.COM     /* Solaris Kerberos */
920Sstevel@tonic-gate     if ((ret = krb5_db_verify_master_key(handle->context, master_princ,
930Sstevel@tonic-gate 					 &handle->master_keyblock))) {
940Sstevel@tonic-gate 	  krb5_db_fini(handle->context);
950Sstevel@tonic-gate 	  return ret;
960Sstevel@tonic-gate     }
970Sstevel@tonic-gate 
980Sstevel@tonic-gate done:
990Sstevel@tonic-gate     if (r == NULL)
1000Sstevel@tonic-gate 	free(realm);
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate     return(ret);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate /*
1060Sstevel@tonic-gate  * Function: kdb_init_hist
1070Sstevel@tonic-gate  *
1080Sstevel@tonic-gate  * Purpose: Initializes the global history variables.
1090Sstevel@tonic-gate  *
1100Sstevel@tonic-gate  * Arguments:
1110Sstevel@tonic-gate  *
1120Sstevel@tonic-gate  *	handle		(r) kadm5 api server handle
1130Sstevel@tonic-gate  *	r		(r) realm of history principal to use, or NULL
1140Sstevel@tonic-gate  *
1150Sstevel@tonic-gate  * Effects: This function sets the value of the following global
1160Sstevel@tonic-gate  * variables:
1170Sstevel@tonic-gate  *
1180Sstevel@tonic-gate  *	hist_princ	krb5_principal holding the history principal
1190Sstevel@tonic-gate  *	hist_db		krb5_db_entry of the history principal
1200Sstevel@tonic-gate  *	hist_key	krb5_keyblock holding the history principal's key
1210Sstevel@tonic-gate  *	hist_encblock	krb5_encrypt_block holding the procssed hist_key
1220Sstevel@tonic-gate  *	hist_kvno	the version number of the history key
1230Sstevel@tonic-gate  *
1240Sstevel@tonic-gate  * If the history principal does not already exist, this function
1250Sstevel@tonic-gate  * attempts to create it with kadm5_create_principal.  WARNING!
1260Sstevel@tonic-gate  * If the history principal is deleted and this function is executed
1270Sstevel@tonic-gate  * (by kadmind, or kadmin.local, or anything else with permission),
1280Sstevel@tonic-gate  * the principal will be assigned a new random key and all existing
1290Sstevel@tonic-gate  * password history information will become useless.
1300Sstevel@tonic-gate  */
kdb_init_hist(kadm5_server_handle_t handle,char * r)1310Sstevel@tonic-gate krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r)
1320Sstevel@tonic-gate {
1330Sstevel@tonic-gate     int	    ret = 0;
1340Sstevel@tonic-gate     char    *realm, *hist_name;
1350Sstevel@tonic-gate     krb5_key_data *key_data;
1360Sstevel@tonic-gate     krb5_key_salt_tuple ks[1];
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate     if (r == NULL)  {
1390Sstevel@tonic-gate 	if ((ret = krb5_get_default_realm(handle->context, &realm)))
1400Sstevel@tonic-gate 	    return ret;
1410Sstevel@tonic-gate     } else {
1420Sstevel@tonic-gate 	realm = r;
1430Sstevel@tonic-gate     }
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate     if ((hist_name = (char *) malloc(strlen(KADM5_HIST_PRINCIPAL) +
1460Sstevel@tonic-gate 				     strlen(realm) + 2)) == NULL)
1470Sstevel@tonic-gate 	goto done;
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate     (void) sprintf(hist_name, "%s@%s", KADM5_HIST_PRINCIPAL, realm);
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate     if ((ret = krb5_parse_name(handle->context, hist_name, &hist_princ)))
1520Sstevel@tonic-gate 	goto done;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate     if ((ret = kdb_get_entry(handle, hist_princ, &hist_db, NULL))) {
1550Sstevel@tonic-gate 	kadm5_principal_ent_rec ent;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	if (ret != KADM5_UNK_PRINC)
1580Sstevel@tonic-gate 	    goto done;
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	/* try to create the principal */
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	memset(&ent, 0, sizeof(ent));
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	ent.principal = hist_princ;
1650Sstevel@tonic-gate 	ent.max_life = KRB5_KDB_DISALLOW_ALL_TIX;
1660Sstevel@tonic-gate 	ent.attributes = 0;
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	/* this uses hist_kvno.  So we set it to 2, which will be the
1690Sstevel@tonic-gate 	   correct value once the principal is created and randomized.
1700Sstevel@tonic-gate 	   Of course, it doesn't make sense to keep a history for the
1710Sstevel@tonic-gate 	   history principal, anyway. */
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 	hist_kvno = 2;
1740Sstevel@tonic-gate 	ks[0].ks_enctype = handle->params.enctype;
1750Sstevel@tonic-gate 	ks[0].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
1760Sstevel@tonic-gate 	ret = kadm5_create_principal_3(handle, &ent,
1772881Smp153739 				       (KADM5_PRINCIPAL | KADM5_MAX_LIFE |
1782881Smp153739 					KADM5_ATTRIBUTES),
1790Sstevel@tonic-gate 				       1, ks,
1802881Smp153739 				       "to-be-random");
1810Sstevel@tonic-gate 	if (ret)
1820Sstevel@tonic-gate 	    goto done;
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	/* this won't let us randomize the hist_princ.  So we cheat. */
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	hist_princ = NULL;
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	ret = kadm5_randkey_principal_3(handle, ent.principal, 0, 1, ks,
1890Sstevel@tonic-gate 					NULL, NULL);
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	hist_princ = ent.principal;
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 	if (ret)
1940Sstevel@tonic-gate 	    goto done;
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 	/* now read the newly-created kdb record out of the
1970Sstevel@tonic-gate 	   database. */
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 	if ((ret = kdb_get_entry(handle, hist_princ, &hist_db, NULL)))
2000Sstevel@tonic-gate 	    goto done;
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate     }
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate     ret = krb5_dbe_find_enctype(handle->context, &hist_db,
2052881Smp153739 				handle->params.enctype, -1, -1, &key_data);
2060Sstevel@tonic-gate     if (ret)
2070Sstevel@tonic-gate 	goto done;
2080Sstevel@tonic-gate 
209*7934SMark.Phalan@Sun.COM     /* Solaris Kerberos */
2100Sstevel@tonic-gate     ret = krb5_dbekd_decrypt_key_data(handle->context,
2112881Smp153739 				 &handle->master_keyblock, key_data, &hist_key, NULL);
2120Sstevel@tonic-gate     if (ret)
2130Sstevel@tonic-gate 	goto done;
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate     hist_kvno = key_data->key_data_kvno;
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate done:
2180Sstevel@tonic-gate     free(hist_name);
2190Sstevel@tonic-gate     if (r == NULL)
2200Sstevel@tonic-gate 	free(realm);
2210Sstevel@tonic-gate     return ret;
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate /*
2250Sstevel@tonic-gate  * Function: kdb_get_entry
2260Sstevel@tonic-gate  *
2270Sstevel@tonic-gate  * Purpose: Gets an entry from the kerberos database and breaks
2280Sstevel@tonic-gate  * it out into a krb5_db_entry and an osa_princ_ent_t.
2290Sstevel@tonic-gate  *
2300Sstevel@tonic-gate  * Arguments:
2310Sstevel@tonic-gate  *
2320Sstevel@tonic-gate  *		handle		(r) the server_handle
2330Sstevel@tonic-gate  * 		principal	(r) the principal to get
2340Sstevel@tonic-gate  * 		kdb		(w) krb5_db_entry to fill in
2350Sstevel@tonic-gate  * 		adb		(w) osa_princ_ent_rec to fill in
2360Sstevel@tonic-gate  *
2370Sstevel@tonic-gate  * when the caller is done with kdb and adb, kdb_free_entry must be
2380Sstevel@tonic-gate  * called to release them.  The adb record is filled in with the
2390Sstevel@tonic-gate  * contents of the KRB5_TL_KADM_DATA record; if that record doesn't
2400Sstevel@tonic-gate  * exist, an empty but valid adb record is returned.
2410Sstevel@tonic-gate  */
2420Sstevel@tonic-gate krb5_error_code
kdb_get_entry(kadm5_server_handle_t handle,krb5_principal principal,krb5_db_entry * kdb,osa_princ_ent_rec * adb)2430Sstevel@tonic-gate kdb_get_entry(kadm5_server_handle_t handle,
2440Sstevel@tonic-gate 	      krb5_principal principal, krb5_db_entry *kdb,
2450Sstevel@tonic-gate 	      osa_princ_ent_rec *adb)
2460Sstevel@tonic-gate {
2470Sstevel@tonic-gate     krb5_error_code ret;
2480Sstevel@tonic-gate     int nprincs;
2490Sstevel@tonic-gate     krb5_boolean more;
2500Sstevel@tonic-gate     krb5_tl_data tl_data;
2510Sstevel@tonic-gate     XDR xdrs;
2520Sstevel@tonic-gate 
2532881Smp153739     ret = krb5_db_get_principal(handle->context, principal, kdb, &nprincs,
2542881Smp153739 				&more);
2552881Smp153739     if (ret)
2560Sstevel@tonic-gate 	return(ret);
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate     if (more) {
2590Sstevel@tonic-gate 	krb5_db_free_principal(handle->context, kdb, nprincs);
2600Sstevel@tonic-gate 	return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
2610Sstevel@tonic-gate     } else if (nprincs != 1) {
2620Sstevel@tonic-gate 	krb5_db_free_principal(handle->context, kdb, nprincs);
2630Sstevel@tonic-gate 	return(KADM5_UNK_PRINC);
2640Sstevel@tonic-gate     }
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate     if (adb) {
2670Sstevel@tonic-gate 	memset(adb, 0, sizeof(*adb));
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	tl_data.tl_data_type = KRB5_TL_KADM_DATA;
2700Sstevel@tonic-gate 	/*
2710Sstevel@tonic-gate 	 * XXX Currently, lookup_tl_data always returns zero; it sets
2720Sstevel@tonic-gate 	 * tl_data->tl_data_length to zero if the type isn't found.
2730Sstevel@tonic-gate 	 * This should be fixed...
2740Sstevel@tonic-gate 	 */
2750Sstevel@tonic-gate 	if ((ret = krb5_dbe_lookup_tl_data(handle->context, kdb, &tl_data))
2760Sstevel@tonic-gate 	    || (tl_data.tl_data_length == 0)) {
2770Sstevel@tonic-gate 	    /* there's no admin data.  this can happen, if the admin
2780Sstevel@tonic-gate 	       server is put into production after some principals
2790Sstevel@tonic-gate 	       are created.  In this case, return valid admin
2800Sstevel@tonic-gate 	       data (which is all zeros with the hist_kvno filled
2810Sstevel@tonic-gate 	       in), and when the entry is written, the admin
2820Sstevel@tonic-gate 	       data will get stored correctly. */
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	    adb->admin_history_kvno = hist_kvno;
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate 	    return(ret);
2870Sstevel@tonic-gate 	}
2880Sstevel@tonic-gate 
289*7934SMark.Phalan@Sun.COM 	/* Solaris Kerberos */
2900Sstevel@tonic-gate 	xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents,
2910Sstevel@tonic-gate 		      tl_data.tl_data_length, XDR_DECODE);
2920Sstevel@tonic-gate 	if (! xdr_osa_princ_ent_rec(&xdrs, adb)) {
2930Sstevel@tonic-gate 	   xdr_destroy(&xdrs);
2940Sstevel@tonic-gate 	   krb5_db_free_principal(handle->context, kdb, 1);
2954960Swillf 	   return(KADM5_XDR_FAILURE);
2960Sstevel@tonic-gate 	}
2970Sstevel@tonic-gate 	xdr_destroy(&xdrs);
2980Sstevel@tonic-gate     }
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate     return(0);
3010Sstevel@tonic-gate }
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate /*
3040Sstevel@tonic-gate  * Function: kdb_free_entry
3050Sstevel@tonic-gate  *
3060Sstevel@tonic-gate  * Purpose: frees the resources allocated by kdb_get_entry
3070Sstevel@tonic-gate  *
3080Sstevel@tonic-gate  * Arguments:
3090Sstevel@tonic-gate  *
3100Sstevel@tonic-gate  *		handle		(r) the server_handle
3110Sstevel@tonic-gate  * 		kdb		(w) krb5_db_entry to fill in
3120Sstevel@tonic-gate  * 		adb		(w) osa_princ_ent_rec to fill in
3130Sstevel@tonic-gate  *
3140Sstevel@tonic-gate  * when the caller is done with kdb and adb, kdb_free_entry must be
3150Sstevel@tonic-gate  * called to release them.
3160Sstevel@tonic-gate  */
3170Sstevel@tonic-gate 
3180Sstevel@tonic-gate krb5_error_code
kdb_free_entry(kadm5_server_handle_t handle,krb5_db_entry * kdb,osa_princ_ent_rec * adb)3190Sstevel@tonic-gate kdb_free_entry(kadm5_server_handle_t handle,
3200Sstevel@tonic-gate 	       krb5_db_entry *kdb, osa_princ_ent_rec *adb)
3210Sstevel@tonic-gate {
3220Sstevel@tonic-gate     XDR xdrs;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate     if (kdb)
3260Sstevel@tonic-gate 	krb5_db_free_principal(handle->context, kdb, 1);
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate     if (adb) {
3290Sstevel@tonic-gate 	xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
3300Sstevel@tonic-gate 	xdr_osa_princ_ent_rec(&xdrs, adb);
3310Sstevel@tonic-gate 	xdr_destroy(&xdrs);
3320Sstevel@tonic-gate     }
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate     return(0);
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate /*
3380Sstevel@tonic-gate  * Function: kdb_put_entry
3390Sstevel@tonic-gate  *
3400Sstevel@tonic-gate  * Purpose: Stores the osa_princ_ent_t and krb5_db_entry into to
3410Sstevel@tonic-gate  * database.
3420Sstevel@tonic-gate  *
3430Sstevel@tonic-gate  * Arguments:
3440Sstevel@tonic-gate  *
3450Sstevel@tonic-gate  *		handle	(r) the server_handle
3460Sstevel@tonic-gate  * 		kdb	(r/w) the krb5_db_entry to store
3470Sstevel@tonic-gate  * 		adb	(r) the osa_princ_db_ent to store
3480Sstevel@tonic-gate  *
3490Sstevel@tonic-gate  * Effects:
3500Sstevel@tonic-gate  *
3510Sstevel@tonic-gate  * The last modifier field of the kdb is set to the caller at now.
3520Sstevel@tonic-gate  * adb is encoded with xdr_osa_princ_ent_ret and stored in kbd as
3530Sstevel@tonic-gate  * KRB5_TL_KADM_DATA.  kdb is then written to the database.
3540Sstevel@tonic-gate  */
3550Sstevel@tonic-gate krb5_error_code
kdb_put_entry(kadm5_server_handle_t handle,krb5_db_entry * kdb,osa_princ_ent_rec * adb)3560Sstevel@tonic-gate kdb_put_entry(kadm5_server_handle_t handle,
3570Sstevel@tonic-gate 	      krb5_db_entry *kdb, osa_princ_ent_rec *adb)
3580Sstevel@tonic-gate {
3590Sstevel@tonic-gate     krb5_error_code ret;
3600Sstevel@tonic-gate     krb5_int32 now;
3610Sstevel@tonic-gate     XDR xdrs;
3620Sstevel@tonic-gate     krb5_tl_data tl_data;
3630Sstevel@tonic-gate     int one;
3640Sstevel@tonic-gate 
3652881Smp153739     ret = krb5_timeofday(handle->context, &now);
3662881Smp153739     if (ret)
3670Sstevel@tonic-gate 	return(ret);
3680Sstevel@tonic-gate 
3692881Smp153739     ret = krb5_dbe_update_mod_princ_data(handle->context, kdb, now,
3702881Smp153739 					 handle->current_caller);
3712881Smp153739     if (ret)
3720Sstevel@tonic-gate 	return(ret);
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate     xdralloc_create(&xdrs, XDR_ENCODE);
3750Sstevel@tonic-gate     if(! xdr_osa_princ_ent_rec(&xdrs, adb)) {
3760Sstevel@tonic-gate 	xdr_destroy(&xdrs);
3774960Swillf 	return(KADM5_XDR_FAILURE);
3780Sstevel@tonic-gate     }
3790Sstevel@tonic-gate     tl_data.tl_data_type = KRB5_TL_KADM_DATA;
3800Sstevel@tonic-gate     tl_data.tl_data_length = xdr_getpos(&xdrs);
381*7934SMark.Phalan@Sun.COM     /* Solaris Kerberos */
3820Sstevel@tonic-gate     tl_data.tl_data_contents = (unsigned char *) xdralloc_getdata(&xdrs);
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate     ret = krb5_dbe_update_tl_data(handle->context, kdb, &tl_data);
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate     xdr_destroy(&xdrs);
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate     if (ret)
3890Sstevel@tonic-gate 	return(ret);
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate     one = 1;
3920Sstevel@tonic-gate 
3932881Smp153739     ret = krb5_db_put_principal(handle->context, kdb, &one);
3942881Smp153739     if (ret)
3950Sstevel@tonic-gate 	return(ret);
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate     return(0);
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate krb5_error_code
kdb_delete_entry(kadm5_server_handle_t handle,krb5_principal name)4010Sstevel@tonic-gate kdb_delete_entry(kadm5_server_handle_t handle, krb5_principal name)
4020Sstevel@tonic-gate {
4030Sstevel@tonic-gate     int one = 1;
4040Sstevel@tonic-gate     krb5_error_code ret;
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate     ret = krb5_db_delete_principal(handle->context, name, &one);
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate     return ret;
4090Sstevel@tonic-gate }
4100Sstevel@tonic-gate 
4110Sstevel@tonic-gate typedef struct _iter_data {
4120Sstevel@tonic-gate     void (*func)(void *, krb5_principal);
4130Sstevel@tonic-gate     void *data;
4140Sstevel@tonic-gate } iter_data;
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate static krb5_error_code
kdb_iter_func(krb5_pointer data,krb5_db_entry * kdb)4170Sstevel@tonic-gate kdb_iter_func(krb5_pointer data, krb5_db_entry *kdb)
4180Sstevel@tonic-gate {
4190Sstevel@tonic-gate     iter_data *id = (iter_data *) data;
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate     (*(id->func))(id->data, kdb->princ);
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate     return(0);
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate 
4260Sstevel@tonic-gate krb5_error_code
kdb_iter_entry(kadm5_server_handle_t handle,char * match_entry,void (* iter_fct)(void *,krb5_principal),void * data)4274960Swillf kdb_iter_entry(kadm5_server_handle_t handle, char *match_entry,
4280Sstevel@tonic-gate 	       void (*iter_fct)(void *, krb5_principal), void *data)
4290Sstevel@tonic-gate {
4300Sstevel@tonic-gate     iter_data id;
4310Sstevel@tonic-gate     krb5_error_code ret;
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate     id.func = iter_fct;
4340Sstevel@tonic-gate     id.data = data;
4350Sstevel@tonic-gate 
4365916Swillf     /* Solaris Kerberos: added support for db_args */
4375916Swillf     ret = krb5_db_iterate(handle->context, match_entry, kdb_iter_func, &id, NULL);
4382881Smp153739     if (ret)
4390Sstevel@tonic-gate 	return(ret);
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate     return(0);
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate 
444