17c478bd9Sstevel@tonic-gate /*
2bd211b85Ssemery * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
6*159d09a2SMark Phalan
7*159d09a2SMark Phalan
8*159d09a2SMark Phalan /*
9*159d09a2SMark Phalan * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
10*159d09a2SMark Phalan */
117c478bd9Sstevel@tonic-gate
127c478bd9Sstevel@tonic-gate /*
137c478bd9Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC.
147c478bd9Sstevel@tonic-gate *
157c478bd9Sstevel@tonic-gate * All rights reserved.
167c478bd9Sstevel@tonic-gate *
177c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may require
187c478bd9Sstevel@tonic-gate * a specific license from the United States Government. It is the
197c478bd9Sstevel@tonic-gate * responsibility of any person or organization contemplating export to
207c478bd9Sstevel@tonic-gate * obtain such a license before exporting.
217c478bd9Sstevel@tonic-gate *
227c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
237c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
247c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
257c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
267c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
277c478bd9Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining
287c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
297c478bd9Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of
307c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
317c478bd9Sstevel@tonic-gate * or implied warranty.
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
347c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
357c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
367c478bd9Sstevel@tonic-gate */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <netdb.h>
4054925bf6Swillf #include "autoconf.h"
4156a424ccSmp153739 #ifdef HAVE_MEMORY_H
427c478bd9Sstevel@tonic-gate #include <memory.h>
4356a424ccSmp153739 #endif
447c478bd9Sstevel@tonic-gate #include <string.h>
457c478bd9Sstevel@tonic-gate #include <com_err.h>
467c478bd9Sstevel@tonic-gate #include <sys/types.h>
477c478bd9Sstevel@tonic-gate #include <sys/socket.h>
487c478bd9Sstevel@tonic-gate #include <netinet/in.h>
497c478bd9Sstevel@tonic-gate #include <k5-int.h> /* for KRB5_ADM_DEFAULT_PORT */
5054925bf6Swillf #include <krb5.h>
517c478bd9Sstevel@tonic-gate #ifdef __STDC__
527c478bd9Sstevel@tonic-gate #include <stdlib.h>
537c478bd9Sstevel@tonic-gate #endif
547c478bd9Sstevel@tonic-gate #include <libintl.h>
557c478bd9Sstevel@tonic-gate
5656a424ccSmp153739 #include <kadm5/admin.h>
5756a424ccSmp153739 #include <kadm5/kadm_rpc.h>
5856a424ccSmp153739 #include "client_internal.h"
5956a424ccSmp153739
607c478bd9Sstevel@tonic-gate #include <syslog.h>
617c478bd9Sstevel@tonic-gate #include <gssapi/gssapi.h>
627c478bd9Sstevel@tonic-gate #include <gssapi_krb5.h>
637c478bd9Sstevel@tonic-gate #include <gssapiP_krb5.h>
647c478bd9Sstevel@tonic-gate #include <rpc/clnt.h>
6556a424ccSmp153739
667c478bd9Sstevel@tonic-gate #include <iprop_hdr.h>
677c478bd9Sstevel@tonic-gate #include "iprop.h"
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate #define ADM_CCACHE "/tmp/ovsec_adm.XXXXXX"
707c478bd9Sstevel@tonic-gate
7156a424ccSmp153739 static int old_auth_gssapi = 0;
727c478bd9Sstevel@tonic-gate /* connection timeout to kadmind in seconds */
737c478bd9Sstevel@tonic-gate #define KADMIND_CONNECT_TIMEOUT 25
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate int _kadm5_check_handle();
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate enum init_type { INIT_PASS, INIT_SKEY, INIT_CREDS };
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate static kadm5_ret_t _kadm5_init_any(char *client_name,
807c478bd9Sstevel@tonic-gate enum init_type init_type,
817c478bd9Sstevel@tonic-gate char *pass,
827c478bd9Sstevel@tonic-gate krb5_ccache ccache_in,
837c478bd9Sstevel@tonic-gate char *service_name,
847c478bd9Sstevel@tonic-gate kadm5_config_params *params,
857c478bd9Sstevel@tonic-gate krb5_ui_4 struct_version,
867c478bd9Sstevel@tonic-gate krb5_ui_4 api_version,
8754925bf6Swillf char **db_args,
887c478bd9Sstevel@tonic-gate void **server_handle);
897c478bd9Sstevel@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)907c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init_with_creds(char *client_name,
917c478bd9Sstevel@tonic-gate krb5_ccache ccache,
927c478bd9Sstevel@tonic-gate char *service_name,
937c478bd9Sstevel@tonic-gate kadm5_config_params *params,
947c478bd9Sstevel@tonic-gate krb5_ui_4 struct_version,
957c478bd9Sstevel@tonic-gate krb5_ui_4 api_version,
9654925bf6Swillf char **db_args,
977c478bd9Sstevel@tonic-gate void **server_handle)
987c478bd9Sstevel@tonic-gate {
997c478bd9Sstevel@tonic-gate return _kadm5_init_any(client_name, INIT_CREDS, NULL, ccache,
1007c478bd9Sstevel@tonic-gate service_name, params,
10154925bf6Swillf struct_version, api_version, db_args,
1027c478bd9Sstevel@tonic-gate server_handle);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate
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)1067c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass,
1077c478bd9Sstevel@tonic-gate char *service_name,
1087c478bd9Sstevel@tonic-gate kadm5_config_params *params,
1097c478bd9Sstevel@tonic-gate krb5_ui_4 struct_version,
1107c478bd9Sstevel@tonic-gate krb5_ui_4 api_version,
11154925bf6Swillf char **db_args,
1127c478bd9Sstevel@tonic-gate void **server_handle)
1137c478bd9Sstevel@tonic-gate {
1147c478bd9Sstevel@tonic-gate return _kadm5_init_any(client_name, INIT_PASS, pass, NULL,
1157c478bd9Sstevel@tonic-gate service_name, params, struct_version,
11654925bf6Swillf api_version, db_args, server_handle);
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate
kadm5_init(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)1197c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init(char *client_name, char *pass,
1207c478bd9Sstevel@tonic-gate char *service_name,
1217c478bd9Sstevel@tonic-gate kadm5_config_params *params,
1227c478bd9Sstevel@tonic-gate krb5_ui_4 struct_version,
1237c478bd9Sstevel@tonic-gate krb5_ui_4 api_version,
12454925bf6Swillf char **db_args,
1257c478bd9Sstevel@tonic-gate void **server_handle)
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate return _kadm5_init_any(client_name, INIT_PASS, pass, NULL,
1287c478bd9Sstevel@tonic-gate service_name, params, struct_version,
12954925bf6Swillf api_version, db_args, server_handle);
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@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)1327c478bd9Sstevel@tonic-gate kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab,
1337c478bd9Sstevel@tonic-gate char *service_name,
1347c478bd9Sstevel@tonic-gate kadm5_config_params *params,
1357c478bd9Sstevel@tonic-gate krb5_ui_4 struct_version,
1367c478bd9Sstevel@tonic-gate krb5_ui_4 api_version,
13754925bf6Swillf char **db_args,
1387c478bd9Sstevel@tonic-gate void **server_handle)
1397c478bd9Sstevel@tonic-gate {
1407c478bd9Sstevel@tonic-gate return _kadm5_init_any(client_name, INIT_SKEY, keytab, NULL,
1417c478bd9Sstevel@tonic-gate service_name, params, struct_version,
14254925bf6Swillf api_version, db_args, server_handle);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate krb5_error_code kadm5_free_config_params();
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate static void
display_status_1(m,code,type,mech)1487c478bd9Sstevel@tonic-gate display_status_1(m, code, type, mech)
1497c478bd9Sstevel@tonic-gate char *m;
1507c478bd9Sstevel@tonic-gate OM_uint32 code;
1517c478bd9Sstevel@tonic-gate int type;
1527c478bd9Sstevel@tonic-gate const gss_OID mech;
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate OM_uint32 maj_stat, min_stat;
1557c478bd9Sstevel@tonic-gate gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
1567c478bd9Sstevel@tonic-gate OM_uint32 msg_ctx;
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate msg_ctx = 0;
1597c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR, "%s\n", m);
1607c478bd9Sstevel@tonic-gate /* LINTED */
1617c478bd9Sstevel@tonic-gate while (1) {
1627c478bd9Sstevel@tonic-gate maj_stat = gss_display_status(&min_stat, code,
1637c478bd9Sstevel@tonic-gate type, mech,
1647c478bd9Sstevel@tonic-gate &msg_ctx, &msg);
1657c478bd9Sstevel@tonic-gate if (maj_stat != GSS_S_COMPLETE) {
1667c478bd9Sstevel@tonic-gate syslog(LOG_ERR,
1677c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
1687c478bd9Sstevel@tonic-gate "error in gss_display_status"
1697c478bd9Sstevel@tonic-gate " called from <%s>\n"), m);
1707c478bd9Sstevel@tonic-gate break;
1717c478bd9Sstevel@tonic-gate } else
1727c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
1737c478bd9Sstevel@tonic-gate "GSS-API error : %s\n"),
1747c478bd9Sstevel@tonic-gate m);
1757c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
1767c478bd9Sstevel@tonic-gate "GSS-API error : %s\n"),
1777c478bd9Sstevel@tonic-gate (char *)msg.value);
1787c478bd9Sstevel@tonic-gate if (msg.length != 0)
1797c478bd9Sstevel@tonic-gate (void) gss_release_buffer(&min_stat, &msg);
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate if (!msg_ctx)
1827c478bd9Sstevel@tonic-gate break;
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate * Function: display_status
1887c478bd9Sstevel@tonic-gate *
1897c478bd9Sstevel@tonic-gate * Purpose: displays GSS-API messages
1907c478bd9Sstevel@tonic-gate *
1917c478bd9Sstevel@tonic-gate * Arguments:
1927c478bd9Sstevel@tonic-gate *
1937c478bd9Sstevel@tonic-gate * msg a string to be displayed with the message
1947c478bd9Sstevel@tonic-gate * maj_stat the GSS-API major status code
1957c478bd9Sstevel@tonic-gate * min_stat the GSS-API minor status code
1967c478bd9Sstevel@tonic-gate * mech kerberos mech
1977c478bd9Sstevel@tonic-gate * Effects:
1987c478bd9Sstevel@tonic-gate *
1997c478bd9Sstevel@tonic-gate * The GSS-API messages associated with maj_stat and min_stat are
2007c478bd9Sstevel@tonic-gate * displayed on stderr, each preceeded by "GSS-API error <msg>: " and
2017c478bd9Sstevel@tonic-gate * followed by a newline.
2027c478bd9Sstevel@tonic-gate */
2037c478bd9Sstevel@tonic-gate void
display_status(msg,maj_stat,min_stat,mech)2047c478bd9Sstevel@tonic-gate display_status(msg, maj_stat, min_stat, mech)
2057c478bd9Sstevel@tonic-gate char *msg;
2067c478bd9Sstevel@tonic-gate OM_uint32 maj_stat;
2077c478bd9Sstevel@tonic-gate OM_uint32 min_stat;
2087c478bd9Sstevel@tonic-gate char *mech;
2097c478bd9Sstevel@tonic-gate {
2107c478bd9Sstevel@tonic-gate gss_OID mech_oid;
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate if (!rpc_gss_mech_to_oid(mech, (rpc_gss_OID *)&mech_oid)) {
2137c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR,
2147c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
2157c478bd9Sstevel@tonic-gate "Invalid mechanism oid <%s>"), mech);
2167c478bd9Sstevel@tonic-gate return;
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate display_status_1(msg, maj_stat, GSS_C_GSS_CODE, mech_oid);
2207c478bd9Sstevel@tonic-gate display_status_1(msg, min_stat, GSS_C_MECH_CODE, mech_oid);
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate /*
2247c478bd9Sstevel@tonic-gate * Open an fd for the given address and connect asynchronously. Wait
2257c478bd9Sstevel@tonic-gate * KADMIND_CONNECT_TIMEOUT seconds or till it succeeds. If it succeeds
2267c478bd9Sstevel@tonic-gate * change fd to blocking and return it, else return -1.
2277c478bd9Sstevel@tonic-gate */
2287c478bd9Sstevel@tonic-gate static int
get_connection(struct netconfig * nconf,struct netbuf netaddr)2297c478bd9Sstevel@tonic-gate get_connection(struct netconfig *nconf, struct netbuf netaddr)
2307c478bd9Sstevel@tonic-gate {
2317c478bd9Sstevel@tonic-gate struct t_info tinfo;
2327c478bd9Sstevel@tonic-gate struct t_call sndcall;
2337c478bd9Sstevel@tonic-gate struct t_call *rcvcall = NULL;
2347c478bd9Sstevel@tonic-gate int connect_time;
2357c478bd9Sstevel@tonic-gate int flags;
2367c478bd9Sstevel@tonic-gate int fd;
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate (void) memset(&tinfo, 0, sizeof (tinfo));
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate /* we'l open with O_NONBLOCK and avoid an fcntl */
2417c478bd9Sstevel@tonic-gate fd = t_open(nconf->nc_device, O_RDWR | O_NONBLOCK, &tinfo);
2427c478bd9Sstevel@tonic-gate if (fd == -1) {
2437c478bd9Sstevel@tonic-gate return (-1);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate if (t_bind(fd, (struct t_bind *)NULL, (struct t_bind *)NULL) == -1) {
2477c478bd9Sstevel@tonic-gate (void) close(fd);
2487c478bd9Sstevel@tonic-gate return (-1);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate /* we can't connect unless fd is in IDLE state */
2527c478bd9Sstevel@tonic-gate if (t_getstate(fd) != T_IDLE) {
2537c478bd9Sstevel@tonic-gate (void) close(fd);
2547c478bd9Sstevel@tonic-gate return (-1);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate /* setup connect parameters */
2587c478bd9Sstevel@tonic-gate netaddr.len = netaddr.maxlen = __rpc_get_a_size(tinfo.addr);
2597c478bd9Sstevel@tonic-gate sndcall.addr = netaddr;
2607c478bd9Sstevel@tonic-gate sndcall.opt.len = sndcall.udata.len = 0;
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate /* we wait for KADMIND_CONNECT_TIMEOUT seconds from now */
2637c478bd9Sstevel@tonic-gate connect_time = time(NULL) + KADMIND_CONNECT_TIMEOUT;
2647c478bd9Sstevel@tonic-gate if (t_connect(fd, &sndcall, rcvcall) != 0) {
2657c478bd9Sstevel@tonic-gate if (t_errno != TNODATA) {
2667c478bd9Sstevel@tonic-gate (void) close(fd);
2677c478bd9Sstevel@tonic-gate return (-1);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate /* loop till success or timeout */
2727c478bd9Sstevel@tonic-gate for (;;) {
2737c478bd9Sstevel@tonic-gate if (t_rcvconnect(fd, rcvcall) == 0)
2747c478bd9Sstevel@tonic-gate break;
2757c478bd9Sstevel@tonic-gate
2767c478bd9Sstevel@tonic-gate if (t_errno != TNODATA || time(NULL) > connect_time) {
2777c478bd9Sstevel@tonic-gate /* we have either timed out or caught an error */
2787c478bd9Sstevel@tonic-gate (void) close(fd);
2797c478bd9Sstevel@tonic-gate if (rcvcall != NULL)
2807c478bd9Sstevel@tonic-gate t_free((char *)rcvcall, T_CALL);
2817c478bd9Sstevel@tonic-gate return (-1);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate sleep(1);
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate /* make the fd blocking (synchronous) */
2877c478bd9Sstevel@tonic-gate flags = fcntl(fd, F_GETFL, 0);
2887c478bd9Sstevel@tonic-gate (void) fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
2897c478bd9Sstevel@tonic-gate if (rcvcall != NULL)
2907c478bd9Sstevel@tonic-gate t_free((char *)rcvcall, T_CALL);
2917c478bd9Sstevel@tonic-gate return (fd);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate /*
2957c478bd9Sstevel@tonic-gate * Open an RPCSEC_GSS connection and
2967c478bd9Sstevel@tonic-gate * get a client handle to use for future RPCSEC calls.
2977c478bd9Sstevel@tonic-gate *
2987c478bd9Sstevel@tonic-gate * This function is only used when changing passwords and
2997c478bd9Sstevel@tonic-gate * the kpasswd_protocol is RPCSEC_GSS
3007c478bd9Sstevel@tonic-gate */
3017c478bd9Sstevel@tonic-gate static int
_kadm5_initialize_rpcsec_gss_handle(kadm5_server_handle_t handle,char * client_name,char * service_name)3027c478bd9Sstevel@tonic-gate _kadm5_initialize_rpcsec_gss_handle(kadm5_server_handle_t handle,
3037c478bd9Sstevel@tonic-gate char *client_name,
3047c478bd9Sstevel@tonic-gate char *service_name)
3057c478bd9Sstevel@tonic-gate {
3067c478bd9Sstevel@tonic-gate struct netbuf netaddr;
3077c478bd9Sstevel@tonic-gate struct hostent *hp;
3087c478bd9Sstevel@tonic-gate int fd;
3097c478bd9Sstevel@tonic-gate struct sockaddr_in addr;
3107c478bd9Sstevel@tonic-gate struct sockaddr_in *sin;
3117c478bd9Sstevel@tonic-gate struct netconfig *nconf;
3127c478bd9Sstevel@tonic-gate int code = 0;
3137c478bd9Sstevel@tonic-gate generic_ret *r;
3147c478bd9Sstevel@tonic-gate char *ccname_orig;
3157c478bd9Sstevel@tonic-gate char *iprop_svc;
3167c478bd9Sstevel@tonic-gate boolean_t iprop_enable = B_FALSE;
3177c478bd9Sstevel@tonic-gate char mech[] = "kerberos_v5";
3187c478bd9Sstevel@tonic-gate gss_OID mech_oid;
3197c478bd9Sstevel@tonic-gate gss_OID_set_desc oid_set;
3207c478bd9Sstevel@tonic-gate gss_name_t gss_client;
3217c478bd9Sstevel@tonic-gate gss_buffer_desc input_name;
3227c478bd9Sstevel@tonic-gate gss_cred_id_t gss_client_creds = GSS_C_NO_CREDENTIAL;
3237c478bd9Sstevel@tonic-gate rpc_gss_options_req_t options_req;
3247c478bd9Sstevel@tonic-gate rpc_gss_options_ret_t options_ret;
3257c478bd9Sstevel@tonic-gate rpc_gss_service_t service = rpc_gss_svc_privacy;
3267c478bd9Sstevel@tonic-gate OM_uint32 gssstat, minor_stat;
3277c478bd9Sstevel@tonic-gate void *handlep;
3287c478bd9Sstevel@tonic-gate enum clnt_stat rpc_err_code;
329bd211b85Ssemery char *server = handle->params.admin_server;
3307c478bd9Sstevel@tonic-gate
331bd211b85Ssemery /*
332bd211b85Ssemery * Try to find the kpasswd_server first if this is for the changepw
333bd211b85Ssemery * service. If defined then it should be resolvable else return error.
334bd211b85Ssemery */
335bd211b85Ssemery if (strncmp(service_name, KADM5_CHANGEPW_HOST_SERVICE,
336bd211b85Ssemery strlen(KADM5_CHANGEPW_HOST_SERVICE)) == 0) {
337bd211b85Ssemery if (handle->params.kpasswd_server != NULL)
338bd211b85Ssemery server = handle->params.kpasswd_server;
339bd211b85Ssemery }
340bd211b85Ssemery hp = gethostbyname(server);
3417c478bd9Sstevel@tonic-gate if (hp == (struct hostent *)NULL) {
3427c478bd9Sstevel@tonic-gate code = KADM5_BAD_SERVER_NAME;
3437c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
3447c478bd9Sstevel@tonic-gate "bad server name\n"));
3457c478bd9Sstevel@tonic-gate goto cleanup;
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate memset(&addr, 0, sizeof (addr));
3497c478bd9Sstevel@tonic-gate addr.sin_family = hp->h_addrtype;
3507c478bd9Sstevel@tonic-gate (void) memcpy((char *)&addr.sin_addr, (char *)hp->h_addr,
3517c478bd9Sstevel@tonic-gate sizeof (addr.sin_addr));
3527c478bd9Sstevel@tonic-gate addr.sin_port = htons((ushort_t)handle->params.kadmind_port);
3537c478bd9Sstevel@tonic-gate sin = &addr;
3547c478bd9Sstevel@tonic-gate #ifdef DEBUG
3557c478bd9Sstevel@tonic-gate printf("kadmin_port %d\n", handle->params.kadmind_port);
3567c478bd9Sstevel@tonic-gate printf("addr: sin_port: %d, sin_family: %d, sin_zero %s\n",
3577c478bd9Sstevel@tonic-gate addr.sin_port, addr.sin_family, addr.sin_zero);
3587c478bd9Sstevel@tonic-gate printf("sin_addr %d:%d\n", addr.sin_addr.S_un.S_un_w.s_w1,
3597c478bd9Sstevel@tonic-gate addr.sin_addr.S_un.S_un_w.s_w2);
3607c478bd9Sstevel@tonic-gate #endif
3617c478bd9Sstevel@tonic-gate if ((handlep = setnetconfig()) == (void *) NULL) {
3627c478bd9Sstevel@tonic-gate (void) syslog(LOG_ERR,
3637c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
3647c478bd9Sstevel@tonic-gate "cannot get any transport information"));
3657c478bd9Sstevel@tonic-gate goto error;
3667c478bd9Sstevel@tonic-gate }
3677c478bd9Sstevel@tonic-gate
3687c478bd9Sstevel@tonic-gate while (nconf = getnetconfig(handlep)) {
3697c478bd9Sstevel@tonic-gate if ((nconf->nc_semantics == NC_TPI_COTS_ORD) &&
3707c478bd9Sstevel@tonic-gate (strcmp(nconf->nc_protofmly, NC_INET) == 0) &&
3717c478bd9Sstevel@tonic-gate (strcmp(nconf->nc_proto, NC_TCP) == 0))
3727c478bd9Sstevel@tonic-gate break;
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate if (nconf == (struct netconfig *)NULL)
3767c478bd9Sstevel@tonic-gate goto error;
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate /* Transform addr to netbuf */
3797c478bd9Sstevel@tonic-gate (void) memset(&netaddr, 0, sizeof (netaddr));
3807c478bd9Sstevel@tonic-gate netaddr.buf = (char *)sin;
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate /* get an fd connected to the given address */
3837c478bd9Sstevel@tonic-gate fd = get_connection(nconf, netaddr);
3847c478bd9Sstevel@tonic-gate if (fd == -1) {
3857c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
3867c478bd9Sstevel@tonic-gate "unable to open connection to ADMIN server "
3877c478bd9Sstevel@tonic-gate "(t_error %i)"), t_errno);
3887c478bd9Sstevel@tonic-gate code = KADM5_RPC_ERROR;
3897c478bd9Sstevel@tonic-gate goto error;
3907c478bd9Sstevel@tonic-gate }
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate #ifdef DEBUG
3937c478bd9Sstevel@tonic-gate printf("fd: %d, KADM: %d, KADMVERS %d\n", fd, KADM, KADMVERS);
3947c478bd9Sstevel@tonic-gate printf("nconf: nc_netid: %s, nc_semantics: %d, nc_flag: %d, "
3957c478bd9Sstevel@tonic-gate "nc_protofmly: %s\n",
3967c478bd9Sstevel@tonic-gate nconf->nc_netid, nconf->nc_semantics, nconf->nc_flag,
3977c478bd9Sstevel@tonic-gate nconf->nc_protofmly);
3987c478bd9Sstevel@tonic-gate printf("nc_proto: %s, nc_device: %s, nc_nlookups: %d, nc_used: %d\n",
3997c478bd9Sstevel@tonic-gate nconf->nc_proto, nconf->nc_device, nconf->nc_nlookups,
4007c478bd9Sstevel@tonic-gate nconf->nc_unused);
4017c478bd9Sstevel@tonic-gate printf("netaddr: maxlen %d, buf: %s, len: %d\n", netaddr.maxlen,
4027c478bd9Sstevel@tonic-gate netaddr.buf, netaddr.len);
4037c478bd9Sstevel@tonic-gate #endif
4047c478bd9Sstevel@tonic-gate /*
4057c478bd9Sstevel@tonic-gate * Tell clnt_tli_create that given fd is already connected
4067c478bd9Sstevel@tonic-gate *
4077c478bd9Sstevel@tonic-gate * If the service_name and client_name are iprop-centric,
4087c478bd9Sstevel@tonic-gate * we need to clnt_tli_create to the appropriate RPC prog
4097c478bd9Sstevel@tonic-gate */
4107c478bd9Sstevel@tonic-gate iprop_svc = strdup(KIPROP_SVC_NAME);
4117c478bd9Sstevel@tonic-gate if (iprop_svc == NULL)
4127c478bd9Sstevel@tonic-gate return (ENOMEM);
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate if ((strstr(service_name, iprop_svc) != NULL) &&
4157c478bd9Sstevel@tonic-gate (strstr(client_name, iprop_svc) != NULL)) {
4167c478bd9Sstevel@tonic-gate iprop_enable = B_TRUE;
4177c478bd9Sstevel@tonic-gate handle->clnt = clnt_tli_create(fd, nconf, NULL,
4187c478bd9Sstevel@tonic-gate KRB5_IPROP_PROG, KRB5_IPROP_VERS, 0, 0);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate else
4217c478bd9Sstevel@tonic-gate handle->clnt = clnt_tli_create(fd, nconf, NULL,
4227c478bd9Sstevel@tonic-gate KADM, KADMVERS, 0, 0);
4237c478bd9Sstevel@tonic-gate
4247c478bd9Sstevel@tonic-gate if (iprop_svc)
4257c478bd9Sstevel@tonic-gate free(iprop_svc);
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate if (handle->clnt == NULL) {
4287c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
4297c478bd9Sstevel@tonic-gate "clnt_tli_create failed\n"));
4307c478bd9Sstevel@tonic-gate code = KADM5_RPC_ERROR;
4317c478bd9Sstevel@tonic-gate (void) close(fd);
4327c478bd9Sstevel@tonic-gate goto error;
4337c478bd9Sstevel@tonic-gate }
4347c478bd9Sstevel@tonic-gate /*
4357c478bd9Sstevel@tonic-gate * The rpc-handle was created on an fd opened and connected
4367c478bd9Sstevel@tonic-gate * by us, so we have to explicitly tell rpc to close it.
4377c478bd9Sstevel@tonic-gate */
4387c478bd9Sstevel@tonic-gate if (clnt_control(handle->clnt, CLSET_FD_CLOSE, NULL) != TRUE) {
4397c478bd9Sstevel@tonic-gate clnt_pcreateerror("ERROR:");
4407c478bd9Sstevel@tonic-gate syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
4417c478bd9Sstevel@tonic-gate "clnt_control failed to set CLSET_FD_CLOSE"));
4427c478bd9Sstevel@tonic-gate code = KADM5_RPC_ERROR;
4437c478bd9Sstevel@tonic-gate (void) close(fd);
4447c478bd9Sstevel@tonic-gate goto error;
4457c478bd9Sstevel@tonic-gate }
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate handle->lhandle->clnt = handle->clnt;
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate /* now that handle->clnt is set, we can check the handle */
4507c478bd9Sstevel@tonic-gate if (code = _kadm5_check_handle((void *) handle))
4517c478bd9Sstevel@tonic-gate goto error;
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate /*
4547c478bd9Sstevel@tonic-gate * The RPC connection is open; establish the GSS-API
4557c478bd9Sstevel@tonic-gate * authentication context.
4567c478bd9Sstevel@tonic-gate */
4577c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
4587c478bd9Sstevel@tonic-gate "have an rpc connection open\n"));
4597c478bd9Sstevel@tonic-gate /* use the kadm5 cache */
4607c478bd9Sstevel@tonic-gate ccname_orig = getenv("KRB5CCNAME");
4617c478bd9Sstevel@tonic-gate if (ccname_orig)
4627c478bd9Sstevel@tonic-gate ccname_orig = strdup(ccname_orig);
4637c478bd9Sstevel@tonic-gate
4647c478bd9Sstevel@tonic-gate (void) krb5_setenv("KRB5CCNAME", handle->cache_name, 1);
4657c478bd9Sstevel@tonic-gate
4667c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR,
4677c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
4687c478bd9Sstevel@tonic-gate "current credential cache: %s"), handle->cache_name);
4697c478bd9Sstevel@tonic-gate input_name.value = client_name;
4707c478bd9Sstevel@tonic-gate input_name.length = strlen((char *)input_name.value) + 1;
4717c478bd9Sstevel@tonic-gate gssstat = gss_import_name(&minor_stat, &input_name,
4727c478bd9Sstevel@tonic-gate (gss_OID)gss_nt_krb5_name, &gss_client);
4737c478bd9Sstevel@tonic-gate if (gssstat != GSS_S_COMPLETE) {
4747c478bd9Sstevel@tonic-gate code = KADM5_GSS_ERROR;
4757c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR,
4767c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
4777c478bd9Sstevel@tonic-gate "gss_import_name failed for client name\n"));
4787c478bd9Sstevel@tonic-gate goto error;
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate
4817c478bd9Sstevel@tonic-gate if (!rpc_gss_mech_to_oid(mech, (rpc_gss_OID *)&mech_oid)) {
4827c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR,
4837c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
4847c478bd9Sstevel@tonic-gate "Invalid mechanism oid <%s>"), mech);
4857c478bd9Sstevel@tonic-gate goto error;
4867c478bd9Sstevel@tonic-gate }
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate oid_set.count = 1;
4897c478bd9Sstevel@tonic-gate oid_set.elements = mech_oid;
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate gssstat = gss_acquire_cred(&minor_stat, gss_client, 0,
4927c478bd9Sstevel@tonic-gate &oid_set, GSS_C_INITIATE,
4937c478bd9Sstevel@tonic-gate &gss_client_creds, NULL, NULL);
4947c478bd9Sstevel@tonic-gate (void) gss_release_name(&minor_stat, &gss_client);
4957c478bd9Sstevel@tonic-gate if (gssstat != GSS_S_COMPLETE) {
4967c478bd9Sstevel@tonic-gate code = KADM5_GSS_ERROR;
4977c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR,
4987c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
4997c478bd9Sstevel@tonic-gate "could not acquire credentials, "
5007c478bd9Sstevel@tonic-gate "major error code: %d\n"), gssstat);
5017c478bd9Sstevel@tonic-gate goto error;
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate handle->my_cred = gss_client_creds;
5047c478bd9Sstevel@tonic-gate options_req.my_cred = gss_client_creds;
5057c478bd9Sstevel@tonic-gate options_req.req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
5067c478bd9Sstevel@tonic-gate options_req.time_req = 0;
5077c478bd9Sstevel@tonic-gate options_req.input_channel_bindings = NULL;
5087c478bd9Sstevel@tonic-gate #ifndef INIT_TEST
5097c478bd9Sstevel@tonic-gate handle->clnt->cl_auth = rpc_gss_seccreate(handle->clnt,
5107c478bd9Sstevel@tonic-gate service_name,
5117c478bd9Sstevel@tonic-gate mech,
5127c478bd9Sstevel@tonic-gate service,
5137c478bd9Sstevel@tonic-gate NULL,
5147c478bd9Sstevel@tonic-gate &options_req,
5157c478bd9Sstevel@tonic-gate &options_ret);
5167c478bd9Sstevel@tonic-gate #endif /* ! INIT_TEST */
5177c478bd9Sstevel@tonic-gate
5187c478bd9Sstevel@tonic-gate if (ccname_orig) {
5197c478bd9Sstevel@tonic-gate (void) krb5_setenv("KRB5CCNAME", ccname_orig, 1);
5207c478bd9Sstevel@tonic-gate free(ccname_orig);
5217c478bd9Sstevel@tonic-gate } else
5227c478bd9Sstevel@tonic-gate (void) krb5_unsetenv("KRB5CCNAME");
5237c478bd9Sstevel@tonic-gate
5247c478bd9Sstevel@tonic-gate if (handle->clnt->cl_auth == NULL) {
5257c478bd9Sstevel@tonic-gate code = KADM5_GSS_ERROR;
5267c478bd9Sstevel@tonic-gate display_status(dgettext(TEXT_DOMAIN,
5277c478bd9Sstevel@tonic-gate "rpc_gss_seccreate failed\n"),
5287c478bd9Sstevel@tonic-gate options_ret.major_status,
5297c478bd9Sstevel@tonic-gate options_ret.minor_status,
5307c478bd9Sstevel@tonic-gate mech);
5317c478bd9Sstevel@tonic-gate goto error;
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate /*
5357c478bd9Sstevel@tonic-gate * Bypass the remainder of the code and return straightaway
5367c478bd9Sstevel@tonic-gate * if the gss service requested is kiprop
5377c478bd9Sstevel@tonic-gate */
5387c478bd9Sstevel@tonic-gate if (iprop_enable == B_TRUE) {
5397c478bd9Sstevel@tonic-gate code = 0;
5407c478bd9Sstevel@tonic-gate goto cleanup;
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate
543*159d09a2SMark Phalan r = init_2(&handle->api_version, handle->clnt);
544*159d09a2SMark Phalan /* Solaris Kerberos: 163 resync */
5457c478bd9Sstevel@tonic-gate if (r == NULL) {
5467c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
5477c478bd9Sstevel@tonic-gate "error during admin api initialization\n"));
5487c478bd9Sstevel@tonic-gate code = KADM5_RPC_ERROR;
5497c478bd9Sstevel@tonic-gate goto error;
5507c478bd9Sstevel@tonic-gate }
551*159d09a2SMark Phalan
5527c478bd9Sstevel@tonic-gate if (r->code) {
5537c478bd9Sstevel@tonic-gate code = r->code;
5547c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR,
5557c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN,
5567c478bd9Sstevel@tonic-gate "error during admin api initialization: %d\n"),
5577c478bd9Sstevel@tonic-gate r->code);
5587c478bd9Sstevel@tonic-gate goto error;
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate error:
5617c478bd9Sstevel@tonic-gate cleanup:
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate if (handlep != (void *) NULL)
5647c478bd9Sstevel@tonic-gate (void) endnetconfig(handlep);
5657c478bd9Sstevel@tonic-gate /*
5667c478bd9Sstevel@tonic-gate * gss_client_creds is freed only when there is an error condition,
5677c478bd9Sstevel@tonic-gate * given that rpc_gss_seccreate() will assign the cred pointer to the
5687c478bd9Sstevel@tonic-gate * my_cred member in the auth handle's private data structure.
5697c478bd9Sstevel@tonic-gate */
5707c478bd9Sstevel@tonic-gate if (code && (gss_client_creds != GSS_C_NO_CREDENTIAL))
5717c478bd9Sstevel@tonic-gate (void) gss_release_cred(&minor_stat, &gss_client_creds);
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate return (code);
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate
_kadm5_init_any(char * client_name,enum init_type init_type,char * pass,krb5_ccache ccache_in,char * service_name,kadm5_config_params * params_in,krb5_ui_4 struct_version,krb5_ui_4 api_version,char ** db_args,void ** server_handle)5767c478bd9Sstevel@tonic-gate static kadm5_ret_t _kadm5_init_any(char *client_name,
5777c478bd9Sstevel@tonic-gate enum init_type init_type,
5787c478bd9Sstevel@tonic-gate char *pass,
5797c478bd9Sstevel@tonic-gate krb5_ccache ccache_in,
5807c478bd9Sstevel@tonic-gate char *service_name,
5817c478bd9Sstevel@tonic-gate kadm5_config_params *params_in,
5827c478bd9Sstevel@tonic-gate krb5_ui_4 struct_version,
5837c478bd9Sstevel@tonic-gate krb5_ui_4 api_version,
58454925bf6Swillf char **db_args,
5857c478bd9Sstevel@tonic-gate void **server_handle)
5867c478bd9Sstevel@tonic-gate {
5877c478bd9Sstevel@tonic-gate int i;
5887c478bd9Sstevel@tonic-gate krb5_creds creds;
5897c478bd9Sstevel@tonic-gate krb5_ccache ccache = NULL;
5907c478bd9Sstevel@tonic-gate krb5_timestamp now;
5917c478bd9Sstevel@tonic-gate OM_uint32 gssstat, minor_stat;
5927c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle;
5937c478bd9Sstevel@tonic-gate kadm5_config_params params_local;
5947c478bd9Sstevel@tonic-gate int code = 0;
5957c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt opt;
5967c478bd9Sstevel@tonic-gate gss_buffer_desc input_name;
5977c478bd9Sstevel@tonic-gate krb5_error_code kret;
5987c478bd9Sstevel@tonic-gate krb5_int32 starttime;
5997c478bd9Sstevel@tonic-gate char *server = NULL;
6007c478bd9Sstevel@tonic-gate krb5_principal serverp = NULL, clientp = NULL;
601fe598cdcSmp153739 krb5_principal saved_server = NULL;
60245526e97Ssemery bool_t cpw = FALSE;
6037c478bd9Sstevel@tonic-gate
6047c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
6057c478bd9Sstevel@tonic-gate "entering kadm5_init_any\n"));
6067c478bd9Sstevel@tonic-gate if (! server_handle) {
60756a424ccSmp153739 return EINVAL;
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate
6107c478bd9Sstevel@tonic-gate if (! (handle = malloc(sizeof(*handle)))) {
61156a424ccSmp153739 return ENOMEM;
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate if (! (handle->lhandle = malloc(sizeof(*handle)))) {
6147c478bd9Sstevel@tonic-gate free(handle);
61556a424ccSmp153739 return ENOMEM;
6167c478bd9Sstevel@tonic-gate }
6177c478bd9Sstevel@tonic-gate
6187c478bd9Sstevel@tonic-gate handle->magic_number = KADM5_SERVER_HANDLE_MAGIC;
6197c478bd9Sstevel@tonic-gate handle->struct_version = struct_version;
6207c478bd9Sstevel@tonic-gate handle->api_version = api_version;
6217c478bd9Sstevel@tonic-gate handle->clnt = 0;
6227c478bd9Sstevel@tonic-gate handle->cache_name = 0;
6237c478bd9Sstevel@tonic-gate handle->destroy_cache = 0;
6247c478bd9Sstevel@tonic-gate *handle->lhandle = *handle;
6257c478bd9Sstevel@tonic-gate handle->lhandle->api_version = KADM5_API_VERSION_2;
6267c478bd9Sstevel@tonic-gate handle->lhandle->struct_version = KADM5_STRUCT_VERSION;
6277c478bd9Sstevel@tonic-gate handle->lhandle->lhandle = handle->lhandle;
6287c478bd9Sstevel@tonic-gate
6297c478bd9Sstevel@tonic-gate kret = krb5_init_context(&handle->context);
6307c478bd9Sstevel@tonic-gate if (kret) {
6317c478bd9Sstevel@tonic-gate free(handle->lhandle);
6327c478bd9Sstevel@tonic-gate free(handle);
6337c478bd9Sstevel@tonic-gate return (kret);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate if(service_name == NULL || client_name == NULL) {
6377c478bd9Sstevel@tonic-gate krb5_free_context(handle->context);
6387c478bd9Sstevel@tonic-gate free(handle->lhandle);
6397c478bd9Sstevel@tonic-gate free(handle);
64056a424ccSmp153739 return EINVAL;
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate memset((char *) &creds, 0, sizeof(creds));
6437c478bd9Sstevel@tonic-gate
6447c478bd9Sstevel@tonic-gate /*
6457c478bd9Sstevel@tonic-gate * Verify the version numbers before proceeding; we can't use
6467c478bd9Sstevel@tonic-gate * CHECK_HANDLE because not all fields are set yet.
6477c478bd9Sstevel@tonic-gate */
6487c478bd9Sstevel@tonic-gate GENERIC_CHECK_HANDLE(handle, KADM5_OLD_LIB_API_VERSION,
6497c478bd9Sstevel@tonic-gate KADM5_NEW_LIB_API_VERSION);
6507c478bd9Sstevel@tonic-gate
6517c478bd9Sstevel@tonic-gate /*
6527c478bd9Sstevel@tonic-gate * Acquire relevant profile entries. In version 2, merge values
6537c478bd9Sstevel@tonic-gate * in params_in with values from profile, based on
6547c478bd9Sstevel@tonic-gate * params_in->mask.
6557c478bd9Sstevel@tonic-gate *
6567c478bd9Sstevel@tonic-gate * In version 1, we've given a realm (which may be NULL) instead
6577c478bd9Sstevel@tonic-gate * of params_in. So use that realm, make params_in contain an
6587c478bd9Sstevel@tonic-gate * empty mask, and behave like version 2.
6597c478bd9Sstevel@tonic-gate */
6607c478bd9Sstevel@tonic-gate memset((char *) ¶ms_local, 0, sizeof(params_local));
6617c478bd9Sstevel@tonic-gate if (api_version == KADM5_API_VERSION_1) {
6627c478bd9Sstevel@tonic-gate if (params_in)
6637c478bd9Sstevel@tonic-gate params_local.mask = KADM5_CONFIG_REALM;
6647c478bd9Sstevel@tonic-gate params_in = ¶ms_local;
6657c478bd9Sstevel@tonic-gate }
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate #define ILLEGAL_PARAMS ( \
6687c478bd9Sstevel@tonic-gate KADM5_CONFIG_ACL_FILE | KADM5_CONFIG_ADB_LOCKFILE | \
6697c478bd9Sstevel@tonic-gate KADM5_CONFIG_DBNAME | KADM5_CONFIG_ADBNAME | \
6707c478bd9Sstevel@tonic-gate KADM5_CONFIG_DICT_FILE | KADM5_CONFIG_ADMIN_KEYTAB | \
6717c478bd9Sstevel@tonic-gate KADM5_CONFIG_STASH_FILE | KADM5_CONFIG_MKEY_NAME | \
6727c478bd9Sstevel@tonic-gate KADM5_CONFIG_ENCTYPE | KADM5_CONFIG_MAX_LIFE | \
6737c478bd9Sstevel@tonic-gate KADM5_CONFIG_MAX_RLIFE | KADM5_CONFIG_EXPIRATION | \
6747c478bd9Sstevel@tonic-gate KADM5_CONFIG_FLAGS | KADM5_CONFIG_ENCTYPES | \
6757c478bd9Sstevel@tonic-gate KADM5_CONFIG_MKEY_FROM_KBD)
6767c478bd9Sstevel@tonic-gate
6777c478bd9Sstevel@tonic-gate if (params_in && params_in->mask & ILLEGAL_PARAMS) {
6787c478bd9Sstevel@tonic-gate krb5_free_context(handle->context);
6797c478bd9Sstevel@tonic-gate free(handle->lhandle);
6807c478bd9Sstevel@tonic-gate free(handle);
6817c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR, dgettext(TEXT_DOMAIN,
6827c478bd9Sstevel@tonic-gate "bad client parameters, returning %d"),
6837c478bd9Sstevel@tonic-gate KADM5_BAD_CLIENT_PARAMS);
68456a424ccSmp153739 return KADM5_BAD_CLIENT_PARAMS;
6857c478bd9Sstevel@tonic-gate }
6867c478bd9Sstevel@tonic-gate
687*159d09a2SMark Phalan if ((code = kadm5_get_config_params(handle->context, 0,
688*159d09a2SMark Phalan params_in, &handle->params))) {
6897c478bd9Sstevel@tonic-gate krb5_free_context(handle->context);
6907c478bd9Sstevel@tonic-gate free(handle->lhandle);
6917c478bd9Sstevel@tonic-gate free(handle);
6927c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR, dgettext(TEXT_DOMAIN,
6937c478bd9Sstevel@tonic-gate "failed to get config_params, return: %d\n"), code);
6947c478bd9Sstevel@tonic-gate return(code);
6957c478bd9Sstevel@tonic-gate }
6967c478bd9Sstevel@tonic-gate
6977c478bd9Sstevel@tonic-gate #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | \
6987c478bd9Sstevel@tonic-gate KADM5_CONFIG_ADMIN_SERVER | \
6997c478bd9Sstevel@tonic-gate KADM5_CONFIG_KADMIND_PORT)
700bd211b85Ssemery #define KPW_REQUIRED_PARAMS (KADM5_CONFIG_REALM | \
701bd211b85Ssemery KADM5_CONFIG_KPASSWD_SERVER | \
702bd211b85Ssemery KADM5_CONFIG_KPASSWD_PORT)
7037c478bd9Sstevel@tonic-gate
704bd211b85Ssemery if (((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) &&
705bd211b85Ssemery ((handle->params.mask & KPW_REQUIRED_PARAMS) != KPW_REQUIRED_PARAMS)) {
7067c478bd9Sstevel@tonic-gate (void) kadm5_free_config_params(handle->context,
7077c478bd9Sstevel@tonic-gate &handle->params);
7087c478bd9Sstevel@tonic-gate krb5_free_context(handle->context);
7097c478bd9Sstevel@tonic-gate free(handle->lhandle);
7107c478bd9Sstevel@tonic-gate free(handle);
7117c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
7127c478bd9Sstevel@tonic-gate "missing config parameters\n"));
71356a424ccSmp153739 return KADM5_MISSING_KRB5_CONF_PARAMS;
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate
7167c478bd9Sstevel@tonic-gate /*
7177c478bd9Sstevel@tonic-gate * Acquire a service ticket for service_name@realm in the name of
7187c478bd9Sstevel@tonic-gate * client_name, using password pass (which could be NULL), and
7197c478bd9Sstevel@tonic-gate * create a ccache to store them in. If INIT_CREDS, use the
7207c478bd9Sstevel@tonic-gate * ccache we were provided instead.
7217c478bd9Sstevel@tonic-gate */
7227c478bd9Sstevel@tonic-gate if ((code = krb5_parse_name(handle->context, client_name,
7237c478bd9Sstevel@tonic-gate &creds.client))) {
7247c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
7257c478bd9Sstevel@tonic-gate "could not parse client name\n"));
7267c478bd9Sstevel@tonic-gate goto error;
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate clientp = creds.client;
7297c478bd9Sstevel@tonic-gate
73045526e97Ssemery if (strncmp(service_name, KADM5_CHANGEPW_HOST_SERVICE,
73145526e97Ssemery strlen(KADM5_CHANGEPW_HOST_SERVICE)) == 0)
73245526e97Ssemery cpw = TRUE;
73345526e97Ssemery
7347c478bd9Sstevel@tonic-gate if (init_type == INIT_PASS &&
73545526e97Ssemery handle->params.kpasswd_protocol == KRB5_CHGPWD_CHANGEPW_V2 &&
73645526e97Ssemery cpw == TRUE) {
7377c478bd9Sstevel@tonic-gate /*
7387c478bd9Sstevel@tonic-gate * The 'service_name' is constructed by the caller
7397c478bd9Sstevel@tonic-gate * but its done before the parameter which determines
7407c478bd9Sstevel@tonic-gate * the kpasswd_protocol is found. The servers that
7417c478bd9Sstevel@tonic-gate * support the SET/CHANGE password protocol expect
7427c478bd9Sstevel@tonic-gate * a slightly different service principal than
7437c478bd9Sstevel@tonic-gate * the normal SEAM kadmind so construct the correct
7447c478bd9Sstevel@tonic-gate * name here and then forget it.
7457c478bd9Sstevel@tonic-gate */
7467c478bd9Sstevel@tonic-gate char *newsvcname = NULL;
7477c478bd9Sstevel@tonic-gate newsvcname = malloc(strlen(KADM5_CHANGEPW_SERVICE) +
7487c478bd9Sstevel@tonic-gate strlen(handle->params.realm) + 2);
7497c478bd9Sstevel@tonic-gate if (newsvcname == NULL) {
750d9976468Sps57422 ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
751d9976468Sps57422 "could not malloc\n"));
752d9976468Sps57422 code = ENOMEM;
753d9976468Sps57422 goto error;
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate sprintf(newsvcname, "%s@%s", KADM5_CHANGEPW_SERVICE,
7567c478bd9Sstevel@tonic-gate handle->params.realm);
7577c478bd9Sstevel@tonic-gate
7587c478bd9Sstevel@tonic-gate if ((code = krb5_parse_name(handle->context, newsvcname,
7597c478bd9Sstevel@tonic-gate &creds.server))) {
7607c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
7617c478bd9Sstevel@tonic-gate "could not parse server "
7627c478bd9Sstevel@tonic-gate "name\n"));
7637c478bd9Sstevel@tonic-gate free(newsvcname);
7647c478bd9Sstevel@tonic-gate goto error;
7657c478bd9Sstevel@tonic-gate }
7667c478bd9Sstevel@tonic-gate free(newsvcname);
7677c478bd9Sstevel@tonic-gate } else {
7687c478bd9Sstevel@tonic-gate input_name.value = service_name;
7697c478bd9Sstevel@tonic-gate input_name.length = strlen((char *)input_name.value) + 1;
770ab9b2e15Sgtb gssstat = krb5_gss_import_name(&minor_stat,
7717c478bd9Sstevel@tonic-gate &input_name,
7727c478bd9Sstevel@tonic-gate (gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
7737c478bd9Sstevel@tonic-gate (gss_name_t *)&creds.server);
7747c478bd9Sstevel@tonic-gate
7757c478bd9Sstevel@tonic-gate if (gssstat != GSS_S_COMPLETE) {
7767c478bd9Sstevel@tonic-gate code = KADM5_GSS_ERROR;
7777c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
7787c478bd9Sstevel@tonic-gate "gss_import_name failed for client name\n"));
7797c478bd9Sstevel@tonic-gate goto error;
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate serverp = creds.server;
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate /* XXX temporarily fix a bug in krb5_cc_get_type */
7857c478bd9Sstevel@tonic-gate #undef krb5_cc_get_type
7867c478bd9Sstevel@tonic-gate #define krb5_cc_get_type(context, cache) ((cache)->ops->prefix)
7877c478bd9Sstevel@tonic-gate
78856a424ccSmp153739
7897c478bd9Sstevel@tonic-gate if (init_type == INIT_CREDS) {
7907c478bd9Sstevel@tonic-gate ccache = ccache_in;
7917c478bd9Sstevel@tonic-gate handle->cache_name = (char *)
7927c478bd9Sstevel@tonic-gate malloc(strlen(krb5_cc_get_type(handle->context, ccache)) +
7937c478bd9Sstevel@tonic-gate strlen(krb5_cc_get_name(handle->context, ccache)) + 2);
7947c478bd9Sstevel@tonic-gate if (handle->cache_name == NULL) {
7957c478bd9Sstevel@tonic-gate code = ENOMEM;
7967c478bd9Sstevel@tonic-gate goto error;
7977c478bd9Sstevel@tonic-gate }
7987c478bd9Sstevel@tonic-gate sprintf(handle->cache_name, "%s:%s",
7997c478bd9Sstevel@tonic-gate krb5_cc_get_type(handle->context, ccache),
8007c478bd9Sstevel@tonic-gate krb5_cc_get_name(handle->context, ccache));
8017c478bd9Sstevel@tonic-gate } else {
80256a424ccSmp153739 #if 0
8037c478bd9Sstevel@tonic-gate handle->cache_name =
8047c478bd9Sstevel@tonic-gate (char *) malloc(strlen(ADM_CCACHE)+strlen("FILE:")+1);
8057c478bd9Sstevel@tonic-gate if (handle->cache_name == NULL) {
8067c478bd9Sstevel@tonic-gate code = ENOMEM;
8077c478bd9Sstevel@tonic-gate goto error;
8087c478bd9Sstevel@tonic-gate }
8097c478bd9Sstevel@tonic-gate sprintf(handle->cache_name, "FILE:%s", ADM_CCACHE);
8107c478bd9Sstevel@tonic-gate mktemp(handle->cache_name + strlen("FILE:"));
81156a424ccSmp153739 #endif
81256a424ccSmp153739 {
81356a424ccSmp153739 static int counter = 0;
81456a424ccSmp153739 handle->cache_name = malloc(sizeof("MEMORY:kadm5_")
81556a424ccSmp153739 + 3*sizeof(counter));
81656a424ccSmp153739 sprintf(handle->cache_name, "MEMORY:kadm5_%u", counter++);
81756a424ccSmp153739 }
8187c478bd9Sstevel@tonic-gate
81956a424ccSmp153739 if ((code = krb5_cc_resolve(handle->context, handle->cache_name,
82056a424ccSmp153739 &ccache)))
8217c478bd9Sstevel@tonic-gate goto error;
8227c478bd9Sstevel@tonic-gate
8237c478bd9Sstevel@tonic-gate if ((code = krb5_cc_initialize (handle->context, ccache,
8247c478bd9Sstevel@tonic-gate creds.client)))
8257c478bd9Sstevel@tonic-gate goto error;
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gate handle->destroy_cache = 1;
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate handle->lhandle->cache_name = handle->cache_name;
8307c478bd9Sstevel@tonic-gate ADMIN_LOG(LOG_ERR, dgettext(TEXT_DOMAIN,
8317c478bd9Sstevel@tonic-gate "cache created: %s\n"), handle->cache_name);
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate if ((code = krb5_timeofday(handle->context, &now)))
8347c478bd9Sstevel@tonic-gate goto error;
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate /*
8377c478bd9Sstevel@tonic-gate * Get a ticket, use the method specified in init_type.
8387c478bd9Sstevel@tonic-gate */
83956a424ccSmp153739
8407c478bd9Sstevel@tonic-gate creds.times.starttime = 0; /* start timer at KDC */
8417c478bd9Sstevel@tonic-gate creds.times.endtime = 0; /* endtime will be limited by service */
8427c478bd9Sstevel@tonic-gate
8437c478bd9Sstevel@tonic-gate memset(&opt, 0, sizeof (opt));
8447c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_init(&opt);
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gate if (creds.times.endtime) {
8477c478bd9Sstevel@tonic-gate if (creds.times.starttime)
8487c478bd9Sstevel@tonic-gate starttime = creds.times.starttime;
8497c478bd9Sstevel@tonic-gate else
8507c478bd9Sstevel@tonic-gate starttime = now;
8517c478bd9Sstevel@tonic-gate
8527c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_tkt_life(&opt,
8537c478bd9Sstevel@tonic-gate creds.times.endtime - starttime);
8547c478bd9Sstevel@tonic-gate }
8557c478bd9Sstevel@tonic-gate code = krb5_unparse_name(handle->context, creds.server, &server);
8567c478bd9Sstevel@tonic-gate if (code)
8577c478bd9Sstevel@tonic-gate goto error;
8587c478bd9Sstevel@tonic-gate
859fe598cdcSmp153739 /*
860fe598cdcSmp153739 * Solaris Kerberos:
861fe598cdcSmp153739 * Save the original creds.server as krb5_get_init_creds*() always
862fe598cdcSmp153739 * sets the realm of the server to the client realm.
863fe598cdcSmp153739 */
864fe598cdcSmp153739 code = krb5_copy_principal(handle->context, creds.server, &saved_server);
865fe598cdcSmp153739 if (code)
866fe598cdcSmp153739 goto error;
867fe598cdcSmp153739
8687c478bd9Sstevel@tonic-gate if (init_type == INIT_PASS) {
8697c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_password(handle->context,
8707c478bd9Sstevel@tonic-gate &creds, creds.client, pass, NULL,
8717c478bd9Sstevel@tonic-gate NULL, creds.times.starttime,
8727c478bd9Sstevel@tonic-gate server, &opt);
8737c478bd9Sstevel@tonic-gate } else if (init_type == INIT_SKEY) {
8747c478bd9Sstevel@tonic-gate krb5_keytab kt = NULL;
8757c478bd9Sstevel@tonic-gate
8767c478bd9Sstevel@tonic-gate if (!(pass && (code = krb5_kt_resolve(handle->context,
8777c478bd9Sstevel@tonic-gate pass, &kt)))) {
8787c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_keytab(
8797c478bd9Sstevel@tonic-gate handle->context,
8807c478bd9Sstevel@tonic-gate &creds, creds.client, kt,
8817c478bd9Sstevel@tonic-gate creds.times.starttime,
8827c478bd9Sstevel@tonic-gate server, &opt);
8837c478bd9Sstevel@tonic-gate
88456a424ccSmp153739 if (pass) krb5_kt_close(handle->context, kt);
8857c478bd9Sstevel@tonic-gate }
8867c478bd9Sstevel@tonic-gate }
8877c478bd9Sstevel@tonic-gate
8887c478bd9Sstevel@tonic-gate /* Improved error messages */
88956a424ccSmp153739 if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) code = KADM5_BAD_PASSWORD;
8907c478bd9Sstevel@tonic-gate if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
8917c478bd9Sstevel@tonic-gate code = KADM5_SECURE_PRINC_MISSING;
8927c478bd9Sstevel@tonic-gate
8937c478bd9Sstevel@tonic-gate if (code != 0) {
8947c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN,
8957c478bd9Sstevel@tonic-gate "failed to obtain credentials cache\n"));
896fe598cdcSmp153739 krb5_free_principal(handle->context, saved_server);
8977c478bd9Sstevel@tonic-gate goto error;
8987c478bd9Sstevel@tonic-gate }
8997c478bd9Sstevel@tonic-gate
9007c478bd9Sstevel@tonic-gate /*
901fe598cdcSmp153739 * Solaris Kerberos:
902fe598cdcSmp153739 * If the server principal had an empty realm then store that in
903fe598cdcSmp153739 * the cred cache and not the server realm as returned by
904d67a66d0Smp153739 * krb5_get_init_creds_{keytab|password}(). This ensures that rpcsec_gss
905d67a66d0Smp153739 * will find the credential in the cred cache even if a "fallback"
906d67a66d0Smp153739 * method is being used to determine the realm.
907fe598cdcSmp153739 */
908d67a66d0Smp153739 if (init_type != INIT_CREDS) {
909fe598cdcSmp153739 krb5_free_principal(handle->context, creds.server);
910d67a66d0Smp153739 }
911fe598cdcSmp153739 creds.server = saved_server;
912fe598cdcSmp153739
913fe598cdcSmp153739 /*
9147c478bd9Sstevel@tonic-gate * If we got this far, save the creds in the cache.
9157c478bd9Sstevel@tonic-gate */
9167c478bd9Sstevel@tonic-gate if (ccache) {
9177c478bd9Sstevel@tonic-gate code = krb5_cc_store_cred(handle->context, ccache, &creds);
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate
9207c478bd9Sstevel@tonic-gate ADMIN_LOGO(LOG_ERR, dgettext(TEXT_DOMAIN, "obtained credentials cache\n"));
9217c478bd9Sstevel@tonic-gate
9227c478bd9Sstevel@tonic-gate #ifdef ZEROPASSWD
9237c478bd9Sstevel@tonic-gate if (pass != NULL)
9247c478bd9Sstevel@tonic-gate memset(pass, 0, strlen(pass));
9257c478bd9Sstevel@tonic-gate #endif
9267c478bd9Sstevel@tonic-gate
9277c478bd9Sstevel@tonic-gate if (init_type != INIT_PASS ||
92845526e97Ssemery handle->params.kpasswd_protocol == KRB5_CHGPWD_RPCSEC ||
92945526e97Ssemery cpw == FALSE) {
9307c478bd9Sstevel@tonic-gate code = _kadm5_initialize_rpcsec_gss_handle(handle,
9317c478bd9Sstevel@tonic-gate client_name, service_name);
932d67a66d0Smp153739
933d67a66d0Smp153739 /*
934d67a66d0Smp153739 * Solaris Kerberos:
935d67a66d0Smp153739 * If _kadm5_initialize_rpcsec_gss_handle() fails it will have
936d67a66d0Smp153739 * called krb5_gss_release_cred(). If the credential cache is a
937d67a66d0Smp153739 * MEMORY cred cache krb5_gss_release_cred() destroys the
938d67a66d0Smp153739 * cred cache data. Make sure that the cred-cache is closed
939d67a66d0Smp153739 * to prevent a double free in the "error" code.
940d67a66d0Smp153739 */
941d67a66d0Smp153739 if (code != 0) {
942*159d09a2SMark Phalan if (init_type != INIT_CREDS) {
943d67a66d0Smp153739 krb5_cc_close(handle->context, ccache);
944*159d09a2SMark Phalan ccache = NULL;
945*159d09a2SMark Phalan }
9467c478bd9Sstevel@tonic-gate goto error;
9477c478bd9Sstevel@tonic-gate }
948d67a66d0Smp153739 }
9497c478bd9Sstevel@tonic-gate
9507c478bd9Sstevel@tonic-gate *server_handle = (void *) handle;
9517c478bd9Sstevel@tonic-gate
9527c478bd9Sstevel@tonic-gate if (init_type != INIT_CREDS)
9537c478bd9Sstevel@tonic-gate krb5_cc_close(handle->context, ccache);
9547c478bd9Sstevel@tonic-gate
9557c478bd9Sstevel@tonic-gate goto cleanup;
9567c478bd9Sstevel@tonic-gate
9577c478bd9Sstevel@tonic-gate error:
9587c478bd9Sstevel@tonic-gate /*
9597c478bd9Sstevel@tonic-gate * Note that it is illegal for this code to execute if "handle"
9607c478bd9Sstevel@tonic-gate * has not been allocated and initialized. I.e., don't use "goto
9617c478bd9Sstevel@tonic-gate * error" before the block of code at the top of the function
9627c478bd9Sstevel@tonic-gate * that allocates and initializes "handle".
9637c478bd9Sstevel@tonic-gate */
9647c478bd9Sstevel@tonic-gate if (handle->cache_name)
9657c478bd9Sstevel@tonic-gate free(handle->cache_name);
9667c478bd9Sstevel@tonic-gate if (handle->destroy_cache && ccache)
9677c478bd9Sstevel@tonic-gate krb5_cc_destroy(handle->context, ccache);
9687c478bd9Sstevel@tonic-gate if(handle->clnt && handle->clnt->cl_auth)
9697c478bd9Sstevel@tonic-gate AUTH_DESTROY(handle->clnt->cl_auth);
9707c478bd9Sstevel@tonic-gate if(handle->clnt)
9717c478bd9Sstevel@tonic-gate clnt_destroy(handle->clnt);
9727c478bd9Sstevel@tonic-gate (void) kadm5_free_config_params(handle->context, &handle->params);
9737c478bd9Sstevel@tonic-gate
9747c478bd9Sstevel@tonic-gate cleanup:
9757c478bd9Sstevel@tonic-gate if (server)
9767c478bd9Sstevel@tonic-gate free(server);
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate /*
979e49962a0Ssemery * cred's server and client pointers could have been overwritten
980e49962a0Ssemery * by the krb5_get_init_* functions. If the addresses are different
981e49962a0Ssemery * before and after the calls then we must free the memory that
982e49962a0Ssemery * was allocated before the call.
9837c478bd9Sstevel@tonic-gate */
984e49962a0Ssemery if (clientp && clientp != creds.client)
9857c478bd9Sstevel@tonic-gate krb5_free_principal(handle->context, clientp);
986e49962a0Ssemery
987e49962a0Ssemery if (serverp && serverp != creds.server)
9887c478bd9Sstevel@tonic-gate krb5_free_principal(handle->context, serverp);
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate krb5_free_cred_contents(handle->context, &creds);
9917c478bd9Sstevel@tonic-gate
9927c478bd9Sstevel@tonic-gate /*
9937c478bd9Sstevel@tonic-gate * Dont clean up the handle if the code is OK (code==0)
9947c478bd9Sstevel@tonic-gate * because it is returned to the caller in the 'server_handle'
9957c478bd9Sstevel@tonic-gate * ptr.
9967c478bd9Sstevel@tonic-gate */
9977c478bd9Sstevel@tonic-gate if (code) {
9987c478bd9Sstevel@tonic-gate krb5_free_context(handle->context);
9997c478bd9Sstevel@tonic-gate free(handle->lhandle);
10007c478bd9Sstevel@tonic-gate free(handle);
10017c478bd9Sstevel@tonic-gate }
10027c478bd9Sstevel@tonic-gate
100356a424ccSmp153739 return code;
10047c478bd9Sstevel@tonic-gate }
10057c478bd9Sstevel@tonic-gate
10067c478bd9Sstevel@tonic-gate kadm5_ret_t
kadm5_destroy(void * server_handle)10077c478bd9Sstevel@tonic-gate kadm5_destroy(void *server_handle)
10087c478bd9Sstevel@tonic-gate {
10097c478bd9Sstevel@tonic-gate krb5_ccache ccache = NULL;
10107c478bd9Sstevel@tonic-gate int code = KADM5_OK;
10117c478bd9Sstevel@tonic-gate kadm5_server_handle_t handle =
10127c478bd9Sstevel@tonic-gate (kadm5_server_handle_t) server_handle;
10137c478bd9Sstevel@tonic-gate OM_uint32 min_stat;
10147c478bd9Sstevel@tonic-gate
10157c478bd9Sstevel@tonic-gate CHECK_HANDLE(server_handle);
101656a424ccSmp153739 /* SUNW14resync:
101756a424ccSmp153739 * krb5_cc_resolve() will resolve a ccache with the same data that
101856a424ccSmp153739 * handle->my_cred points to. If the ccache is a MEMORY ccache then
101956a424ccSmp153739 * gss_release_cred() will free that data (it doesn't do this when ccache
102056a424ccSmp153739 * is a FILE ccache).
102156a424ccSmp153739 * if'ed out to avoid the double free.
102256a424ccSmp153739 */
102356a424ccSmp153739 #if 0
10247c478bd9Sstevel@tonic-gate if (handle->destroy_cache && handle->cache_name) {
10257c478bd9Sstevel@tonic-gate if ((code = krb5_cc_resolve(handle->context,
10267c478bd9Sstevel@tonic-gate handle->cache_name, &ccache)) == 0)
10277c478bd9Sstevel@tonic-gate code = krb5_cc_destroy (handle->context, ccache);
10287c478bd9Sstevel@tonic-gate }
102956a424ccSmp153739 #endif
10307c478bd9Sstevel@tonic-gate if (handle->cache_name)
10317c478bd9Sstevel@tonic-gate free(handle->cache_name);
10327c478bd9Sstevel@tonic-gate if (handle->clnt && handle->clnt->cl_auth) {
10337c478bd9Sstevel@tonic-gate /*
10347c478bd9Sstevel@tonic-gate * Since kadm5 doesn't use the default credentials we
10357c478bd9Sstevel@tonic-gate * must clean this up manually.
10367c478bd9Sstevel@tonic-gate */
10377c478bd9Sstevel@tonic-gate if (handle->my_cred != GSS_C_NO_CREDENTIAL)
10387c478bd9Sstevel@tonic-gate (void) gss_release_cred(&min_stat, &handle->my_cred);
10397c478bd9Sstevel@tonic-gate AUTH_DESTROY(handle->clnt->cl_auth);
10407c478bd9Sstevel@tonic-gate }
10417c478bd9Sstevel@tonic-gate if (handle->clnt)
10427c478bd9Sstevel@tonic-gate clnt_destroy(handle->clnt);
10437c478bd9Sstevel@tonic-gate if (handle->lhandle)
10447c478bd9Sstevel@tonic-gate free (handle->lhandle);
10457c478bd9Sstevel@tonic-gate
10467c478bd9Sstevel@tonic-gate kadm5_free_config_params(handle->context, &handle->params);
10477c478bd9Sstevel@tonic-gate krb5_free_context(handle->context);
10487c478bd9Sstevel@tonic-gate
10497c478bd9Sstevel@tonic-gate handle->magic_number = 0;
10507c478bd9Sstevel@tonic-gate free(handle);
10517c478bd9Sstevel@tonic-gate
105256a424ccSmp153739 return code;
10537c478bd9Sstevel@tonic-gate }
105456a424ccSmp153739 /* not supported on client */
kadm5_lock(void * server_handle)105556a424ccSmp153739 kadm5_ret_t kadm5_lock(void *server_handle)
10567c478bd9Sstevel@tonic-gate {
105756a424ccSmp153739 return EINVAL;
10587c478bd9Sstevel@tonic-gate }
10597c478bd9Sstevel@tonic-gate
106056a424ccSmp153739 /* not supported on client */
kadm5_unlock(void * server_handle)106156a424ccSmp153739 kadm5_ret_t kadm5_unlock(void *server_handle)
106256a424ccSmp153739 {
106356a424ccSmp153739 return EINVAL;
106456a424ccSmp153739 }
106556a424ccSmp153739
kadm5_flush(void * server_handle)106656a424ccSmp153739 kadm5_ret_t kadm5_flush(void *server_handle)
106756a424ccSmp153739 {
106856a424ccSmp153739 return KADM5_OK;
106956a424ccSmp153739 }
107056a424ccSmp153739
_kadm5_check_handle(void * handle)107156a424ccSmp153739 int _kadm5_check_handle(void *handle)
10727c478bd9Sstevel@tonic-gate {
10737c478bd9Sstevel@tonic-gate CHECK_HANDLE(handle);
107456a424ccSmp153739 return 0;
10757c478bd9Sstevel@tonic-gate }
10767c478bd9Sstevel@tonic-gate
kadm5_init_krb5_context(krb5_context * ctx)107754925bf6Swillf krb5_error_code kadm5_init_krb5_context (krb5_context *ctx)
107854925bf6Swillf {
107954925bf6Swillf return krb5_init_context(ctx);
108054925bf6Swillf }
108154925bf6Swillf
10827c478bd9Sstevel@tonic-gate /*
10837c478bd9Sstevel@tonic-gate * Stub function for kadmin. It was created to eliminate the dependency on
10847c478bd9Sstevel@tonic-gate * libkdb's ulog functions. The srv equivalent makes the actual calls.
10857c478bd9Sstevel@tonic-gate */
10867c478bd9Sstevel@tonic-gate krb5_error_code
kadm5_init_iprop(void * handle)10877c478bd9Sstevel@tonic-gate kadm5_init_iprop(void *handle)
10887c478bd9Sstevel@tonic-gate {
10897c478bd9Sstevel@tonic-gate return (0);
10907c478bd9Sstevel@tonic-gate }
1091