components/krb5/patches/034-migrate.patch
changeset 5490 9bf0bc57423a
child 6599 1d033832c5e7
equal deleted inserted replaced
5489:a5031bb8b66d 5490:9bf0bc57423a
       
     1 #
       
     2 # This patch provides an authorization scheme for kadmind when used to
       
     3 # auto-migrate UNIX based users to Kerberos.  This is required to support
       
     4 # the auto-migrate module, pam_krb5_migrate(5).
       
     5 #
       
     6 # Note: MIT will unlikely want the pam_krb5_migrate kadmind authorization
       
     7 # functionality as this is specific to a 3rd party migration design.
       
     8 # Patch source: in-house
       
     9 #
       
    10 diff -pur old/src/kadmin/server/Makefile.in new/src/kadmin/server/Makefile.in
       
    11 --- old/src/kadmin/server/Makefile.in	2015-04-30 01:12:10.540747993 -0600
       
    12 +++ new/src/kadmin/server/Makefile.in	2015-05-20 21:20:31.285698636 -0600
       
    13 @@ -13,7 +13,7 @@ SRCS = kadm_rpc_svc.c server_stubs.c ovs
       
    14  all:: $(PROG)
       
    15  
       
    16  $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB) $(VERTO_DEPLIB)
       
    17 -	$(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) $(VERTO_LIBS)
       
    18 +	$(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) $(VERTO_LIBS) -lpam
       
    19  
       
    20  install::
       
    21  	$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(SERVER_BINDIR)/$(PROG)
       
    22 diff -pur old/src/kadmin/server/server_stubs.c new/src/kadmin/server/server_stubs.c
       
    23 --- old/src/kadmin/server/server_stubs.c	2015-04-30 01:12:10.540973547 -0600
       
    24 +++ new/src/kadmin/server/server_stubs.c	2015-05-20 21:16:21.635418741 -0600
       
    25 @@ -16,6 +16,7 @@
       
    26  #include <syslog.h>
       
    27  #include <adm_proto.h>  /* krb5_klog_syslog */
       
    28  #include "misc.h"
       
    29 +#include <security/pam_appl.h>
       
    30  
       
    31  extern gss_name_t                       gss_changepw_name;
       
    32  extern gss_name_t                       gss_oldchangepw_name;
       
    33 @@ -352,6 +353,80 @@ log_done(
       
    34                              client_addr(rqstp->rq_xprt));
       
    35  }
       
    36  
       
    37 +/*
       
    38 + * This routine primarily validates the username and password
       
    39 + * of the principal to be created, if a prior acl check for
       
    40 + * the 'u' privilege succeeds. Validation is done using
       
    41 + * the PAM `k5migrate' service. k5migrate normally stacks
       
    42 + * pam_unix_auth.so and pam_unix_account.so in its auth and
       
    43 + * account stacks respectively.
       
    44 + *
       
    45 + * Returns 1 (true), if validation is successful,
       
    46 + * else returns 0 (false).
       
    47 + */
       
    48 +int
       
    49 +verify_pam_pw(char *userdata, char *pwd)
       
    50 +{
       
    51 +	pam_handle_t *pamh;
       
    52 +	int err = 0;
       
    53 +	int result = 1;
       
    54 +	char *user = NULL;
       
    55 +	char *ptr = NULL;
       
    56 +
       
    57 +	ptr = strchr(userdata, '@');
       
    58 +	if (ptr != NULL) {
       
    59 +		user = (char *)malloc(ptr - userdata + 1);
       
    60 +		if (user == NULL)
       
    61 +			return (0);
       
    62 +		(void) strlcpy(user, userdata, (ptr - userdata) + 1);
       
    63 +	} else {
       
    64 +		user = (char *)strdup(userdata);
       
    65 +		if (user == NULL)
       
    66 +			return (0);
       
    67 +	}
       
    68 +
       
    69 +	err = pam_start("k5migrate", user, NULL, &pamh);
       
    70 +	if (err != PAM_SUCCESS) {
       
    71 +		syslog(LOG_ERR, "verify_pam_pw: pam_start() failed, %s\n",
       
    72 +				pam_strerror(pamh, err));
       
    73 +		free(user);
       
    74 +		return (0);
       
    75 +	}
       
    76 +
       
    77 +	err = pam_set_item(pamh, PAM_AUTHTOK, (void *)pwd);
       
    78 +	if (err != PAM_SUCCESS) {
       
    79 +		syslog(LOG_ERR, "verify_pam_pw: pam_set_item() failed, %s\n",
       
    80 +				pam_strerror(pamh, err));
       
    81 +		free(user);
       
    82 +		(void) pam_end(pamh, err);
       
    83 +		return (0);
       
    84 +	}
       
    85 +
       
    86 +	err = pam_authenticate(pamh, PAM_SILENT);
       
    87 +	if (err != PAM_SUCCESS) {
       
    88 +		syslog(LOG_ERR, "verify_pam_pw: pam_authenticate() failed for "
       
    89 +				"user=%s, %s\n", user,
       
    90 +				pam_strerror(pamh, err));
       
    91 +		free(user);
       
    92 +		(void) pam_end(pamh, err);
       
    93 +		return (0);
       
    94 +	}
       
    95 +
       
    96 +	err = pam_acct_mgmt(pamh, PAM_SILENT);
       
    97 +	if (err != PAM_SUCCESS) {
       
    98 +		syslog(LOG_ERR, "verify_pam_pw: pam_acct_mgmt() failed for "
       
    99 +				"user=%s, %s\n", user,
       
   100 +				pam_strerror(pamh, err));
       
   101 +		free(user);
       
   102 +		(void) pam_end(pamh, err);
       
   103 +		return (0);
       
   104 +	}
       
   105 +
       
   106 +	free(user);
       
   107 +	(void) pam_end(pamh, PAM_SUCCESS);
       
   108 +	return (result);
       
   109 +}
       
   110 +
       
   111  generic_ret *
       
   112  create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
       
   113  {
       
   114 @@ -363,6 +438,8 @@ create_principal_2_svc(cprinc_arg *arg,
       
   115      restriction_t               *rp;
       
   116      const char                  *errmsg = NULL;
       
   117      gss_name_t                  name = NULL;
       
   118 +    int				policy_migrate = 0;
       
   119 +    kadm5_ret_t			retval;
       
   120  
       
   121      xdr_free(xdr_generic_ret, (char *) &ret);
       
   122  
       
   123 @@ -387,9 +464,17 @@ create_principal_2_svc(cprinc_arg *arg,
       
   124          ret.code = KADM5_FAILURE;
       
   125          goto exit_func;
       
   126      }
       
   127 +
       
   128 +    if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
       
   129 +	arg->rec.principal, &rp) &&
       
   130 +	verify_pam_pw(prime_arg, arg->passwd)) {
       
   131 +	policy_migrate = 1;
       
   132 +    }
       
   133 +
       
   134      if (CHANGEPW_SERVICE(rqstp)
       
   135 -        || !kadm5int_acl_check(handle->context, name, ACL_ADD,
       
   136 -                               arg->rec.principal, &rp)
       
   137 +        || (!kadm5int_acl_check(handle->context, name, ACL_ADD,
       
   138 +                               arg->rec.principal, &rp) &&
       
   139 +		!(policy_migrate))
       
   140          || kadm5int_acl_impose_restrictions(handle->context,
       
   141                                              &arg->rec, &arg->mask, rp)) {
       
   142          ret.code = KADM5_AUTH_ADD;
       
   143 @@ -408,6 +493,25 @@ create_principal_2_svc(cprinc_arg *arg,
       
   144  
       
   145          if (errmsg != NULL)
       
   146              krb5_free_error_message(handle->context, errmsg);
       
   147 +
       
   148 +	if (policy_migrate && (ret.code == 0)) {
       
   149 +		arg->rec.policy = strdup("default");
       
   150 +		if ((arg->mask & KADM5_PW_EXPIRATION)) {
       
   151 +			arg->mask = 0;
       
   152 +			arg->mask |= KADM5_POLICY;
       
   153 +			arg->mask |= KADM5_PW_EXPIRATION;
       
   154 +		} else {
       
   155 +			arg->mask = 0;
       
   156 +			arg->mask |= KADM5_POLICY;
       
   157 +		}
       
   158 +
       
   159 +		retval = kadm5_modify_principal((void *)handle,
       
   160 +				&arg->rec, arg->mask);
       
   161 +		log_done("kadm5_modify_principal",
       
   162 +			prime_arg, ((retval == 0) ? "success" :
       
   163 +			error_message(retval)), &client_name,
       
   164 +			&service_name, rqstp);
       
   165 +	}
       
   166      }
       
   167      free(prime_arg);
       
   168      gss_release_buffer(&minor_stat, &client_name);
       
   169 @@ -431,6 +535,8 @@ create_principal3_2_svc(cprinc3_arg *arg
       
   170      restriction_t               *rp;
       
   171      const char                  *errmsg = NULL;
       
   172      gss_name_t                  name = NULL;
       
   173 +    int				policy_migrate = 0;
       
   174 +    kadm5_ret_t			retval;
       
   175  
       
   176      xdr_free(xdr_generic_ret, (char *) &ret);
       
   177  
       
   178 @@ -455,9 +561,17 @@ create_principal3_2_svc(cprinc3_arg *arg
       
   179          ret.code = KADM5_FAILURE;
       
   180          goto exit_func;
       
   181      }
       
   182 +
       
   183 +    if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE,
       
   184 +	arg->rec.principal, &rp) &&
       
   185 +	verify_pam_pw(prime_arg, arg->passwd)) {
       
   186 +	policy_migrate = 1;
       
   187 +    }
       
   188 +
       
   189      if (CHANGEPW_SERVICE(rqstp)
       
   190 -        || !kadm5int_acl_check(handle->context, name, ACL_ADD,
       
   191 -                               arg->rec.principal, &rp)
       
   192 +        || (!kadm5int_acl_check(handle->context, name, ACL_ADD,
       
   193 +                               arg->rec.principal, &rp) &&
       
   194 +	    !(policy_migrate))
       
   195          || kadm5int_acl_impose_restrictions(handle->context,
       
   196                                              &arg->rec, &arg->mask, rp)) {
       
   197          ret.code = KADM5_AUTH_ADD;
       
   198 @@ -477,6 +591,24 @@ create_principal3_2_svc(cprinc3_arg *arg
       
   199  
       
   200          if (errmsg != NULL)
       
   201              krb5_free_error_message(handle->context, errmsg);
       
   202 +
       
   203 +	if (policy_migrate && (ret.code == 0)) {
       
   204 +	 	arg->rec.policy = strdup("default");
       
   205 +	 	if ((arg->mask & KADM5_PW_EXPIRATION)) {
       
   206 +	 		arg->mask = 0;
       
   207 +	 		arg->mask |= KADM5_POLICY;
       
   208 +	 		arg->mask |= KADM5_PW_EXPIRATION;
       
   209 +	 	} else {
       
   210 +	 		arg->mask = 0;
       
   211 +	 		arg->mask |= KADM5_POLICY;
       
   212 +	 	}
       
   213 +
       
   214 +		retval = kadm5_modify_principal((void *)handle,
       
   215 +					   &arg->rec, arg->mask);
       
   216 +		log_done("kadm5_modify_principal", prime_arg,
       
   217 +			((retval == 0) ? "success" : error_message(retval)),
       
   218 +			&client_name, &service_name, rqstp);
       
   219 +	 }
       
   220      }
       
   221      free(prime_arg);
       
   222      gss_release_buffer(&minor_stat, &client_name);
       
   223 diff -pur old/src/lib/kadm5/srv/server_acl.c new/src/lib/kadm5/srv/server_acl.c
       
   224 --- old/src/lib/kadm5/srv/server_acl.c	2015-04-30 01:12:10.576699515 -0600
       
   225 +++ new/src/lib/kadm5/srv/server_acl.c	2015-05-20 21:00:21.476861745 -0600
       
   226 @@ -24,6 +24,10 @@
       
   227   * or implied warranty.
       
   228   */
       
   229  
       
   230 +/*
       
   231 + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
       
   232 + */
       
   233 +
       
   234  #include "k5-int.h"
       
   235  #include <syslog.h>
       
   236  #include <sys/param.h>
       
   237 @@ -63,6 +67,7 @@ static const aop_t acl_op_table[] = {
       
   238      { 'l',      ACL_LIST },
       
   239      { 'p',      ACL_IPROP },
       
   240      { 's',      ACL_SETKEY },
       
   241 +    { 'u',	ACL_MIGRATE },
       
   242      { 'x',      ACL_ALL_MASK },
       
   243      { '*',      ACL_ALL_MASK },
       
   244      { '\0',     0 }
       
   245 diff -pur old/src/lib/kadm5/srv/server_acl.h new/src/lib/kadm5/srv/server_acl.h
       
   246 --- old/src/lib/kadm5/srv/server_acl.h	2015-04-30 01:12:10.575948391 -0600
       
   247 +++ new/src/lib/kadm5/srv/server_acl.h	2015-05-20 21:00:26.742448675 -0600
       
   248 @@ -24,6 +24,10 @@
       
   249   * or implied warranty.
       
   250   */
       
   251  
       
   252 +/*
       
   253 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
       
   254 + */
       
   255 +
       
   256  #ifndef SERVER_ACL_H__
       
   257  #define SERVER_ACL_H__
       
   258  
       
   259 @@ -59,6 +63,7 @@
       
   260  #define ACL_SETKEY              256
       
   261  #define ACL_IPROP               512
       
   262  #define ACL_RENAME              (ACL_ADD+ACL_DELETE)
       
   263 +#define	ACL_MIGRATE		1024
       
   264  
       
   265  #define ACL_ALL_MASK            (ACL_ADD        |       \
       
   266                                   ACL_DELETE     |       \
       
   267 @@ -67,7 +72,8 @@
       
   268                                   ACL_INQUIRE    |       \
       
   269                                   ACL_LIST       |       \
       
   270                                   ACL_IPROP      |       \
       
   271 -                                 ACL_SETKEY)
       
   272 +                                 ACL_SETKEY	|	\
       
   273 +				 ACL_MIGRATE)
       
   274  
       
   275  typedef struct _restriction {
       
   276      long                mask;