The branch, v4-0-test has been updated
       via  ba864cfd7ce4b69179431131cac9661cbf48bf32 (commit)
       via  aa3901311eb7ce6f2d2b2413323e31a5b064cfc4 (commit)
       via  7a46e72f8dbb191ac8a811eb4cd95210fab7dc7b (commit)
       via  acda1f69bc9b9c43e157e254d0bae54d11363661 (commit)
       via  447d5a795441aa6beab2f057c5ac1bc3c04e08c4 (commit)
       via  16378219fbf9e8a26621f848e85426180822ea29 (commit)
       via  bf7166e785e5c5d52dbb0c12e5e4206d74e72f4e (commit)
       via  0a5fa41dd7ed76e4848fe4a779edff2a12e8ea67 (commit)
       via  68dcd1073cfed830fb6e2013e27d2ebbc443c451 (commit)
      from  5753d7fd8300d36558d3304418e1b0a300f56575 (commit)

http://gitweb.samba.org/?samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit ba864cfd7ce4b69179431131cac9661cbf48bf32
Merge: aa3901311eb7ce6f2d2b2413323e31a5b064cfc4 
5753d7fd8300d36558d3304418e1b0a300f56575
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 10:33:54 2008 +1100

    Merge branch 'v4-0-test' of git://git.samba.org/samba into 4-0-local

commit aa3901311eb7ce6f2d2b2413323e31a5b064cfc4
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 10:32:06 2008 +1100

    Fix up the libnet tests.
    
    These tests still do not pass against windows, but at least now it
    doesn't reset acct_flags to 0.
    
    This is enough to have Samba4 pass it's own tests for the moment.
    
    Andrew Bartlett

commit 7a46e72f8dbb191ac8a811eb4cd95210fab7dc7b
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 10:05:32 2008 +1100

    Check for and reject invalid account flags.
    
    (lest we have an account set with 0 flags)
    
    Andrew Bartlett

commit acda1f69bc9b9c43e157e254d0bae54d11363661
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 08:50:00 2008 +1100

    Generate ACB_PW_EXPIRED correctly
    
    More correctly handle expired passwords, and do not expire machine accounts.
    
    Test that the behaviour is consistant with windows, using the RPC-SAMR test.
    
    Change NETLOGON to directly query the userAccountControl, just because
    we don't want to do the extra expiry processing here.
    
    Andrew Bartlett

commit 447d5a795441aa6beab2f057c5ac1bc3c04e08c4
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 08:43:10 2008 +1100

    Users and computers now share the same template.
    
    Slowly work away at the samldb module again, it is clear that AD does
    not use much of a templating system.  samAccountType is managed, as
    far as I can tell, when groupType or userAccountControl changes.
    
    Andrew Bartlett

commit 16378219fbf9e8a26621f848e85426180822ea29
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 08:39:45 2008 +1100

    Reorder modules to have rdn_name before objectclass.
    
    This ensures the relative DN is placed in the correct case into the
    DB.
    
    Andrew Bartlett

commit bf7166e785e5c5d52dbb0c12e5e4206d74e72f4e
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 08:38:53 2008 +1100

    Fix rdn_name errors.
    
    Return the correct error when the DN is mismatched with it's RDN
    attribute (now matches AD).
    
    Andrew Bartlett

commit 0a5fa41dd7ed76e4848fe4a779edff2a12e8ea67
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 08:37:11 2008 +1100

    Extend the ldap.js test
    
    Now we verify sAMAccountType and userAccountControl, as well as rename and
    DN mismatch semantics.
    
    Andrew Bartlett

commit 68dcd1073cfed830fb6e2013e27d2ebbc443c451
Author: Andrew Bartlett <[EMAIL PROTECTED]>
Date:   Thu Feb 28 08:36:13 2008 +1100

    Do not re-randomise in an individual test.
    
    smbtorture calls srandom() once for the whole suite, with command line
    override to allow reproduceable random tests.
    
    Andrew Bartlett

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

