[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-4184-g8627f68

Günther Deschner gd at samba.org
Fri Sep 26 23:05:06 GMT 2008


The branch, v3-3-test has been updated
       via  8627f684c64d0185245dea9b6b73aa2e2633a8f6 (commit)
      from  1861a8b8e1958c3118008f536817e93cca410fa4 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit 8627f684c64d0185245dea9b6b73aa2e2633a8f6
Author: Günther Deschner <gd at samba.org>
Date:   Fri Aug 15 02:00:46 2008 +0200

    libwbclient: add wbcChangeUserPassword and wbcChangeUserPasswordEx.
    
    Guenther
    (cherry picked from commit 62e7b4aa32051bce34c890cb41270e5fe31111ca)

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

Summary of changes:
 source/nsswitch/libwbclient/wbc_pam.c  |  271 ++++++++++++++++++++++++++++++++
 source/nsswitch/libwbclient/wbclient.c |    2 +
 source/nsswitch/libwbclient/wbclient.h |   78 +++++++++-
 3 files changed, 350 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/nsswitch/libwbclient/wbc_pam.c b/source/nsswitch/libwbclient/wbc_pam.c
index 293f71c..20b42b6 100644
--- a/source/nsswitch/libwbclient/wbc_pam.c
+++ b/source/nsswitch/libwbclient/wbc_pam.c
@@ -236,6 +236,30 @@ done:
 	return wbc_status;
 }
 
