[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Apr 6 12:04:03 UTC 2017


The branch, master has been updated
       via  e69aa55 winbindd: let WBFLAG_PAM_GET_PWD_POLICY only fake the password policy
       via  fba7ed9 pam_winbind: no longer use wbcUserPasswordPolicyInfo when authenticating
      from  5ee494c tests dsdb: load paramaters from test environment

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e69aa55c5dae0722e78fc67716c04dec2bec1c46
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 4 09:24:11 2017 +0200

    winbindd: let WBFLAG_PAM_GET_PWD_POLICY only fake the password policy
    
    As WBFLAG_PAM_GET_PWD_POLICY is only kept for legacy external callers
    of libwbclient, we should avoid having the complexity to do additional
    network roundtrips to our domain, while we still can't garantee that
    the returned password policy actually represents the reality for
    the current authentication.
    
    Instead we're calculating r->data.auth.policy.expire and
    r->data.auth.policy.min_passwordage based on the effective
    {last,allow,force}_password_change values.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Christof Schmitt <cs at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Apr  6 14:03:09 CEST 2017 on sn-devel-144

commit fba7ed9a3fa6fcb2d90d1271ae81ec11b554bd2d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Apr 3 00:19:25 2017 +0200

    pam_winbind: no longer use wbcUserPasswordPolicyInfo when authenticating
    
    The expiry time for the specific user comes from
    info->pass_must_change_time and nothing else.
    
    The authenticating DC knows which password policy applies
    to the user, that's nothing the client can do, as
    domain trusts and fine-grained password policies makes
    this a very complex task.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12725
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Christof Schmitt <cs at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 nsswitch/pam_winbind.c          | 58 +++++++++-------------------------------
 source3/winbindd/winbindd_pam.c | 59 ++++++++++++++++++++++++++---------------
 2 files changed, 49 insertions(+), 68 deletions(-)


Changeset truncated at 500 lines:

diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
index 746b157..4ae6464 100644
--- a/nsswitch/pam_winbind.c
+++ b/nsswitch/pam_winbind.c
@@ -1004,7 +1004,6 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
 
 static void _pam_warn_password_expiry(struct pwb_context *ctx,
 				      const struct wbcAuthUserInfo *info,
-				      const struct wbcUserPasswordPolicyInfo *policy,
 				      int warn_pwd_expire,
 				      bool *already_expired,
 				      bool *change_pwd)
@@ -1012,7 +1011,7 @@ static void _pam_warn_password_expiry(struct pwb_context *ctx,
 	time_t now = time(NULL);
 	time_t next_change = 0;
 
-	if (!info || !policy) {
+	if (info == NULL) {
 		return;
 	}
 
@@ -1044,23 +1043,6 @@ static void _pam_warn_password_expiry(struct pwb_context *ctx,
 		return;
 	}
 
-	/* now check for the global password policy */
-	/* good catch from Ralf Haferkamp: an expiry of "never" is translated
-	 * to -1 */
-	if ((policy->expire == (int64_t)-1) ||
-	    (policy->expire == 0)) {
-		return;
-	}
-
-	next_change = info->pass_last_set_time + policy->expire;
-
-	if (_pam_send_password_expiry_message(ctx, next_change, now,
-					      warn_pwd_expire,
-					      already_expired,
-					      change_pwd)) {
-		return;
-	}
-
 	/* no warning sent */
 }
 
@@ -1696,23 +1678,17 @@ static int winbind_auth_request(struct pwb_context *ctx,
 				const int warn_pwd_expire,
 				struct wbcAuthErrorInfo **p_error,
 				struct wbcLogonUserInfo **p_info,
-				struct wbcUserPasswordPolicyInfo **p_policy,
 				time_t *pwd_last_set,
 				char **user_ret)
 {
 	wbcErr wbc_status;
-
 	struct wbcLogonUserParams logon;
 	char membership_of[1024];
 	uid_t user_uid = -1;
-	uint32_t flags = WBFLAG_PAM_INFO3_TEXT |
-			 WBFLAG_PAM_GET_PWD_POLICY;
-
+	uint32_t flags = WBFLAG_PAM_INFO3_TEXT;
 	struct wbcLogonUserInfo *info = NULL;
 	struct wbcAuthUserInfo *user_info = NULL;
 	struct wbcAuthErrorInfo *error = NULL;
-	struct wbcUserPasswordPolicyInfo *policy = NULL;
-
 	int ret = PAM_AUTH_ERR;
 	int i;
 	const char *codes[] = {
@@ -1845,7 +1821,7 @@ static int winbind_auth_request(struct pwb_context *ctx,
 				     &logon,
 				     &info,
 				     &error,
-				     &policy);
+				     NULL);
 	ret = wbc_auth_error_to_pam_error(ctx, error, wbc_status,
 					  user, "wbcLogonUser");
 	wbcFreeMemory(logon.blobs);
@@ -1863,10 +1839,6 @@ static int winbind_auth_request(struct pwb_context *ctx,
 		*p_info = info;
 	}
 
-	if (p_policy && policy) {
-		*p_policy = policy;
-	}
-
 	if (p_error && error) {
 		/* We want to process the error in the caller. */
 		*p_error = error;
@@ -1881,13 +1853,13 @@ static int winbind_auth_request(struct pwb_context *ctx,
 		}
 	}
 
-	if ((ret == PAM_SUCCESS) && user_info && policy && info) {
+	if ((ret == PAM_SUCCESS) && user_info && info) {
 
 		bool already_expired = false;
 		bool change_pwd = false;
 
 		/* warn a user if the password is about to expire soon */
-		_pam_warn_password_expiry(ctx, user_info, policy,
+		_pam_warn_password_expiry(ctx, user_info,
 					  warn_pwd_expire,
 					  &already_expired,
 					  &change_pwd);
@@ -1895,15 +1867,15 @@ static int winbind_auth_request(struct pwb_context *ctx,
 		if (already_expired == true) {
 
 			SMB_TIME_T last_set = user_info->pass_last_set_time;
+			SMB_TIME_T must_set = user_info->pass_must_change_time;
 
 			_pam_log_debug(ctx, LOG_DEBUG,
 				       "Password has expired "
 				       "(Password was last set: %lld, "
-				       "the policy says it should expire here "
+				       "it must be changed here "
 				       "%lld (now it's: %ld))\n",
 				       (long long int)last_set,
-				       (long long int)last_set +
-				       policy->expire,
+				       (long long int)must_set,
 				       (long)time(NULL));
 
 			return PAM_AUTHTOK_EXPIRED;
@@ -1942,9 +1914,6 @@ static int winbind_auth_request(struct pwb_context *ctx,
 	if (info && !p_info) {
 		wbcFreeMemory(info);
 	}
-	if (policy && !p_policy) {
-		wbcFreeMemory(policy);
-	}
 
 	return ret;
 }
@@ -2741,8 +2710,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
 	/* Now use the username to look up password */
 	retval = winbind_auth_request(ctx, real_username, password,
 				      member, cctype, warn_pwd_expire,
-				      NULL, NULL, NULL,
-				      NULL, &username_ret);
+				      NULL, NULL, NULL, &username_ret);
 
 	if (retval == PAM_NEW_AUTHTOK_REQD ||
 	    retval == PAM_AUTHTOK_EXPIRED) {
@@ -3152,7 +3120,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
 		ret = winbind_auth_request(ctx, user, pass_old,
 					   NULL, NULL, 0,
-					   &error, NULL, NULL,
+					   &error, NULL,
 					   &pwdlastset_prelim, NULL);
 
 		if (ret != PAM_ACCT_EXPIRED &&
@@ -3260,7 +3228,6 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 			const char *cctype = NULL;
 			int warn_pwd_expire;
 			struct wbcLogonUserInfo *info = NULL;
-			struct wbcUserPasswordPolicyInfo *policy = NULL;
 
 			member = get_member_from_config(ctx);
 			cctype = get_krb5_cc_type_from_config(ctx);
@@ -3276,7 +3243,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
 			ret = winbind_auth_request(ctx, user, pass_new,
 						   member, cctype, 0,
-						   &error, &info, &policy,
+						   &error, &info,
 						   NULL, &username_ret);
 			pass_old = pass_new = NULL;
 
@@ -3290,7 +3257,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
 				/* warn a user if the password is about to
 				 * expire soon */
-				_pam_warn_password_expiry(ctx, user_info, policy,
+				_pam_warn_password_expiry(ctx, user_info,
 							  warn_pwd_expire,
 							  NULL, NULL);
 
@@ -3316,7 +3283,6 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 				wbcFreeMemory(info->blobs);
 			}
 			wbcFreeMemory(info);
-			wbcFreeMemory(policy);
 
 			goto out;
 		}
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 8139cbe..a466015 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -384,6 +384,35 @@ struct winbindd_domain *find_auth_domain(uint8_t flags,
 	return find_our_domain();
 }
 
+static void fake_password_policy(struct winbindd_response *r,
+				 const struct netr_SamBaseInfo *bi)
+{
+	NTTIME min_password_age;
+	NTTIME max_password_age;
+
+	if (bi->allow_password_change > bi->last_password_change) {
+		min_password_age = bi->allow_password_change -
+				   bi->last_password_change;
+	} else {
+		min_password_age = 0;
+	}
+
+	if (bi->force_password_change > bi->last_password_change) {
+		max_password_age = bi->force_password_change -
+				   bi->last_password_change;
+	} else {
+		max_password_age = 0;
+	}
+
+	r->data.auth.policy.min_length_password = 0;
+	r->data.auth.policy.password_history = 0;
+	r->data.auth.policy.password_properties = 0;
+	r->data.auth.policy.expire =
+		nt_time_to_unix_abs(&max_password_age);
+	r->data.auth.policy.min_passwordage =
+		nt_time_to_unix_abs(&min_password_age);
+}
+
 static void fill_in_password_policy(struct winbindd_response *r,
 				    const struct samr_DomInfo1 *p)
 {
@@ -1930,28 +1959,14 @@ process_result:
 		}
 
 		if (state->request->flags & WBFLAG_PAM_GET_PWD_POLICY) {
-			struct winbindd_domain *our_domain = find_our_domain();
-
-			/* This is not entirely correct I believe, but it is
-			   consistent.  Only apply the password policy settings
-			   too warn users for our own domain.  Cannot obtain these
-			   from trusted DCs all the  time so don't do it at all.
-			   -- jerry */
-
-			result = NT_STATUS_NOT_SUPPORTED;
-			if (strequal(name_domain, our_domain->name)) {
-				result = fillup_password_policy(
-					our_domain, state->response);
-			}
-
-			if (!NT_STATUS_IS_OK(result)
-			    && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) )
-			{
-				DBG_DEBUG("Failed to get password policies for "
-					  "domain %s: %s\n", our_domain->name,
-					  nt_errstr(result));
-				goto done;
-			}
+			/*
+			 * WBFLAG_PAM_GET_PWD_POLICY is not used within
+			 * any Samba caller anymore.
+			 *
+			 * We just fake this based on the effective values
+			 * for the user, for legacy callers.
+			 */
+			fake_password_policy(state->response, &info3->base);
 		}
 
 		result = NT_STATUS_OK;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list