The branch, master has been updated
       via  d6ccd4c... s4:ldap_backend.c - fix a DS error code after WERROR 
change
       via  7ffae93... werror.h - fix order and duplicate DS error codes
       via  ab3e20b... s4:libnet - free the "c" context also on error conditions
       via  2de63aa... talloc:documentation - explain that "talloc_free" works 
also with "NULL" pointers
       via  07af3f2... s4:samdb_set_password - return 
"NT_STATUS_WRONG_PASSWORD" when a user account doesn't exist
       via  1fa9e99... s4:password_hash LDB module - improve an error message
       via  4b569d7... s4:password_hash LDB module - implement the SAMR 
behaviour when checking old passwords
       via  e335b24... s4:password_hash LDB module - fix wrong error codes
       via  a9b0552... s4:passwords.py - test the error code when there doesn't 
exist any password yet
       via  c335c5f... s4:passwords.py - perform testing of wrong old passwords 
on change operations
       via  4f63770... s4:torture/rpc/samr.c - fix a wrong torture error message
      from  13a4922... s3: Remove a conn NULL check from claim_connection

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


- Log -----------------------------------------------------------------
commit d6ccd4c9daaaf19e9fb4dd16ba8b6599d28ef1d5
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 19:44:58 2010 +0200

    s4:ldap_backend.c - fix a DS error code after WERROR change

commit 7ffae937625afa59f2e554f4aa7dc2113699f7df
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 19:41:46 2010 +0200

    werror.h - fix order and duplicate DS error codes

