1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 6*0Sstevel@tonic-gate 7*0Sstevel@tonic-gate /* 8*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 9*0Sstevel@tonic-gate * 10*0Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 11*0Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 12*0Sstevel@tonic-gate * source code before consulting with your legal department. 13*0Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 14*0Sstevel@tonic-gate * product before consulting with your legal department. 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * For further information, read the top-level Openvision 17*0Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 18*0Sstevel@tonic-gate * copyright. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 21*0Sstevel@tonic-gate * 22*0Sstevel@tonic-gate */ 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate /* 26*0Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 27*0Sstevel@tonic-gate * 28*0Sstevel@tonic-gate * $Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_kdb.c,v 1.2 1998/10/30 02:54:39 marc Exp $ 29*0Sstevel@tonic-gate */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__) 32*0Sstevel@tonic-gate static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_kdb.c,v 1.2 1998/10/30 02:54:39 marc Exp $"; 33*0Sstevel@tonic-gate #endif 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #include <stdio.h> 36*0Sstevel@tonic-gate #include <stdlib.h> 37*0Sstevel@tonic-gate #include <com_err.h> 38*0Sstevel@tonic-gate #include <kadm5/admin.h> 39*0Sstevel@tonic-gate #include <krb5.h> 40*0Sstevel@tonic-gate #include "server_internal.h" 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate extern caddr_t xdralloc_getdata(XDR *xdrs); 43*0Sstevel@tonic-gate extern void xdralloc_create(XDR *xdrs, enum xdr_op op); 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate krb5_principal master_princ; 46*0Sstevel@tonic-gate krb5_db_entry master_db; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate krb5_principal hist_princ; 49*0Sstevel@tonic-gate krb5_encrypt_block hist_encblock; 50*0Sstevel@tonic-gate krb5_keyblock hist_key; 51*0Sstevel@tonic-gate krb5_db_entry hist_db; 52*0Sstevel@tonic-gate krb5_kvno hist_kvno; 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate /* much of this code is stolen from the kdc. there should be some 55*0Sstevel@tonic-gate library code to deal with this. */ 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate krb5_error_code kdb_init_master(kadm5_server_handle_t handle, 58*0Sstevel@tonic-gate char *r, int from_keyboard) 59*0Sstevel@tonic-gate { 60*0Sstevel@tonic-gate int ret = 0; 61*0Sstevel@tonic-gate char *realm; 62*0Sstevel@tonic-gate krb5_keyblock tmk; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate if (r == NULL) { 65*0Sstevel@tonic-gate if ((ret = krb5_get_default_realm(handle->context, &realm))) 66*0Sstevel@tonic-gate return ret; 67*0Sstevel@tonic-gate } else { 68*0Sstevel@tonic-gate realm = r; 69*0Sstevel@tonic-gate } 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate if ((ret = krb5_db_setup_mkey_name(handle->context, 72*0Sstevel@tonic-gate handle->params.mkey_name, 73*0Sstevel@tonic-gate realm, NULL, &master_princ))) 74*0Sstevel@tonic-gate goto done; 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate if (ret = krb5_db_fetch_mkey(handle->context, master_princ, 77*0Sstevel@tonic-gate handle->params.enctype, 78*0Sstevel@tonic-gate from_keyboard, 79*0Sstevel@tonic-gate FALSE /* only prompt once */, 80*0Sstevel@tonic-gate handle->params.stash_file, 81*0Sstevel@tonic-gate NULL /* I'm not sure about this, 82*0Sstevel@tonic-gate but it's what the kdc does --marc */, 83*0Sstevel@tonic-gate &handle->master_keyblock)) 84*0Sstevel@tonic-gate goto done; 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate if ((ret = krb5_db_init(handle->context)) != KSUCCESS) 87*0Sstevel@tonic-gate goto done; 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate if ((ret = krb5_db_verify_master_key(handle->context, master_princ, 90*0Sstevel@tonic-gate &handle->master_keyblock))) { 91*0Sstevel@tonic-gate krb5_db_fini(handle->context); 92*0Sstevel@tonic-gate return ret; 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate done: 96*0Sstevel@tonic-gate if (r == NULL) 97*0Sstevel@tonic-gate free(realm); 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate return(ret); 100*0Sstevel@tonic-gate } 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate /* 103*0Sstevel@tonic-gate * Function: kdb_init_hist 104*0Sstevel@tonic-gate * 105*0Sstevel@tonic-gate * Purpose: Initializes the global history variables. 106*0Sstevel@tonic-gate * 107*0Sstevel@tonic-gate * Arguments: 108*0Sstevel@tonic-gate * 109*0Sstevel@tonic-gate * handle (r) kadm5 api server handle 110*0Sstevel@tonic-gate * r (r) realm of history principal to use, or NULL 111*0Sstevel@tonic-gate * 112*0Sstevel@tonic-gate * Effects: This function sets the value of the following global 113*0Sstevel@tonic-gate * variables: 114*0Sstevel@tonic-gate * 115*0Sstevel@tonic-gate * hist_princ krb5_principal holding the history principal 116*0Sstevel@tonic-gate * hist_db krb5_db_entry of the history principal 117*0Sstevel@tonic-gate * hist_key krb5_keyblock holding the history principal's key 118*0Sstevel@tonic-gate * hist_encblock krb5_encrypt_block holding the procssed hist_key 119*0Sstevel@tonic-gate * hist_kvno the version number of the history key 120*0Sstevel@tonic-gate * 121*0Sstevel@tonic-gate * If the history principal does not already exist, this function 122*0Sstevel@tonic-gate * attempts to create it with kadm5_create_principal. WARNING! 123*0Sstevel@tonic-gate * If the history principal is deleted and this function is executed 124*0Sstevel@tonic-gate * (by kadmind, or kadmin.local, or anything else with permission), 125*0Sstevel@tonic-gate * the principal will be assigned a new random key and all existing 126*0Sstevel@tonic-gate * password history information will become useless. 127*0Sstevel@tonic-gate */ 128*0Sstevel@tonic-gate krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r) 129*0Sstevel@tonic-gate { 130*0Sstevel@tonic-gate int ret = 0; 131*0Sstevel@tonic-gate char *realm, *hist_name; 132*0Sstevel@tonic-gate krb5_key_data *key_data; 133*0Sstevel@tonic-gate krb5_key_salt_tuple ks[1]; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate if (r == NULL) { 136*0Sstevel@tonic-gate if ((ret = krb5_get_default_realm(handle->context, &realm))) 137*0Sstevel@tonic-gate return ret; 138*0Sstevel@tonic-gate } else { 139*0Sstevel@tonic-gate realm = r; 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate if ((hist_name = (char *) malloc(strlen(KADM5_HIST_PRINCIPAL) + 143*0Sstevel@tonic-gate strlen(realm) + 2)) == NULL) 144*0Sstevel@tonic-gate goto done; 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate (void) sprintf(hist_name, "%s@%s", KADM5_HIST_PRINCIPAL, realm); 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if ((ret = krb5_parse_name(handle->context, hist_name, &hist_princ))) 149*0Sstevel@tonic-gate goto done; 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate if ((ret = kdb_get_entry(handle, hist_princ, &hist_db, NULL))) { 152*0Sstevel@tonic-gate kadm5_principal_ent_rec ent; 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate if (ret != KADM5_UNK_PRINC) 155*0Sstevel@tonic-gate goto done; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate /* try to create the principal */ 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate memset(&ent, 0, sizeof(ent)); 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate ent.principal = hist_princ; 162*0Sstevel@tonic-gate ent.max_life = KRB5_KDB_DISALLOW_ALL_TIX; 163*0Sstevel@tonic-gate ent.attributes = 0; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate /* this uses hist_kvno. So we set it to 2, which will be the 166*0Sstevel@tonic-gate correct value once the principal is created and randomized. 167*0Sstevel@tonic-gate Of course, it doesn't make sense to keep a history for the 168*0Sstevel@tonic-gate history principal, anyway. */ 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate hist_kvno = 2; 171*0Sstevel@tonic-gate ks[0].ks_enctype = handle->params.enctype; 172*0Sstevel@tonic-gate ks[0].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; 173*0Sstevel@tonic-gate ret = kadm5_create_principal_3(handle, &ent, 174*0Sstevel@tonic-gate (KADM5_PRINCIPAL | 175*0Sstevel@tonic-gate KADM5_MAX_LIFE | 176*0Sstevel@tonic-gate KADM5_ATTRIBUTES), 177*0Sstevel@tonic-gate 1, ks, 178*0Sstevel@tonic-gate "to-be-random"); 179*0Sstevel@tonic-gate if (ret) 180*0Sstevel@tonic-gate goto done; 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate /* this won't let us randomize the hist_princ. So we cheat. */ 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate hist_princ = NULL; 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate ret = kadm5_randkey_principal_3(handle, ent.principal, 0, 1, ks, 187*0Sstevel@tonic-gate NULL, NULL); 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate hist_princ = ent.principal; 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate if (ret) 192*0Sstevel@tonic-gate goto done; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate /* now read the newly-created kdb record out of the 195*0Sstevel@tonic-gate database. */ 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate if ((ret = kdb_get_entry(handle, hist_princ, &hist_db, NULL))) 198*0Sstevel@tonic-gate goto done; 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate ret = krb5_dbe_find_enctype(handle->context, &hist_db, 203*0Sstevel@tonic-gate handle->params.enctype, -1, -1, &key_data); 204*0Sstevel@tonic-gate if (ret) 205*0Sstevel@tonic-gate goto done; 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate ret = krb5_dbekd_decrypt_key_data(handle->context, 208*0Sstevel@tonic-gate &handle->master_keyblock, key_data, &hist_key, NULL); 209*0Sstevel@tonic-gate if (ret) 210*0Sstevel@tonic-gate goto done; 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate hist_kvno = key_data->key_data_kvno; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate done: 215*0Sstevel@tonic-gate free(hist_name); 216*0Sstevel@tonic-gate if (r == NULL) 217*0Sstevel@tonic-gate free(realm); 218*0Sstevel@tonic-gate return ret; 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate /* 222*0Sstevel@tonic-gate * Function: kdb_get_entry 223*0Sstevel@tonic-gate * 224*0Sstevel@tonic-gate * Purpose: Gets an entry from the kerberos database and breaks 225*0Sstevel@tonic-gate * it out into a krb5_db_entry and an osa_princ_ent_t. 226*0Sstevel@tonic-gate * 227*0Sstevel@tonic-gate * Arguments: 228*0Sstevel@tonic-gate * 229*0Sstevel@tonic-gate * handle (r) the server_handle 230*0Sstevel@tonic-gate * principal (r) the principal to get 231*0Sstevel@tonic-gate * kdb (w) krb5_db_entry to fill in 232*0Sstevel@tonic-gate * adb (w) osa_princ_ent_rec to fill in 233*0Sstevel@tonic-gate * 234*0Sstevel@tonic-gate * when the caller is done with kdb and adb, kdb_free_entry must be 235*0Sstevel@tonic-gate * called to release them. The adb record is filled in with the 236*0Sstevel@tonic-gate * contents of the KRB5_TL_KADM_DATA record; if that record doesn't 237*0Sstevel@tonic-gate * exist, an empty but valid adb record is returned. 238*0Sstevel@tonic-gate */ 239*0Sstevel@tonic-gate krb5_error_code 240*0Sstevel@tonic-gate kdb_get_entry(kadm5_server_handle_t handle, 241*0Sstevel@tonic-gate krb5_principal principal, krb5_db_entry *kdb, 242*0Sstevel@tonic-gate osa_princ_ent_rec *adb) 243*0Sstevel@tonic-gate { 244*0Sstevel@tonic-gate krb5_error_code ret; 245*0Sstevel@tonic-gate int nprincs; 246*0Sstevel@tonic-gate krb5_boolean more; 247*0Sstevel@tonic-gate krb5_tl_data tl_data; 248*0Sstevel@tonic-gate XDR xdrs; 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate if (ret = krb5_db_get_principal(handle->context, principal, kdb, &nprincs, 251*0Sstevel@tonic-gate &more)) 252*0Sstevel@tonic-gate return(ret); 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate if (more) { 255*0Sstevel@tonic-gate krb5_db_free_principal(handle->context, kdb, nprincs); 256*0Sstevel@tonic-gate return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); 257*0Sstevel@tonic-gate } else if (nprincs != 1) { 258*0Sstevel@tonic-gate krb5_db_free_principal(handle->context, kdb, nprincs); 259*0Sstevel@tonic-gate return(KADM5_UNK_PRINC); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate if (adb) { 263*0Sstevel@tonic-gate memset(adb, 0, sizeof(*adb)); 264*0Sstevel@tonic-gate 265*0Sstevel@tonic-gate tl_data.tl_data_type = KRB5_TL_KADM_DATA; 266*0Sstevel@tonic-gate /* 267*0Sstevel@tonic-gate * XXX Currently, lookup_tl_data always returns zero; it sets 268*0Sstevel@tonic-gate * tl_data->tl_data_length to zero if the type isn't found. 269*0Sstevel@tonic-gate * This should be fixed... 270*0Sstevel@tonic-gate */ 271*0Sstevel@tonic-gate if ((ret = krb5_dbe_lookup_tl_data(handle->context, kdb, &tl_data)) 272*0Sstevel@tonic-gate || (tl_data.tl_data_length == 0)) { 273*0Sstevel@tonic-gate /* there's no admin data. this can happen, if the admin 274*0Sstevel@tonic-gate server is put into production after some principals 275*0Sstevel@tonic-gate are created. In this case, return valid admin 276*0Sstevel@tonic-gate data (which is all zeros with the hist_kvno filled 277*0Sstevel@tonic-gate in), and when the entry is written, the admin 278*0Sstevel@tonic-gate data will get stored correctly. */ 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate adb->admin_history_kvno = hist_kvno; 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate return(ret); 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents, 286*0Sstevel@tonic-gate tl_data.tl_data_length, XDR_DECODE); 287*0Sstevel@tonic-gate if (! xdr_osa_princ_ent_rec(&xdrs, adb)) { 288*0Sstevel@tonic-gate xdr_destroy(&xdrs); 289*0Sstevel@tonic-gate krb5_db_free_principal(handle->context, kdb, 1); 290*0Sstevel@tonic-gate return(OSA_ADB_XDR_FAILURE); 291*0Sstevel@tonic-gate } 292*0Sstevel@tonic-gate xdr_destroy(&xdrs); 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate return(0); 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate /* 299*0Sstevel@tonic-gate * Function: kdb_free_entry 300*0Sstevel@tonic-gate * 301*0Sstevel@tonic-gate * Purpose: frees the resources allocated by kdb_get_entry 302*0Sstevel@tonic-gate * 303*0Sstevel@tonic-gate * Arguments: 304*0Sstevel@tonic-gate * 305*0Sstevel@tonic-gate * handle (r) the server_handle 306*0Sstevel@tonic-gate * kdb (w) krb5_db_entry to fill in 307*0Sstevel@tonic-gate * adb (w) osa_princ_ent_rec to fill in 308*0Sstevel@tonic-gate * 309*0Sstevel@tonic-gate * when the caller is done with kdb and adb, kdb_free_entry must be 310*0Sstevel@tonic-gate * called to release them. 311*0Sstevel@tonic-gate */ 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate krb5_error_code 314*0Sstevel@tonic-gate kdb_free_entry(kadm5_server_handle_t handle, 315*0Sstevel@tonic-gate krb5_db_entry *kdb, osa_princ_ent_rec *adb) 316*0Sstevel@tonic-gate { 317*0Sstevel@tonic-gate XDR xdrs; 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate if (kdb) 321*0Sstevel@tonic-gate krb5_db_free_principal(handle->context, kdb, 1); 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate if (adb) { 324*0Sstevel@tonic-gate xdrmem_create(&xdrs, NULL, 0, XDR_FREE); 325*0Sstevel@tonic-gate xdr_osa_princ_ent_rec(&xdrs, adb); 326*0Sstevel@tonic-gate xdr_destroy(&xdrs); 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate return(0); 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate /* 333*0Sstevel@tonic-gate * Function: kdb_put_entry 334*0Sstevel@tonic-gate * 335*0Sstevel@tonic-gate * Purpose: Stores the osa_princ_ent_t and krb5_db_entry into to 336*0Sstevel@tonic-gate * database. 337*0Sstevel@tonic-gate * 338*0Sstevel@tonic-gate * Arguments: 339*0Sstevel@tonic-gate * 340*0Sstevel@tonic-gate * handle (r) the server_handle 341*0Sstevel@tonic-gate * kdb (r/w) the krb5_db_entry to store 342*0Sstevel@tonic-gate * adb (r) the osa_princ_db_ent to store 343*0Sstevel@tonic-gate * 344*0Sstevel@tonic-gate * Effects: 345*0Sstevel@tonic-gate * 346*0Sstevel@tonic-gate * The last modifier field of the kdb is set to the caller at now. 347*0Sstevel@tonic-gate * adb is encoded with xdr_osa_princ_ent_ret and stored in kbd as 348*0Sstevel@tonic-gate * KRB5_TL_KADM_DATA. kdb is then written to the database. 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate krb5_error_code 351*0Sstevel@tonic-gate kdb_put_entry(kadm5_server_handle_t handle, 352*0Sstevel@tonic-gate krb5_db_entry *kdb, osa_princ_ent_rec *adb) 353*0Sstevel@tonic-gate { 354*0Sstevel@tonic-gate krb5_error_code ret; 355*0Sstevel@tonic-gate krb5_int32 now; 356*0Sstevel@tonic-gate XDR xdrs; 357*0Sstevel@tonic-gate krb5_tl_data tl_data; 358*0Sstevel@tonic-gate int one; 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate if (ret = krb5_timeofday(handle->context, &now)) 361*0Sstevel@tonic-gate return(ret); 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate if (ret = krb5_dbe_update_mod_princ_data(handle->context, kdb, now, 364*0Sstevel@tonic-gate handle->current_caller)) 365*0Sstevel@tonic-gate return(ret); 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate xdralloc_create(&xdrs, XDR_ENCODE); 368*0Sstevel@tonic-gate if(! xdr_osa_princ_ent_rec(&xdrs, adb)) { 369*0Sstevel@tonic-gate xdr_destroy(&xdrs); 370*0Sstevel@tonic-gate return(OSA_ADB_XDR_FAILURE); 371*0Sstevel@tonic-gate } 372*0Sstevel@tonic-gate tl_data.tl_data_type = KRB5_TL_KADM_DATA; 373*0Sstevel@tonic-gate tl_data.tl_data_length = xdr_getpos(&xdrs); 374*0Sstevel@tonic-gate tl_data.tl_data_contents = (unsigned char *) xdralloc_getdata(&xdrs); 375*0Sstevel@tonic-gate 376*0Sstevel@tonic-gate ret = krb5_dbe_update_tl_data(handle->context, kdb, &tl_data); 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate xdr_destroy(&xdrs); 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate if (ret) 381*0Sstevel@tonic-gate return(ret); 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate one = 1; 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate if (ret = krb5_db_put_principal(handle->context, kdb, &one)) 386*0Sstevel@tonic-gate return(ret); 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate return(0); 389*0Sstevel@tonic-gate } 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate krb5_error_code 392*0Sstevel@tonic-gate kdb_delete_entry(kadm5_server_handle_t handle, krb5_principal name) 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate int one = 1; 395*0Sstevel@tonic-gate krb5_error_code ret; 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate ret = krb5_db_delete_principal(handle->context, name, &one); 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate return ret; 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate typedef struct _iter_data { 403*0Sstevel@tonic-gate void (*func)(void *, krb5_principal); 404*0Sstevel@tonic-gate void *data; 405*0Sstevel@tonic-gate } iter_data; 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate static krb5_error_code 408*0Sstevel@tonic-gate kdb_iter_func(krb5_pointer data, krb5_db_entry *kdb) 409*0Sstevel@tonic-gate { 410*0Sstevel@tonic-gate iter_data *id = (iter_data *) data; 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate (*(id->func))(id->data, kdb->princ); 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate return(0); 415*0Sstevel@tonic-gate } 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gate krb5_error_code 418*0Sstevel@tonic-gate kdb_iter_entry(kadm5_server_handle_t handle, 419*0Sstevel@tonic-gate void (*iter_fct)(void *, krb5_principal), void *data) 420*0Sstevel@tonic-gate { 421*0Sstevel@tonic-gate iter_data id; 422*0Sstevel@tonic-gate krb5_error_code ret; 423*0Sstevel@tonic-gate 424*0Sstevel@tonic-gate id.func = iter_fct; 425*0Sstevel@tonic-gate id.data = data; 426*0Sstevel@tonic-gate 427*0Sstevel@tonic-gate if (ret = krb5_db_iterate(handle->context, kdb_iter_func, &id)) 428*0Sstevel@tonic-gate return(ret); 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate return(0); 431*0Sstevel@tonic-gate } 432*0Sstevel@tonic-gate 433