#
# Make MIT Kerberos use Solaris RPC and RPCSEC_GSS instead of libgssrpc.
#
# MIT Kerberos bundles the RPC and RPCSEC_GSS implementation with the
# source in separate libgssrpc library. The RPC implementation is based on
# an ancient SUN donated code. It is inferior to the RPC implementation in
# Solaris libc in features and possibly in performance too. Also introducing
# a duplicate implementation would not be wise.
#
# The patch modifies MIT code to use the standard RPC and RPCSEC_GSS in Solaris.
#
# Specifically:
# - it modifies the Makefiles not to build libgssrpc and not to link with it
# - related to above, it strips libgssrpc from krb5-config
# - moves xdr_alloc.c out of libgssrpc and fixes it for 64-bit
# - includes correct headers - rpc/rpc.h instead of gssrpc/rpc.h
# - modifies net-server code to support TI-RPC (transport independent, XTI)
# - implement kadmin protocol and incr. prop. using Solaris RPCSEC_GSS
# - reverts MIT modification to iprop, that were needed for RPC differences
# - hierarchical incremental propagation tests are removed from t_iprop.py,
# because the Solaris RPC implementation precludes running this scenario on
# a single host
# - server side support for RPCSEC_GSS base changepw protocol
# - recognize sunw_dbprop_* config options for backward compatibility
# - defines several functions to locate servers (admin, cpw, kiprop,...)
# - updates generated dependencies for kadm_host_srv_names.so to build
# - defines xdr_u_int32 and xdr_int32
#
# This patch is Solaris specific and is not intended for upstream contribution.
# In the future MIT might provide support for system native RPC implementation.
# Patch source: in-house
#
--- a/src/build-tools/krb5-config.in
+++ b/src/build-tools/krb5-config.in
@@ -97,9 +97,6 @@ while test $# != 0; do
gssapi)
library=gssapi
;;
- gssrpc)
- library=gssrpc
- ;;
kadm-client)
library=kadm_client
;;
@@ -142,7 +139,6 @@ if test -n "$do_help"; then
echo "Libraries:"
echo " krb5 Kerberos 5 application"
echo " gssapi GSSAPI application with Kerberos 5 bindings"
- echo " gssrpc GSSAPI RPC application"
echo " kadm-client Kadmin client"
echo " kadm-server Kadmin server"
echo " kdb Application that accesses the kerberos database"
@@ -232,17 +228,10 @@ if test -n "$do_libs"; then
if test $library = 'kadm_server'; then
lib_flags="$lib_flags -lkadm5srv_mit -lkdb5 $KDB5_DB_LIB"
- library=gssrpc
fi
if test $library = 'kadm_client'; then
lib_flags="$lib_flags -lkadm5clnt_mit"
- library=gssrpc
- fi
-
- if test $library = 'gssrpc'; then
- lib_flags="$lib_flags -lgssrpc"
- library=gssapi
fi
if test $library = 'gssapi'; then
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -318,7 +318,7 @@ KDB5_PLUGIN_LIBS = @KDB5_PLUGIN_LIBS@
KADMCLNT_DEPLIB = $(TOPLIBD)/libkadm5clnt_mit$(DEPLIBEXT)
KADMSRV_DEPLIB = $(TOPLIBD)/libkadm5srv_mit$(DEPLIBEXT)
KDB5_DEPLIB = $(TOPLIBD)/libkdb5$(DEPLIBEXT)
-GSSRPC_DEPLIB = $(TOPLIBD)/libgssrpc$(DEPLIBEXT)
+GSSRPC_DEPLIB = # empty
GSS_DEPLIB = $(TOPLIBD)/libgssapi_krb5$(DEPLIBEXT)
KRB5_DEPLIB = $(TOPLIBD)/libkrb5$(DEPLIBEXT)
CRYPTO_DEPLIB = $(TOPLIBD)/libk5crypto$(DEPLIBEXT)
@@ -399,7 +399,7 @@ KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN
KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS)
GSS_LIBS = $(GSS_KRB5_LIB)
# needs fixing if ever used on Mac OS X!
-GSSRPC_LIBS = -lgssrpc $(GSS_LIBS)
+GSSRPC_LIBS = $(GSS_LIBS)
KADM_COMM_LIBS = $(GSSRPC_LIBS)
# need fixing if ever used on Mac OS X!
KADMSRV_LIBS = -lkadm5srv_mit $(HESIOD_LIBS) $(KDB5_LIBS) $(KADM_COMM_LIBS)
--- a/src/include/iprop.h
+++ b/src/include/iprop.h
@@ -6,8 +6,7 @@
#ifndef _IPROP_H_RPCGEN
#define _IPROP_H_RPCGEN
-#include <gssrpc/rpc.h>
-
+#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -218,11 +218,14 @@ typedef unsigned char u_char;
#define KRB5_CONF_HTTP_ANCHORS "http_anchors"
#define KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME "ignore_acceptor_hostname"
#define KRB5_CONF_IPROP_ENABLE "iprop_enable"
+#define KRB5_CONF_SUNW_DBPROP_ENABLE "sunw_dbprop_enable"
#define KRB5_CONF_IPROP_LOGFILE "iprop_logfile"
#define KRB5_CONF_IPROP_MASTER_ULOGSIZE "iprop_master_ulogsize"
+#define KRB5_CONF_SUNW_DBPROP_MASTER_ULOGSIZE "sunw_dbprop_master_ulogsize"
#define KRB5_CONF_IPROP_PORT "iprop_port"
#define KRB5_CONF_IPROP_RESYNC_TIMEOUT "iprop_resync_timeout"
#define KRB5_CONF_IPROP_SLAVE_POLL "iprop_slave_poll"
+#define KRB5_CONF_SUNW_DBPROP_SLAVE_POLL "sunw_dbprop_slave_poll"
#define KRB5_CONF_K5LOGIN_AUTHORITATIVE "k5login_authoritative"
#define KRB5_CONF_K5LOGIN_DIRECTORY "k5login_directory"
#define KRB5_CONF_KADMIND_PORT "kadmind_port"
--- a/src/kadmin/dbutil/kadm5_create.c
+++ b/src/kadmin/dbutil/kadm5_create.c
@@ -158,11 +158,20 @@ static int add_admin_princs(void *handle, krb5_context context, char *realm)
ADMIN_LIFETIME)))
goto clean_and_exit;
+ if ((ret = add_admin_sname_princ(handle, context,
+ KADM5_CHANGEPW_HOST_SERVICE, realm,
+ KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE,
+ ADMIN_LIFETIME)))
+ goto clean_and_exit;
+
+/* kadmin/admin unusable with Solaris rpcsec_gss */
+#if 0
if ((ret = add_admin_princ(handle, context,
KADM5_ADMIN_SERVICE, realm,
KRB5_KDB_DISALLOW_TGT_BASED,
ADMIN_LIFETIME)))
goto clean_and_exit;
+#endif
if ((ret = add_admin_princ(handle, context,
KADM5_CHANGEPW_SERVICE, realm,
--- a/src/kadmin/server/ipropd_svc.c
+++ b/src/kadmin/server/ipropd_svc.c
@@ -137,6 +137,8 @@ iprop_get_updates_1_svc(kdb_last_t *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle = global_server_handle;
char *client_name = 0, *service_name = 0;
char obuf[256] = {0};
+ gss_name_t name = NULL;
+ OM_uint32 min_stat;
/* default return code */
ret.ret = UPDATE_ERROR;
@@ -173,8 +175,14 @@ iprop_get_updates_1_svc(kdb_last_t *arg, struct svc_req *rqstp)
DPRINT("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n", whoami, client_name,
service_name);
+ if (!(name = rqst2name(rqstp))) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: Couldn't obtain client's name"),
+ whoami);
+ goto out;
+ }
if (!kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_IPROP,
NULL,
NULL)) {
@@ -222,6 +230,8 @@ out:
debprret(whoami, ret.ret, ret.lastentry.last_sno);
free(client_name);
free(service_name);
+ if (name)
+ gss_release_name(&min_stat, &name);
return (&ret);
}
@@ -252,6 +262,18 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp)
int pret, fret;
FILE *p;
kadm5_server_handle_t handle = global_server_handle;
+ /*
+ * The following two definitions are dead code in upstream krb5.
+ *
+ * OM_uint32 min_stat;
+ * gss_name_t name = NULL;
+ *
+ * They come from initial Sun donation of iprop.
+ * For Solaris specific RPC implementation we need them back.
+ * If upstream removes the dead code, hopefuly placing this comment
+ * in this place will result in an easy-to-debug patch error,
+ * rather then failure to compile.
+ */
OM_uint32 min_stat;
gss_name_t name = NULL;
char *client_name = NULL, *service_name = NULL;
@@ -300,8 +322,14 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp)
DPRINT("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n",
whoami, client_name, service_name);
+ if (!(name = rqst2name(rqstp))) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: Couldn't obtain client's name"),
+ whoami);
+ goto out;
+ }
if (!kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_IPROP,
NULL,
NULL)) {
@@ -448,6 +476,7 @@ iprop_full_resync_ext_1_svc(uint32_t *argp, struct svc_req *rqstp)
return ipropx_resync(*argp, rqstp);
}
+#if 0
static int
check_iprop_rpcsec_auth(struct svc_req *rqstp)
{
@@ -520,6 +549,7 @@ fail_name:
gss_release_name(&min_stat, &name);
return success;
}
+#endif
void
krb5_iprop_prog_1(struct svc_req *rqstp,
@@ -533,6 +563,7 @@ krb5_iprop_prog_1(struct svc_req *rqstp,
char *(*local)(/* union XXX *, struct svc_req * */);
char *whoami = "krb5_iprop_prog_1";
+#if 0
if (!check_iprop_rpcsec_auth(rqstp)) {
krb5_klog_syslog(LOG_ERR, _("authentication attempt failed: %s, RPC "
"authentication flavor %d"),
@@ -541,6 +572,7 @@ krb5_iprop_prog_1(struct svc_req *rqstp,
svcerr_weakauth(transp);
return;
}
+#endif
switch (rqstp->rq_proc) {
case NULLPROC:
--- a/src/kadmin/server/kadm_rpc_svc.c
+++ b/src/kadmin/server/kadm_rpc_svc.c
@@ -5,7 +5,7 @@
*/
#include <k5-int.h>
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
#include <syslog.h>
#include <kadm5/kadm_rpc.h>
@@ -63,8 +63,7 @@ void kadm_1(rqstp, transp)
bool_t (*xdr_argument)(), (*xdr_result)();
char *(*local)();
- if (rqstp->rq_cred.oa_flavor != AUTH_GSSAPI &&
- !check_rpcsec_auth(rqstp)) {
+ if (rqstp->rq_cred.oa_flavor != RPCSEC_GSS) {
krb5_klog_syslog(LOG_ERR, "Authentication attempt failed: %s, "
"RPC authentication flavor %d",
client_addr(rqstp->rq_xprt),
@@ -229,7 +228,7 @@ void kadm_1(rqstp, transp)
return;
}
memset(&argument, 0, sizeof(argument));
- if (!svc_getargs(transp, xdr_argument, &argument)) {
+ if (!svc_getargs(transp, xdr_argument, (char *)&argument)) {
svcerr_decode(transp);
return;
}
@@ -239,13 +238,15 @@ void kadm_1(rqstp, transp)
"continuing.");
svcerr_systemerr(transp);
}
- if (!svc_freeargs(transp, xdr_argument, &argument)) {
+ if (!svc_freeargs(transp, xdr_argument, (char *)&argument)) {
krb5_klog_syslog(LOG_ERR, "WARNING! Unable to free arguments, "
"continuing.");
}
return;
}
+#if 0
+
static int
check_rpcsec_auth(struct svc_req *rqstp)
{
@@ -337,3 +338,4 @@ gss_to_krb5_name_1(struct svc_req *rqstp, krb5_context ctx, gss_name_t gss_name,
free(str);
return success;
}
+#endif
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -45,10 +45,9 @@
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <gssapi/gssapi.h>
#include "gssapiP_krb5.h" /* for kg_get_context */
-#include <gssrpc/auth_gssapi.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include <kadm5/server_acl.h>
@@ -57,6 +56,8 @@
#include <string.h>
#include "kadm5/server_internal.h" /* XXX for kadm5_server_handle_t */
#include <kdb_log.h>
+#include <rpc/rpcsec_gss.h>
+#include <kadm5/kadm_rpc.h>
#include "misc.h"
@@ -347,19 +348,20 @@ main(int argc, char *argv[])
OM_uint32 minor_status;
gss_buffer_desc in_buf;
gss_OID nt_krb5_name_oid = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
- auth_gssapi_name names[4];
+ char *names[4];
kadm5_config_params params;
verto_ctx *vctx;
const char *pid_file = NULL;
char **db_args = NULL, **tmpargs;
int ret, i, db_args_size = 0, strong_random = 1, proponly = 0;
+ char **tmp_srv_names;
+ krb5_principal princ;
+ char *pos;
setlocale(LC_ALL, "");
setvbuf(stderr, NULL, _IONBF, 0);
- names[0].name = names[1].name = names[2].name = names[3].name = NULL;
- names[0].type = names[1].type = names[2].type = names[3].type =
- nt_krb5_name_oid;
+ names[0] = names[1] = names[2] = names[3] = NULL;
progname = (strrchr(argv[0], '/') != NULL) ? strrchr(argv[0], '/') + 1 :
argv[0];
@@ -463,28 +465,88 @@ main(int argc, char *argv[])
if (!(params.mask & KADM5_CONFIG_ACL_FILE))
fail_to_start(0, _("Missing required ACL file configuration"));
- ret = setup_loop(proponly, &vctx);
+ ret = kadm5_get_adm_host_srv_names(context, params.realm, &tmp_srv_names);
if (ret)
- fail_to_start(ret, _("initializing network"));
+ fail_to_start(ret, _("building GSSAPI auth names"));
+ names[0] = strdup(tmp_srv_names[0]);
+ if (names[0] == NULL)
+ fail_to_start(ENOMEM, _("copying GSSAPI auth names"));
+ free_srv_names(tmp_srv_names);
+ tmp_srv_names = NULL;
- names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
- names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
- if (names[0].name == NULL || names[1].name == NULL)
- fail_to_start(0, _("Cannot build GSSAPI auth names"));
+ ret = kadm5_get_cpw_host_srv_names(context, params.realm, &tmp_srv_names);
+ if (ret)
+ fail_to_start(ret, _("building GSSAPI auth names"));
+ names[1] = strdup(tmp_srv_names[0]);
+ if (names[1] == NULL)
+ fail_to_start(ENOMEM, _("copying GSSAPI auth names"));
+ free_srv_names(tmp_srv_names);
+ tmp_srv_names = NULL;
+
+ if (params.iprop_enabled == TRUE) {
+ ret = kadm5_get_kiprop_host_srv_names(context, params.realm,
+ &tmp_srv_names);
+ if (ret)
+ fail_to_start(ret, _("building GSSAPI auth names"));
+ names[2] = strdup(tmp_srv_names[0]);
+ if (names[2] == NULL)
+ fail_to_start(ENOMEM, _("copying GSSAPI auth names"));
+ free_srv_names(tmp_srv_names);
+ tmp_srv_names = NULL;
+
+ /*
+ * For hierarchical incremental propagation we need kadmind
+ * on slave KDCs to register local hostbased kiprop service principal,
+ * not the one for admin server. For least surprise on upgrade we
+ * register both.
+ */
+ ret = krb5_sname_to_principal(context, NULL, KADM5_KIPROP_HOST_SERVICE,
+ KRB5_NT_SRV_HST, &princ);
+ if (ret)
+ fail_to_start(ret, _("building GSSAPI auth names"));
+ ret = krb5_unparse_name(context, princ, &names[3]);
+ if (ret)
+ fail_to_start(ret, _("building GSSAPI auth names"));
+ if ((pos = strchr(names[3], '@')) != NULL)
+ *pos = '\0';
+ if ((pos = strchr(names[3], '/')) != NULL)
+ *pos = '@';
+ }
ret = setup_kdb_keytab();
if (ret)
fail_to_start(0, _("Cannot set up KDB keytab"));
-
+#if 0
if (svcauth_gssapi_set_names(names, 2) == FALSE)
fail_to_start(0, _("Cannot set GSSAPI authentication names"));
+#endif
+ if (!rpc_gss_set_svc_name(names[0], "kerberos_v5", 0, KADM, KADMVERS))
+ fail_to_start(0, _("Cannot set GSSAPI authentication names"));
+ if (!rpc_gss_set_svc_name(names[1], "kerberos_v5", 0, KADM, KADMVERS))
+ fail_to_start(0, _("Cannot set GSSAPI authentication names"));
+ if (params.iprop_enabled == TRUE) {
+ if (!rpc_gss_set_svc_name(names[2], "kerberos_v5", 0,
+ KRB5_IPROP_PROG, KRB5_IPROP_VERS))
+ fail_to_start(0, _("Cannot set GSSAPI authentication names"));
+ if (strcmp(names[2], names[3])){
+ if (!rpc_gss_set_svc_name(names[3], "kerberos_v5", 0,
+ KRB5_IPROP_PROG, KRB5_IPROP_VERS))
+ fail_to_start(0, _("Cannot set GSSAPI authentication names"));
+
+ }
+ }
/* if set_names succeeded, this will too */
- in_buf.value = names[1].name;
- in_buf.length = strlen(names[1].name) + 1;
+ in_buf.value = names[1];
+ in_buf.length = strlen(names[1]);
(void)gss_import_name(&minor_status, &in_buf, nt_krb5_name_oid,
&gss_changepw_name);
+ ret = setup_loop(proponly, &vctx);
+ if (ret)
+ fail_to_start(ret, _("initializing network"));
+
+#if 0
svcauth_gssapi_set_log_badauth2_func(log_badauth, NULL);
svcauth_gssapi_set_log_badverf_func(log_badverf, NULL);
svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);
@@ -495,6 +557,7 @@ main(int argc, char *argv[])
if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE)
fail_to_start(0, _("Cannot initialize GSSAPI service name"));
+#endif
ret = kadm5int_acl_init(context, 0, params.acl_file);
if (ret)
@@ -535,14 +598,16 @@ main(int argc, char *argv[])
krb5_klog_syslog(LOG_INFO, _("finished, exiting"));
/* Clean up memory, etc */
+#if 0
svcauth_gssapi_unset_names();
+#endif
kadm5_destroy(global_server_handle);
loop_free(vctx);
kadm5int_acl_finish(context, 0);
(void)gss_release_name(&minor_status, &gss_changepw_name);
(void)gss_release_name(&minor_status, &gss_oldchangepw_name);
for (i = 0; i < 4; i++)
- free(names[i].name);
+ free(names[i]);
krb5_klog_close(context);
krb5_free_context(context);
--- a/src/kadmin/server/server_stubs.c
+++ b/src/kadmin/server/server_stubs.c
@@ -21,10 +21,10 @@ extern gss_name_t gss_changepw_name;
extern gss_name_t gss_oldchangepw_name;
extern void * global_server_handle;
-#define CHANGEPW_SERVICE(rqstp) \
- (cmp_gss_names_rel_1(acceptor_name(rqstp->rq_svccred), gss_changepw_name) | \
- (gss_oldchangepw_name && \
- cmp_gss_names_rel_1(acceptor_name(rqstp->rq_svccred), \
+#define CHANGEPW_SERVICE(rqstp) \
+ (cmp_gss_names_rel_1(acceptor_name(rqstp), gss_changepw_name) | \
+ (gss_oldchangepw_name && \
+ cmp_gss_names_rel_1(acceptor_name(rqstp), \
gss_oldchangepw_name)))
@@ -33,7 +33,7 @@ static int gss_to_krb5_name(kadm5_server_handle_t handle,
static int gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str);
-static gss_name_t acceptor_name(gss_ctx_id_t context);
+static gss_name_t acceptor_name(struct svc_req *rqstp);
gss_name_t rqst2name(struct svc_req *rqstp);
@@ -107,6 +107,8 @@ static kadm5_ret_t new_server_handle(krb5_ui_4 api_version,
*out_handle)
{
kadm5_server_handle_t handle;
+ gss_name_t name = NULL;
+ OM_uint32 min_stat;
*out_handle = NULL;
@@ -117,13 +119,18 @@ static kadm5_ret_t new_server_handle(krb5_ui_4 api_version,
*handle = *(kadm5_server_handle_t)global_server_handle;
handle->api_version = api_version;
- if (! gss_to_krb5_name(handle, rqst2name(rqstp),
- &handle->current_caller)) {
+ if (!(name = rqst2name(rqstp))) {
free(handle);
return KADM5_FAILURE;
}
+ if (! gss_to_krb5_name(handle, name, &handle->current_caller)) {
+ free(handle);
+ gss_release_name(&min_stat, &name);
+ return KADM5_FAILURE;
+ }
*out_handle = handle;
+ gss_release_name(&min_stat, &name);
return 0;
}
@@ -182,38 +189,54 @@ int setup_gss_names(struct svc_req *rqstp,
gss_buffer_desc *client_name,
gss_buffer_desc *server_name)
{
- OM_uint32 maj_stat, min_stat;
- gss_name_t server_gss_name;
+ OM_uint32 min_stat;
+ gss_name_t name = NULL;
+ rpc_gss_rawcred_t *raw_cred;
- if (gss_name_to_string(rqst2name(rqstp), client_name) != 0)
+ if (!(name = rqst2name(rqstp))) {
return -1;
- maj_stat = gss_inquire_context(&min_stat, rqstp->rq_svccred, NULL,
- &server_gss_name, NULL, NULL, NULL,
- NULL, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- gss_release_buffer(&min_stat, client_name);
- gss_release_name(&min_stat, &server_gss_name);
+ }
+ if (gss_name_to_string(name, client_name) != 0) {
+ gss_release_name(&min_stat, &name);
return -1;
}
- if (gss_name_to_string(server_gss_name, server_name) != 0) {
+ gss_release_name(&min_stat, &name);
+
+ rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
+ server_name->value = strdup(raw_cred->svc_principal);
+ if (server_name->value == NULL) {
gss_release_buffer(&min_stat, client_name);
- gss_release_name(&min_stat, &server_gss_name);
return -1;
}
- gss_release_name(&min_stat, &server_gss_name);
+ server_name->length = strlen(raw_cred->svc_principal);
+
return 0;
}
-static gss_name_t acceptor_name(gss_ctx_id_t context)
+static gss_name_t acceptor_name(struct svc_req *rqstp)
{
OM_uint32 maj_stat, min_stat;
- gss_name_t name;
+ gss_name_t name = NULL;
+ rpc_gss_rawcred_t *raw_cred;
+ gss_buffer_desc name_buff;
- maj_stat = gss_inquire_context(&min_stat, context, NULL, &name,
- NULL, NULL, NULL, NULL, NULL);
- if (maj_stat != GSS_S_COMPLETE)
- return NULL;
- return name;
+ rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
+ name_buff.value = raw_cred->svc_principal;
+ name_buff.length = strlen(raw_cred->svc_principal);
+ maj_stat = gss_import_name(&min_stat, &name_buff,
+ (gss_OID) gss_nt_krb5_name, &name);
+ if (maj_stat != GSS_S_COMPLETE) {
+ gss_release_buffer(&min_stat, &name_buff);
+ return (NULL);
+ }
+ maj_stat = gss_display_name(&min_stat, name, &name_buff, NULL);
+ if (maj_stat != GSS_S_COMPLETE) {
+ gss_release_buffer(&min_stat, &name_buff);
+ return (NULL);
+ }
+ gss_release_buffer(&min_stat, &name_buff);
+
+ return name;
}
static int cmp_gss_krb5_name(kadm5_server_handle_t handle,
@@ -340,8 +363,9 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
restriction_t *rp;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -360,8 +384,12 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_ADD,
+ || !kadm5int_acl_check(handle->context, name, ACL_ADD,
arg->rec.principal, &rp)
|| kadm5int_acl_impose_restrictions(handle->context,
&arg->rec, &arg->mask, rp)) {
@@ -388,6 +416,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -402,8 +432,9 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
restriction_t *rp;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -422,8 +453,12 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_ADD,
+ || !kadm5int_acl_check(handle->context, name, ACL_ADD,
arg->rec.principal, &rp)
|| kadm5int_acl_impose_restrictions(handle->context,
&arg->rec, &arg->mask, rp)) {
@@ -451,6 +486,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -464,8 +501,9 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -484,8 +522,12 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_DELETE,
+ || !kadm5int_acl_check(handle->context, name, ACL_DELETE,
arg->princ, NULL)) {
ret.code = KADM5_AUTH_DELETE;
log_unauth("kadm5_delete_principal", prime_arg,
@@ -508,6 +550,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -522,8 +566,9 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
restriction_t *rp;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -540,8 +585,12 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_MODIFY,
+ || !kadm5int_acl_check(handle->context, name, ACL_MODIFY,
arg->rec.principal, &rp)
|| kadm5int_acl_impose_restrictions(handle->context,
&arg->rec, &arg->mask, rp)) {
@@ -565,6 +614,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -581,8 +632,9 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
const char *errmsg = NULL;
size_t tlen1, tlen2, clen, slen;
char *tdots1, *tdots2, *cdots, *sdots;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -608,13 +660,17 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
slen = service_name.length;
trunc_name(&slen, &sdots);
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
ret.code = KADM5_OK;
if (! CHANGEPW_SERVICE(rqstp)) {
- if (!kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ if (!kadm5int_acl_check(handle->context, name,
ACL_DELETE, arg->src, NULL))
ret.code = KADM5_AUTH_DELETE;
/* any restrictions at all on the ADD kills the RENAME */
- if (!kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ if (!kadm5int_acl_check(handle->context, name,
ACL_ADD, arg->dest, &rp) || rp) {
if (ret.code == KADM5_AUTH_DELETE)
ret.code = KADM5_AUTH_INSUFFICIENT;
@@ -662,6 +718,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -675,8 +733,9 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_gprinc_ret, &ret);
+ xdr_free(xdr_gprinc_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -697,9 +756,13 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (! cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ) &&
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (! cmp_gss_krb5_name(handle, name, arg->princ) &&
(CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_INQUIRE,
arg->princ,
NULL))) {
@@ -724,6 +787,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -737,8 +802,9 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_gprincs_ret, &ret);
+ xdr_free(xdr_gprincs_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -756,8 +822,12 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
if (prime_arg == NULL)
prime_arg = "*";
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_LIST,
NULL,
NULL)) {
@@ -782,6 +852,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -795,8 +867,9 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -815,11 +888,15 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (cmp_gss_krb5_name(handle, name, arg->princ)) {
ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
FALSE, 0, NULL, arg->pass);
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_CHANGEPW, arg->princ, NULL)) {
ret.code = kadm5_chpass_principal((void *)handle, arg->princ,
arg->pass);
@@ -845,6 +922,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -858,8 +937,9 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -878,14 +958,18 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (cmp_gss_krb5_name(handle, name, arg->princ)) {
ret.code = chpass_principal_wrapper_3((void *)handle, arg->princ,
arg->keepold,
arg->n_ks_tuple,
arg->ks_tuple,
arg->pass);
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_CHANGEPW, arg->princ, NULL)) {
ret.code = kadm5_chpass_principal_3((void *)handle, arg->princ,
arg->keepold,
@@ -914,6 +998,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -927,8 +1013,9 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -947,8 +1034,12 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_SETKEY, arg->princ, NULL)) {
ret.code = kadm5_setv4key_principal((void *)handle, arg->princ,
arg->keyblock);
@@ -974,6 +1065,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -987,8 +1080,9 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1007,8 +1101,12 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_SETKEY, arg->princ, NULL)) {
ret.code = kadm5_setkey_principal((void *)handle, arg->princ,
arg->keyblocks, arg->n_keys);
@@ -1034,6 +1132,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1047,8 +1147,9 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1067,8 +1168,12 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_SETKEY, arg->princ, NULL)) {
ret.code = kadm5_setkey_principal_3((void *)handle, arg->princ,
arg->keepold,
@@ -1097,6 +1202,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1112,8 +1219,9 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_chrand_ret, &ret);
+ xdr_free(xdr_chrand_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1135,11 +1243,15 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (cmp_gss_krb5_name(handle, name, arg->princ)) {
ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
FALSE, 0, NULL, &k, &nkeys);
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_CHANGEPW, arg->princ, NULL)) {
ret.code = kadm5_randkey_principal((void *)handle, arg->princ,
&k, &nkeys);
@@ -1169,6 +1281,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1184,8 +1298,9 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_chrand_ret, &ret);
+ xdr_free(xdr_chrand_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1206,14 +1321,18 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ)) {
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (cmp_gss_krb5_name(handle, name, arg->princ)) {
ret.code = randkey_principal_wrapper_3((void *)handle, arg->princ,
arg->keepold,
arg->n_ks_tuple,
arg->ks_tuple,
&k, &nkeys);
} else if (!(CHANGEPW_SERVICE(rqstp)) &&
- kadm5int_acl_check(handle->context, rqst2name(rqstp),
+ kadm5int_acl_check(handle->context, name,
ACL_CHANGEPW, arg->princ, NULL)) {
ret.code = kadm5_randkey_principal_3((void *)handle, arg->princ,
arg->keepold,
@@ -1246,6 +1365,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1259,8 +1380,9 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1276,8 +1398,12 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
}
prime_arg = arg->rec.policy;
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_ADD, NULL, NULL)) {
ret.code = KADM5_AUTH_ADD;
log_unauth("kadm5_create_policy", prime_arg,
@@ -1300,6 +1426,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1313,8 +1441,9 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1330,8 +1459,12 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
}
prime_arg = arg->name;
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_DELETE, NULL, NULL)) {
log_unauth("kadm5_delete_policy", prime_arg,
&client_name, &service_name, rqstp);
@@ -1352,6 +1485,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1365,8 +1500,9 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1382,8 +1518,12 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
}
prime_arg = arg->rec.policy;
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_MODIFY, NULL, NULL)) {
log_unauth("kadm5_modify_policy", prime_arg,
&client_name, &service_name, rqstp);
@@ -1405,6 +1545,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1420,8 +1562,9 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
kadm5_principal_ent_rec caller_ent;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_gpol_ret, &ret);
+ xdr_free(xdr_gpol_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1439,9 +1582,13 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
}
prime_arg = arg->name;
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
ret.code = KADM5_AUTH_GET;
if (!CHANGEPW_SERVICE(rqstp) && kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_INQUIRE, NULL, NULL))
ret.code = KADM5_OK;
else {
@@ -1480,6 +1627,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1494,8 +1643,9 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_gpols_ret, &ret);
+ xdr_free(xdr_gpols_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1513,8 +1663,12 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
if (prime_arg == NULL)
prime_arg = "*";
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_LIST, NULL, NULL)) {
ret.code = KADM5_AUTH_LIST;
log_unauth("kadm5_get_policies", prime_arg,
@@ -1536,6 +1690,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1548,7 +1704,7 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
const char *errmsg = NULL;
- xdr_free(xdr_getprivs_ret, &ret);
+ xdr_free(xdr_getprivs_ret, (char *) &ret);
if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
goto exit_func;
@@ -1591,8 +1747,9 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp)
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1613,9 +1770,13 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (!cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ) &&
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (!cmp_gss_krb5_name(handle, name, arg->princ) &&
(CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_MODIFY,
+ || !kadm5int_acl_check(handle->context, name, ACL_MODIFY,
arg->princ, NULL))) {
ret.code = KADM5_AUTH_MODIFY;
log_unauth(funcname, prime_arg, &client_name, &service_name, rqstp);
@@ -1636,6 +1797,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1649,8 +1812,9 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_gstrings_ret, &ret);
+ xdr_free(xdr_gstrings_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1669,9 +1833,13 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
- if (! cmp_gss_krb5_name(handle, rqst2name(rqstp), arg->princ) &&
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
+ if (! cmp_gss_krb5_name(handle, name, arg->princ) &&
(CHANGEPW_SERVICE(rqstp) || !kadm5int_acl_check(handle->context,
- rqst2name(rqstp),
+ name,
ACL_INQUIRE,
arg->princ,
NULL))) {
@@ -1695,6 +1863,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1708,8 +1878,9 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
OM_uint32 minor_stat;
kadm5_server_handle_t handle;
const char *errmsg = NULL;
+ gss_name_t name = NULL;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(arg->api_version, rqstp, &handle)))
goto exit_func;
@@ -1728,8 +1899,12 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
goto exit_func;
}
+ if (!(name = rqst2name(rqstp))) {
+ ret.code = KADM5_FAILURE;
+ goto exit_func;
+ }
if (CHANGEPW_SERVICE(rqstp)
- || !kadm5int_acl_check(handle->context, rqst2name(rqstp), ACL_MODIFY,
+ || !kadm5int_acl_check(handle->context, name, ACL_MODIFY,
arg->princ, NULL)) {
ret.code = KADM5_AUTH_MODIFY;
log_unauth("kadm5_mod_strings", prime_arg,
@@ -1751,6 +1926,8 @@ exit_func:
gss_release_buffer(&minor_stat, &client_name);
gss_release_buffer(&minor_stat, &service_name);
free_server_handle(handle);
+ if (name)
+ gss_release_name(&minor_stat, &name);
return &ret;
}
@@ -1765,7 +1942,7 @@ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
size_t clen, slen;
char *cdots, *sdots;
- xdr_free(xdr_generic_ret, &ret);
+ xdr_free(xdr_generic_ret, (char *) &ret);
if ((ret.code = new_server_handle(*arg, rqstp, &handle)))
goto exit_func;
@@ -1810,9 +1987,18 @@ exit_func:
gss_name_t
rqst2name(struct svc_req *rqstp)
{
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name;
+ rpc_gss_rawcred_t * raw_cred;
+ gss_buffer_desc name_buff;
- if (rqstp->rq_cred.oa_flavor == RPCSEC_GSS)
- return rqstp->rq_clntname;
- else
- return rqstp->rq_clntcred;
+ rpc_gss_getcred(rqstp, &raw_cred, NULL, NULL);
+ name_buff.value = raw_cred->client_principal->name;
+ name_buff.length = raw_cred->client_principal->len;
+ maj_stat = gss_import_name(&min_stat, &name_buff,
+ (gss_OID) GSS_C_NT_EXPORT_NAME, &name);
+ if (maj_stat != GSS_S_COMPLETE) {
+ return (NULL);
+ }
+ return (name);
}
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -1,5 +1,5 @@
mydir=lib
-SUBDIRS=crypto krb5 gssapi rpc kdb kadm5 apputils krad
+SUBDIRS=crypto krb5 gssapi kdb kadm5 apputils krad
WINSUBDIRS=crypto krb5 gssapi
BUILDTOP=$(REL)..
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -32,7 +32,7 @@
#include "port-sockets.h"
#include "socket-utils.h"
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#ifdef HAVE_NETINET_IN_H
#include <sys/types.h>
@@ -228,6 +228,9 @@ struct connection {
#define FREE_SET_DATA(set) \
(free(set.data), set.data = 0, set.max = 0, set.n = 0)
+#define EMPTY(set) \
+ (set.n == 0)
+
/*
* N.B.: The Emacs cc-mode indentation code seems to get confused if
* the macro argument here is one word only. So use "unsigned short"
@@ -546,6 +549,127 @@ add_tcp_read_fd(struct socksetup *data, int sock)
process_tcp_connection_read, 1);
}
+static int
+set_tli_opt(int fd, int level, int name, const void *val, unsigned int val_len)
+{
+ struct t_optmgmt req, rep;
+ struct opthdr *opt;
+ char reqbuf[256];
+
+ if (val_len + sizeof (struct opthdr) > sizeof (reqbuf))
+ return -1;
+
+ opt = (struct opthdr *) reqbuf;
+ opt->level = level;
+ opt->name = name;
+ opt->len = val_len;
+
+ memcpy(reqbuf + sizeof (struct opthdr), val, val_len);
+
+ req.flags = T_NEGOTIATE;
+ req.opt.len = sizeof (struct opthdr) + opt->len;
+ req.opt.buf = (char *) opt;
+
+ rep.flags = 0;
+ rep.opt.buf = reqbuf;
+ rep.opt.maxlen = sizeof (reqbuf);
+
+ if (t_optmgmt(fd, &req, &rep) < 0 || rep.flags != T_SUCCESS) {
+ t_error("t_optmgmt");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Create a tli/xti endpoint and bind it to port. Ensure the file descriptor
+ * will work with select. Set cloexec, reuseaddr, and if applicable v6-only.
+ * Does not call listen(). Returns -1 on failure after logging an error.
+ */
+static int
+create_server_endpoint(struct socksetup *data, struct netconfig *nconf,
+ u_short port)
+{
+ int fd, on;
+ struct t_info tinfo;
+ struct t_bind *tbind, *tres;
+ struct sockaddr_in *sin4;
+ struct sockaddr_in6 *sin6;
+
+ /* open transport endpoint */
+ fd = t_open(nconf->nc_device, O_RDWR, &tinfo);
+ if (fd == -1) {
+ data ->retval = errno;
+ com_err(data->prog, errno,
+ _("unable to open connection for ADMIN server"));
+ return -1;
+ }
+ set_cloexec_fd(fd);
+
+ /* ensure fd works with select */
+#ifndef _WIN32 /* Windows FD_SETSIZE is a count. */
+ if (fd >= FD_SETSIZE) {
+ t_close(fd);
+ com_err(data->prog, 0, _("endpoint fd number %d too high"), fd);
+ return -1;
+ }
+#endif
+
+ /* set SO_REUSEADDR */
+ on = 1;
+ if (set_tli_opt(fd, SOL_SOCKET, SO_REUSEADDR , &on, sizeof (on)) < 0)
+ com_err(data->prog, errno,
+ _("cannot enable SO_REUSEADDR on fd %d"), fd);
+
+ /* set IPv6-only as appropriate */
+ if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
+#ifdef IPV6_V6ONLY
+ if (set_tli_opt(fd, IPPROTO_IPV6, IPV6_V6ONLY , &on, sizeof (on)) < 0)
+ com_err(data->prog, errno,
+ _("cannot set IPV6_V6ONLY on fd %d"), fd);
+#else
+ krb5_klog_syslog(LOG_INFO, _("no IPV6_V6ONLY socket option support"));
+#endif /* IPV6_V6ONLY */
+ }
+
+ /* bind fd to specified port */
+ if (port != 0) {
+ tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR);
+ if (tbind == NULL) {
+ com_err(data->prog, errno,
+ _("Cannot allocate t_bind structure."));
+ t_close(fd);
+ return -1;
+ }
+
+ tbind->qlen = 8;
+ tbind->addr.len = tbind->addr.maxlen;
+ if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
+ sin6 = (struct sockaddr_in6 *)tbind->addr.buf;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_addr = in6addr_any;
+ sin6->sin6_port = htons(port);
+ } else if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
+ sin4 = (struct sockaddr_in *)tbind->addr.buf;
+ sin4->sin_family = AF_INET;
+ sin4->sin_addr.s_addr = INADDR_ANY;
+ sin4->sin_port = htons(port);
+ }
+
+ if (t_bind(fd, tbind, NULL) < 0) {
+ data->retval = errno;
+ com_err(data->prog, errno,
+ _("Cannot bind transport endpoint on %d"), port);
+ t_free(tbind, T_BIND);
+ t_close(fd);
+ return -1;
+ }
+ t_free(tbind, T_BIND);
+ }
+
+ return fd;
+}
+
/*
* Create a socket and bind it to addr. Ensure the socket will work with
* select(). Set the socket cloexec, reuseaddr, and if applicable v6-only.
@@ -604,12 +728,13 @@ create_server_socket(struct socksetup *data, struct sockaddr *addr, int type)
}
static verto_ev *
-add_rpc_listener_fd(struct socksetup *data, struct rpc_svc_data *svc, int sock)
+add_rpc_listener_fd(struct socksetup *data, struct netconfig *nconf,
+ struct rpc_svc_data *svc, int fd)
{
struct connection *conn;
verto_ev *ev;
- ev = add_fd(data, sock, CONN_RPC_LISTENER,
+ ev = add_fd(data, fd, CONN_RPC_LISTENER,
VERTO_EV_FLAG_IO_READ |
VERTO_EV_FLAG_PERSIST |
VERTO_EV_FLAG_REINITIABLE,
@@ -618,7 +743,7 @@ add_rpc_listener_fd(struct socksetup *data, struct rpc_svc_data *svc, int sock)
return NULL;
conn = verto_get_private(ev);
- conn->transp = svctcp_create(sock, 0, 0);
+ conn->transp = svc_tli_create(fd, nconf, NULL, 0, 0);
if (conn->transp == NULL) {
krb5_klog_syslog(LOG_ERR,
_("Cannot create RPC service: %s; continuing"),
@@ -627,11 +752,14 @@ add_rpc_listener_fd(struct socksetup *data, struct rpc_svc_data *svc, int sock)
return NULL;
}
- if (!svc_register(conn->transp, svc->prognum, svc->versnum,
- svc->dispatch, 0)) {
+ if (!svc_reg(conn->transp, svc->prognum, svc->versnum,
+ svc->dispatch, nconf)) {
krb5_klog_syslog(LOG_ERR,
- _("Cannot register RPC service: %s; continuing"),
- strerror(errno));
+ _("Cannot register RPC prog %d vers %d on %s; "
+ "continuing"),
+ (int) svc->prognum,
+ (int) svc->versnum,
+ nconf->nc_netid);
verto_del(ev);
return NULL;
}
@@ -760,53 +888,99 @@ setup_tcp_listener_ports(struct socksetup *data)
return 0;
}
+static void
+log_rpc_listen(int fd, struct rpc_svc_data *svc, struct netconfig *nconf) {
+ if (svc->port != 0)
+ krb5_klog_syslog(LOG_INFO,
+ _("listening on fd %d: %s port %hd "
+ "(RPC prog %d vers %d)"),
+ fd, nconf->nc_netid, svc->port,
+ (int) svc->prognum, (int) svc->versnum);
+ else
+ krb5_klog_syslog(LOG_INFO,
+ _("listening on fd %d: %s random port "
+ "(RPC prog %d vers %d)"),
+ fd, nconf->nc_netid,
+ (int) svc->prognum, (int) svc->versnum);
+
+}
+
static int
setup_rpc_listener_ports(struct socksetup *data)
{
struct sockaddr_in sin4;
struct sockaddr_in6 sin6;
- int i;
+ int i, fd, ret = -1, n_svcs = 0;
struct rpc_svc_data svc;
+ void *handlep;
+ struct netconfig *nconf, *nconf4 = NULL, *nconf6 = NULL;
+ char *protofmly = NULL;
- memset(&sin4, 0, sizeof(sin4));
- sin4.sin_family = AF_INET;
- sin4.sin_addr.s_addr = INADDR_ANY;
+ /* pick the right network: tcp and tcp6 */
+ if ((handlep = setnetconfig()) == NULL) {
+ com_err(data->prog, errno, _("cannot get any transport information"));
+ goto cleanup;
+ }
- memset(&sin6, 0, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = in6addr_any;
+ while (nconf = getnetconfig(handlep)) {
+ if ((nconf->nc_semantics == NC_TPI_COTS_ORD) &&
+ (strcmp(nconf->nc_proto, NC_TCP) == 0)){
+ if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
+ nconf4 = nconf;
+ if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
+ nconf6 = nconf;
+ }
+ }
+
+ if (nconf4 == NULL && nconf6 == NULL) {
+ com_err(data->prog, 0, _("no transport with proto=%s"), NC_TCP);
+ goto cleanup;
+ }
FOREACH_ELT (rpc_svc_data, i, svc) {
- int s4;
- int s6;
+ fd = create_server_endpoint(data, nconf4, svc.port);
+ if (fd < 0)
+ goto cleanup;
- sa_setport((struct sockaddr *)&sin4, svc.port);
- s4 = create_server_socket(data, (struct sockaddr *)&sin4, SOCK_STREAM);
- if (s4 < 0)
- return -1;
-
- if (add_rpc_listener_fd(data, &svc, s4) == NULL)
- close(s4);
- else
- krb5_klog_syslog(LOG_INFO, _("listening on fd %d: rpc %s"),
- s4, paddr((struct sockaddr *)&sin4));
+ if (add_rpc_listener_fd(data, nconf4, &svc, fd) == NULL)
+ close(fd);
+ else {
+ n_svcs++;
+ log_rpc_listen(fd, &svc, nconf4);
+ }
if (ipv6_enabled()) {
- sa_setport((struct sockaddr *)&sin6, svc.port);
- s6 = create_server_socket(data, (struct sockaddr *)&sin6,
- SOCK_STREAM);
- if (s6 < 0)
- return -1;
+ fd = create_server_endpoint(data, nconf6, svc.port);
+ if (fd < 0)
+ goto cleanup;
- if (add_rpc_listener_fd(data, &svc, s6) == NULL)
- close(s6);
- else
- krb5_klog_syslog(LOG_INFO, _("listening on fd %d: rpc %s"),
- s6, paddr((struct sockaddr *)&sin6));
+ if (add_rpc_listener_fd(data, nconf6, &svc, fd) == NULL)
+ close(fd);
+ else {
+ n_svcs++;
+ log_rpc_listen(fd, &svc, nconf6);
+ }
}
}
+ if (n_svcs > 0) {
+ krb5_klog_syslog(LOG_INFO, _("%d RPC services registered"), n_svcs);
+ } else if (!EMPTY(rpc_svc_data)){
+ /*
+ * If rpc_svc_data is not empty and n_svcs is 0, it means that
+ * we have tried to register some RPC services, but failed for all of
+ * them. In that case, refuse to start.
+ * If rpc_svc_data was emtpy, it means we were not registering any RPC
+ * services in the firstplace. krb5kdc is an example of daemon
+ * that does not register any RPC services.
+ */
+ com_err(data->prog, 0, _("Cannot register any RPC services, exiting."));
+ exit (1);
+ }
+ ret = 0;
- return 0;
+cleanup:
+ endnetconfig(handlep);
+ return ret;
}
#if defined(CMSG_SPACE) && defined(HAVE_STRUCT_CMSGHDR) && \
--- a/src/lib/kadm5/Makefile.in
+++ b/src/lib/kadm5/Makefile.in
@@ -21,6 +21,7 @@ SRCS = kadm_err.c \
$(srcdir)/chpass_util.c \
$(srcdir)/alt_prof.c \
$(srcdir)/str_conv.c \
+ $(srcdir)/kadm_host_srv_names.c \
$(srcdir)/logger.c
OBJS = kadm_err.$(OBJEXT) \
@@ -30,6 +31,7 @@ OBJS = kadm_err.$(OBJEXT) \
chpass_util.$(OBJEXT) \
alt_prof.$(OBJEXT) \
str_conv.$(OBJEXT) \
+ kadm_host_srv_names.$(OBJEXT) \
logger.$(OBJEXT)
STLIBOBJS = \
@@ -40,6 +42,7 @@ STLIBOBJS = \
chpass_util.o \
alt_prof.o \
str_conv.o \
+ kadm_host_srv_names.o \
logger.o
HDRDIR=$(BUILDTOP)/include/kadm5
--- a/src/lib/kadm5/admin.h
+++ b/src/lib/kadm5/admin.h
@@ -42,7 +42,7 @@
#define __KADM5_ADMIN_H__
#include <sys/types.h>
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <krb5.h>
#include <kdb.h>
#include <com_err.h>
@@ -67,6 +67,7 @@ KADM5INT_BEGIN_DECLS
#define KADM5_KIPROP_HOST_SERVICE "kiprop"
#define KADM5_ADMIN_HOST_SERVICE "kadmin"
+#define KADM5_CHANGEPW_HOST_SERVICE "changepw"
typedef krb5_principal kadm5_princ_t;
typedef char *kadm5_policy_t;
@@ -453,6 +454,21 @@ kadm5_ret_t kadm5_free_key_data(void *server_handle,
kadm5_ret_t kadm5_free_name_list(void *server_handle, char **names,
int count);
+kadm5_ret_t
+kadm5_get_adm_host_srv_names(krb5_context context,
+ const char *realm, char ***host_service_names);
+
+kadm5_ret_t
+kadm5_get_cpw_host_srv_names(krb5_context context,
+ const char *realm, char ***host_service_names);
+
+kadm5_ret_t
+kadm5_get_kiprop_host_srv_names(krb5_context context,
+ const char *realm, char ***host_service_names);
+
+void
+free_srv_names(char **srv_names);
+
krb5_error_code kadm5_init_krb5_context (krb5_context *);
krb5_error_code kadm5_init_iprop(void *server_handle, char **db_args);
--- a/src/lib/kadm5/alt_prof.c
+++ b/src/lib/kadm5/alt_prof.c
@@ -746,10 +746,17 @@ krb5_error_code kadm5_get_config_params(krb5_context context,
params.mask |= KADM5_CONFIG_IPROP_ENABLED;
params.iprop_enabled = params_in->iprop_enabled;
} else {
- if (aprofile &&
- !krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
- params.iprop_enabled = bvalue;
- params.mask |= KADM5_CONFIG_IPROP_ENABLED;
+ if (aprofile) {
+ if(!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
+ params.iprop_enabled = bvalue;
+ params.mask |= KADM5_CONFIG_IPROP_ENABLED;
+ } else {
+ hierarchy[2] = KRB5_CONF_SUNW_DBPROP_ENABLE;
+ if(!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)){
+ params.iprop_enabled = bvalue;
+ params.mask |= KADM5_CONFIG_IPROP_ENABLED;
+ }
+ }
}
}
@@ -778,18 +785,30 @@ krb5_error_code kadm5_get_config_params(krb5_context context,
params.mask |= KADM5_CONFIG_ULOG_SIZE;
params.iprop_ulogsize = params_in->iprop_ulogsize;
} else {
- if (aprofile != NULL &&
- !krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
- if (ivalue <= 0)
- params.iprop_ulogsize = DEF_ULOGENTRIES;
- else
- params.iprop_ulogsize = ivalue;
- params.mask |= KADM5_CONFIG_ULOG_SIZE;
+ if (aprofile != NULL) {
+ if (!krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
+ if (ivalue <= 0)
+ params.iprop_ulogsize = DEF_ULOGENTRIES;
+ else
+ params.iprop_ulogsize = ivalue;
+ params.mask |= KADM5_CONFIG_ULOG_SIZE;
+ } else {
+ hierarchy[2] = KRB5_CONF_SUNW_DBPROP_MASTER_ULOGSIZE;
+ if (!krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
+ if (ivalue <= 0)
+ params.iprop_ulogsize = DEF_ULOGENTRIES;
+ else
+ params.iprop_ulogsize = ivalue;
+ params.mask |= KADM5_CONFIG_ULOG_SIZE;
+ }
+ }
}
}
GET_DELTAT_PARAM(iprop_poll_time, KADM5_CONFIG_POLL_TIME,
- KRB5_CONF_IPROP_SLAVE_POLL, 2 * 60); /* 2m */
+ KRB5_CONF_SUNW_DBPROP_SLAVE_POLL, 2 * 60); /* 2m */
+ GET_DELTAT_PARAM(iprop_poll_time, KADM5_CONFIG_POLL_TIME,
+ KRB5_CONF_IPROP_SLAVE_POLL, params.iprop_poll_time);
*params_out = params;
--- a/src/lib/kadm5/clnt/Makefile.in
+++ b/src/lib/kadm5/clnt/Makefile.in
@@ -7,12 +7,11 @@ LIBMAJOR=10
LIBMINOR=0
STOBJLISTS=../OBJS.ST OBJS.ST
SHLIB_EXPDEPS=\
- $(TOPLIBD)/libgssrpc$(SHLIBEXT) \
$(TOPLIBD)/libgssapi_krb5$(SHLIBEXT) \
$(TOPLIBD)/libkrb5$(SHLIBEXT) \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
$(COM_ERR_DEPLIB) $(SUPPORT_LIBDEP)
-SHLIB_EXPLIBS=-lgssrpc -lgssapi_krb5 -lkrb5 -lk5crypto $(SUPPORT_LIB) -lcom_err $(LIBS)
+SHLIB_EXPLIBS= -lgssapi_krb5 -lkrb5 -lk5crypto $(SUPPORT_LIB) -lcom_err $(LIBS)
RELDIR=kadm5/clnt
##DOSBUILDTOP = ..\..\..
--- a/src/lib/kadm5/clnt/client_init.c
+++ b/src/lib/kadm5/clnt/client_init.c
@@ -44,12 +44,12 @@
#include <iprop_hdr.h>
#include "iprop.h"
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_krb5.h>
-#include <gssrpc/auth_gssapi.h>
#define ADM_CCACHE "/tmp/ovsec_adm.XXXXXX"
+#define KADMIND_CONNECT_TIMEOUT 25
enum init_type { INIT_PASS, INIT_SKEY, INIT_CREDS, INIT_ANONYMOUS };
@@ -138,9 +138,385 @@ kadm5_init_with_skey(krb5_context context, char *client_name,
server_handle);
}
+/*
+ * Open an fd for the given address and connect asynchronously. Wait
+ * KADMIND_CONNECT_TIMEOUT seconds or till it succeeds. If it succeeds
+ * change fd to blocking and return it, else return -1.
+ */
+static int
+get_connection(struct netconfig *nconf, struct netbuf netaddr)
+{
+ struct t_info tinfo;
+ struct t_call sndcall;
+ struct t_call *rcvcall = NULL;
+ int connect_time;
+ int flags;
+ int fd;
+
+ (void) memset(&tinfo, 0, sizeof (tinfo));
+
+ /* we'l open with O_NONBLOCK and avoid an fcntl */
+ fd = t_open(nconf->nc_device, O_RDWR | O_NONBLOCK, &tinfo);
+ if (fd == -1) {
+ return (-1);
+ }
+
+ if (t_bind(fd, (struct t_bind *)NULL, (struct t_bind *)NULL) == -1) {
+ (void) t_close(fd);
+ return (-1);
+ }
+
+ /* we can't connect unless fd is in IDLE state */
+ if (t_getstate(fd) != T_IDLE) {
+ (void) t_close(fd);
+ return (-1);
+ }
+
+ /* setup connect parameters */
+ netaddr.len = netaddr.maxlen = __rpc_get_a_size(tinfo.addr);
+ sndcall.addr = netaddr;
+ sndcall.opt.len = sndcall.udata.len = 0;
+
+ /* we wait for KADMIND_CONNECT_TIMEOUT seconds from now */
+ connect_time = time(NULL) + KADMIND_CONNECT_TIMEOUT;
+ if (t_connect(fd, &sndcall, rcvcall) != 0) {
+ if (t_errno != TNODATA) {
+ (void) t_close(fd);
+ return (-1);
+ }
+ }
+
+ /* loop till success or timeout */
+ for (;;) {
+ if (t_rcvconnect(fd, rcvcall) == 0)
+ break;
+
+ if (t_errno != TNODATA || time(NULL) > connect_time) {
+ /* we have either timed out or caught an error */
+ (void) t_close(fd);
+ if (rcvcall != NULL)
+ t_free((char *)rcvcall, T_CALL);
+ return (-1);
+ }
+ sleep(1);
+ }
+
+ /* make the fd blocking (synchronous) */
+ flags = fcntl(fd, F_GETFL, 0);
+ (void) fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ if (rcvcall != NULL)
+ t_free((char *)rcvcall, T_CALL);
+ return (fd);
+}
+
+/*
+ * Wrapper over clnt_tli_create.
+ * Opens a connection to host:port and calls clnt_tli_create.
+ * Returns a client handle or NULL on failure.
+ */
+static CLIENT*
+clnt_create_with_port(const char *host, int port,
+ const rpcprog_t prog, const rpcvers_t vers)
+{
+ struct netbuf netaddr;
+ struct hostent *hp;
+ int fd;
+ struct sockaddr_in addr;
+ struct sockaddr_in *sin;
+ struct netconfig *nconf;
+ void *handlep = NULL;
+ CLIENT *clnt = NULL;
+
+ hp = gethostbyname(host);
+ if (hp == (struct hostent *)NULL) {
+ goto cleanup;
+ }
+
+ memset(&addr, 0, sizeof (addr));
+ addr.sin_family = hp->h_addrtype;
+ (void) memcpy((char *)&addr.sin_addr, (char *)hp->h_addr,
+ sizeof (addr.sin_addr));
+ addr.sin_port = htons((ushort_t)port);
+ sin = &addr;
+ if ((handlep = setnetconfig()) == (void *) NULL) {
+ goto cleanup;
+ }
+
+ while (nconf = getnetconfig(handlep)) {
+ if ((nconf->nc_semantics == NC_TPI_COTS_ORD) &&
+ (strcmp(nconf->nc_protofmly, NC_INET) == 0) &&
+ (strcmp(nconf->nc_proto, NC_TCP) == 0))
+ break;
+ }
+
+ if (nconf == (struct netconfig *)NULL)
+ goto cleanup;
+
+ /* Transform addr to netbuf */
+ (void) memset(&netaddr, 0, sizeof (netaddr));
+ netaddr.buf = (char *)sin;
+
+ /* get an fd connected to the given address */
+ fd = get_connection(nconf, netaddr);
+ if (fd == -1) {
+ goto cleanup;
+ }
+
+ clnt = clnt_tli_create(fd, nconf, NULL, prog, vers, 0, 0);
+ if (clnt == NULL) {
+ clnt_pcreateerror("ERROR:");
+ (void) t_close(fd);
+ goto cleanup;
+ }
+ /*
+ * The rpc-handle was created on an fd opened and connected
+ * by us, so we have to explicitly tell rpc to close it.
+ */
+ if (clnt_control(clnt, CLSET_FD_CLOSE, NULL) != TRUE) {
+ clnt_destroy(clnt);
+ clnt = NULL;
+ (void) t_close(fd);
+ }
+
+cleanup:
+ if (handlep != (void *) NULL)
+ (void) endnetconfig(handlep);
+
+ return (clnt);
+}
+
+/*
+ * Open an RPCSEC_GSS connection and
+ * get a client handle to use for future RPCSEC calls.
+ *
+ * This function is only used when changing passwords and
+ * the kpasswd_protocol is RPCSEC_GSS
+ */
+static int
+_kadm5_initialize_rpcsec_gss_handle(kadm5_server_handle_t handle,
+ char *client_name,
+ char *service_name)
+{
+ int code = 0;
+ generic_ret *r;
+ char *ccname_orig = NULL;
+ char *iprop_svc;
+ boolean_t iprop_enable = B_FALSE;
+ char mech[] = "kerberos_v5";
+ gss_OID mech_oid;
+ gss_OID_set_desc oid_set;
+ gss_name_t gss_client;
+ gss_buffer_desc input_name;
+ gss_cred_id_t gss_client_creds = GSS_C_NO_CREDENTIAL;
+ rpc_gss_options_req_t options_req;
+ rpc_gss_options_ret_t options_ret;
+ rpc_gss_service_t service = rpc_gss_svc_privacy;
+ OM_uint32 gssstat, minor_stat;
+ enum clnt_stat rpc_err_code;
+ char *server;
+ int port;
+ struct timeval timeout;
+
+ /* service name is service/host */
+ server = strpbrk(service_name, "/");
+ if (!server) {
+ code = KADM5_BAD_SERVER_NAME;
+ goto cleanup;
+ }
+
+ /* but rpc_gss_secreate expects service@host */
+ *server++ = '@';
+
+ iprop_svc = strdup(KIPROP_SVC_NAME);
+ if (iprop_svc == NULL)
+ return (ENOMEM);
+
+ /*
+ * If the service_name and client_name are iprop-centric
+ * use iprop service; otherwise use kadmin service.
+ */
+ if ((strstr(service_name, iprop_svc) != NULL) &&
+ (strstr(client_name, iprop_svc) != NULL)) {
+ iprop_enable = B_TRUE;
+ }
+
+ /*
+ * iprop fallback logic:
+ * - if iprop_port is configured, connect to iprop_port
+ * - if not, query remote rpc/bind
+ * - if that fails, try consuming iprop service on kadmin port
+ */
+ if (iprop_enable && handle->params.iprop_port != 0){
+ port = handle->params.iprop_port;
+ handle->clnt = clnt_create_with_port(server, port,
+ KRB5_IPROP_PROG,
+ KRB5_IPROP_VERS);
+ } else if (iprop_enable && handle->params.iprop_port == 0) {
+ /* using remote rpc/bind first */
+ handle->clnt = clnt_create(server, KRB5_IPROP_PROG,
+ KRB5_IPROP_VERS, NC_TCP);
+ if (handle->clnt == NULL) {
+ /* possible rpc/bind failure, try kadmin port */
+ port = handle->params.kadmind_port;
+ handle->clnt = clnt_create_with_port(server, port,
+ KRB5_IPROP_PROG,
+ KRB5_IPROP_VERS);
+ }
+ } else {
+ /* kadmin service */
+ port = handle->params.kadmind_port;
+ handle->clnt = clnt_create_with_port(server, port,
+ KADM, KADMVERS);
+ }
+
+ if (handle->clnt == NULL) {
+ code = KADM5_RPC_ERROR;
+ goto error;
+ }
+
+ if (iprop_svc)
+ free(iprop_svc);
+
+ /* Set a one-hour timeout. */
+ timeout.tv_sec = 3600;
+ timeout.tv_usec = 0;
+ (void)clnt_control(handle->clnt, CLSET_TIMEOUT, (char *)&timeout);
+
+ handle->lhandle->clnt = handle->clnt;
+
+ /* now that handle->clnt is set, we can check the handle */
+ if (code = _kadm5_check_handle((void *) handle))
+ goto error;
+
+ /*
+ * The RPC connection is open; establish the GSS-API
+ * authentication context.
+ */
+ /* use the kadm5 cache */
+ gssstat = gss_krb5_ccache_name(&minor_stat, handle->cache_name,
+ (const char **)&ccname_orig);
+ if (gssstat != GSS_S_COMPLETE) {
+ code = KADM5_GSS_ERROR;
+ goto error;
+ }
+ if (ccname_orig)
+ ccname_orig = strdup(ccname_orig);
+
+ input_name.value = client_name;
+ input_name.length = strlen((char *)input_name.value) + 1;
+ gssstat = gss_import_name(&minor_stat, &input_name,
+ (gss_OID)gss_nt_krb5_name, &gss_client);
+ if (gssstat != GSS_S_COMPLETE) {
+ code = KADM5_GSS_ERROR;
+ goto error;
+ }
+
+ if (!rpc_gss_mech_to_oid(mech, (rpc_gss_OID *)&mech_oid)) {
+ goto error;
+ }
+
+ oid_set.count = 1;
+ oid_set.elements = mech_oid;
+
+ gssstat = gss_acquire_cred(&minor_stat, gss_client, 0,
+ &oid_set, GSS_C_INITIATE,
+ &gss_client_creds, NULL, NULL);
+ (void) gss_release_name(&minor_stat, &gss_client);
+ if (gssstat != GSS_S_COMPLETE) {
+ code = KADM5_GSS_ERROR;
+ goto error;
+ }
+ options_req.my_cred = gss_client_creds;
+ options_req.req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+ options_req.time_req = 0;
+ options_req.input_channel_bindings = NULL;
+#ifndef INIT_TEST
+ handle->clnt->cl_auth = rpc_gss_seccreate(handle->clnt,
+ service_name,
+ mech,
+ service,
+ NULL,
+ &options_req,
+ &options_ret);
+#endif /* ! INIT_TEST */
+
+ if (ccname_orig) {
+ gssstat = gss_krb5_ccache_name(&minor_stat, ccname_orig, NULL);
+ free(ccname_orig);
+ if (gssstat != GSS_S_COMPLETE) {
+ code = KADM5_GSS_ERROR;
+ goto error;
+ }
+ } else {
+ gssstat = gss_krb5_ccache_name(&minor_stat, NULL, NULL);
+ if (gssstat != GSS_S_COMPLETE) {
+ code = KADM5_GSS_ERROR;
+ goto error;
+ }
+ }
+
+ if (handle->clnt->cl_auth == NULL) {
+ code = KADM5_GSS_ERROR;
+ goto error;
+ }
+
+ /*
+ * Bypass the remainder of the code and return straightaway
+ * if the gss service requested is kiprop
+ */
+ if (iprop_enable == B_TRUE) {
+ code = 0;
+ goto cleanup;
+ }
+
+ r = init_2(&handle->api_version, handle->clnt);
+ if (r == NULL) {
+ code = KADM5_RPC_ERROR;
+ goto error;
+ }
+
+ /* Drop down to v3 wire protocol if server does not support v4 */
+ if (r->code == KADM5_NEW_SERVER_API_VERSION &&
+ handle->api_version == KADM5_API_VERSION_4) {
+ handle->api_version = KADM5_API_VERSION_3;
+ r = init_2(&handle->api_version, handle->clnt);
+ if (r == NULL) {
+ code = KADM5_RPC_ERROR;
+ goto error;
+ }
+ }
+
+ /* Drop down to v2 wire protocol if server does not support v3 */
+ if (r->code == KADM5_NEW_SERVER_API_VERSION &&
+ handle->api_version == KADM5_API_VERSION_3) {
+ handle->api_version = KADM5_API_VERSION_2;
+ r = init_2(&handle->api_version, handle->clnt);
+ if (r == NULL) {
+ code = KADM5_RPC_ERROR;
+ goto error;
+ }
+ }
+
+ if (r->code) {
+ code = r->code;
+ goto error;
+ }
+error:
+cleanup:
+ /*
+ * gss_client_creds is freed only when there is an error condition,
+ * given that rpc_gss_seccreate() will assign the cred pointer to the
+ * my_cred member in the auth handle's private data structure.
+ */
+ if (code && (gss_client_creds != GSS_C_NO_CREDENTIAL))
+ (void) gss_release_cred(&minor_stat, &gss_client_creds);
+
+ return (code);
+}
+
static kadm5_ret_t
init_any(krb5_context context, char *client_name, enum init_type init_type,
- char *pass, krb5_ccache ccache_in, char *service_name,
+ char *pass, krb5_ccache ccache_in, char *svcname_in,
kadm5_config_params *params_in, krb5_ui_4 struct_version,
krb5_ui_4 api_version, char **db_args, void **server_handle)
{
@@ -152,13 +528,13 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
rpcvers_t rpc_vers;
krb5_ccache ccache;
krb5_principal client = NULL, server = NULL;
- struct timeval timeout;
kadm5_server_handle_t handle;
kadm5_config_params params_local;
int code = 0;
generic_ret *r;
+ char svcname[BUFSIZ];
initialize_ovk_error_table();
/* initialize_adb_error_table(); */
@@ -226,105 +602,27 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
if (code)
goto error;
- /*
- * Get credentials. Also does some fallbacks in case kadmin/fqdn
- * principal doesn't exist.
- */
+ /* NULL svcname means use host-based. */
+ if (svcname_in == NULL) {
+ code = kadm5_get_admin_service_name(handle->context,
+ handle->params.realm,
+ svcname, sizeof(svcname));
+ if (code)
+ goto error;
+ } else {
+ strncpy(svcname, svcname_in, sizeof(svcname));
+ svcname[sizeof(svcname)-1] = '\0';
+ }
+
+ /* Get credentials. */
code = get_init_creds(handle, client, init_type, pass, ccache_in,
- service_name, handle->params.realm, &server);
+ svcname, handle->params.realm, &server);
if (code)
goto error;
- /* If the service_name and client_name are iprop-centric, use the iprop
- * port and RPC identifiers. */
- iprop_enable = (service_name != NULL &&
- strstr(service_name, KIPROP_SVC_NAME) != NULL &&
- strstr(client_name, KIPROP_SVC_NAME) != NULL);
- if (iprop_enable) {
- port = handle->params.iprop_port;
- rpc_prog = KRB5_IPROP_PROG;
- rpc_vers = KRB5_IPROP_VERS;
- } else {
- port = handle->params.kadmind_port;
- rpc_prog = KADM;
- rpc_vers = KADMVERS;
- }
-
- code = connect_to_server(handle->params.admin_server, port, &fd);
- if (code)
- goto error;
-
- handle->clnt = clnttcp_create(NULL, rpc_prog, rpc_vers, &fd, 0, 0);
- if (handle->clnt == NULL) {
- code = KADM5_RPC_ERROR;
-#ifdef DEBUG
- clnt_pcreateerror("clnttcp_create");
-#endif
- goto error;
- }
-
- /* Set a one-hour timeout. */
- timeout.tv_sec = 3600;
- timeout.tv_usec = 0;
- (void)clnt_control(handle->clnt, CLSET_TIMEOUT, &timeout);
-
- handle->client_socket = fd;
- handle->lhandle->clnt = handle->clnt;
- handle->lhandle->client_socket = fd;
-
- /* now that handle->clnt is set, we can check the handle */
- if ((code = _kadm5_check_handle((void *) handle)))
- goto error;
-
- /*
- * The RPC connection is open; establish the GSS-API
- * authentication context.
- */
- code = setup_gss(handle, params_in,
- (init_type == INIT_CREDS) ? client : NULL, server);
- if (code)
- goto error;
-
- /*
- * Bypass the remainder of the code and return straightaway
- * if the gss service requested is kiprop
- */
- if (iprop_enable) {
- code = 0;
- *server_handle = (void *) handle;
- goto cleanup;
- }
-
- r = init_2(&handle->api_version, handle->clnt);
- if (r == NULL) {
- code = KADM5_RPC_ERROR;
-#ifdef DEBUG
- clnt_perror(handle->clnt, "init_2 null resp");
-#endif
- goto error;
- }
- /* Drop down to v3 wire protocol if server does not support v4 */
- if (r->code == KADM5_NEW_SERVER_API_VERSION &&
- handle->api_version == KADM5_API_VERSION_4) {
- handle->api_version = KADM5_API_VERSION_3;
- r = init_2(&handle->api_version, handle->clnt);
- if (r == NULL) {
- code = KADM5_RPC_ERROR;
- goto error;
- }
- }
- /* Drop down to v2 wire protocol if server does not support v3 */
- if (r->code == KADM5_NEW_SERVER_API_VERSION &&
- handle->api_version == KADM5_API_VERSION_3) {
- handle->api_version = KADM5_API_VERSION_2;
- r = init_2(&handle->api_version, handle->clnt);
- if (r == NULL) {
- code = KADM5_RPC_ERROR;
- goto error;
- }
- }
- if (r->code) {
- code = r->code;
+ code = _kadm5_initialize_rpcsec_gss_handle(handle, client_name,
+ svcname);
+ if (code != 0) {
goto error;
}
@@ -364,31 +662,17 @@ cleanup:
return code;
}
-/* Get initial credentials for authenticating to server. Perform fallback from
- * kadmin/fqdn to kadmin/admin if svcname_in is NULL. */
+/* Get initial credentials for authenticating to server. */
static kadm5_ret_t
get_init_creds(kadm5_server_handle_t handle, krb5_principal client,
enum init_type init_type, char *pass, krb5_ccache ccache_in,
- char *svcname_in, char *realm, krb5_principal *server_out)
+ char *svcname, char *realm, krb5_principal *server_out)
{
kadm5_ret_t code;
krb5_ccache ccache = NULL;
- char svcname[BUFSIZ];
*server_out = NULL;
- /* NULL svcname means use host-based. */
- if (svcname_in == NULL) {
- code = kadm5_get_admin_service_name(handle->context,
- handle->params.realm,
- svcname, sizeof(svcname));
- if (code)
- goto error;
- } else {
- strncpy(svcname, svcname_in, sizeof(svcname));
- svcname[sizeof(svcname)-1] = '\0';
- }
-
/*
* Acquire a service ticket for svcname@realm for client, using password
* pass (which could be NULL), and create a ccache to store them in. If
@@ -426,12 +710,6 @@ get_init_creds(kadm5_server_handle_t handle, krb5_principal client,
code = gic_iter(handle, init_type, ccache, client, pass, svcname, realm,
server_out);
- if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
- || code == KRB5_CC_NOTFOUND) && svcname_in == NULL) {
- /* Retry with old host-independent service principal. */
- code = gic_iter(handle, init_type, ccache, client, pass,
- KADM5_ADMIN_SERVICE, realm, server_out);
- }
/* Improved error messages */
if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) code = KADM5_BAD_PASSWORD;
if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
@@ -698,6 +976,26 @@ rpc_auth(kadm5_server_handle_t handle, kadm5_config_params *params_in,
gss_cred_id_t gss_client_creds, gss_name_t gss_target)
{
OM_uint32 gssstat, minor_stat;
+ gss_buffer_desc buf;
+ rpc_gss_options_req_t options_req;
+ rpc_gss_options_ret_t options_ret;
+
+ if (gss_display_name(&minor_stat, gss_target, &buf, NULL) != GSS_S_COMPLETE)
+ return;
+
+ options_req.my_cred = gss_client_creds;
+ options_req.req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+ options_req.time_req = 0;
+ options_req.input_channel_bindings = NULL;
+ handle->clnt->cl_auth = rpc_gss_seccreate(handle->clnt,
+ (char*) buf.value,
+ "kerberos_v5",
+ rpc_gss_svc_privacy,
+ NULL,
+ &options_req,
+ &options_ret);
+
+#if 0
struct rpc_gss_sec sec;
/* Allow unauthenticated option for testing. */
@@ -732,6 +1030,7 @@ rpc_auth(kadm5_server_handle_t handle, kadm5_config_params *params_in,
GSS_C_MUTUAL_FLAG
| GSS_C_REPLAY_FLAG,
0, NULL, NULL, NULL);
+#endif
}
kadm5_ret_t
--- a/src/lib/kadm5/clnt/client_principal.c
+++ b/src/lib/kadm5/clnt/client_principal.c
@@ -5,7 +5,7 @@
* $Header$
*/
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#ifdef HAVE_MEMORY_H
--- a/src/lib/kadm5/clnt/client_rpc.c
+++ b/src/lib/kadm5/clnt/client_rpc.c
@@ -1,5 +1,5 @@
/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <kadm5/kadm_rpc.h>
#include <krb5.h>
#include <kadm5/admin.h>
--- a/src/lib/kadm5/clnt/clnt_policy.c
+++ b/src/lib/kadm5/clnt/clnt_policy.c
@@ -5,7 +5,7 @@
* $Header$
*/
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include "client_internal.h"
--- a/src/lib/kadm5/clnt/clnt_privs.c
+++ b/src/lib/kadm5/clnt/clnt_privs.c
@@ -7,7 +7,7 @@
*
*/
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <kadm5/admin.h>
#include <kadm5/kadm_rpc.h>
#include "client_internal.h"
--- a/src/lib/kadm5/deps
+++ b/src/lib/kadm5/deps
@@ -90,6 +90,20 @@ str_conv.so str_conv.po $(OUTPRE)str_conv.$(OBJEXT): \
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
$(top_srcdir)/include/socket-utils.h admin_internal.h \
str_conv.c
+kadm_host_srv_names.so kadm_host_srv_names.po $(OUTPRE)kadm_host_srv_names.$(OBJEXT): \
+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb5/os/os-proto.h \
+ $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \
+ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h admin.h kadm_host_srv_names.c
logger.so logger.po $(OUTPRE)logger.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/adm_proto.h \
--- a/src/lib/kadm5/kadm_rpc.h
+++ b/src/lib/kadm5/kadm_rpc.h
@@ -2,7 +2,7 @@
#ifndef __KADM_RPC_H__
#define __KADM_RPC_H__
-#include <gssrpc/types.h>
+#include <rpc/types.h>
#include <krb5.h>
#include <kadm5/admin.h>
@@ -345,5 +345,8 @@ extern bool_t xdr_gstrings_ret ();
extern bool_t xdr_sstring_arg ();
extern bool_t xdr_krb5_string_attr ();
+/* Solaris libc doesn't define 32 bit version of xdr_int and xdr_u_int */
+#define xdr_int32 xdr_int
+#define xdr_u_int32 xdr_u_int
#endif /* __KADM_RPC_H__ */
--- a/src/lib/kadm5/kadm_rpc_xdr.c
+++ b/src/lib/kadm5/kadm_rpc_xdr.c
@@ -3,7 +3,7 @@
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*/
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <krb5.h>
#include <errno.h>
#include <kadm5/admin.h>
--- a/src/lib/kadm5/server_internal.h
+++ b/src/lib/kadm5/server_internal.h
@@ -264,4 +264,8 @@ k5_kadm5_hook_rename (krb5_context context,
/** @}*/
+/* Solaris Kerberos: symbols available in libkadm5srv_mit */
+extern void xdralloc_create(XDR *xdrs, enum xdr_op op);
+extern caddr_t xdralloc_getdata(XDR *xdrs);
+
#endif /* __KADM5_SERVER_INTERNAL_H__ */
--- a/src/lib/kadm5/srv/Makefile.in
+++ b/src/lib/kadm5/srv/Makefile.in
@@ -14,13 +14,12 @@ LIBMINOR=0
STOBJLISTS=../OBJS.ST OBJS.ST
SHLIB_EXPDEPS=\
- $(TOPLIBD)/libgssrpc$(SHLIBEXT) \
$(TOPLIBD)/libgssapi_krb5$(SHLIBEXT) \
$(TOPLIBD)/libkdb5$(SHLIBEXT) \
$(TOPLIBD)/libkrb5$(SHLIBEXT) \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
$(COM_ERR_DEPLIB) $(SUPPORT_LIBDEP)
-SHLIB_EXPLIBS = -lgssrpc -lgssapi_krb5 -lkdb5 $(KDB5_DB_LIB) \
+SHLIB_EXPLIBS = -lgssapi_krb5 -lkdb5 $(KDB5_DB_LIB) \
-lkrb5 -lk5crypto $(SUPPORT_LIB) -lcom_err @GEN_LIB@ $(LIBS)
RELDIR=kadm5/srv
@@ -38,6 +37,8 @@ SRCS = $(srcdir)/pwqual.c \
$(srcdir)/server_init.c \
$(srcdir)/svr_iters.c \
$(srcdir)/svr_chpass_util.c \
+ $(srcdir)/xdr_alloc.c \
+ $(srcdir)/dyn.c \
$(srcdir)/adb_xdr.c
OBJS = pwqual.$(OBJEXT) \
@@ -54,6 +55,8 @@ OBJS = pwqual.$(OBJEXT) \
server_init.$(OBJEXT) \
svr_iters.$(OBJEXT) \
svr_chpass_util.$(OBJEXT) \
+ xdr_alloc.$(OBJEXT) \
+ dyn.$(OBJEXT) \
adb_xdr.$(OBJEXT)
STLIBOBJS = \
@@ -71,6 +74,8 @@ STLIBOBJS = \
server_init.o \
svr_iters.o \
svr_chpass_util.o \
+ xdr_alloc.o \
+ dyn.o \
adb_xdr.o
all-unix:: includes
--- a/src/lib/kadm5/srv/adb_xdr.c
+++ b/src/lib/kadm5/srv/adb_xdr.c
@@ -7,7 +7,7 @@
#include <sys/types.h>
#include <krb5.h>
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include "server_internal.h"
#include "admin_xdr.h"
#ifdef HAVE_MEMORY_H
--- a/src/lib/kadm5/srv/server_init.c
+++ b/src/lib/kadm5/srv/server_init.c
@@ -233,8 +233,7 @@ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
#define IPROP_REQUIRED_PARAMS \
(KADM5_CONFIG_IPROP_ENABLED | \
- KADM5_CONFIG_IPROP_LOGFILE | \
- KADM5_CONFIG_IPROP_PORT)
+ KADM5_CONFIG_IPROP_LOGFILE)
if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
kadm5_free_config_params(handle->context, &handle->params);
--- a/src/lib/kdb/Makefile.in
+++ b/src/lib/kdb/Makefile.in
@@ -14,9 +14,8 @@ RELDIR=kdb
SHLIB_EXPDEPS = \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
- $(TOPLIBD)/libgssrpc$(SHLIBEXT) \
$(TOPLIBD)/libkrb5$(SHLIBEXT)
-SHLIB_EXPLIBS=-lgssrpc -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB) $(DL_LIB) $(LIBS)
+SHLIB_EXPLIBS= -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB) $(DL_LIB) $(LIBS)
adb_err.$(OBJEXT): adb_err.c
adb_err.c adb_err.h: $(srcdir)/adb_err.et
--- a/src/lib/kdb/iprop_xdr.c
+++ b/src/lib/kdb/iprop_xdr.c
@@ -9,6 +9,7 @@
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
+#if 0
static bool_t
xdr_int16_t (XDR *xdrs, int16_t *objp)
{
@@ -38,6 +39,7 @@ xdr_uint32_t (XDR *xdrs, uint32_t *objp)
return FALSE;
return TRUE;
}
+#endif
bool_t
xdr_utf8str_t (XDR *xdrs, utf8str_t *objp)
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -57,7 +57,7 @@ struct sendto_callback_context {
* Wrapper function for the two backends
*/
-static krb5_error_code
+krb5_error_code
locate_kpasswd(krb5_context context, const krb5_data *realm,
struct serverlist *serverlist, krb5_boolean no_udp)
{
--- a/src/lib/krb5/os/locate_kdc.c
+++ b/src/lib/krb5/os/locate_kdc.c
@@ -675,6 +675,14 @@ k5_locate_kdc(krb5_context context, const krb5_data *realm,
return k5_locate_server(context, realm, serverlist, stype, no_udp);
}
+krb5_error_code
+k5_locate_kadmin(krb5_context context, const krb5_data *realm,
+ struct serverlist *serverlist)
+{
+ return k5_locate_server(context, realm, serverlist, locate_service_kadmin,
+ 1);
+}
+
krb5_boolean
k5_kdc_is_master(krb5_context context, const krb5_data *realm,
struct server_entry *server)
--- a/src/lib/rpc/xdr_alloc.c
+++ b/src/lib/rpc/xdr_alloc.c
@@ -35,18 +35,23 @@
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
*/
-#include <gssrpc/types.h>
-#include <gssrpc/xdr.h>
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <inttypes.h>
#include "dyn.h"
static bool_t xdralloc_putlong(XDR *, long *);
-static bool_t xdralloc_putbytes(XDR *, caddr_t, unsigned int);
+static bool_t xdralloc_putbytes(XDR *, caddr_t, int);
static unsigned int xdralloc_getpos(XDR *);
static rpc_inline_t * xdralloc_inline(XDR *, int);
static void xdralloc_destroy(XDR *);
+static bool_t xdralloc_putint32(XDR *, int32_t *);
static bool_t xdralloc_notsup_getlong(XDR *, long *);
-static bool_t xdralloc_notsup_getbytes(XDR *, caddr_t, unsigned int);
+static bool_t xdralloc_notsup_getbytes(XDR *, caddr_t, int);
static bool_t xdralloc_notsup_setpos(XDR *, unsigned int);
+static bool_t xdralloc_notsup_getint32(XDR *, int32_t *);
+static bool_t xdralloc_notsup_control(XDR *, int, void *);
static struct xdr_ops xdralloc_ops = {
xdralloc_notsup_getlong,
xdralloc_putlong,
@@ -56,6 +61,11 @@ static struct xdr_ops xdralloc_ops = {
xdralloc_notsup_setpos,
xdralloc_inline,
xdralloc_destroy,
+ xdralloc_notsup_control,
+#if defined(_LP64)
+ xdralloc_notsup_getint32,
+ xdralloc_putint32,
+#endif
};
/*
@@ -96,7 +106,12 @@ static bool_t xdralloc_putlong(
register XDR *xdrs,
long *lp)
{
- int l = htonl((uint32_t) *lp); /* XXX need bounds checking */
+#if defined(_LP64)
+ if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
+ return FALSE;
+#endif
+
+ int l = htonl((uint32_t) *lp);
/* XXX assumes sizeof(int)==4 */
if (DynInsert((DynObject) xdrs->x_private,
@@ -106,11 +121,33 @@ static bool_t xdralloc_putlong(
return (TRUE);
}
+#if defined(_LP64)
+static bool_t xdralloc_notsup_getint32(
+ register XDR *xdrs,
+ int32_t *lp)
+{
+ return FALSE;
+}
+
+static bool_t xdralloc_putint32(
+ register XDR *xdrs,
+ int32_t *lp)
+{
+ int l = htonl((uint32_t) *lp);
+
+ /* XXX assumes sizeof(int)==4 */
+ if (DynInsert((DynObject) xdrs->x_private,
+ DynSize((DynObject) xdrs->x_private), &l,
+ sizeof(int)) != DYN_OK)
+ return FALSE;
+ return (TRUE);
+}
+#endif
static bool_t xdralloc_notsup_getbytes(
register XDR *xdrs,
caddr_t addr,
- register unsigned int len)
+ register int len)
{
return FALSE;
}
@@ -119,7 +156,7 @@ static bool_t xdralloc_notsup_getbytes(
static bool_t xdralloc_putbytes(
register XDR *xdrs,
caddr_t addr,
- register unsigned int len)
+ register int len)
{
if (DynInsert((DynObject) xdrs->x_private,
DynSize((DynObject) xdrs->x_private),
@@ -148,3 +185,10 @@ static rpc_inline_t *xdralloc_inline(
{
return (rpc_inline_t *) 0;
}
+
+static bool_t xdralloc_notsup_control(XDR *xdrs,
+ int request,
+ void *info)
+{
+ return FALSE;
+}
--- a/src/plugins/kdb/db2/adb_policy.c
+++ b/src/plugins/kdb/db2/adb_policy.c
@@ -28,6 +28,9 @@
return cl_ret; \
}
+/* Solaris Kerberos: symbols available from libkadm5srv_mit */
+extern void xdralloc_create(XDR *, enum xdr_op);
+extern caddr_t xdralloc_getdata(XDR *);
/*
* Function: osa_adb_create_policy
--- a/src/plugins/kdb/db2/pol_xdr.c
+++ b/src/plugins/kdb/db2/pol_xdr.c
@@ -1,6 +1,6 @@
#include <sys/types.h>
#include <krb5.h>
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#include <kdb.h>
#include <kadm5/admin_xdr.h>
#include "policy_db.h"
--- a/src/plugins/kdb/db2/policy_db.h
+++ b/src/plugins/kdb/db2/policy_db.h
@@ -28,8 +28,8 @@
A better fix might be for db.h to include netinet/in.h if that's
where we find u_int32_t. */
-#include <gssrpc/types.h>
-#include <gssrpc/xdr.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
#include <db.h>
#include "adb_err.h"
#include <com_err.h>
--- a/src/plugins/kdb/ldap/libkdb_ldap/princ_xdr.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/princ_xdr.c
@@ -3,6 +3,10 @@
#include "princ_xdr.h"
#include <kadm5/admin.h>
+/* Solaris Kerberos: symbols available from libkadm5srv_mit*/
+extern void xdralloc_create(XDR *, enum xdr_op);
+extern caddr_t xdralloc_getdata(XDR *);
+
bool_t
ldap_xdr_krb5_ui_2(XDR *xdrs, krb5_ui_2 *objp)
{
--- a/src/plugins/kdb/ldap/libkdb_ldap/princ_xdr.h
+++ b/src/plugins/kdb/ldap/libkdb_ldap/princ_xdr.h
@@ -4,7 +4,7 @@
#include <sys/types.h>
#include <krb5.h>
#include <kdb.h>
-#include <gssrpc/rpc.h>
+#include <rpc/rpc.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
--- a/src/slave/kpropd.c
+++ b/src/slave/kpropd.c
@@ -588,12 +588,12 @@ full_resync(CLIENT *clnt)
memset(&clnt_res, 0, sizeof(clnt_res));
- status = clnt_call(clnt, IPROP_FULL_RESYNC_EXT, (xdrproc_t)xdr_u_int32,
+ status = clnt_call(clnt, IPROP_FULL_RESYNC_EXT, (xdrproc_t)xdr_u_int,
(caddr_t)&vers, (xdrproc_t)xdr_kdb_fullresync_result_t,
(caddr_t)&clnt_res, full_resync_timeout);
if (status == RPC_PROCUNAVAIL) {
status = clnt_call(clnt, IPROP_FULL_RESYNC, (xdrproc_t)xdr_void,
- (caddr_t *)&vers,
+ (caddr_t)&vers,
(xdrproc_t)xdr_kdb_fullresync_result_t,
(caddr_t)&clnt_res, full_resync_timeout);
}
--- a/src/tests/misc/Makefile.in
+++ b/src/tests/misc/Makefile.in
@@ -12,18 +12,16 @@ SRCS=\
$(srcdir)/test_cxx_krb5.cpp \
$(srcdir)/test_cxx_k5int.cpp \
$(srcdir)/test_cxx_gss.cpp \
- $(srcdir)/test_cxx_rpc.cpp \
$(srcdir)/test_cxx_kadm5.cpp
all:: test_getpw test_chpw_message
-check:: test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_rpc test_cxx_k5int test_cxx_kadm5
+check:: test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_k5int test_cxx_kadm5
$(RUN_TEST) ./test_getpw
$(RUN_TEST) ./test_chpw_message
$(RUN_TEST) ./test_cxx_krb5
$(RUN_TEST) ./test_cxx_k5int
$(RUN_TEST) ./test_cxx_gss
- $(RUN_TEST) ./test_cxx_rpc
$(RUN_TEST) ./test_cxx_kadm5
test_getpw: $(OUTPRE)test_getpw.$(OBJEXT) $(SUPPORT_DEPLIB)
@@ -41,18 +39,15 @@ test_cxx_k5int: $(OUTPRE)test_cxx_k5int.$(OBJEXT) $(KRB5_DEPLIB)
$(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_k5int $(OUTPRE)test_cxx_k5int.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS)
test_cxx_gss: $(OUTPRE)test_cxx_gss.$(OBJEXT)
$(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_gss $(OUTPRE)test_cxx_gss.$(OBJEXT) $(LIBS)
-test_cxx_rpc: $(OUTPRE)test_cxx_rpc.$(OBJEXT) $(GSSRPC_DEPLIBS)
- $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_rpc $(OUTPRE)test_cxx_rpc.$(OBJEXT) $(GSSRPC_LIBS) $(KRB5_BASE_LIBS) $(LIBS)
test_cxx_kadm5: $(OUTPRE)test_cxx_kadm5.$(OBJEXT) $(KADMCLNT_DEPLIBS)
$(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_kadm5 $(OUTPRE)test_cxx_kadm5.$(OBJEXT) $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) $(LIBS)
test_cxx_krb5.$(OBJEXT): test_cxx_krb5.cpp
test_cxx_gss.$(OBJEXT): test_cxx_gss.cpp
-test_cxx_rpc.$(OBJEXT): test_cxx_rpc.cpp
test_cxx_kadm5.$(OBJEXT): test_cxx_kadm5.cpp
install::
clean::
- $(RM) test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_k5int test_cxx_rpc test_cxx_kadm5 *.o
+ $(RM) test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_k5int test_cxx_kadm5 *.o
--- a/src/tests/t_ccache.py
+++ b/src/tests/t_ccache.py
@@ -51,7 +51,7 @@ realm.kinit(realm.user_princ, password('user'))
realm.run([klist, '-s'])
realm.kinit(realm.user_princ, password('user'), ['-l', '-1s'])
realm.run([klist, '-s'], expected_code=1)
-realm.kinit(realm.user_princ, password('user'), ['-S', 'kadmin/admin'])
+realm.kinit(realm.user_princ, password('user'), ['-S', 'kadmin/changepw'])
realm.run([klist, '-s'])
realm.run([kdestroy])
realm.run([klist, '-s'], expected_code=1)
--- a/src/tests/t_iprop.py
+++ b/src/tests/t_iprop.py
@@ -109,8 +109,8 @@ def check_ulog(num, first, last, entries
if eprinc != None:
fail('Expected princ %s in update entry %d' % (eprinc, ser))
-# slave1 will receive updates from master, and slave2 will receive
-# updates from slave1. Because of the awkward way iprop and kprop
+# slave1 will receive updates from master.
+# Because of the awkward way iprop and kprop
# port configuration currently works, we need separate config files
# for the slave and master sides of slave1, but they use the same DB
# and ulog file.
@@ -119,18 +119,9 @@ conf = {'realms': {'$realm': {'iprop_ena
conf_slave1 = {'realms': {'$realm': {'iprop_slave_poll': '600',
'iprop_logfile': '$testdir/ulog.slave1'}},
'dbmodules': {'db': {'database_name': '$testdir/db.slave1'}}}
-conf_slave1m = {'realms': {'$realm': {'iprop_logfile': '$testdir/ulog.slave1',
- 'iprop_port': '$port8'}},
- 'dbmodules': {'db': {'database_name': '$testdir/db.slave1'}}}
-conf_slave2 = {'realms': {'$realm': {'iprop_slave_poll': '600',
- 'iprop_logfile': '$testdir/ulog.slave2',
- 'iprop_port': '$port8'}},
- 'dbmodules': {'db': {'database_name': '$testdir/db.slave2'}}}
realm = K5Realm(kdc_conf=conf, create_user=False, start_kadmind=True)
slave1 = realm.special_env('slave1', True, kdc_conf=conf_slave1)
-slave1m = realm.special_env('slave1m', True, kdc_conf=conf_slave1m)
-slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2)
# Define some principal names. pr3 is long enough to cause internal
# reallocs, but not long enough to grow the basic ulog entry size.
@@ -155,11 +146,10 @@ if not os.path.exists(ulog):
kiprop_princ = 'kiprop/' + hostname
realm.extract_keytab(kiprop_princ, realm.keytab)
-# Create the initial slave1 and slave2 databases.
+# Create the initial slave1 databases.
dumpfile = os.path.join(realm.testdir, 'dump')
realm.run([kdb5_util, 'dump', dumpfile])
realm.run([kdb5_util, 'load', dumpfile], slave1)
-realm.run([kdb5_util, 'load', dumpfile], slave2)
# Reinitialize the master ulog so we know exactly what to expect in
# it.
@@ -192,31 +182,10 @@ out = realm.run([kadminl, 'getprinc', pr
if 'Attributes: DISALLOW_ALL_TIX' not in out:
fail('slave1 does not have modification from master')
-# Start kadmind -proponly for slave1. (Use the slave1m environment
-# which defines iprop_port to $port8.)
+# Start kadmind -proponly for slave1.
slave1_out_dump_path = os.path.join(realm.testdir, 'dump.slave1.out')
-slave2_in_dump_path = os.path.join(realm.testdir, 'dump.slave2.in')
-slave2_kprop_port = str(realm.portbase + 9)
-slave1m['KPROP_PORT'] = slave2_kprop_port
-realm.start_server([kadmind, '-nofork', '-proponly', '-W', '-p', kdb5_util,
- '-K', kprop, '-F', slave1_out_dump_path], 'starting...',
- slave1m)
-
-# Start kpropd for slave2. The -A option isn't needed since we're
-# talking to the same host as master (we specify it anyway to exercise
-# the code), but slave2 defines iprop_port to $port8 so it will talk
-# to slave1. Get a full dump from slave1.
-kpropd2 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port,
- '-f', slave2_in_dump_path, '-p', kdb5_util,
- '-a', acl_file, '-A', hostname], 'ready', slave2)
-wait_for_prop(kpropd2, True, 1, 7)
-check_ulog(1, 7, 7, [None], slave2)
-out = realm.run([kadminl, 'listprincs'], env=slave1)
-if pr1 not in out or pr2 not in out or pr3 not in out:
- fail('slave2 does not have all principals from slave1')
-# Make another change and check that it propagates incrementally to
-# both slaves.
+# Make another change and check that it propagates incrementally to slave1.
realm.run([kadminl, 'modprinc', '-maxrenewlife', '22 hours', pr1])
check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1])
kpropd1.send_signal(signal.SIGUSR1)
@@ -225,28 +194,16 @@ check_ulog(3, 6, 8, [None, pr2, pr1], sl
out = realm.run([kadminl, 'getprinc', pr1], env=slave1)
if 'Maximum renewable life: 0 days 22:00:00\n' not in out:
fail('slave1 does not have modification from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 7, 8)
-check_ulog(2, 7, 8, [None, pr1], slave2)
-out = realm.run([kadminl, 'getprinc', pr1], env=slave2)
-if 'Maximum renewable life: 0 days 22:00:00\n' not in out:
- fail('slave2 does not have modification from slave1')
# Reset the ulog on slave1 to force a full resync from master. The
# resync will use the old dump file and then propagate changes.
-# slave2 should still be in sync with slave1 after the resync, so make
-# sure it doesn't take a full resync.
realm.run([kproplog, '-R'], slave1)
check_ulog(1, 1, 1, [None], slave1)
kpropd1.send_signal(signal.SIGUSR1)
wait_for_prop(kpropd1, True, 1, 8)
check_ulog(3, 6, 8, [None, pr2, pr1], slave1)
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 8, 8)
-check_ulog(2, 7, 8, [None, pr1], slave2)
-# Make another change and check that it propagates incrementally to
-# both slaves.
+# Make another change and check that it propagates incrementally to slave1.
realm.run([kadminl, 'modprinc', '+allow_tix', 'w'])
check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr2])
kpropd1.send_signal(signal.SIGUSR1)
@@ -255,12 +212,6 @@ check_ulog(4, 6, 9, [None, pr2, pr1, pr2
out = realm.run([kadminl, 'getprinc', pr2], env=slave1)
if 'Attributes:\n' not in out:
fail('slave1 does not have modification from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 8, 9)
-check_ulog(3, 7, 9, [None, pr1, pr2], slave2)
-out = realm.run([kadminl, 'getprinc', pr2], env=slave2)
-if 'Attributes:\n' not in out:
- fail('slave2 does not have modification from slave1')
# Create a policy and check that it propagates via full resync.
realm.run([kadminl, 'addpol', '-minclasses', '2', 'testpol'])
@@ -271,12 +222,6 @@ check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1)
if 'Minimum number of password character classes: 2' not in out:
fail('slave1 does not have policy from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 9, 1)
-check_ulog(1, 1, 1, [None], slave2)
-out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2)
-if 'Minimum number of password character classes: 2' not in out:
- fail('slave2 does not have policy from slave1')
# Modify the policy and test that it also propagates via full resync.
realm.run([kadminl, 'modpol', '-minlength', '17', 'testpol'])
@@ -287,12 +232,6 @@ check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1)
if 'Minimum password length: 17' not in out:
fail('slave1 does not have policy change from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 1, 1)
-check_ulog(1, 1, 1, [None], slave2)
-out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2)
-if 'Minimum password length: 17' not in out:
- fail('slave2 does not have policy change from slave1')
# Delete the policy and test that it propagates via full resync.
realm.run([kadminl, 'delpol', 'testpol'])
@@ -303,12 +242,6 @@ check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_code=1)
if 'Policy does not exist' not in out:
fail('slave1 did not get policy deletion from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 1, 1)
-check_ulog(1, 1, 1, [None], slave2)
-out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_code=1)
-if 'Policy does not exist' not in out:
- fail('slave2 did not get policy deletion from slave1')
# Modify a principal on the master and test that it propagates incrementally.
realm.run([kadminl, 'modprinc', '-maxlife', '10 minutes', pr1])
@@ -319,12 +252,6 @@ check_ulog(2, 1, 2, [None, pr1], slave1)
out = realm.run([kadminl, 'getprinc', pr1], env=slave1)
if 'Maximum ticket life: 0 days 00:10:00' not in out:
fail('slave1 does not have modification from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 1, 2)
-check_ulog(2, 1, 2, [None, pr1], slave2)
-out = realm.run([kadminl, 'getprinc', pr1], env=slave2)
-if 'Maximum ticket life: 0 days 00:10:00' not in out:
- fail('slave2 does not have modification from slave1')
# Delete a principal and test that it propagates incrementally.
realm.run([kadminl, 'delprinc', pr3])
@@ -335,12 +262,6 @@ check_ulog(3, 1, 3, [None, pr1, pr3], sl
out = realm.run([kadminl, 'getprinc', pr3], env=slave1, expected_code=1)
if 'Principal does not exist' not in out:
fail('slave1 does not have principal deletion from master')
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 2, 3)
-check_ulog(3, 1, 3, [None, pr1, pr3], slave2)
-out = realm.run([kadminl, 'getprinc', pr3], env=slave2, expected_code=1)
-if 'Principal does not exist' not in out:
- fail('slave2 does not have principal deletion from slave1')
# Reset the ulog on the master to force a full resync.
realm.run([kproplog, '-R'])
@@ -348,13 +269,9 @@ check_ulog(1, 1, 1, [None])
kpropd1.send_signal(signal.SIGUSR1)
wait_for_prop(kpropd1, True, 3, 1)
check_ulog(1, 1, 1, [None], slave1)
-kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 3, 1)
-check_ulog(1, 1, 1, [None], slave2)
-# Stop the kprop daemons so we can test kpropd -t.
+# Stop the kprop daemon so we can test kpropd -t.
stop_daemon(kpropd1)
-stop_daemon(kpropd2)
# Test the case where no updates are needed.
out = realm.run_kpropd_once(slave1, ['-d'])
--- a/src/tests/t_kadmin_acl.py
+++ b/src/tests/t_kadmin_acl.py
@@ -9,7 +9,7 @@ def make_client(name):
ccache = os.path.join(realm.testdir,
'kadmin_ccache_' + name.replace('/', '_'))
realm.kinit(name, password(name),
- flags=['-S', 'kadmin/admin', '-c', ccache])
+ flags=['-S', 'kadmin/' + hostname, '-c', ccache])
return ccache
def kadmin_as(client, query, **kwargs):
--- a/src/util/gss-kernel-lib/Makefile.in
+++ b/src/util/gss-kernel-lib/Makefile.in
@@ -7,7 +7,7 @@ ALL_CFLAGS=$(CPPFLAGS) $(CFLAGS) $(WARN_CFLAGS) $(DEFS) $(DEFINES) -I. -Igssapi
SHLIB_EXPDEPS = \
$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
$(TOPLIBD)/libkrb5$(SHLIBEXT)
-SHLIB_EXPLIBS=-lgssrpc -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB) $(LIBS)
+SHLIB_EXPLIBS= -lkrb5 -lk5crypto -lcom_err $(SUPPORT_LIB) $(LIBS)
SRCS= \
k5seal.c \
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -997,7 +997,7 @@ class K5Realm(object):
princname = self.admin_princ
pw = password('admin')
return self.kinit(princname, pw,
- flags=['-S', 'kadmin/admin',
+ flags=['-S', 'kadmin/' + hostname,
'-c', self.kadmin_ccache] + flags)
def run_kadmin(self, args, **keywords):