+static wbcErr wbc_create_password_policy_info(TALLOC_CTX *mem_ctx,
+					      const struct winbindd_response *resp,
+					      struct wbcUserPasswordPolicyInfo **_i)
+{
+	wbcErr wbc_status = WBC_ERR_SUCCESS;
+	struct wbcUserPasswordPolicyInfo *i;
+
+	i = talloc(mem_ctx, struct wbcUserPasswordPolicyInfo);
+	BAIL_ON_PTR_ERROR(i, wbc_status);
+
+	i->min_passwordage	= resp->data.auth.policy.min_passwordage;
+	i->min_length_password	= resp->data.auth.policy.min_length_password;
+	i->password_history	= resp->data.auth.policy.password_history;
+	i->password_properties	= resp->data.auth.policy.password_properties;
+	i->expire		= resp->data.auth.policy.expire;
+
+	*_i = i;
+	i = NULL;
+
+done:
+	talloc_free(i);
+	return wbc_status;
+}
+
 /** @brief Authenticate with more detailed information
  *
  * @param params       Input parameters, WBC_AUTH_USER_LEVEL_HASH
@@ -523,3 +547,250 @@ wbcErr wbcLogoffUser(const char *username,
  done:
 	return wbc_status;
 }
+
+/** @brief Change a password for a user with more detailed information upon
+ * 	   failure
+ * @param params                Input parameters
+ * @param error                 User output details on WBC_ERR_PWD_CHANGE_FAILED
+ * @param reject_reason         New password reject reason on WBC_ERR_PWD_CHANGE_FAILED
+ * @param policy                Password policy output details on WBC_ERR_PWD_CHANGE_FAILED
+ *
+ * @return #wbcErr
+ **/
+
+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
+			       struct wbcAuthErrorInfo **error,
+			       enum wbcPasswordChangeRejectReason *reject_reason,
+			       struct wbcUserPasswordPolicyInfo **policy)
+{
+	struct winbindd_request request;
+	struct winbindd_response response;
+	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+	int cmd = 0;
+
+	/* validate input */
+
+	if (!params->account_name) {
+		wbc_status = WBC_ERR_INVALID_PARAM;
+		BAIL_ON_WBC_ERROR(wbc_status);
+	}
+
+	if (error) {
+		*error = NULL;
+	}
+
+	if (policy) {
+		*policy = NULL;
+	}
+
+	if (reject_reason) {
+		*reject_reason = -1;
+	}
+
+	ZERO_STRUCT(request);
+	ZERO_STRUCT(response);
+
+	switch (params->level) {
+	case WBC_CHANGE_PASSWORD_LEVEL_PLAIN:
+		cmd = WINBINDD_PAM_CHAUTHTOK;
+
+		if (!params->account_name) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		strncpy(request.data.chauthtok.user, params->account_name,
+			sizeof(request.data.chauthtok.user) - 1);
+
+		if (params->old_password.plaintext) {
+			strncpy(request.data.chauthtok.oldpass,
+				params->old_password.plaintext,
+				sizeof(request.data.chauthtok.oldpass) - 1);
+		}
+
+		if (params->new_password.plaintext) {
+			strncpy(request.data.chauthtok.newpass,
+				params->new_password.plaintext,
+				sizeof(request.data.chauthtok.newpass) - 1);
+		}
+		break;
+
+	case WBC_CHANGE_PASSWORD_LEVEL_RESPONSE:
+		cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP;
+
+		if (!params->account_name || !params->domain_name) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->old_password.response.old_lm_hash_enc_length &&
+		    !params->old_password.response.old_lm_hash_enc_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->old_password.response.old_lm_hash_enc_length == 0 &&
+		    params->old_password.response.old_lm_hash_enc_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->old_password.response.old_nt_hash_enc_length &&
+		    !params->old_password.response.old_nt_hash_enc_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->old_password.response.old_nt_hash_enc_length == 0 &&
+		    params->old_password.response.old_nt_hash_enc_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->new_password.response.lm_length &&
+		    !params->new_password.response.lm_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->new_password.response.lm_length == 0 &&
+		    params->new_password.response.lm_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->new_password.response.nt_length &&
+		    !params->new_password.response.nt_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		if (params->new_password.response.nt_length == 0 &&
+		    params->new_password.response.nt_data) {
+			wbc_status = WBC_ERR_INVALID_PARAM;
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+		strncpy(request.data.chng_pswd_auth_crap.user,
+			params->account_name,
+			sizeof(request.data.chng_pswd_auth_crap.user) - 1);
+
+		strncpy(request.data.chng_pswd_auth_crap.domain,
+			params->domain_name,
+			sizeof(request.data.chng_pswd_auth_crap.domain) - 1);
+
+		if (params->new_password.response.nt_data) {
+			memcpy(request.data.chng_pswd_auth_crap.new_nt_pswd,
+			       params->new_password.response.nt_data,
+			       request.data.chng_pswd_auth_crap.new_nt_pswd_len);
+			request.data.chng_pswd_auth_crap.new_nt_pswd_len =
+				params->new_password.response.nt_length;
+		}
+
+		if (params->new_password.response.lm_data) {
+			memcpy(request.data.chng_pswd_auth_crap.new_lm_pswd,
+			       params->new_password.response.lm_data,
+			       request.data.chng_pswd_auth_crap.new_lm_pswd_len);
+			request.data.chng_pswd_auth_crap.new_lm_pswd_len =
+				params->new_password.response.lm_length;
+		}
+
+		if (params->old_password.response.old_nt_hash_enc_data) {
+			memcpy(request.data.chng_pswd_auth_crap.old_nt_hash_enc,
+			       params->old_password.response.old_nt_hash_enc_data,
+			       request.data.chng_pswd_auth_crap.old_nt_hash_enc_len);
+			request.data.chng_pswd_auth_crap.old_nt_hash_enc_len =
+				params->old_password.response.old_nt_hash_enc_length;
+		}
+
+		if (params->old_password.response.old_lm_hash_enc_data) {
+			memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc,
+			       params->old_password.response.old_lm_hash_enc_data,
+			       request.data.chng_pswd_auth_crap.old_lm_hash_enc_len);
+			request.data.chng_pswd_auth_crap.old_lm_hash_enc_len =
+				params->old_password.response.old_lm_hash_enc_length;
+		}
+
+		break;
+	default:
+		wbc_status = WBC_ERR_INVALID_PARAM;
+		BAIL_ON_WBC_ERROR(wbc_status);
+		break;
+	}
+
+	if (cmd == 0) {
+		wbc_status = WBC_ERR_INVALID_PARAM;
+		BAIL_ON_WBC_ERROR(wbc_status);
+	}
+
+	/* Send request */
+
+	wbc_status = wbcRequestResponse(cmd,
+					&request,
+					&response);
+	if (WBC_ERROR_IS_OK(wbc_status)) {
+		goto done;
+	}
+
+	/* Take the response above and return it to the caller */
+
+	if (response.data.auth.nt_status != 0) {
+		if (error) {
+			wbc_status = wbc_create_error_info(NULL,
+							   &response,
+							   error);
+			BAIL_ON_WBC_ERROR(wbc_status);
+		}
+
+	}
+
+	if (policy) {
+		wbc_status = wbc_create_password_policy_info(NULL,
+							     &response,
+							     policy);
+		BAIL_ON_WBC_ERROR(wbc_status);
+	}
+
+	if (reject_reason) {
+		*reject_reason = response.data.auth.reject_reason;
+	}
+
+	wbc_status = WBC_ERR_PWD_CHANGE_FAILED;
+	BAIL_ON_WBC_ERROR(wbc_status);
+
+ done:
+	return wbc_status;
+}
+
+/** @brief Change a password for a user
+ *
+ * @param username		Name of user to authenticate
+ * @param old_password		Old clear text password of user
+ * @param new_password		New clear text password of user
+ *
+ * @return #wbcErr
+ **/
+
+wbcErr wbcChangeUserPassword(const char *username,
+			     const char *old_password,
+			     const char *new_password)
+{
+	wbcErr wbc_status = WBC_ERR_SUCCESS;
+	struct wbcChangePasswordParams params;
+
+	ZERO_STRUCT(params);
+
+	params.account_name		= username;
+	params.level			= WBC_CHANGE_PASSWORD_LEVEL_PLAIN;
+	params.old_password.plaintext	= old_password;
+	params.new_password.plaintext	= new_password;
+
+	wbc_status = wbcChangeUserPasswordEx(&params,
+					     NULL,
+					     NULL,
+					     NULL);
+	BAIL_ON_WBC_ERROR(wbc_status);
+
+done:
+	return wbc_status;
+}
diff --git a/source/nsswitch/libwbclient/wbclient.c b/source/nsswitch/libwbclient/wbclient.c
index 82decc2..bdde562 100644
--- a/source/nsswitch/libwbclient/wbclient.c
+++ b/source/nsswitch/libwbclient/wbclient.c
@@ -116,6 +116,8 @@ const char *wbcErrorString(wbcErr error)
 		return "WBC_ERR_UNKNOWN_GROUP";
 	case WBC_ERR_AUTH_ERROR:
 		return "WBC_ERR_AUTH_ERROR";