Summary of changes:
 source/auth/auth_sam.c                       |    4 +-
 source/auth/sam.c                            |   36 +++---
 source/dsdb/common/util.c                    |   34 +++++-
 source/dsdb/samdb/ldb_modules/samldb.c       |  135 +++++++++++++++------
 source/lib/ldb/modules/rdn_name.c            |    3 +-
 source/rpc_server/netlogon/dcerpc_netlogon.c |   22 ++--
 source/rpc_server/samr/dcesrv_samr.c         |   42 +++++--
 source/scripting/python/samba/provision.py   |    2 +-
 source/setup/provision_self_join.ldif        |    2 -
 source/setup/provision_templates.ldif        |   26 +----
 source/setup/provision_users.ldif            |   20 ---
 source/torture/libnet/libnet_user.c          |   17 ++-
 source/torture/libnet/userman.c              |    2 +-
 source/torture/rpc/samr.c                    |   45 ++++++--
 testprogs/ejs/ldap.js                        |  168 ++++++++++++++++++++++++--
 15 files changed, 404 insertions(+), 154 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index 9189640..4cb8d2b 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -226,7 +226,9 @@ static NTSTATUS authsam_authenticate(struct auth_context 
*auth_context,
 {
        struct samr_Password *lm_pwd, *nt_pwd;
        NTSTATUS nt_status;
-       uint16_t acct_flags = samdb_result_acct_flags(msgs[0], 
"userAccountControl");
+       struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, 
msgs_domain_ref[0], "nCName", NULL);
+
+       uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, 
msgs[0], domain_dn);
        
        /* Quit if the account was locked out. */
        if (acct_flags & ACB_AUTOLOCK) {
diff --git a/source/auth/sam.c b/source/auth/sam.c
index fdd7de7..abcb72f 100644
--- a/source/auth/sam.c
+++ b/source/auth/sam.c
@@ -156,7 +156,7 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
        NTTIME now;
        DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", 
name_for_logs));
 
-       acct_flags = samdb_result_acct_flags(msg, "userAccountControl");
+       acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
        
        acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
        must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 
@@ -186,22 +186,20 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
                return NT_STATUS_ACCOUNT_EXPIRED;
        }
 
-       if (!(acct_flags & ACB_PWNOEXP)) {
-               /* check for immediate expiry "must change at next logon" */
-               if (must_change_time == 0 && last_set_time != 0) {
-                       DEBUG(1,("sam_account_ok: Account for user '%s' 
password must change!.\n", 
-                                name_for_logs));
-                       return NT_STATUS_PASSWORD_MUST_CHANGE;
-               }
+       /* check for immediate expiry "must change at next logon" */
+       if (!(acct_flags & ACB_PWNOEXP) && (must_change_time == 0 && 
last_set_time != 0)) {
+               DEBUG(1,("sam_account_ok: Account for user '%s' password must 
change!.\n", 
+                        name_for_logs));
+               return NT_STATUS_PASSWORD_MUST_CHANGE;
+       }
 
-               /* check for expired password */
-               if ((must_change_time != 0) && (must_change_time < now)) {
-                       DEBUG(1,("sam_account_ok: Account for user '%s' 
password expired!.\n", 
-                                name_for_logs));
-                       DEBUG(1,("sam_account_ok: Password expired at '%s' unix 
time.\n", 
-                                nt_time_string(mem_ctx, must_change_time)));
-                       return NT_STATUS_PASSWORD_EXPIRED;
-               }
+       /* check for expired password (dynamicly gnerated in 
samdb_result_acct_flags) */
+       if (acct_flags & ACB_PW_EXPIRED) {
+               DEBUG(1,("sam_account_ok: Account for user '%s' password 
expired!.\n", 
+                        name_for_logs));
+               DEBUG(1,("sam_account_ok: Password expired at '%s' unix 
time.\n", 
+                        nt_time_string(mem_ctx, must_change_time)));
+               return NT_STATUS_PASSWORD_EXPIRED;
        }
 
        /* Test workstation. Workstation list is comma separated. */
@@ -267,6 +265,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX 
*mem_ctx, struct ldb_conte
        struct dom_sid **groupSIDs = NULL;
        struct dom_sid *account_sid;
        struct dom_sid *primary_group_sid;
+       struct ldb_dn *domain_dn;
        const char *str;
        struct ldb_dn *ncname;
        int i;
@@ -368,7 +367,10 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX 
*mem_ctx, struct ldb_conte
        server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);
        server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount", 
