[SCM] Samba Shared Repository - branch master updated
Matthias Dieter Wallnöfer
mdw at samba.org
Thu Nov 5 04:43:26 MST 2009
The branch, master has been updated
via 1685ee3... s4:torture/rpc/samr - Add a comment for "ValidatePassword" test
via 3372e2a... s4:dcesrv_samr - Implement "dcesrv_samr_ValidatePassword" using my new check password call
via 85f61e5... s4:dsdb/common/util - Add a new utility function "samdb_check_password"
via 3a6bde7... s4:samdb_set_password/samdb_set_password_sid - Better comments and cosmetics
from d415d4d... s3: Add parameter "ctdb timeout"
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 1685ee3ee7b40ee8e36ab799c447ffacdc5d93ea
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Thu Nov 5 12:37:16 2009 +0100
s4:torture/rpc/samr - Add a comment for "ValidatePassword" test
commit 3372e2a0cc479bf17f04481b172087fbef711ea3
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Wed Nov 4 12:02:02 2009 +0100
s4:dcesrv_samr - Implement "dcesrv_samr_ValidatePassword" using my new check password call
This implements a very basic method for password validation using my new
"samdb_check_password" call.
commit 85f61e5342bd3b57983045d54de3d824c81079b2
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Sat Oct 24 20:21:04 2009 +0200
s4:dsdb/common/util - Add a new utility function "samdb_check_password"
This function performs basic password checks and will be used by the
"samrValidatePassword" call and the "password_hash" module.
commit 3a6bde799d7fd7dffddbde885abe991407233c07
Author: Matthias Dieter Wallnöfer <mwallnoefer at yahoo.de>
Date: Sat Oct 24 19:31:01 2009 +0200
s4:samdb_set_password/samdb_set_password_sid - Better comments and cosmetics
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/common/util.c | 116 ++++++++++++++++++++++-----------
source4/rpc_server/samr/dcesrv_samr.c | 56 ++++++++++++++--
source4/torture/rpc/samr.c | 2 +
3 files changed, 130 insertions(+), 44 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index ace8e18..d953e63 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -1574,20 +1574,55 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
/*
- set the user password using plaintext, obeying any user or domain
- password restrictions
+ * Performs checks on a user password (plaintext UTF 16 format - attribute
+ * "password"). The remaining parameters have to be extracted from the domain
+ * object in the AD.
+ *
+ * Result codes from "enum samr_ValidationStatus" (consider "samr.idl")
+ */
+enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ const DATA_BLOB *password,
+ const uint32_t pwdProperties,
+ const uint32_t minPwdLength)
+{
+ char *utf8_password;
+ size_t utf8_password_len;
- note that this function doesn't actually store the result in the
- database, it just fills in the "mod" structure with ldb modify
- elements to setup the correct change when samdb_replace() is
- called. This allows the caller to combine the change with other
- changes (as is needed by some of the set user info levels)
+ /* checks if the "minPwdLength" property is satisfied */
+ if (minPwdLength > utf16_len_n(password->data, password->length) / 2)
+ return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
- The caller should probably have a transaction wrapping this
-*/
+ /* Try to convert the password to UTF8 and perform other checks */
+ if (convert_string_talloc_convenience(mem_ctx,
+ lp_iconv_convenience(lp_ctx),
+ CH_UTF16MUNGED, CH_UTF8,
+ password->data, password->length,
+ (void **)&utf8_password,
+ &utf8_password_len, false)) {
+ /* checks the password complexity */
+ if (((pwdProperties & DOMAIN_PASSWORD_COMPLEX) != 0)
+ && (!check_password_quality(utf8_password)))
+ return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
+ }
+
+ return SAMR_VALIDATION_STATUS_SUCCESS;
+}
+
+/*
+ * Sets the user password using plaintext UTF16 (attribute "new_password") or
+ * LM (attribute "lmNewHash") or NT (attribute "ntNewHash") hash. Also pass
+ * as parameter if it's a user change or not ("userChange"). The "rejectReason"
+ * gives some more informations if the changed failed.
+ *
+ * The caller should have a LDB transaction wrapping this.
+ *
+ * Results: NT_STATUS_OK, NT_STATUS_INTERNAL_DB_CORRUPTION,
+ * NT_STATUS_INVALID_PARAMETER, NT_STATUS_UNSUCCESSFUL,
+ * NT_STATUS_PASSWORD_RESTRICTION
+ */
NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
- struct ldb_dn *user_dn,
- struct ldb_dn *domain_dn,
+ struct ldb_dn *user_dn, struct ldb_dn *domain_dn,
struct ldb_message *mod,
const DATA_BLOB *new_password,
struct samr_Password *param_lmNewHash,
@@ -1851,16 +1886,24 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
/*
- set the user password using plaintext, obeying any user or domain
- password restrictions
-
- This wrapper function takes a SID as input, rather than a user DN,
- and actually performs the password change
-
-*/
-NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
+ * Sets the user password using plaintext UTF16 (attribute "new_password") or
+ * LM (attribute "lmNewHash") or NT (attribute "ntNewHash") hash. Also pass
+ * as parameter if it's a user change or not ("userChange"). The "rejectReason"
+ * gives some more informations if the changed failed.
+ *
+ * This wrapper function for "samdb_set_password" takes a SID as input rather
+ * than a user DN.
+ *
+ * This call encapsulates a new LDB transaction for changing the password;
+ * therefore the user hasn't to start a new one.
+ *
+ * Results: NT_STATUS_OK, NT_STATUS_INTERNAL_DB_CORRUPTION,
+ * NT_STATUS_INVALID_PARAMETER, NT_STATUS_UNSUCCESSFUL,
+ * NT_STATUS_PASSWORD_RESTRICTION
+ */
+NTSTATUS samdb_set_password_sid(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
const struct dom_sid *user_sid,
- const DATA_BLOB *new_pass,
+ const DATA_BLOB *new_password,
struct samr_Password *lmNewHash,
struct samr_Password *ntNewHash,
bool user_change,
@@ -1872,17 +1915,17 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
struct ldb_message *msg;
int ret;
- ret = ldb_transaction_start(ctx);
- if (ret) {
- DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(ctx)));
+ ret = ldb_transaction_start(ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(ldb)));
return NT_STATUS_TRANSACTION_ABORTED;
}
- user_dn = samdb_search_dn(ctx, mem_ctx, NULL,
+ user_dn = samdb_search_dn(ldb, mem_ctx, NULL,
"(&(objectSid=%s)(objectClass=user))",
ldap_encode_ndr_dom_sid(mem_ctx, user_sid));
if (!user_dn) {
- ldb_transaction_cancel(ctx);
+ ldb_transaction_cancel(ldb);
DEBUG(3, ("samdb_set_password_sid: SID %s not found in samdb, returning NO_SUCH_USER\n",
dom_sid_string(mem_ctx, user_sid)));
return NT_STATUS_NO_SUCH_USER;
@@ -1890,46 +1933,45 @@ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
- ldb_transaction_cancel(ctx);
+ ldb_transaction_cancel(ldb);
return NT_STATUS_NO_MEMORY;
}
msg->dn = ldb_dn_copy(msg, user_dn);
if (!msg->dn) {
- ldb_transaction_cancel(ctx);
+ ldb_transaction_cancel(ldb);
return NT_STATUS_NO_MEMORY;
}
- nt_status = samdb_set_password(ctx, mem_ctx,
+ nt_status = samdb_set_password(ldb, mem_ctx,
user_dn, NULL,
- msg, new_pass,
+ msg, new_password,
lmNewHash, ntNewHash,
user_change, /* This is a password set, not change */
reject_reason, _dominfo);
if (!NT_STATUS_IS_OK(nt_status)) {
- ldb_transaction_cancel(ctx);
+ ldb_transaction_cancel(ldb);
return nt_status;
}
/* modify the samdb record */
- ret = samdb_replace(ctx, mem_ctx, msg);
- if (ret != 0) {
- ldb_transaction_cancel(ctx);
+ ret = samdb_replace(ldb, mem_ctx, msg);
+ if (ret != LDB_SUCCESS) {
+ ldb_transaction_cancel(ldb);
return NT_STATUS_ACCESS_DENIED;
}
- ret = ldb_transaction_commit(ctx);
- if (ret != 0) {
+ ret = ldb_transaction_commit(ldb);
+ if (ret != LDB_SUCCESS) {
DEBUG(0,("Failed to commit transaction to change password on %s: %s\n",
ldb_dn_get_linearized(msg->dn),
- ldb_errstring(ctx)));
+ ldb_errstring(ldb)));
return NT_STATUS_TRANSACTION_ABORTED;
}
return NT_STATUS_OK;
}
-
NTSTATUS samdb_create_foreign_security_principal(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
struct dom_sid *sid, struct ldb_dn **ret_dn)
{
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 7be1cf9..eecc00d 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -4179,7 +4179,9 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
ZERO_STRUCTP(r->out.info);
- sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
@@ -4354,15 +4356,55 @@ static NTSTATUS dcesrv_samr_SetDsrmPassword(struct dcesrv_call_state *dce_call,
/*
- samr_ValidatePassword
+ samr_ValidatePassword
+
+ For now the call checks the password complexity (if active) and the minimum
+ password length on level 2 and 3. Level 1 is ignored for now.
*/
-static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct samr_ValidatePassword *r)
+static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct samr_ValidatePassword *r)
{
- /* just say it's OK for now - we need to hook this into our
- password strength code later */
- DEBUG(0,(__location__ ": Faking samr_ValidatePassword reply\n"));
+ struct samr_GetDomPwInfo r2;
+ DATA_BLOB password;
+ enum samr_ValidationStatus res;
+ NTSTATUS status;
+
(*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep);
+
+ r2.in.domain_name = NULL;
+ status = dcesrv_samr_GetDomPwInfo(dce_call, mem_ctx, &r2);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ switch (r->in.level) {
+ case NetValidateAuthentication:
+ /* we don't support this yet */
+ return NT_STATUS_NOT_SUPPORTED;
+ break;
+ case NetValidatePasswordChange:
+ password = data_blob_const(r->in.req->req2.password.string,
+ r->in.req->req2.password.length);
+ res = samdb_check_password(mem_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ &password,
+ r2.out.info->password_properties,
+ r2.out.info->min_password_length);
+ (*r->out.rep)->ctr2.status = res;
+ break;
+ case NetValidatePasswordReset:
+ password = data_blob_const(r->in.req->req3.password.string,
+ r->in.req->req3.password.length);
+ res = samdb_check_password(mem_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ &password,
+ r2.out.info->password_properties,
+ r2.out.info->min_password_length);
+ (*r->out.rep)->ctr3.status = res;
+ break;
+ }
+
return NT_STATUS_OK;
}
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 41de9d8..5462e3a 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -6765,6 +6765,8 @@ static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_con
const char *passwords[] = { "penguin", "p at ssw0rd", "p at ssw0rd123$", NULL };
int i;
+ torture_comment(tctx, "testing samr_ValidatePassword\n");
+
ZERO_STRUCT(r);
r.in.level = NetValidatePasswordReset;
r.in.req = &req;
--
Samba Shared Repository
More information about the samba-cvs
mailing list