commit ab3e20b82fca206d03a68acc501fdbd5a59b47a7
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 18:47:15 2010 +0200

    s4:libnet - free the "c" context also on error conditions
    
    (and if it's NULL then "talloc_free" does ignore it)

commit 2de63aa2801a907905b3e05557074af5b896d486
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 18:36:49 2010 +0200

    talloc:documentation - explain that "talloc_free" works also with "NULL" 
pointers
    
    (talloc.c)
    ...
    > static inline int _talloc_free_internal(void *ptr, const char *location)
    > {
    >        struct talloc_chunk *tc;
    >
    >        if (unlikely(ptr == NULL)) {
    >                return -1;
    >        }
    >
    >        tc = talloc_chunk_from_ptr(ptr);
    ...
    
    Obviously this never had been documented before.

commit 07af3f289e403396a9ddef744cf42e2badc1f1cc
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 17:11:40 2010 +0200

    s4:samdb_set_password - return "NT_STATUS_WRONG_PASSWORD" when a user 
account doesn't exist
    
    This is for the (SAMR) account detection protection mechanism.

commit 1fa9e994423b96cc6a13682f79e827cae6850553
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 17:10:59 2010 +0200

    s4:password_hash LDB module - improve an error message

commit 4b569d74a4be62a65e9c6ef1248eb83eae215831
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 11:51:47 2010 +0200

    s4:password_hash LDB module - implement the SAMR behaviour when checking 
old passwords
    
    Sooner or later this module should take over all password change actions.

commit e335b24ad00c3398f2bd4b7da9c4df6087597121
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 11:19:29 2010 +0200

    s4:password_hash LDB module - fix wrong error codes
    
    To match the passwords.py test

commit a9b055291c39198be5fb1648ba1f51418af16e09
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 11:59:47 2010 +0200

    s4:passwords.py - test the error code when there doesn't exist any password 
yet
    
    After the creation of a user object we don't have any password yet.

commit c335c5f54a2bb174b558f7edaced468e597c7ed6
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 10:46:38 2010 +0200

    s4:passwords.py - perform testing of wrong old passwords on change 
operations

commit 4f6377043dc7a524a2afd05cd151c82350f06cfe
Author: Matthias Dieter Wallnöfer <[email protected]>
Date:   Sat Aug 14 11:19:53 2010 +0200

    s4:torture/rpc/samr.c - fix a wrong torture error message

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

Summary of changes:
 lib/talloc/talloc.h                            |   31 +++++--
 lib/talloc/talloc_guide.txt                    |    9 +-
 libcli/util/doserr.c                           |    5 +-
 libcli/util/werror.h                           |  111 +++++++++++------------
 source4/dsdb/common/util.c                     |    2 +
 source4/dsdb/samdb/ldb_modules/password_hash.c |   33 +++++---
 source4/dsdb/tests/python/passwords.py         |   72 +++++++++++++++-
 source4/ldap_server/ldap_backend.c             |    2 +-
 source4/libnet/libnet_group.c                  |    1 +
 source4/libnet/libnet_user.c                   |    3 +-
 source4/torture/rpc/samr.c                     |    2 +-
 11 files changed, 177 insertions(+), 94 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h
index c59fd35..187d7e7 100644
--- a/lib/talloc/talloc.h
+++ b/lib/talloc/talloc.h
@@ -158,16 +158,25 @@ void *talloc_init(const char *fmt, ...) 
PRINTF_ATTRIBUTE(1,2);
 /**
  * @brief Free a chunk of talloc memory.
  *
- * This function frees a piece of talloc memory, and all its children. It
- * operates recursively on its children. You can call talloc_free() on any
- * pointer returned by talloc().
+ * The talloc_free() function frees a piece of talloc memory, and all its
+ * children. You can call talloc_free() on any pointer returned by
+ * talloc().
  *
- * If this pointer has an additional parent when talloc_free() is called then
- * the memory is not actually released, but instead the most recently
- * established parent is destroyed. See talloc_reference() for details on
- * establishing additional parents.
+ * The return value of talloc_free() indicates success or failure, with 0
+ * returned for success and -1 for failure. A possible failure condition
+ * is if the pointer had a destructor attached to it and the destructor
+ * returned -1. See talloc_set_destructor() for details on
+ * destructors. Likewise, if "ptr" is NULL, then the function will make
+ * no modifications and return -1.
  *
- * For more control on which parent is removed, see talloc_unlink().
+ * If this pointer has an additional parent when talloc_free() is called
+ * then the memory is not actually released, but instead the most
+ * recently established parent is destroyed. See talloc_reference() for
+ * details on establishing additional parents.
+ *
+ * For more control on which parent is removed, see talloc_unlink()
+ *
+ * talloc_free() operates recursively on its children.
  *
  * From the 2.0 version of talloc, as a special case, talloc_free() is
  * refused on pointers that have more than one parent, as talloc would
@@ -190,9 +199,11 @@ void *talloc_init(const char *fmt, ...) 
PRINTF_ATTRIBUTE(1,2);
  *
  * @param[in]  ptr      The chunk to be freed.
  *
- * @return              Returns 0 on success and -1 on error. The only possible
+ * @return              Returns 0 on success and -1 on error. A possible
  *                      failure condition is if the pointer had a destructor
- *                      attached to it and the destructor returned -1.
+ *                      attached to it and the destructor returned -1. 
Likewise,
+ *                      if "ptr" is NULL, then the function will make no
+ *                      modifications and returns -1.
  *
  * Example:
  * @code
diff --git a/lib/talloc/talloc_guide.txt b/lib/talloc/talloc_guide.txt
index 79387bf..a79fd03 100644
--- a/lib/talloc/talloc_guide.txt
+++ b/lib/talloc/talloc_guide.txt
@@ -117,10 +117,11 @@ children. You can call talloc_free() on any pointer 
returned by
 talloc().
 
 The return value of talloc_free() indicates success or failure, with 0
-returned for success and -1 for failure. The only possible failure
-condition is if the pointer had a destructor attached to it and the
-destructor returned -1. See talloc_set_destructor() for details on
-destructors.
+returned for success and -1 for failure. A possible failure condition
+is if the pointer had a destructor attached to it and the destructor
+returned -1. See talloc_set_destructor() for details on
+destructors. Likewise, if "ptr" is NULL, then the function will make
+no modifications and returns -1.
 
 If this pointer has an additional parent when talloc_free() is called
 then the memory is not actually released, but instead the most
diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c
index 958c617..fd0233c 100644
--- a/libcli/util/doserr.c
+++ b/libcli/util/doserr.c
@@ -126,7 +126,6 @@ static const struct werror_code_struct dos_errs[] =
        { "WERR_DS_OPERATIONS_ERROR", WERR_DS_OPERATIONS_ERROR },
        { "WERR_DS_PROTOCOL_ERROR", WERR_DS_PROTOCOL_ERROR },
        { "WERR_DS_TIMELIMIT_EXCEEEDED", WERR_DS_TIMELIMIT_EXCEEDED },
-       { "WERR_DS_SIZE_LIMIT_EXCEEDED", WERR_DS_SIZE_LIMIT_EXCEEDED },
        { "WERR_DS_ADMIN_LIMIT_EXCEEEDED", WERR_DS_ADMIN_LIMIT_EXCEEDED },
        { "WERR_DS_COMPARE_FALSE", WERR_DS_COMPARE_FALSE },
        { "WERR_DS_COMPARE_TRUE", WERR_DS_COMPARE_TRUE },
@@ -165,7 +164,6 @@ static const struct werror_code_struct dos_errs[] =
        { "WERR_DS_DRA_ACCESS_DENIED", WERR_DS_DRA_ACCESS_DENIED },
        { "WERR_DS_DRA_SOURCE_DISABLED", WERR_DS_DRA_SOURCE_DISABLED },
        { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE },
-       { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", 
WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX },
        { "WERR_DS_NO_MSDS_INTID", WERR_DS_NO_MSDS_INTID },
        { "WERR_DS_DUP_MSDS_INTID", WERR_DS_DUP_MSDS_INTID },
        { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE },
@@ -1962,7 +1960,6 @@ static const struct werror_code_struct dos_errs[] =
        { "WERR_FRS_ERR_INVALID_SERVICE_PARAMETER", 
WERR_FRS_ERR_INVALID_SERVICE_PARAMETER },
        { "WERR_DS_NOT_INSTALLED", WERR_DS_NOT_INSTALLED },
        { "WERR_DS_MEMBERSHIP_EVALUATED_LOCALLY", 
WERR_DS_MEMBERSHIP_EVALUATED_LOCALLY },
-       { "WERR_DS_INVALID_ATTRIBUTE_YNTAX", WERR_DS_INVALID_ATTRIBUTE_YNTAX },
        { "WERR_DS_NO_RIDS_ALLOCATED", WERR_DS_NO_RIDS_ALLOCATED },
        { "WERR_DS_NO_MORE_RIDS", WERR_DS_NO_MORE_RIDS },
        { "WERR_DS_INCORRECT_ROLE_OWNER", WERR_DS_INCORRECT_ROLE_OWNER },
@@ -4473,7 +4470,7 @@ const struct werror_str_struct dos_err_strs[] = {
        { WERR_DS_NOT_INSTALLED, "An error occurred while installing the 
directory service. For more information, see the event log." },
        { WERR_DS_MEMBERSHIP_EVALUATED_LOCALLY, "The directory service 
evaluated group memberships locally." },
        { WERR_DS_NO_ATTRIBUTE_OR_VALUE, "The specified directory service 
attribute or value does not exist." },
-       { WERR_DS_INVALID_ATTRIBUTE_YNTAX, "The attribute syntax specified to 
the directory service is invalid." },
+       { WERR_DS_INVALID_ATTRIBUTE_SYNTAX, "The attribute syntax specified to 
the directory service is invalid." },
        { WERR_DS_ATTRIBUTE_TYPE_UNDEFINED, "The attribute type specified to 
the directory service is not defined." },
        { WERR_DS_ATTRIBUTE_OR_VALUE_EXISTS, "The specified directory service 
attribute or value already exists." },
        { WERR_DS_BUSY, "The directory service is busy." },
diff --git a/libcli/util/werror.h b/libcli/util/werror.h
index ac4fb37..3b717d2 100644
--- a/libcli/util/werror.h
+++ b/libcli/util/werror.h
@@ -234,63 +234,6 @@ typedef uint32_t WERROR;
 #define WERR_SETUP_DOMAIN_CONTROLLER   W_ERROR(0x00000A85)
 #define WERR_DEFAULT_JOIN_REQUIRED     W_ERROR(0x00000A86)
 
-/* DS errors */
-#define WERR_DS_NO_ATTRIBUTE_OR_VALUE W_ERROR(0x0000200A)
-#define WERR_DS_INVALID_ATTRIBUTE_SYNTAX W_ERROR(0x0000200B)
-#define WERR_DS_ATTRIBUTE_TYPE_UNDEFINED W_ERROR(0x0000200C)
-#define WERR_DS_ATTRIBUTE_OR_VALUE_EXISTS W_ERROR(0x0000200D)
-#define WERR_DS_BUSY W_ERROR(0x0000200E)
-#define WERR_DS_UNAVAILABLE W_ERROR(0x0000200F)
-#define WERR_DS_OBJ_CLASS_VIOLATION W_ERROR(0x00002014)
-#define WERR_DS_CANT_ON_NON_LEAF W_ERROR(0x00002015)
-#define WERR_DS_CANT_ON_RDN W_ERROR(0x00002016)
-#define WERR_DS_CANT_MOD_OBJ_CLASS W_ERROR(0x00002017)
-#define WERR_DS_OPERATIONS_ERROR W_ERROR(0x00002020)
-#define WERR_DS_PROTOCOL_ERROR W_ERROR(0x00002021)
-#define WERR_DS_TIMELIMIT_EXCEEDED W_ERROR(0x00002022)
-#define WERR_DS_SIZE_LIMIT_EXCEEDED W_ERROR(0x00002023)
-#define WERR_DS_ADMIN_LIMIT_EXCEEDED W_ERROR(0x00002024)
-#define WERR_DS_COMPARE_FALSE W_ERROR(0x00002025)
-#define WERR_DS_COMPARE_TRUE W_ERROR(0x00002026)
-#define WERR_DS_AUTH_METHOD_NOT_SUPPORTED W_ERROR(0x00002027)
-#define WERR_DS_STRONG_AUTH_REQUIRED W_ERROR(0x00002028)
-#define WERR_DS_INAPPROPRIATE_AUTH W_ERROR(0x00002029)
-#define WERR_DS_REFERRAL W_ERROR(0x0000202B)
-#define WERR_DS_UNAVAILABLE_CRIT_EXTENSION W_ERROR(0x0000202C)
-#define WERR_DS_CONFIDENTIALITY_REQUIRED W_ERROR(0x0000202D)
-#define WERR_DS_INAPPROPRIATE_MATCHING W_ERROR(0x0000202E)
-#define WERR_DS_CONSTRAINT_VIOLATION W_ERROR(0x0000202F)
-#define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030)
-#define WERR_DS_ALIAS_PROBLEM W_ERROR(0x00002031)
-#define WERR_DS_INVALID_DN_SYNTAX W_ERROR(0x00002032)
-#define WERR_DS_ALIAS_DEREF_PROBLEM W_ERROR(0x00002034)
-#define WERR_DS_UNWILLING_TO_PERFORM W_ERROR(0x00002035)
-#define WERR_DS_LOOP_DETECT W_ERROR(0x00002036)
-#define WERR_DS_NAMING_VIOLATION W_ERROR(0x00002037)
-#define WERR_DS_AFFECTS_MULTIPLE_DSAS W_ERROR(0x00002039)
-#define WERR_DS_OBJ_STRING_NAME_EXISTS W_ERROR(0x00002071)
-#define WERR_DS_OBJ_NOT_FOUND W_ERROR(0x0000208D)
-#define WERR_DS_GENERIC_ERROR W_ERROR(0x00002095)
-#define WERR_DS_INSUFF_ACCESS_RIGHTS W_ERROR(0x00002098)
-#define WERR_DS_SCHEMA_NOT_LOADED W_ERROR(0x20DE)
-#define WERR_DS_SCHEMA_ALLOC_FAILED W_ERROR(0x20DF)
-#define WERR_DS_ATT_SCHEMA_REQ_SYNTAX W_ERROR(0x000020E0)
-#define WERR_DS_DRA_SCHEMA_MISMATCH W_ERROR(0x000020E2)
-#define WERR_DS_DRA_INVALID_PARAMETER W_ERROR(0x000020F5)
-#define WERR_DS_DRA_BAD_DN W_ERROR(0x000020F7)
-#define WERR_DS_DRA_BAD_NC W_ERROR(0x000020F8)
-#define WERR_DS_DRA_INTERNAL_ERROR W_ERROR(0x000020FA)
-#define WERR_DS_DRA_OUT_OF_MEM W_ERROR(0x000020FE)
-#define WERR_DS_SINGLE_VALUE_CONSTRAINT W_ERROR(0x00002081)
-#define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103)
-#define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104)
-#define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105)
-#define WERR_DS_DRA_SOURCE_DISABLED W_ERROR(0x00002108)
-#define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214C)
-#define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150)
-#define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194)
-#define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195)
-
 /* FRS errors */
 #define WERR_FRS_INSUFFICIENT_PRIV W_ERROR(0x00001F47)
 #define WERR_FRS_SYSVOL_IS_BUSY W_ERROR(0x00001F4F)
@@ -2057,11 +2000,20 @@ typedef uint32_t WERROR;
 #define WERR_FRS_ERR_INVALID_SERVICE_PARAMETER W_ERROR(0x00001F51)
 #define WERR_DS_NOT_INSTALLED  W_ERROR(0x00002008)
 #define WERR_DS_MEMBERSHIP_EVALUATED_LOCALLY   W_ERROR(0x00002009)
-#define WERR_DS_INVALID_ATTRIBUTE_YNTAX        W_ERROR(0x0000200B)
+#define WERR_DS_NO_ATTRIBUTE_OR_VALUE  W_ERROR(0x0000200A)
+#define WERR_DS_INVALID_ATTRIBUTE_SYNTAX       W_ERROR(0x0000200B)
+#define WERR_DS_ATTRIBUTE_TYPE_UNDEFINED       W_ERROR(0x0000200C)
+#define WERR_DS_ATTRIBUTE_OR_VALUE_EXISTS      W_ERROR(0x0000200D)
+#define WERR_DS_BUSY   W_ERROR(0x0000200E)
+#define WERR_DS_UNAVAILABLE    W_ERROR(0x0000200F)
 #define WERR_DS_NO_RIDS_ALLOCATED      W_ERROR(0x00002010)
 #define WERR_DS_NO_MORE_RIDS   W_ERROR(0x00002011)
 #define WERR_DS_INCORRECT_ROLE_OWNER   W_ERROR(0x00002012)
 #define WERR_DS_RIDMGR_INIT_ERROR      W_ERROR(0x00002013)
+#define WERR_DS_OBJ_CLASS_VIOLATION    W_ERROR(0x00002014)
+#define WERR_DS_CANT_ON_NON_LEAF       W_ERROR(0x00002015)
+#define WERR_DS_CANT_ON_RDN     W_ERROR(0x00002016)
+#define WERR_DS_CANT_MOD_OBJ_CLASS     W_ERROR(0x00002017)
 #define WERR_DS_CROSS_DOM_MOVE_ERROR   W_ERROR(0x00002018)
 #define WERR_DS_GC_NOT_AVAILABLE       W_ERROR(0x00002019)
 #define WERR_SHARED_POLICY     W_ERROR(0x0000201A)
@@ -2069,10 +2021,32 @@ typedef uint32_t WERROR;
 #define WERR_POLICY_ONLY_IN_DS W_ERROR(0x0000201C)
 #define WERR_PROMOTION_ACTIVE  W_ERROR(0x0000201D)
 #define WERR_NO_PROMOTION_ACTIVE       W_ERROR(0x0000201E)
+#define WERR_DS_OPERATIONS_ERROR       W_ERROR(0x00002020)
+#define WERR_DS_PROTOCOL_ERROR         W_ERROR(0x00002021)
+#define WERR_DS_TIMELIMIT_EXCEEDED     W_ERROR(0x00002022)
 #define WERR_DS_SIZELIMIT_EXCEEDED     W_ERROR(0x00002023)
+#define WERR_DS_ADMIN_LIMIT_EXCEEDED   W_ERROR(0x00002024)
+#define WERR_DS_COMPARE_FALSE  W_ERROR(0x00002025)
+#define WERR_DS_COMPARE_TRUE   W_ERROR(0x00002026)
+#define WERR_DS_AUTH_METHOD_NOT_SUPPORTED      W_ERROR(0x00002027)
+#define WERR_DS_STRONG_AUTH_REQUIRED   W_ERROR(0x00002028)
+#define WERR_DS_INAPPROPRIATE_AUTH     W_ERROR(0x00002029)
 #define WERR_DS_AUTH_UNKNOWN   W_ERROR(0x0000202A)
+#define WERR_DS_REFERRAL       W_ERROR(0x0000202B)
+#define WERR_DS_UNAVAILABLE_CRIT_EXTENSION     W_ERROR(0x0000202C)
+#define WERR_DS_CONFIDENTIALITY_REQUIRED       W_ERROR(0x0000202D)
+#define WERR_DS_INAPPROPRIATE_MATCHING W_ERROR(0x0000202E)
+#define WERR_DS_CONSTRAINT_VIOLATION   W_ERROR(0x0000202F)
+#define WERR_DS_NO_SUCH_OBJECT W_ERROR(0x00002030)
+#define WERR_DS_ALIAS_PROBLEM  W_ERROR(0x00002031)
+#define WERR_DS_INVALID_DN_SYNTAX      W_ERROR(0x00002032)
 #define WERR_DS_IS_LEAF        W_ERROR(0x00002033)
+#define WERR_DS_ALIAS_DEREF_PROBLEM    W_ERROR(0x00002034)
+#define WERR_DS_UNWILLING_TO_PERFORM   W_ERROR(0x00002035)
+#define WERR_DS_LOOP_DETECT    W_ERROR(0x00002036)
+#define WERR_DS_NAMING_VIOLATION       W_ERROR(0x00002037)
 #define WERR_DS_OBJECT_RESULTS_TOO_LARGE       W_ERROR(0x00002038)
+#define WERR_DS_AFFECTS_MULTIPLE_DSAS  W_ERROR(0x00002039)
 #define WERR_DS_SERVER_DOWN    W_ERROR(0x0000203A)
 #define WERR_DS_LOCAL_ERROR    W_ERROR(0x0000203B)
 #define WERR_DS_ENCODING_ERROR W_ERROR(0x0000203C)
@@ -2090,6 +2064,7 @@ typedef uint32_t WERROR;
 #define WERR_DS_ADD_REPLICA_INHIBITED  W_ERROR(0x0000206E)
 #define WERR_DS_ATT_NOT_DEF_IN_SCHEMA  W_ERROR(0x0000206F)
 #define WERR_DS_MAX_OBJ_SIZE_EXCEEDED  W_ERROR(0x00002070)
+#define WERR_DS_OBJ_STRING_NAME_EXISTS W_ERROR(0x00002071)
 #define WERR_DS_NO_RDN_DEFINED_IN_SCHEMA       W_ERROR(0x00002072)
 #define WERR_DS_RDN_DOESNT_MATCH_SCHEMA        W_ERROR(0x00002073)
 #define WERR_DS_NO_REQUESTED_ATTS_FOUND        W_ERROR(0x00002074)
@@ -2104,6 +2079,7 @@ typedef uint32_t WERROR;
 #define WERR_DS_ATT_NOT_DEF_FOR_CLASS  W_ERROR(0x0000207D)
 #define WERR_DS_ATT_ALREADY_EXISTS     W_ERROR(0x0000207E)
 #define WERR_DS_CANT_ADD_ATT_VALUES    W_ERROR(0x00002080)
+#define WERR_DS_SINGLE_VALUE_CONSTRAINT        W_ERROR(0x00002081)
 #define WERR_DS_RANGE_CONSTRAINT       W_ERROR(0x00002082)
 #define WERR_DS_ATT_VAL_ALREADY_EXISTS W_ERROR(0x00002083)
 #define WERR_DS_CANT_REM_MISSING_ATT   W_ERROR(0x00002084)
@@ -2115,6 +2091,7 @@ typedef uint32_t WERROR;
 #define WERR_DS_PARENT_IS_AN_ALIAS     W_ERROR(0x0000208A)
 #define WERR_DS_CANT_MIX_MASTER_AND_REPS       W_ERROR(0x0000208B)
 #define WERR_DS_CHILDREN_EXIST W_ERROR(0x0000208C)
+#define WERR_DS_OBJ_NOT_FOUND  W_ERROR(0x0000208D)
 #define WERR_DS_ALIASED_OBJ_MISSING    W_ERROR(0x0000208E)
 #define WERR_DS_BAD_NAME_SYNTAX        W_ERROR(0x0000208F)
 #define WERR_DS_ALIAS_POINTS_TO_ALIAS  W_ERROR(0x00002090)
@@ -2122,8 +2099,10 @@ typedef uint32_t WERROR;
 #define WERR_DS_OUT_OF_SCOPE   W_ERROR(0x00002092)
 #define WERR_DS_OBJECT_BEING_REMOVED   W_ERROR(0x00002093)
 #define WERR_DS_CANT_DELETE_DSA_OBJ    W_ERROR(0x00002094)
+#define WERR_DS_GENERIC_ERROR  W_ERROR(0x00002095)
 #define WERR_DS_DSA_MUST_BE_INT_MASTER W_ERROR(0x00002096)
 #define WERR_DS_CLASS_NOT_DSA  W_ERROR(0x00002097)
+#define WERR_DS_INSUFF_ACCESS_RIGHTS   W_ERROR(0x00002098)
 #define WERR_DS_ILLEGAL_SUPERIOR       W_ERROR(0x00002099)
 #define WERR_DS_ATTRIBUTE_OWNED_BY_SAM W_ERROR(0x0000209A)
 #define WERR_DS_NAME_TOO_MANY_PARTS    W_ERROR(0x0000209B)
@@ -2192,7 +2171,11 @@ typedef uint32_t WERROR;
 #define WERR_DS_MISSING_EXPECTED_ATT   W_ERROR(0x000020DB)
 #define WERR_DS_NCNAME_MISSING_CR_REF  W_ERROR(0x000020DC)
 #define WERR_DS_SECURITY_CHECKING_ERROR        W_ERROR(0x000020DD)
+#define WERR_DS_SCHEMA_NOT_LOADED      W_ERROR(0x20DE)
+#define WERR_DS_SCHEMA_ALLOC_FAILED    W_ERROR(0x20DF)
+#define WERR_DS_ATT_SCHEMA_REQ_SYNTAX  W_ERROR(0x000020E0)
 #define WERR_DS_GCVERIFY_ERROR W_ERROR(0x000020E1)
+#define WERR_DS_DRA_SCHEMA_MISMATCH    W_ERROR(0x000020E2)
 #define WERR_DS_CANT_FIND_DSA_OBJ      W_ERROR(0x000020E3)
 #define WERR_DS_CANT_FIND_EXPECTED_NC  W_ERROR(0x000020E4)
 #define WERR_DS_CANT_FIND_NC_IN_CACHE  W_ERROR(0x000020E5)
@@ -2211,17 +2194,26 @@ typedef uint32_t WERROR;
 #define WERR_DS_MISSING_FSMO_SETTINGS  W_ERROR(0x000020F2)
 #define WERR_DS_UNABLE_TO_SURRENDER_ROLES      W_ERROR(0x000020F3)
 #define WERR_DS_DRA_GENERIC    W_ERROR(0x000020F4)
+#define WERR_DS_DRA_INVALID_PARAMETER  W_ERROR(0x000020F5)
 #define WERR_DS_DRA_BUSY       W_ERROR(0x000020F6)
+#define WERR_DS_DRA_BAD_DN     W_ERROR(0x000020F7)
+#define WERR_DS_DRA_BAD_NC     W_ERROR(0x000020F8)
 #define WERR_DS_DRA_DN_EXISTS  W_ERROR(0x000020F9)
+#define WERR_DS_DRA_INTERNAL_ERROR     W_ERROR(0x000020FA)
 #define WERR_DS_DRA_INCONSISTENT_DIT   W_ERROR(0x000020FB)
 #define WERR_DS_DRA_CONNECTION_FAILED  W_ERROR(0x000020FC)
 #define WERR_DS_DRA_BAD_INSTANCE_TYPE  W_ERROR(0x000020FD)
+#define WERR_DS_DRA_OUT_OF_MEM W_ERROR(0x000020FE)
 #define WERR_DS_DRA_MAIL_PROBLEM       W_ERROR(0x000020FF)
 #define WERR_DS_DRA_REF_ALREADY_EXISTS W_ERROR(0x00002100)
 #define WERR_DS_DRA_REF_NOT_FOUND      W_ERROR(0x00002101)
 #define WERR_DS_DRA_OBJ_IS_REP_SOURCE  W_ERROR(0x00002102)
+#define WERR_DS_DRA_DB_ERROR   W_ERROR(0x00002103)
+#define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104)
+#define WERR_DS_DRA_ACCESS_DENIED      W_ERROR(0x00002105)
 #define WERR_DS_DRA_NOT_SUPPORTED      W_ERROR(0x00002106)
 #define WERR_DS_DRA_RPC_CANCELLED      W_ERROR(0x00002107)
+#define WERR_DS_DRA_SOURCE_DISABLED    W_ERROR(0x00002108)
 #define WERR_DS_DRA_SINK_DISABLED      W_ERROR(0x00002109)
 #define WERR_DS_DRA_NAME_COLLISION     W_ERROR(0x0000210A)
 #define WERR_DS_DRA_SOURCE_REINSTALLED W_ERROR(0x0000210B)
@@ -2287,6 +2279,7 @@ typedef uint32_t WERROR;
 #define WERR_DS_HAVE_PRIMARY_MEMBERS   W_ERROR(0x00002149)
 #define WERR_DS_STRING_SD_CONVERSION_FAILED    W_ERROR(0x0000214A)
 #define WERR_DS_NAMING_MASTER_GC       W_ERROR(0x0000214B)
+#define WERR_DS_DNS_LOOKUP_FAILURE     W_ERROR(0x0000214C)
 #define WERR_DS_COULDNT_UPDATE_SPNS    W_ERROR(0x0000214D)
 #define WERR_DS_CANT_RETRIEVE_SD       W_ERROR(0x0000214E)
 #define WERR_DS_KEY_NOT_UNIQUE W_ERROR(0x0000214F)
@@ -2356,6 +2349,8 @@ typedef uint32_t WERROR;
 #define WERR_DS_DIFFERENT_REPL_EPOCHS  W_ERROR(0x00002191)
 #define WERR_DS_DRS_EXTENSIONS_CHANGED W_ERROR(0x00002192)
 #define WERR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR  
W_ERROR(0x00002193)
+#define WERR_DS_NO_MSDS_INTID  W_ERROR(0x00002194)
+#define WERR_DS_DUP_MSDS_INTID W_ERROR(0x00002195)
 #define WERR_DS_EXISTS_IN_RDNATTID     W_ERROR(0x00002196)
 #define WERR_DS_AUTHORIZATION_FAILED   W_ERROR(0x00002197)
 #define WERR_DS_INVALID_SCRIPT W_ERROR(0x00002198)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 7c5fd8a..be8e3a9 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2147,6 +2147,8 @@ NTSTATUS samdb_set_password(struct ldb_context *ldb, 
TALLOC_CTX *mem_ctx,
                status = NT_STATUS_WRONG_PASSWORD;
        } else if (ret == LDB_ERR_CONSTRAINT_VIOLATION) {
                status = NT_STATUS_PASSWORD_RESTRICTION;
+       } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+               status = NT_STATUS_WRONG_PASSWORD;
        } else if (ret != LDB_SUCCESS) {
                status = NT_STATUS_UNSUCCESSFUL;
        } else {
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c 
b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 0f078b5..cf239fb 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1437,46 +1437,57 @@ static int check_password_restrictions(struct 
setup_password_fields_io *io)
 
        /* First check the old password is correct, for password changes */
        if (!io->ac->pwd_reset && !io->ac->change_old_pw_checked) {
+               bool nt_hash_checked = false;
+
                /* we need to old nt or lm hash given by the client */
                if (!io->og.nt_hash && !io->og.lm_hash) {
                        ldb_asprintf_errstring(ldb,
                                "check_password_restrictions: "
-                               "You need to provide the old password "
-                               "in order to change your password!");
+                               "You need to provide the old password in order "
+                               "to change it!");
                        return LDB_ERR_UNWILLING_TO_PERFORM;
                }
 
+               /* The password modify through the NT hash is encouraged and
+                  has no problems at all */
                if (io->og.nt_hash) {
                        if (!io->o.nt_hash) {
                                ldb_asprintf_errstring(ldb,
                                        "check_password_restrictions: "
                                        "There's no old nt_hash, which is 
needed "
                                        "in order to change your password!");
-                               return LDB_ERR_UNWILLING_TO_PERFORM;
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
                        }
 
-                       /* The password modify through the NT hash is encouraged
-                          and has no problems at all */
                        if (memcmp(io->og.nt_hash->hash, io->o.nt_hash->hash, 
16) != 0) {
                                ldb_asprintf_errstring(ldb,
                                        "check_password_restrictions: "
                                        "The old password specified doesn't 
match!");
-                               return LDB_ERR_UNWILLING_TO_PERFORM;
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
                        }
-               } else if (io->og.lm_hash) {
-                       if (!io->o.lm_hash) {
+
+                       nt_hash_checked = true;
+               }
+
+               /* But it is also possible to change a password by the LM hash
+                * alone for compatibility reasons. This check is optional if
+                * the NT hash was already checked - otherwise it's mandatory.
+                * (as the SAMR operations request it). */
+               if (io->og.lm_hash) {
+                       if (!io->o.lm_hash && !nt_hash_checked) {
                                ldb_asprintf_errstring(ldb,
                                        "check_password_restrictions: "
                                        "There's no old lm_hash, which is 
needed "
                                        "in order to change your password!");
-                               return LDB_ERR_UNWILLING_TO_PERFORM;
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
                        }
 
-                       if (memcmp(io->og.lm_hash->hash, io->o.lm_hash->hash, 
16) != 0) {
+                       if (io->o.lm_hash &&
+                           memcmp(io->og.lm_hash->hash, io->o.lm_hash->hash, 
16) != 0) {
                                ldb_asprintf_errstring(ldb,
                                        "check_password_restrictions: "
                                        "The old password specified doesn't 
match!");
-                               return LDB_ERR_UNWILLING_TO_PERFORM;
+                               return LDB_ERR_CONSTRAINT_VIOLATION;
                        }
                }
        }
diff --git a/source4/dsdb/tests/python/passwords.py 
b/source4/dsdb/tests/python/passwords.py
index de1889f..a8a19e1 100755
--- a/source4/dsdb/tests/python/passwords.py
+++ b/source4/dsdb/tests/python/passwords.py
@@ -79,14 +79,34 @@ class PasswordTests(samba.tests.TestCase):
         self.ldb = ldb
         self.base_dn = self.find_basedn(ldb)
 
-        # (Re)adds the test user "testuser" with the inital password
-        # "thatsAcomplPASS1"
+        # (Re)adds the test user "testuser" with no password atm
         self.delete_force(self.ldb, "cn=testuser,cn=users," + self.base_dn)
         self.ldb.add({
              "dn": "cn=testuser,cn=users," + self.base_dn,
              "objectclass": ["user", "person"],
-             "sAMAccountName": "testuser",
-             "userPassword": "thatsAcomplPASS1" })
+             "sAMAccountName": "testuser"})
+
+        # Tests a password change when we don't have a password yet
+        try:
+            self.ldb.modify_ldif("""
+dn: cn=testuser,cn=users,""" + self.base_dn + """
+changetype: modify
+delete: userPassword
+userPassword: thatsAcomplPASS1
+add: userPassword
+userPassword: thatsAcomplPASS2
+""")
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
+        # Sets the initial user password and enables the account
+        self.ldb.modify_ldif("""
+dn: cn=testuser,cn=users,""" + self.base_dn + """
+changetype: modify
+replace: userPassword
+userPassword: thatsAcomplPASS1
+""")
         self.ldb.enable_account("(sAMAccountName=testuser)")
 
         # Open a second LDB connection with the user credentials. Use the
@@ -155,6 +175,20 @@ add: unicodePwd
 unicodePwd:: """ + 
base64.b64encode("\"thatsAcomplPASS2\"".encode('utf-16-le')) + """
 """)
 
+        # Wrong old password
+        try:
+            self.ldb2.modify_ldif("""
+dn: cn=testuser,cn=users,""" + self.base_dn + """
+changetype: modify
+delete: unicodePwd
+unicodePwd:: """ + 
base64.b64encode("\"thatsAcomplPASS3\"".encode('utf-16-le')) + """
+add: unicodePwd
+unicodePwd:: """ + 
base64.b64encode("\"thatsAcomplPASS4\"".encode('utf-16-le')) + """
+""")
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
         # A change to the same password again will not work (password history)
         try:
             self.ldb2.modify_ldif("""
@@ -225,6 +259,20 @@ add: userPassword
 userPassword: thatsAcomplPASS2
 """)
 
+        # Wrong old password
+        try:
+            self.ldb2.modify_ldif("""
+dn: cn=testuser,cn=users,""" + self.base_dn + """
+changetype: modify
+delete: userPassword
+userPassword: thatsAcomplPASS3
+add: userPassword
+userPassword: thatsAcomplPASS4
+""")
+            self.fail()
+        except LdbError, (num, _):
+            self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
+
         # A change to the same password again will not work (password history)
         try:
             self.ldb2.modify_ldif("""
@@ -274,6 +322,22 @@ clearTextPassword:: """ + 
base64.b64encode("thatsAcomplPASS2".encode('utf-16-le'
             if num != ERR_NO_SUCH_ATTRIBUTE:
                 raise LdbError(num, msg)
 
+        # Wrong old password
+        try:


-- 
Samba Shared Repository

Reply via email to