0);
 
-       server_info->acct_flags = samdb_result_acct_flags(msg, 
"userAccountControl");
+       domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", 
NULL);
+
+       server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, 
+                                                         msg, domain_dn);
 
        server_info->user_session_key = user_sess_key;
        server_info->lm_session_key = lm_sess_key;
diff --git a/source/dsdb/common/util.c b/source/dsdb/common/util.c
index bee1eac..c9c0285 100644
--- a/source/dsdb/common/util.c
+++ b/source/dsdb/common/util.c
@@ -596,11 +596,37 @@ struct samr_LogonHours 
samdb_result_logon_hours(TALLOC_CTX *mem_ctx, struct ldb_
 
 /*
   pull a set of account_flags from a result set. 
+
+  This requires that the attributes: 
+   pwdLastSet
+   userAccountControl
+  be included in 'msg'
 */
-uint16_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr)
-{
-       uint_t userAccountControl = ldb_msg_find_attr_as_uint(msg, attr, 0);
-       return samdb_uf2acb(userAccountControl);
+uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX 
*mem_ctx, 
+                                struct ldb_message *msg, struct ldb_dn 
*domain_dn)
+{
+       uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, 
"userAccountControl", 0);
+       uint32_t acct_flags = samdb_uf2acb(userAccountControl); 
+       if ((userAccountControl & UF_NORMAL_ACCOUNT) && !(userAccountControl & 
UF_DONT_EXPIRE_PASSWD)) {
+               NTTIME must_change_time;
+               NTTIME pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
+               if (pwdLastSet == 0) {
+                       acct_flags |= ACB_PW_EXPIRED;
+               } else {
+                       NTTIME now;
+                       
+                       must_change_time = 
samdb_result_force_password_change(sam_ctx, mem_ctx, 
+                                                                             
domain_dn, msg);
+                       
+                       /* Test account expire time */
+                       unix_to_nt_time(&now, time(NULL));
+                       /* check for expired password */
+                       if ((must_change_time != 0) && (must_change_time < 
now)) {
+                               acct_flags |= ACB_PW_EXPIRED;
+                       }
+               }
+       }
+       return acct_flags;
 }
 
 
diff --git a/source/dsdb/samdb/ldb_modules/samldb.c 
b/source/dsdb/samdb/ldb_modules/samldb.c
index 178149a..905cd4a 100644
--- a/source/dsdb/samdb/ldb_modules/samldb.c
+++ b/source/dsdb/samdb/ldb_modules/samldb.c
@@ -396,6 +396,7 @@ static int samldb_fill_group_object(struct ldb_module 
*module, const struct ldb_
                                                    struct ldb_message 
**ret_msg)
 {
        int ret;
+       unsigned int group_type;
        char *name;
        struct ldb_message *msg2;
        struct ldb_dn *dom_dn;
@@ -452,6 +453,26 @@ static int samldb_fill_group_object(struct ldb_module 
*module, const struct ldb_
                }
        }
        