+	case WBC_ERR_PWD_CHANGE_FAILED:
+		return "WBC_ERR_PWD_CHANGE_FAILED";
 	}
 
 	return "unknown wbcErr value";
diff --git a/source/nsswitch/libwbclient/wbclient.h b/source/nsswitch/libwbclient/wbclient.h
index 2fefe0c..cae3fee 100644
--- a/source/nsswitch/libwbclient/wbclient.h
+++ b/source/nsswitch/libwbclient/wbclient.h
@@ -44,7 +44,8 @@ enum _wbcErrType {
 	WBC_ERR_NSS_ERROR,            /**< NSS_STATUS error **/
 	WBC_ERR_AUTH_ERROR,        /**< Authentication failed **/
 	WBC_ERR_UNKNOWN_USER,      /**< User account cannot be found */
-	WBC_ERR_UNKNOWN_GROUP      /**< Group account cannot be found */
+	WBC_ERR_UNKNOWN_GROUP,     /**< Group account cannot be found */
+	WBC_ERR_PWD_CHANGE_FAILED  /**< Password Change has failed */
 };
 
 typedef enum _wbcErrType wbcErr;
@@ -204,6 +205,41 @@ struct wbcAuthUserParams {
 	} password;
 };
 
+/**
+ * @brief ChangePassword Parameters
+ **/
+
+struct wbcChangePasswordParams {
+	const char *account_name;
+	const char *domain_name;
+
+	uint32_t flags;
+
+	enum wbcChangePasswordLevel {
+		WBC_CHANGE_PASSWORD_LEVEL_PLAIN = 1,
+		WBC_CHANGE_PASSWORD_LEVEL_RESPONSE = 2
+	} level;
+
+	union {
+		const char *plaintext;
+		struct {
+			uint32_t old_nt_hash_enc_length;
+			uint8_t *old_nt_hash_enc_data;
+			uint32_t old_lm_hash_enc_length;
+			uint8_t *old_lm_hash_enc_data;
+		} response;
+	} old_password;
+	union {
+		const char *plaintext;
+		struct {
+			uint32_t nt_length;
+			uint8_t *nt_data;
+			uint32_t lm_length;
+			uint8_t *lm_data;
+		} response;
+	} new_password;
+};
+
 /* wbcAuthUserParams->parameter_control */
 
 #define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED		0x00000002
@@ -304,6 +340,38 @@ struct wbcAuthErrorInfo {
 	char *display_string;
 };
 
+/**
+ * @brief User Password Policy Information
+ **/
+
+/* wbcUserPasswordPolicyInfo->password_properties */
+
+#define WBC_DOMAIN_PASSWORD_COMPLEX		0x00000001
+#define WBC_DOMAIN_PASSWORD_NO_ANON_CHANGE	0x00000002
+#define WBC_DOMAIN_PASSWORD_NO_CLEAR_CHANGE	0x00000004
+#define WBC_DOMAIN_PASSWORD_LOCKOUT_ADMINS	0x00000008
+#define WBC_DOMAIN_PASSWORD_STORE_CLEARTEXT	0x00000010
+#define WBC_DOMAIN_REFUSE_PASSWORD_CHANGE	0x00000020
+
+struct wbcUserPasswordPolicyInfo {
+	uint32_t min_length_password;
+	uint32_t password_history;
+	uint32_t password_properties;
+	uint64_t expire;
+	uint64_t min_passwordage;
+};
+
+/**
+ * @brief Change Password Reject Reason
+ **/
+
+enum wbcPasswordChangeRejectReason {
+	WBC_PWD_CHANGE_REJECT_OTHER=0,
+	WBC_PWD_CHANGE_REJECT_TOO_SHORT=1,
+	WBC_PWD_CHANGE_REJECT_IN_HISTORY=2,
+	WBC_PWD_CHANGE_REJECT_COMPLEXITY=5
+};
+
 /*
  * DomainControllerInfo struct
  */
@@ -478,6 +546,14 @@ wbcErr wbcLogoffUser(const char *username,
 		     uid_t uid,
 		     const char *ccfilename);
 
+wbcErr wbcChangeUserPassword(const char *username,
+			     const char *old_password,
+			     const char *new_password);
+
+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
+			       struct wbcAuthErrorInfo **error,
+			       enum wbcPasswordChangeRejectReason *reject_reason,
+			       struct wbcUserPasswordPolicyInfo **policy);
 
 /*
  * Resolve functions


-- 
Samba Shared Repository


More information about the samba-cvs mailing list