17c478bd9Sstevel@tonic-gate /*
27c64d375Smp  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
8*55fea89dSDan Cross  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
117c478bd9Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
127c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
137c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
147c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
177c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
187c478bd9Sstevel@tonic-gate  *	copyright.
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
217c478bd9Sstevel@tonic-gate  *
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
277c478bd9Sstevel@tonic-gate  *
28159d09a2SMark Phalan  * $Id: server_init.c 18584 2006-09-13 20:30:23Z raeburn $
29159d09a2SMark Phalan  * $Source$
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
3356a424ccSmp static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/server_init.c,v 1.8 2002/10/15 15:40:49 epeisach Exp $";
347c478bd9Sstevel@tonic-gate #endif
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <stdio.h>
377c478bd9Sstevel@tonic-gate #include <stdlib.h>
38159d09a2SMark Phalan #include <errno.h>
397c478bd9Sstevel@tonic-gate #include <com_err.h>
40159d09a2SMark Phalan #include "k5-int.h"		/* needed for gssapiP_krb5.h */
417c478bd9Sstevel@tonic-gate #include <kadm5/admin.h>
427c478bd9Sstevel@tonic-gate #include <krb5.h>
437c478bd9Sstevel@tonic-gate #include "server_internal.h"
447c478bd9Sstevel@tonic-gate #include <kdb/kdb_log.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate  * Function check_handle
487c478bd9Sstevel@tonic-gate  *
497c478bd9Sstevel@tonic-gate  * Purpose: Check a server handle and return a com_err code if it is
507c478bd9Sstevel@tonic-gate  * invalid or 0 if it is valid.
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  * Arguments:
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  * 	handle		The server handle.
557c478bd9Sstevel@tonic-gate  */
567c478bd9Sstevel@tonic-gate 
check_handle(void * handle)577c478bd9Sstevel@tonic-gate static int check_handle(void *handle)
587c478bd9Sstevel@tonic-gate {
597c478bd9Sstevel@tonic-gate      CHECK_HANDLE(handle);
607c478bd9Sstevel@tonic-gate      return 0;
617c478bd9Sstevel@tonic-gate }
627c478bd9Sstevel@tonic-gate 
dup_db_args(kadm5_server_handle_t handle,char ** db_args)6354925bf6Swillf static int dup_db_args(kadm5_server_handle_t handle, char **db_args)
6454925bf6Swillf {
6554925bf6Swillf     int count  = 0;
6654925bf6Swillf     int ret = 0;
6754925bf6Swillf 
6854925bf6Swillf     for (count=0; db_args && db_args[count]; count++);
6954925bf6Swillf     if (count == 0) {
7054925bf6Swillf 	handle->db_args = NULL;
7154925bf6Swillf 	goto clean_n_exit;
7254925bf6Swillf     }
7354925bf6Swillf 
7454925bf6Swillf     handle->db_args = calloc(sizeof(char*), count+1);
7554925bf6Swillf     if (handle->db_args == NULL) {
7654925bf6Swillf 	ret=ENOMEM;
7754925bf6Swillf 	goto clean_n_exit;
7854925bf6Swillf     }
7954925bf6Swillf 
8054925bf6Swillf     for (count=0; db_args[count]; count++) {
8154925bf6Swillf 	handle->db_args[count] = strdup(db_args[count]);
8254925bf6Swillf 	if (handle->db_args[count] == NULL) {
8354925bf6Swillf 	    ret = ENOMEM;
8454925bf6Swillf 	    goto clean_n_exit;
8554925bf6Swillf 	}
8654925bf6Swillf     }
8754925bf6Swillf 
8854925bf6Swillf  clean_n_exit:
8954925bf6Swillf     if (ret && handle->db_args) {
9054925bf6Swillf 	for (count=0; handle->db_args[count]; count++)
9154925bf6Swillf 	    free(handle->db_args[count]);
9254925bf6Swillf 
9354925bf6Swillf 	free(handle->db_args), handle->db_args = NULL;
9454925bf6Swillf     }
9554925bf6Swillf 
9654925bf6Swillf     return ret;
9754925bf6Swillf }
9854925bf6Swillf 
free_db_args(kadm5_server_handle_t handle)9954925bf6Swillf static void free_db_args(kadm5_server_handle_t handle)
10054925bf6Swillf {
10154925bf6Swillf     int count;
10254925bf6Swillf 
10354925bf6Swillf     if (handle->db_args) {
10454925bf6Swillf 	for (count=0; handle->db_args[count]; count++)
10554925bf6Swillf 	    free(handle->db_args[count]);
10654925bf6Swillf 
10754925bf6Swillf 	free(handle->db_args), handle->db_args = NULL;
10854925bf6Swillf     }
10954925bf6Swillf }
11054925bf6Swillf 
kadm5_init_with_password(char * client_name,char * pass,char * service_name,kadm5_config_params * params,krb5_ui_4 struct_version,krb5_ui_4 api_version,char ** db_args,void ** server_handle)1117c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass,
1127c478bd9Sstevel@tonic-gate 				     char *service_name,
1137c478bd9Sstevel@tonic-gate 				     kadm5_config_params *params,
1147c478bd9Sstevel@tonic-gate 				     krb5_ui_4 struct_version,
1157c478bd9Sstevel@tonic-gate 				     krb5_ui_4 api_version,
11654925bf6Swillf 				     char **db_args,
1177c478bd9Sstevel@tonic-gate 				     void **server_handle)
1187c478bd9Sstevel@tonic-gate {
1197c478bd9Sstevel@tonic-gate      return kadm5_init(client_name, pass, service_name, params,
12054925bf6Swillf 		       struct_version, api_version, db_args,
1217c478bd9Sstevel@tonic-gate 		       server_handle);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate 
kadm5_init_with_creds(char * client_name,krb5_ccache ccache,char * service_name,kadm5_config_params * params,krb5_ui_4 struct_version,krb5_ui_4 api_version,char ** db_args,void ** server_handle)1247c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init_with_creds(char *client_name,
1257c478bd9Sstevel@tonic-gate 				  krb5_ccache ccache,
1267c478bd9Sstevel@tonic-gate 				  char *service_name,
1277c478bd9Sstevel@tonic-gate 				  kadm5_config_params *params,
1287c478bd9Sstevel@tonic-gate 				  krb5_ui_4 struct_version,
1297c478bd9Sstevel@tonic-gate 				  krb5_ui_4 api_version,
13054925bf6Swillf 				  char **db_args,
1317c478bd9Sstevel@tonic-gate 				  void **server_handle)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate      /*
1347c478bd9Sstevel@tonic-gate       * A program calling init_with_creds *never* expects to prompt the
1357c478bd9Sstevel@tonic-gate       * user.  Therefore, always pass a dummy password in case this is
1367c478bd9Sstevel@tonic-gate       * KADM5_API_VERSION_1.  If this is KADM5_API_VERSION_2 and
1377c478bd9Sstevel@tonic-gate       * MKEY_FROM_KBD is non-zero, return an error.
1387c478bd9Sstevel@tonic-gate       */
1397c478bd9Sstevel@tonic-gate      if (api_version == KADM5_API_VERSION_2 && params &&
1407c478bd9Sstevel@tonic-gate 	 (params->mask & KADM5_CONFIG_MKEY_FROM_KBD) &&
1417c478bd9Sstevel@tonic-gate 	 params->mkey_from_kbd)
1427c478bd9Sstevel@tonic-gate 	  return KADM5_BAD_SERVER_PARAMS;
1437c478bd9Sstevel@tonic-gate      return kadm5_init(client_name, NULL, service_name, params,
14454925bf6Swillf 		       struct_version, api_version, db_args,
1457c478bd9Sstevel@tonic-gate 		       server_handle);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 
kadm5_init_with_skey(char * client_name,char * keytab,char * service_name,kadm5_config_params * params,krb5_ui_4 struct_version,krb5_ui_4 api_version,char ** db_args,void ** server_handle)1497c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab,
1507c478bd9Sstevel@tonic-gate 				 char *service_name,
1517c478bd9Sstevel@tonic-gate 				 kadm5_config_params *params,
1527c478bd9Sstevel@tonic-gate 				 krb5_ui_4 struct_version,
1537c478bd9Sstevel@tonic-gate 				 krb5_ui_4 api_version,
15454925bf6Swillf 				 char **db_args,
1557c478bd9Sstevel@tonic-gate 				 void **server_handle)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate      /*
1587c478bd9Sstevel@tonic-gate       * A program calling init_with_skey *never* expects to prompt the
1597c478bd9Sstevel@tonic-gate       * user.  Therefore, always pass a dummy password in case this is
1607c478bd9Sstevel@tonic-gate       * KADM5_API_VERSION_1.  If this is KADM5_API_VERSION_2 and
1617c478bd9Sstevel@tonic-gate       * MKEY_FROM_KBD is non-zero, return an error.
1627c478bd9Sstevel@tonic-gate       */
1637c478bd9Sstevel@tonic-gate      if (api_version == KADM5_API_VERSION_2 && params &&
1647c478bd9Sstevel@tonic-gate 	 (params->mask & KADM5_CONFIG_MKEY_FROM_KBD) &&
1657c478bd9Sstevel@tonic-gate 	 params->mkey_from_kbd)
1667c478bd9Sstevel@tonic-gate 	  return KADM5_BAD_SERVER_PARAMS;
1677c478bd9Sstevel@tonic-gate      return kadm5_init(client_name, NULL, service_name, params,
16854925bf6Swillf 		       struct_version, api_version, db_args,
1697c478bd9Sstevel@tonic-gate 		       server_handle);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c64d375Smp /*
1737c64d375Smp  * Solaris Kerberos:
1747c64d375Smp  * A private extended version of kadm5_init which potentially
1757c64d375Smp  * returns more information in case of an error.
1767c64d375Smp  */
kadm5_init2(char * client_name,char * pass,char * service_name,kadm5_config_params * params_in,krb5_ui_4 struct_version,krb5_ui_4 api_version,char ** db_args,void ** server_handle,char ** emsg)1777c64d375Smp kadm5_ret_t kadm5_init2(char *client_name, char *pass,
1787c478bd9Sstevel@tonic-gate 		       char *service_name,
1797c478bd9Sstevel@tonic-gate 		       kadm5_config_params *params_in,
1807c478bd9Sstevel@tonic-gate 		       krb5_ui_4 struct_version,
1817c478bd9Sstevel@tonic-gate 		       krb5_ui_4 api_version,
18254925bf6Swillf 		       char **db_args,
1837c64d375Smp 		       void **server_handle,
1847c64d375Smp 		       char **emsg)
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate      int ret;
1877c478bd9Sstevel@tonic-gate      kadm5_server_handle_t handle;
1887c478bd9Sstevel@tonic-gate      kadm5_config_params params_local; /* for v1 compat */
1897c478bd9Sstevel@tonic-gate 
1907c64d375Smp     if (emsg)
1917c64d375Smp 	*emsg = NULL;
1927c64d375Smp 
1937c478bd9Sstevel@tonic-gate     if (! server_handle)
1947c478bd9Sstevel@tonic-gate 	 return EINVAL;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate     if (! client_name)
1977c478bd9Sstevel@tonic-gate 	 return EINVAL;
19854925bf6Swillf 
1997c478bd9Sstevel@tonic-gate     if (! (handle = (kadm5_server_handle_t) malloc(sizeof *handle)))
2007c478bd9Sstevel@tonic-gate 	 return ENOMEM;
2017c478bd9Sstevel@tonic-gate     memset(handle, 0, sizeof(*handle));
2027c478bd9Sstevel@tonic-gate 
20354925bf6Swillf     ret = dup_db_args(handle, db_args);
20456a424ccSmp     if (ret) {
20554925bf6Swillf 	free(handle);
20654925bf6Swillf 	return ret;
20754925bf6Swillf     }
20854925bf6Swillf 
20954925bf6Swillf     ret = (int) krb5int_init_context_kdc(&(handle->context));
21054925bf6Swillf     if (ret) {
21154925bf6Swillf 	 free_db_args(handle);
2127c478bd9Sstevel@tonic-gate 	 free(handle);
2137c478bd9Sstevel@tonic-gate 	 return(ret);
2147c478bd9Sstevel@tonic-gate     }
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate     handle->magic_number = KADM5_SERVER_HANDLE_MAGIC;
2177c478bd9Sstevel@tonic-gate     handle->struct_version = struct_version;
2187c478bd9Sstevel@tonic-gate     handle->api_version = api_version;
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate      /*
2217c478bd9Sstevel@tonic-gate       * Verify the version numbers before proceeding; we can't use
2227c478bd9Sstevel@tonic-gate       * CHECK_HANDLE because not all fields are set yet.
2237c478bd9Sstevel@tonic-gate       */
2247c478bd9Sstevel@tonic-gate      GENERIC_CHECK_HANDLE(handle, KADM5_OLD_SERVER_API_VERSION,
2257c478bd9Sstevel@tonic-gate 			  KADM5_NEW_SERVER_API_VERSION);
22654925bf6Swillf 
2277c478bd9Sstevel@tonic-gate      /*
2287c478bd9Sstevel@tonic-gate       * Acquire relevant profile entries.  In version 2, merge values
2297c478bd9Sstevel@tonic-gate       * in params_in with values from profile, based on
2307c478bd9Sstevel@tonic-gate       * params_in->mask.
2317c478bd9Sstevel@tonic-gate       *
2327c478bd9Sstevel@tonic-gate       * In version 1, we've given a realm (which may be NULL) instead
2337c478bd9Sstevel@tonic-gate       * of params_in.  So use that realm, make params_in contain an
2347c478bd9Sstevel@tonic-gate       * empty mask, and behave like version 2.
2357c478bd9Sstevel@tonic-gate       */
2367c478bd9Sstevel@tonic-gate      memset((char *) &params_local, 0, sizeof(params_local));
2377c478bd9Sstevel@tonic-gate      if (api_version == KADM5_API_VERSION_1) {
2387c478bd9Sstevel@tonic-gate 	  params_local.realm = (char *) params_in;
2397c478bd9Sstevel@tonic-gate 	  if (params_in)
2407c478bd9Sstevel@tonic-gate 	       params_local.mask = KADM5_CONFIG_REALM;
2417c478bd9Sstevel@tonic-gate 	  params_in = &params_local;
2427c478bd9Sstevel@tonic-gate      }
2437c478bd9Sstevel@tonic-gate 
24454925bf6Swillf #if 0 /* Now that we look at krb5.conf as well as kdc.conf, we can
24554925bf6Swillf 	 expect to see admin_server being set sometimes.  */
2467c478bd9Sstevel@tonic-gate #define ILLEGAL_PARAMS (KADM5_CONFIG_ADMIN_SERVER)
2477c478bd9Sstevel@tonic-gate      if (params_in && (params_in->mask & ILLEGAL_PARAMS)) {
2487c478bd9Sstevel@tonic-gate 	  krb5_free_context(handle->context);
24954925bf6Swillf 	  free_db_args(handle);
2507c478bd9Sstevel@tonic-gate 	  free(handle);
2517c478bd9Sstevel@tonic-gate 	  return KADM5_BAD_SERVER_PARAMS;
2527c478bd9Sstevel@tonic-gate      }
25354925bf6Swillf #endif
2547c478bd9Sstevel@tonic-gate 
255159d09a2SMark Phalan      ret = kadm5_get_config_params(handle->context, 1, params_in,
25656a424ccSmp 				       &handle->params);
25756a424ccSmp      if (ret) {
2587c478bd9Sstevel@tonic-gate 	  krb5_free_context(handle->context);
25954925bf6Swillf 	  free_db_args(handle);
2607c478bd9Sstevel@tonic-gate 	  free(handle);
2617c478bd9Sstevel@tonic-gate 	  return(ret);
2627c478bd9Sstevel@tonic-gate      }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_DBNAME | \
2657c478bd9Sstevel@tonic-gate 			 KADM5_CONFIG_ADBNAME | \
2667c478bd9Sstevel@tonic-gate 			 KADM5_CONFIG_ADB_LOCKFILE | \
2677c478bd9Sstevel@tonic-gate 			 KADM5_CONFIG_ENCTYPE | \
2687c478bd9Sstevel@tonic-gate 			 KADM5_CONFIG_FLAGS | \
2697c478bd9Sstevel@tonic-gate 			 KADM5_CONFIG_MAX_LIFE | KADM5_CONFIG_MAX_RLIFE | \
27054925bf6Swillf 			 KADM5_CONFIG_EXPIRATION | KADM5_CONFIG_ENCTYPES)
27156a424ccSmp 
2727c478bd9Sstevel@tonic-gate      if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
2737c64d375Smp 	  kadm5_free_config_params(handle->context, &handle->params);
2747c478bd9Sstevel@tonic-gate 	  krb5_free_context(handle->context);
27554925bf6Swillf 	  free_db_args(handle);
2767c478bd9Sstevel@tonic-gate 	  free(handle);
2777c478bd9Sstevel@tonic-gate 	  return KADM5_MISSING_CONF_PARAMS;
2787c478bd9Sstevel@tonic-gate      }
2797c478bd9Sstevel@tonic-gate 
28054925bf6Swillf      ret = krb5_set_default_realm(handle->context, handle->params.realm);
28154925bf6Swillf      if (ret) {
2827c64d375Smp 	  kadm5_free_config_params(handle->context, &handle->params);
28354925bf6Swillf 	  krb5_free_context(handle->context);
28454925bf6Swillf 	  free_db_args(handle);
28554925bf6Swillf 	  free(handle);
28654925bf6Swillf 	  return ret;
28754925bf6Swillf      }
2887c478bd9Sstevel@tonic-gate 
28954925bf6Swillf     ret = krb5_db_open(handle->context, db_args,
29054925bf6Swillf 		       KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN);
29156a424ccSmp     if (ret) {
2927c64d375Smp 	 if (emsg) {
2937c64d375Smp 		 const char *m = krb5_get_error_message(handle->context, ret);
2947c64d375Smp 		 *emsg = strdup(m);
2957c64d375Smp 		 krb5_free_error_message(handle->context, m);
2967c64d375Smp 	 }
2977c64d375Smp 	 kadm5_free_config_params(handle->context, &handle->params);
2987c478bd9Sstevel@tonic-gate 	 krb5_free_context(handle->context);
29954925bf6Swillf 	 free_db_args(handle);
3007c478bd9Sstevel@tonic-gate 	 free(handle);
3017c478bd9Sstevel@tonic-gate 	 return(ret);
3027c478bd9Sstevel@tonic-gate     }
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate     if ((ret = krb5_parse_name(handle->context, client_name,
3057c478bd9Sstevel@tonic-gate 			       &handle->current_caller))) {
3067c478bd9Sstevel@tonic-gate 	 krb5_db_fini(handle->context);
3077c64d375Smp 	 kadm5_free_config_params(handle->context, &handle->params);
3087c478bd9Sstevel@tonic-gate 	 krb5_free_context(handle->context);
30954925bf6Swillf 	 free_db_args(handle);
3107c478bd9Sstevel@tonic-gate 	 free(handle);
3117c478bd9Sstevel@tonic-gate 	 return ret;
3127c478bd9Sstevel@tonic-gate     }
3137c478bd9Sstevel@tonic-gate 
31456a424ccSmp     if (! (handle->lhandle = malloc(sizeof(*handle)))) {
3157c478bd9Sstevel@tonic-gate 	 krb5_db_fini(handle->context);
3167c64d375Smp 	 kadm5_free_config_params(handle->context, &handle->params);
3177c478bd9Sstevel@tonic-gate 	 krb5_free_context(handle->context);
31854925bf6Swillf 	 free_db_args(handle);
3197c478bd9Sstevel@tonic-gate 	 free(handle);
32056a424ccSmp 	 return ENOMEM;
3217c478bd9Sstevel@tonic-gate     }
32256a424ccSmp     *handle->lhandle = *handle;
32356a424ccSmp     handle->lhandle->api_version = KADM5_API_VERSION_2;
32456a424ccSmp     handle->lhandle->struct_version = KADM5_STRUCT_VERSION;
32556a424ccSmp     handle->lhandle->lhandle = handle->lhandle;
32656a424ccSmp 
32756a424ccSmp     /* can't check the handle until current_caller is set */
32856a424ccSmp     ret = check_handle((void *) handle);
32956a424ccSmp     if (ret) {
3307c64d375Smp 	krb5_db_fini(handle->context);
3317c64d375Smp 	kadm5_free_config_params(handle->context, &handle->params);
3327c64d375Smp 	krb5_free_context(handle->context);
33354925bf6Swillf 	free_db_args(handle);
33454925bf6Swillf 	free(handle);
33556a424ccSmp 	return ret;
33656a424ccSmp     }
33754925bf6Swillf 
33856a424ccSmp     /*
33956a424ccSmp      * The KADM5_API_VERSION_1 spec said "If pass (or keytab) is NULL
34056a424ccSmp      * or an empty string, reads the master password from [the stash
34156a424ccSmp      * file].  Otherwise, the non-NULL password is ignored and the
34256a424ccSmp      * user is prompted for it via the tty."  However, the code was
34356a424ccSmp      * implemented the other way: when a non-NULL password was
34456a424ccSmp      * provided, the stash file was used.  This is somewhat more
34556a424ccSmp      * sensible, as then a local or remote client that provides a
34656a424ccSmp      * password does not prompt the user.  This code maintains the
34756a424ccSmp      * previous actual behavior, and not the old spec behavior,
34856a424ccSmp      * because that is how the unit tests are written.
34956a424ccSmp      *
35056a424ccSmp      * In KADM5_API_VERSION_2, this decision is controlled by
35156a424ccSmp      * params.
35256a424ccSmp      *
35356a424ccSmp      * kdb_init_master's third argument is "from_keyboard".
35456a424ccSmp      */
3553441f6a1Ssemery     /*
3563441f6a1Ssemery      * Solaris Kerberos: Setting to an unknown enc type will make the function
3573441f6a1Ssemery      * read the encryption type in the stash file instead of assumming that it
3583441f6a1Ssemery      * is the default type.
3593441f6a1Ssemery      */
3603441f6a1Ssemery     if (handle->params.enctype == DEFAULT_KDC_ENCTYPE)
3613441f6a1Ssemery 	handle->params.enctype = ENCTYPE_UNKNOWN;
36256a424ccSmp     ret = kdb_init_master(handle, handle->params.realm,
36356a424ccSmp 			  (handle->api_version == KADM5_API_VERSION_1 ?
36456a424ccSmp 			   ((pass == NULL) || !(strlen(pass))) :
36556a424ccSmp 			   ((handle->params.mask & KADM5_CONFIG_MKEY_FROM_KBD)
36656a424ccSmp 			    && handle->params.mkey_from_kbd)
36754925bf6Swillf 			));
36856a424ccSmp     if (ret) {
36954925bf6Swillf 	krb5_db_fini(handle->context);
3707c64d375Smp 	kadm5_free_config_params(handle->context, &handle->params);
37156a424ccSmp 	krb5_free_context(handle->context);
37254925bf6Swillf 	free_db_args(handle);
37356a424ccSmp 	free(handle);
37456a424ccSmp 	return ret;
37556a424ccSmp     }
3763441f6a1Ssemery     /*
3773441f6a1Ssemery      * Solaris Kerberos: We used the enc type that was discovered in the stash
3783441f6a1Ssemery      * file to associate with the other magic principals in the database.
3793441f6a1Ssemery      */
3803441f6a1Ssemery     handle->params.enctype = handle->master_keyblock.enctype;
38154925bf6Swillf 
38256a424ccSmp     ret = kdb_init_hist(handle, handle->params.realm);
38356a424ccSmp     if (ret) {
3847c478bd9Sstevel@tonic-gate 	 krb5_db_fini(handle->context);
3857c64d375Smp 	 kadm5_free_config_params(handle->context, &handle->params);
3867c478bd9Sstevel@tonic-gate 	 krb5_free_context(handle->context);
38754925bf6Swillf 	 free_db_args(handle);
3887c478bd9Sstevel@tonic-gate 	 free(handle);
3897c478bd9Sstevel@tonic-gate 	 return ret;
3907c478bd9Sstevel@tonic-gate     }
3917c478bd9Sstevel@tonic-gate 
39256a424ccSmp     ret = init_dict(&handle->params);
39356a424ccSmp     if (ret) {
3947c478bd9Sstevel@tonic-gate 	 krb5_db_fini(handle->context);
3957c478bd9Sstevel@tonic-gate 	 krb5_free_principal(handle->context, handle->current_caller);
3967c64d375Smp 	 kadm5_free_config_params(handle->context, &handle->params);
3977c478bd9Sstevel@tonic-gate 	 krb5_free_context(handle->context);
39854925bf6Swillf 	 free_db_args(handle);
3997c478bd9Sstevel@tonic-gate 	 free(handle);
4007c478bd9Sstevel@tonic-gate 	 return ret;
4017c478bd9Sstevel@tonic-gate     }
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate     *server_handle = (void *) handle;
40454925bf6Swillf 
4057c478bd9Sstevel@tonic-gate     return KADM5_OK;
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
kadm5_init(char * client_name,char * pass,char * service_name,kadm5_config_params * params_in,krb5_ui_4 struct_version,krb5_ui_4 api_version,char ** db_args,void ** server_handle)4087c64d375Smp kadm5_ret_t kadm5_init(char *client_name, char *pass,
4097c64d375Smp 		       char *service_name,
4107c64d375Smp 		       kadm5_config_params *params_in,
4117c64d375Smp 		       krb5_ui_4 struct_version,
4127c64d375Smp 		       krb5_ui_4 api_version,
4137c64d375Smp 		       char **db_args,
4147c64d375Smp 		       void **server_handle) {
4157c64d375Smp 	return (kadm5_init2(client_name, pass, service_name, params_in,
4167c64d375Smp 	    struct_version, api_version, db_args, server_handle, NULL));
4177c64d375Smp 
4187c64d375Smp }
4197c64d375Smp 
kadm5_destroy(void * server_handle)4207c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_destroy(void *server_handle)
4217c478bd9Sstevel@tonic-gate {
4227c478bd9Sstevel@tonic-gate     kadm5_server_handle_t handle = server_handle;
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate     CHECK_HANDLE(server_handle);
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate     destroy_dict();
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate     adb_policy_close(handle);
4297c478bd9Sstevel@tonic-gate     krb5_db_fini(handle->context);
4307c478bd9Sstevel@tonic-gate     krb5_free_principal(handle->context, handle->current_caller);
4317c478bd9Sstevel@tonic-gate     kadm5_free_config_params(handle->context, &handle->params);
4327c478bd9Sstevel@tonic-gate     krb5_free_context(handle->context);
4337c478bd9Sstevel@tonic-gate     handle->magic_number = 0;
4347c478bd9Sstevel@tonic-gate     free(handle->lhandle);
43554925bf6Swillf     free_db_args(handle);
4367c478bd9Sstevel@tonic-gate     free(handle);
43754925bf6Swillf 
4387c478bd9Sstevel@tonic-gate     return KADM5_OK;
4397c478bd9Sstevel@tonic-gate }
44056a424ccSmp 
kadm5_lock(void * server_handle)44156a424ccSmp kadm5_ret_t kadm5_lock(void *server_handle)
44256a424ccSmp {
44356a424ccSmp     kadm5_server_handle_t handle = server_handle;
44456a424ccSmp     kadm5_ret_t ret;
44556a424ccSmp 
44656a424ccSmp     CHECK_HANDLE(server_handle);
44754925bf6Swillf     ret = krb5_db_lock(handle->context, KRB5_DB_LOCKMODE_EXCLUSIVE);
44856a424ccSmp     if (ret)
44956a424ccSmp 	return ret;
45056a424ccSmp 
45156a424ccSmp     return KADM5_OK;
45256a424ccSmp }
45356a424ccSmp 
kadm5_unlock(void * server_handle)45456a424ccSmp kadm5_ret_t kadm5_unlock(void *server_handle)
45556a424ccSmp {
45656a424ccSmp     kadm5_server_handle_t handle = server_handle;
45756a424ccSmp     kadm5_ret_t ret;
45856a424ccSmp 
45956a424ccSmp     CHECK_HANDLE(server_handle);
46056a424ccSmp     ret = krb5_db_unlock(handle->context);
46156a424ccSmp     if (ret)
46256a424ccSmp 	return ret;
46356a424ccSmp 
46456a424ccSmp     return KADM5_OK;
46556a424ccSmp }
4667c478bd9Sstevel@tonic-gate 
kadm5_flush(void * server_handle)4677c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_flush(void *server_handle)
4687c478bd9Sstevel@tonic-gate {
4697c478bd9Sstevel@tonic-gate      kadm5_server_handle_t handle = server_handle;
4707c478bd9Sstevel@tonic-gate      kadm5_ret_t ret;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate      CHECK_HANDLE(server_handle);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate      if ((ret = krb5_db_fini(handle->context)) ||
47554925bf6Swillf 	 (ret = krb5_db_open(handle->context, handle->db_args,
47654925bf6Swillf 			     KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN)) ||
4777c478bd9Sstevel@tonic-gate 	 (ret = adb_policy_close(handle)) ||
4787c478bd9Sstevel@tonic-gate 	 (ret = adb_policy_init(handle))) {
4797c478bd9Sstevel@tonic-gate 	  (void) kadm5_destroy(server_handle);
4807c478bd9Sstevel@tonic-gate 	  return ret;
4817c478bd9Sstevel@tonic-gate      }
4827c478bd9Sstevel@tonic-gate      return KADM5_OK;
4837c478bd9Sstevel@tonic-gate }
4847c478bd9Sstevel@tonic-gate 
_kadm5_check_handle(void * handle)4857c478bd9Sstevel@tonic-gate int _kadm5_check_handle(void *handle)
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate      CHECK_HANDLE(handle);
4887c478bd9Sstevel@tonic-gate      return 0;
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate 
49154925bf6Swillf #include "gssapiP_krb5.h"
kadm5_init_krb5_context(krb5_context * ctx)49254925bf6Swillf krb5_error_code kadm5_init_krb5_context (krb5_context *ctx)
49354925bf6Swillf {
49454925bf6Swillf     /* Solaris Kerberos: not needed */
49554925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/
49654925bf6Swillf     static int first_time = 1;
49754925bf6Swillf     if (first_time) {
49854925bf6Swillf 	krb5_error_code err;
49954925bf6Swillf 	err = krb5_gss_use_kdc_context();
50054925bf6Swillf 	if (err)
50154925bf6Swillf 	    return err;
50254925bf6Swillf 	first_time = 0;
50354925bf6Swillf     }
50454925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/
50554925bf6Swillf     return krb5int_init_context_kdc(ctx);
50654925bf6Swillf }
50754925bf6Swillf 
5087c478bd9Sstevel@tonic-gate krb5_error_code
kadm5_init_iprop(void * handle)5097c478bd9Sstevel@tonic-gate kadm5_init_iprop(void *handle)
5107c478bd9Sstevel@tonic-gate {
5117c478bd9Sstevel@tonic-gate 	kadm5_server_handle_t iprop_h;
5127c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	iprop_h = handle;
5157c478bd9Sstevel@tonic-gate 	if (iprop_h->params.iprop_enabled) {
5167c478bd9Sstevel@tonic-gate 		ulog_set_role(iprop_h->context, IPROP_MASTER);
5177c478bd9Sstevel@tonic-gate 		if ((retval = ulog_map(iprop_h->context, &iprop_h->params,
5187c478bd9Sstevel@tonic-gate 		    FKCOMMAND)) != 0)
5197c478bd9Sstevel@tonic-gate 			return (retval);
5207c478bd9Sstevel@tonic-gate 	}
5217c478bd9Sstevel@tonic-gate 	return (0);
5227c478bd9Sstevel@tonic-gate }
523