+       if (ldb_msg_find_element(msg2, "sAMAccountType") != NULL) {
+               ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be 
specified");
+               talloc_free(mem_ctx);
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+       group_type = samdb_result_uint(msg2, "groupType", 0);
+       if (group_type == 0) {
+               ldb_asprintf_errstring(module->ldb, "groupType invalid");
+               talloc_free(mem_ctx);
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       } else {
+               unsigned int account_type = samdb_gtype2atype(group_type);
+               ret = samdb_msg_add_uint(module->ldb, msg2, msg2,
+                                        "sAMAccountType",
+                                        account_type);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
        /* Manage SID allocation, conflicts etc */
        ret = samldb_handle_sid(module, mem_ctx, msg2, dom_dn); 
 
@@ -473,6 +494,7 @@ static int samldb_fill_user_or_computer_object(struct 
ldb_module *module, const
        const char *rdn_name;
        TALLOC_CTX *mem_ctx = talloc_new(msg);
        const char *errstr;
+       unsigned int user_account_control;
        if (!mem_ctx) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -485,36 +507,15 @@ static int samldb_fill_user_or_computer_object(struct 
ldb_module *module, const
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       if (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") 
!= NULL) {
-
-               ret = samdb_copy_template(module->ldb, msg2, 
-                                         "computer",
-                                         &errstr);
-               if (ret) {
-                       ldb_asprintf_errstring(module->ldb, 
-                                              
"samldb_fill_user_or_computer_object: "
-                                              "Error copying computer 
template: %s",
-                                              errstr);
-                       talloc_free(mem_ctx);
-                       return ret;
-               }
-       } else {
-               ret = samdb_copy_template(module->ldb, msg2, 
-                                         "user",
-                                         &errstr);
-               if (ret) {
-                       ldb_asprintf_errstring(module->ldb, 
-                                              
"samldb_fill_user_or_computer_object: Error copying user template: %s\n",
-                                              errstr);
-                       talloc_free(mem_ctx);
-                       return ret;
-               }
-               /* readd user objectclass */
-               ret = samdb_find_or_add_value(module->ldb, msg2, "objectclass", 
"user");
-               if (ret) {
-                       talloc_free(mem_ctx);
-                       return ret;
-               }
+       ret = samdb_copy_template(module->ldb, msg2, 
+                                 "user",
+                                 &errstr);
+       if (ret) {
+               ldb_asprintf_errstring(module->ldb, 
+                                      "samldb_fill_user_or_computer_object: 
Error copying user template: %s\n",
+                                      errstr);
+               talloc_free(mem_ctx);
+               return ret;
        }
 
        rdn_name = ldb_dn_get_rdn_name(msg2->dn);
@@ -545,14 +546,30 @@ static int samldb_fill_user_or_computer_object(struct 
ldb_module *module, const
                }
        }
 
-       /*
-         TODO: useraccountcontrol: setting value 0 gives 0x200 for users
-       */
+       if (ldb_msg_find_element(msg2, "sAMAccountType") != NULL) {
+               ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be 
specified");
+               talloc_free(mem_ctx);
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+       user_account_control = samdb_result_uint(msg2, "userAccountControl", 0);
+       if (user_account_control == 0) {
+               ldb_asprintf_errstring(module->ldb, "userAccountControl 
invalid");
+               talloc_free(mem_ctx);
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       } else {
+               unsigned int account_type = 
samdb_uf2atype(user_account_control);
+               ret = samdb_msg_add_uint(module->ldb, msg2, msg2,
+                                        "sAMAccountType",
+                                        account_type);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
 
        /* Manage SID allocation, conflicts etc */
        ret = samldb_handle_sid(module, mem_ctx, msg2, dom_dn); 
 
-       /* TODO: objectCategory, userAccountControl, badPwdCount, codePage, 
countryCode, badPasswordTime, lastLogoff, lastLogon, pwdLastSet, 
primaryGroupID, accountExpires, logonCount */
+       /* TODO: userAccountControl, badPwdCount, codePage, countryCode, 
badPasswordTime, lastLogoff, lastLogon, pwdLastSet, primaryGroupID, 
accountExpires, logonCount */
 
        if (ret == 0) {
                *ret_msg = msg2;
@@ -689,7 +706,7 @@ static int samldb_add(struct ldb_module *module, struct 
ldb_request *req)
        }
 
        /* is user or computer? */
-       if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != 
NULL) ||
+       if ((samdb_find_attribute(module->ldb, msg, "objectclass", "user") != 
NULL) || 
            (samdb_find_attribute(module->ldb, msg, "objectclass", "computer") 
!= NULL)) {
                /*  add all relevant missing objects */
                ret = samldb_fill_user_or_computer_object(module, msg, &msg2);
@@ -745,6 +762,53 @@ static int samldb_add(struct ldb_module *module, struct 
ldb_request *req)
        return ret;
 }
 
+/* modify */
+static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
+{
+       struct ldb_message *msg;
+       struct ldb_message_element *el, *el2;
+       int ret;
+       unsigned int group_type, user_account_control, account_type;
+       if (ldb_msg_find_element(req->op.mod.message, "sAMAccountType") != 
NULL) {
+               ldb_asprintf_errstring(module->ldb, "sAMAccountType must not be 
specified");
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
+       el = ldb_msg_find_element(req->op.mod.message, "groupType");
+       if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && 
el->num_values == 1) {
+               req->op.mod.message = msg = ldb_msg_copy_shallow(req, 
req->op.mod.message);
+
+               group_type = strtoul((const char *)el->values[0].data, NULL, 0);
+               account_type =  samdb_gtype2atype(group_type);
+               ret = samdb_msg_add_uint(module->ldb, msg, msg,
+                                        "sAMAccountType",
+                                        account_type);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+               el2 = ldb_msg_find_element(msg, "sAMAccountType");
+               el2->flags = LDB_FLAG_MOD_REPLACE;
+       }
+
+       el = ldb_msg_find_element(req->op.mod.message, "userAccountControl");
+       if (el && el->flags & (LDB_FLAG_MOD_ADD|LDB_FLAG_MOD_REPLACE) && 
el->num_values == 1) {
+               req->op.mod.message = msg = ldb_msg_copy_shallow(req, 
req->op.mod.message);
+
+               user_account_control = strtoul((const char 
*)el->values[0].data, NULL, 0);
+               account_type = samdb_uf2atype(user_account_control);
+               ret = samdb_msg_add_uint(module->ldb, msg, msg,
+                                        "sAMAccountType",
+                                        account_type);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+               el2 = ldb_msg_find_element(msg, "sAMAccountType");
+               el2->flags = LDB_FLAG_MOD_REPLACE;
+       }
+       return ldb_next_request(module, req);
+}
+
+
 static int samldb_init(struct ldb_module *module)
 {
        return ldb_next_init(module);
@@ -754,4 +818,5 @@ _PUBLIC_ const struct ldb_module_ops ldb_samldb_module_ops 
= {
        .name          = "samldb",
        .init_context  = samldb_init,
        .add           = samldb_add,
+       .modify        = samldb_modify
 };
diff --git a/source/lib/ldb/modules/rdn_name.c 
b/source/lib/ldb/modules/rdn_name.c
index c4de8e8..65c044c 100644
--- a/source/lib/ldb/modules/rdn_name.c
+++ b/source/lib/ldb/modules/rdn_name.c
@@ -119,7 +119,8 @@ static int rdn_name_add(struct ldb_module *module, struct 
ldb_request *req)
                                      "RDN mismatch on %s: %s (%s)", 
                                      ldb_dn_get_linearized(msg->dn), rdn_name, 
rdn_val.data);
                        talloc_free(down_req);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       /* Match AD's error here */
+                       return LDB_ERR_INVALID_DN_SYNTAX;
                }
        }
 
diff --git a/source/rpc_server/netlogon/dcerpc_netlogon.c 
b/source/rpc_server/netlogon/dcerpc_netlogon.c
index 4d38dc0..37e6351 100644
--- a/source/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source/rpc_server/netlogon/dcerpc_netlogon.c
@@ -27,6 +27,7 @@
 #include "auth/auth.h"
 #include "auth/auth_sam_reply.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/common/flags.h"
 #include "rpc_server/samr/proto.h"
 #include "util/util_ldb.h"
 #include "libcli/auth/libcli_auth.h"
@@ -76,7 +77,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct 
dcesrv_call_state *dce_ca
        struct creds_CredentialState *creds;
        void *sam_ctx;
        struct samr_Password *mach_pwd;
-       uint16_t acct_flags;
+       uint32_t user_account_control;
        int num_records;
        struct ldb_message **msgs;
        NTSTATUS nt_status;
@@ -113,27 +114,28 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct 
dcesrv_call_state *dce_ca
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       acct_flags = samdb_result_acct_flags(msgs[0], 
-                                            "userAccountControl");
+       
+       user_account_control = ldb_msg_find_attr_as_uint(msgs[0], 
"userAccountControl", 0);
 
-       if (acct_flags & ACB_DISABLED) {
+       if (user_account_control & UF_ACCOUNTDISABLE) {
                DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
                return NT_STATUS_ACCESS_DENIED;
        }
 
        if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
-               if (!(acct_flags & ACB_WSTRUST)) {
-                       DEBUG(1, ("Client asked for a workstation secure 
channel, but is not a workstation (member server) acb flags: 0x%x\n", 
acct_flags));
+               if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
+                       DEBUG(1, ("Client asked for a workstation secure 
channel, but is not a workstation (member server) acb flags: 0x%x\n", 
user_account_control));
                        return NT_STATUS_ACCESS_DENIED;
                }
        } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
-               if (!(acct_flags & ACB_DOMTRUST)) {
-                       DEBUG(1, ("Client asked for a trusted domain secure 
channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
+               if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
+                       DEBUG(1, ("Client asked for a trusted domain secure 
channel, but is not a trusted domain: acb flags: 0x%x\n", 
user_account_control));
+                       
                        return NT_STATUS_ACCESS_DENIED;
                }
        } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
-               if (!(acct_flags & ACB_SVRTRUST)) {
-                       DEBUG(1, ("Client asked for a server secure channel, 
but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
+               if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
+                       DEBUG(1, ("Client asked for a server secure channel, 
but is not a server (domain controller): acb flags: 0x%x\n", 
user_account_control));
                        return NT_STATUS_ACCESS_DENIED;
                }
        } else {
diff --git a/source/rpc_server/samr/dcesrv_samr.c 
b/source/rpc_server/samr/dcesrv_samr.c
index 760d774..8193e0a 100644
--- a/source/rpc_server/samr/dcesrv_samr.c
+++ b/source/rpc_server/samr/dcesrv_samr.c
@@ -56,7 +56,7 @@
 #define QUERY_LHOURS(msg, field, attr) \
        r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
 #define QUERY_AFLAGS(msg, field, attr) \
-       r->out.info->field = samdb_result_acct_flags(msg, attr);
+       r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, 
a_state->domain_state->domain_dn);
 
 
 /* these are used to make the Set[User|Group]Info code easier to follow */
@@ -102,10 +102,25 @@
         set_el = ldb_msg_find_element(msg, attr);                      \
        set_el->flags = LDB_FLAG_MOD_REPLACE;                           \
 } while (0)                                                            
-                                                                       
+
+#define CHECK_FOR_MULTIPLES(value, flag, poss_flags)   \
+       do { \
+               if ((value & flag) && ((value & flag) != (value & 
(poss_flags)))) { \
+                       return NT_STATUS_INVALID_PARAMETER;             \
+               }                                                       \
+       } while (0)                                                     \
+       
+/* Set account flags, discarding flags that cannot be set with SAMR */         
                                                
 #define SET_AFLAGS(msg, field, attr) do {                              \
        struct ldb_message_element *set_el;                             \
-       if (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, 
r->in.info->field) != 0) { \
+       if ((r->in.info->field & (ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | 
ACB_SVRTRUST)) == 0) { \
+               return NT_STATUS_INVALID_PARAMETER; \
+       }                                                               \
+       CHECK_FOR_MULTIPLES(r->in.info->field, ACB_NORMAL, ACB_NORMAL | 
ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+       CHECK_FOR_MULTIPLES(r->in.info->field, ACB_DOMTRUST, ACB_NORMAL | 
ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+       CHECK_FOR_MULTIPLES(r->in.info->field, ACB_WSTRUST, ACB_NORMAL | 
ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+       CHECK_FOR_MULTIPLES(r->in.info->field, ACB_SVRTRUST, ACB_NORMAL | 
ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \
+       if (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, 
(r->in.info->field & ~(ACB_AUTOLOCK|ACB_PW_EXPIRED))) != 0) { \
                return NT_STATUS_NO_MEMORY;                             \
        }                                                               \
         set_el = ldb_msg_find_element(msg, attr);                      \
@@ -1484,8 +1499,8 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct 
dcesrv_call_state *dce_call,
        for (i=0;i<count;i++) {
                /* Check if a mask has been requested */
                if (r->in.acct_flags
-                   && ((samdb_result_acct_flags(res[i], 
-                                                "userAccountControl") & 
r->in.acct_flags) == 0)) {
+                   && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, 
res[i], 
+                                                d_state->domain_dn) & 
r->in.acct_flags) == 0)) {
                        continue;
                }
                entries[num_filtered_entries].idx = 
samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
@@ -3066,7 +3081,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct 
dcesrv_call_state *dce_call, TA
        }
        case 16:
        {
-               static const char * const attrs2[] = {"userAccountControl", 
NULL};
+               static const char * const attrs2[] = {"userAccountControl", 
"pwdLastSet", NULL};
                attrs = attrs2;
                break;
        }
@@ -3613,7 +3628,7 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct 
dcesrv_call_state *dce_call,
        struct ldb_message **res;
        int ldb_cnt, count, i;
        const char * const attrs[] = { "objectSid", "sAMAccountName", 
"displayName",
-                                       "description", "userAccountControl", 
NULL };
+                                      "description", "userAccountControl", 
"pwdLastSet", NULL };
        struct samr_DispEntryFull *entriesFull = NULL;
        struct samr_DispEntryFullGroup *entriesFullGroup = NULL;
        struct samr_DispEntryAscii *entriesAscii = NULL;
@@ -3702,8 +3717,9 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct 
dcesrv_call_state *dce_call,
                        entriesGeneral[count].rid = 
                                objectsid->sub_auths[objectsid->num_auths-1];
                        entriesGeneral[count].acct_flags =
-                               samdb_result_acct_flags(res[i], 
-                                                       "userAccountControl");
+                               samdb_result_acct_flags(d_state->sam_ctx, 
mem_ctx,
+                                                       res[i], 
+                                                       d_state->domain_dn);
                        entriesGeneral[count].account_name.string =
                                samdb_result_string(res[i],
                                                    "sAMAccountName", "");
@@ -3719,8 +3735,9 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct 
dcesrv_call_state *dce_call,
 
                        /* No idea why we need to or in ACB_NORMAL here, but 
this is what Win2k3 seems to do... */
                        entriesFull[count].acct_flags =
-                               samdb_result_acct_flags(res[i], 
-                                                       "userAccountControl") | 
ACB_NORMAL;
+                               samdb_result_acct_flags(d_state->sam_ctx, 
mem_ctx,
+                                                       res[i], 
+                                                       d_state->domain_dn) | 
ACB_NORMAL;
                        entriesFull[count].account_name.string =
                                samdb_result_string(res[i], "sAMAccountName",
                                                    "");
@@ -3731,9 +3748,6 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct 
dcesrv_call_state *dce_call,
                        entriesFullGroup[count].idx = count + 1;
                        entriesFullGroup[count].rid =
                                objectsid->sub_auths[objectsid->num_auths-1];
-                       entriesFullGroup[count].acct_flags =
-                               samdb_result_acct_flags(res[i], 


-- 
Samba Shared Repository

Reply via email to