The branch, master has been updated
       via  1595f56 CVE-2015-8467: samdb: Match MS15-096 behaviour for 
userAccountControl
       via  bc2d859 CVE-2015-5296: libcli/smb: make sure we require signing 
when we demand encryption on a session
       via  aef4113 CVE-2015-5296: s3:libsmb: force signing when requiring 
encryption in SMBC_server_internal()
       via  f8b0f7f CVE-2015-5296: s3:libsmb: force signing when requiring 
encryption in do_connect()
       via  acbb4dd CVE-2015-5299: s3-shadow-copy2: fix missing access check on 
snapdir
       via  cc137fa CVE-2015-5252: s3: smbd: Fix symlink verification (file 
access outside the share).
       via  7606c0d CVE-2015-5252: s3: smbd: Fix symlink verification (file 
access outside the share).
      from  067640b Merge tag 'ldb-1.1.24' into master

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


- Log -----------------------------------------------------------------
commit 1595f56634a8950c4493799b30c2dbe254466751
Author: Andrew Bartlett <[email protected]>
Date:   Wed Nov 18 17:36:21 2015 +1300

    CVE-2015-8467: samdb: Match MS15-096 behaviour for userAccountControl
    
    Swapping between account types is now restricted
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=11552
    
    Signed-off-by: Andrew Bartlett <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    
    Autobuild-User(master): Stefan Metzmacher <[email protected]>
    Autobuild-Date(master): Wed Dec 16 16:03:18 CET 2015 on sn-devel-104

commit bc2d8592f4e22dd91790bcd78e7a1a99b8a83de5
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Sep 30 21:23:25 2015 +0200

    CVE-2015-5296: libcli/smb: make sure we require signing when we demand 
encryption on a session
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit aef4113823a48cffc429ed6b7eb2c01e80fd639a
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Sep 30 21:17:02 2015 +0200

    CVE-2015-5296: s3:libsmb: force signing when requiring encryption in 
SMBC_server_internal()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit f8b0f7fd94cf3c7630a108b80ea745d3e4e947be
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Sep 30 21:17:02 2015 +0200

    CVE-2015-5296: s3:libsmb: force signing when requiring encryption in 
do_connect()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit acbb4ddb6876c15543c5370e6d27faacebc8a231
Author: Jeremy Allison <[email protected]>
Date:   Fri Oct 23 14:54:31 2015 -0700

    CVE-2015-5299: s3-shadow-copy2: fix missing access check on snapdir
    
    Fix originally from <[email protected]>
    
    https://bugzilla.samba.org/show_bug.cgi?id=11529
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: David Disseldorp <[email protected]>

commit cc137fa3868c9f84519a9c3aa047aefacc0c4878
Author: Jeremy Allison <[email protected]>
Date:   Thu Jul 9 13:57:58 2015 -0700

    CVE-2015-5252: s3: smbd: Fix symlink verification (file access outside the 
share).
    
    New tests for fix.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

commit 7606c0db257b3f9d84da5b2bf5fbb4034cc8d77d
Author: Jeremy Allison <[email protected]>
Date:   Thu Jul 9 10:58:11 2015 -0700

    CVE-2015-5252: s3: smbd: Fix symlink verification (file access outside the 
share).
    
    Ensure matching component ends in '/' or '\0'.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395
    
    Signed-off-by: Jeremy Allison <[email protected]>
    Reviewed-by: Volker Lendecke <[email protected]>

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

Summary of changes:
 libcli/smb/smbXcli_base.c                         | 11 ++++
 selftest/target/Samba3.pm                         | 30 +++++++++++
 source3/libsmb/clidfs.c                           |  7 ++-
 source3/libsmb/libsmb_server.c                    | 15 ++++--
 source3/modules/vfs_shadow_copy2.c                | 45 ++++++++++++++++
 source3/script/tests/test_smbclient_s3.sh         | 60 +++++++++++++++++++++
 source3/smbd/vfs.c                                | 13 +++--
 source4/dsdb/samdb/ldb_modules/samldb.c           | 24 ++++++++-
 source4/dsdb/tests/python/user_account_control.py | 63 +++++++++++++++++++----
 9 files changed, 250 insertions(+), 18 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 1f1b6cd..5fc380e 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -5445,6 +5445,9 @@ uint8_t smb2cli_session_security_mode(struct 
smbXcli_session *session)
        if (conn->mandatory_signing) {
                security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
        }
+       if (session->smb2->should_sign) {
+               security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
+       }
 
        return security_mode;
 }
@@ -5876,6 +5879,14 @@ NTSTATUS smb2cli_session_set_channel_key(struct 
smbXcli_session *session,
 
 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
 {
+       if (!session->smb2->should_sign) {
+               /*
+                * We need required signing on the session
+                * in order to prevent man in the middle attacks.
+                */
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
        if (session->smb2->should_encrypt) {
                return NT_STATUS_OK;
        }
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 94612b2..c9e57ad 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1118,6 +1118,12 @@ sub provision($$$$$$$$)
        my $manglenames_shrdir="$shrdir/manglenames";
        push(@dirs,$manglenames_shrdir);
 
+       my $widelinks_shrdir="$shrdir/widelinks";
+       push(@dirs,$widelinks_shrdir);
+
+       my $widelinks_linkdir="$shrdir/widelinks_foo";
+       push(@dirs,$widelinks_linkdir);
+
        # this gets autocreated by winbindd
        my $wbsockdir="$prefix_abs/winbindd";
        my $wbsockprivdir="$lockdir/winbindd_privileged";
@@ -1207,6 +1213,25 @@ sub provision($$$$$$$$)
         my $manglename_target = "$manglenames_shrdir/foo:bar";
        mkdir($manglename_target, 0777);
 
+       ##
+       ## create symlinks for widelinks tests.
+       ##
+       my $widelinks_target = "$widelinks_linkdir/target";
+       unless (open(WIDELINKS_TARGET, ">$widelinks_target")) {
+               warn("Unable to open $widelinks_target");
+               return undef;
+       }
+       close(WIDELINKS_TARGET);
+       chmod 0666, $widelinks_target;
+       ##
+       ## This link should get ACCESS_DENIED
+       ##
+       symlink "$widelinks_target", "$widelinks_shrdir/source";
+       ##
+       ## This link should be allowed
+       ##
+       symlink "$widelinks_shrdir", "$widelinks_shrdir/dot";
+
        my $conffile="$libdir/server.conf";
 
        my $nss_wrapper_pl = "$ENV{PERL} 
$self->{srcdir}/lib/nss_wrapper/nss_wrapper.pl";
@@ -1512,6 +1537,11 @@ sub provision($$$$$$$$)
        path = $shrdir/%R
        guest ok = yes
 
+[widelinks_share]
+       path = $widelinks_shrdir
+       wide links = no
+       guest ok = yes
+
 [fsrvp_share]
        path = $shrdir
        comment = fake shapshots using rsync
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 2121ad0..d3b0580 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -114,6 +114,11 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
        const char *domain;
        NTSTATUS status;
        int flags = 0;
+       int signing_state = get_cmdline_auth_info_signing_state(auth_info);
+
+       if (force_encrypt) {
+               signing_state = SMB_SIGNING_REQUIRED;
+       }
 
        /* make a copy so we don't modify the global string 'service' */
        servicename = talloc_strdup(ctx,share);
@@ -152,7 +157,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 
        status = cli_connect_nb(
                server, NULL, port, name_type, NULL,
-               get_cmdline_auth_info_signing_state(auth_info),
+               signing_state,
                flags, &c);
 
        if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 07d51ea..2abd37e 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -273,6 +273,7 @@ SMBC_server_internal(TALLOC_CTX *ctx,
        char *newserver, *newshare;
        int flags = 0;
        struct smbXcli_tcon *tcon = NULL;
+       int signing_state = SMB_SIGNING_DEFAULT;
 
        ZERO_STRUCT(c);
        *in_cache = false;
@@ -439,6 +440,10 @@ SMBC_server_internal(TALLOC_CTX *ctx,
                flags |= CLI_FULL_CONNECTION_USE_NT_HASH;
        }
 
+       if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) {
+               signing_state = SMB_SIGNING_REQUIRED;
+       }
+
        if (port == 0) {
                if (share == NULL || *share == '\0' || is_ipc) {
                        /*
@@ -446,7 +451,7 @@ SMBC_server_internal(TALLOC_CTX *ctx,
                         */
                        status = cli_connect_nb(server_n, NULL, NBT_SMB_PORT, 
0x20,
                                        smbc_getNetbiosName(context),
-                                       SMB_SIGNING_DEFAULT, flags, &c);
+                                       signing_state, flags, &c);
                }
        }
 
@@ -456,7 +461,7 @@ SMBC_server_internal(TALLOC_CTX *ctx,
                 */
                status = cli_connect_nb(server_n, NULL, port, 0x20,
                                        smbc_getNetbiosName(context),
-                                       SMB_SIGNING_DEFAULT, flags, &c);
+                                       signing_state, flags, &c);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -737,6 +742,7 @@ SMBC_attr_server(TALLOC_CTX *ctx,
         ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$",
                                    pp_workgroup, pp_username, pp_password);
         if (!ipc_srv) {
+               int signing_state = SMB_SIGNING_DEFAULT;
 
                 /* We didn't find a cached connection.  Get the password */
                if (!*pp_password || (*pp_password)[0] == '\0') {
@@ -758,6 +764,9 @@ SMBC_attr_server(TALLOC_CTX *ctx,
                 if (smbc_getOptionUseCCache(context)) {
                         flags |= CLI_FULL_CONNECTION_USE_CCACHE;
                 }
+               if (context->internal->smb_encryption_level != 
SMBC_ENCRYPTLEVEL_NONE) {
+                       signing_state = SMB_SIGNING_REQUIRED;
+               }
 
                 nt_status = cli_full_connection(&ipc_cli,
                                                lp_netbios_name(), server,
@@ -766,7 +775,7 @@ SMBC_attr_server(TALLOC_CTX *ctx,
                                                *pp_workgroup,
                                                *pp_password,
                                                flags,
-                                               SMB_SIGNING_DEFAULT);
+                                               signing_state);
                 if (! NT_STATUS_IS_OK(nt_status)) {
                         DEBUG(1,("cli_full_connection failed! (%s)\n",
                                  nt_errstr(nt_status)));
diff --git a/source3/modules/vfs_shadow_copy2.c 
b/source3/modules/vfs_shadow_copy2.c
index 4d2ec54..d1673a4 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -30,6 +30,7 @@
  */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "system/filesys.h"
 #include "include/ntioctl.h"
 #include "util_tdb.h"
@@ -1180,6 +1181,42 @@ static char *have_snapdir(struct vfs_handle_struct 
*handle,
        return NULL;
 }
 
+static bool check_access_snapdir(struct vfs_handle_struct *handle,
+                               const char *path)
+{
+       struct smb_filename smb_fname;
+       int ret;
+       NTSTATUS status;
+
+       ZERO_STRUCT(smb_fname);
+       smb_fname.base_name = talloc_asprintf(talloc_tos(),
+                                               "%s",
+                                               path);
+       if (smb_fname.base_name == NULL) {
+               return false;
+       }
+
+       ret = SMB_VFS_NEXT_STAT(handle, &smb_fname);
+       if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) {
+               TALLOC_FREE(smb_fname.base_name);
+               return false;
+       }
+
+       status = smbd_check_access_rights(handle->conn,
+                                       &smb_fname,
+                                       false,
+                                       SEC_DIR_LIST);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("user does not have list permission "
+                       "on snapdir %s\n",
+                       smb_fname.base_name));
+               TALLOC_FREE(smb_fname.base_name);
+               return false;
+       }
+       TALLOC_FREE(smb_fname.base_name);
+       return true;
+}
+
 /**
  * Find the snapshot directory (if any) for the given
  * filename (which is relative to the share).
@@ -1329,6 +1366,7 @@ static int shadow_copy2_get_shadow_copy_data(
        const char *snapdir;
        struct dirent *d;
        TALLOC_CTX *tmp_ctx = talloc_stackframe();
+       bool ret;
 
        snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle, fsp->fsp_name);
        if (snapdir == NULL) {
@@ -1338,6 +1376,13 @@ static int shadow_copy2_get_shadow_copy_data(
                talloc_free(tmp_ctx);
                return -1;
        }
+       ret = check_access_snapdir(handle, snapdir);
+       if (!ret) {
+               DEBUG(0,("access denied on listing snapdir %s\n", snapdir));
+               errno = EACCES;
+               talloc_free(tmp_ctx);
+               return -1;
+       }
 
        p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0);
 
diff --git a/source3/script/tests/test_smbclient_s3.sh 
b/source3/script/tests/test_smbclient_s3.sh
index c073b43..5e3db5d 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -1003,6 +1003,62 @@ EOF
     fi
 }
 
+# Test wide links are restricted.
+test_widelinks()
+{
+    tmpfile=$PREFIX/smbclient_interactive_prompt_commands
+    cat > $tmpfile <<EOF
+cd dot
+ls
+quit
+EOF
+    cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD 
//$SERVER/widelinks_share -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
+    eval echo "$cmd"
+    out=`eval $cmd`
+    ret=$?
+    rm -f $tmpfile
+
+    if [ $ret != 0 ] ; then
+       echo "$out"
+       echo "failed accessing widelinks_share with error $ret"
+       false
+       return
+    fi
+
+    echo "$out" | grep 'NT_STATUS'
+    ret=$?
+    if [ $ret == 0 ] ; then
+       echo "$out"
+       echo "failed - NT_STATUS_XXXX listing \\widelinks_share\\dot"
+       false
+    fi
+
+    cat > $tmpfile <<EOF
+allinfo source
+quit
+EOF
+    cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD 
//$SERVER/widelinks_share -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
+    eval echo "$cmd"
+    out=`eval $cmd`
+    ret=$?
+    rm -f $tmpfile
+
+    if [ $ret != 0 ] ; then
+       echo "$out"
+       echo "failed accessing widelinks_share with error $ret"
+       false
+       return
+    fi
+
+# This should fail with NT_STATUS_ACCESS_DENIED
+    echo "$out" | grep 'NT_STATUS_ACCESS_DENIED'
+    ret=$?
+    if [ $ret != 0 ] ; then
+       echo "$out"
+       echo "failed - should get NT_STATUS_ACCESS_DENIED listing 
\\widelinks_share\\source"
+       false
+    fi
+}
 
 LOGDIR_PREFIX=test_smbclient_s3
 
@@ -1095,6 +1151,10 @@ testit "creating a :stream at root of share" \
     test_toplevel_stream || \
     failed=`expr $failed + 1`
 
+testit "Ensure widelinks are restricted" \
+    test_widelinks || \
+    failed=`expr $failed + 1`
+
 testit "rm -rf $LOGDIR" \
     rm -rf $LOGDIR || \
     failed=`expr $failed + 1`
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 0c272a7..27b38d6 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -982,6 +982,7 @@ NTSTATUS 
check_reduced_name_with_privilege(connection_struct *conn,
        struct smb_filename *smb_fname_cwd = NULL;
        struct privilege_paths *priv_paths = NULL;
        int ret;
+       bool matched;
 
        DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
                        fname,
@@ -1076,7 +1077,10 @@ NTSTATUS 
check_reduced_name_with_privilege(connection_struct *conn,
        }
 
        rootdir_len = strlen(conn_rootdir);
-       if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
+       matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0);
+
+       if (!matched || (resolved_name[rootdir_len] != '/' &&
+                        resolved_name[rootdir_len] != '\0')) {
                DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
                        "attempt: %s is a symlink outside the "
                        "share path\n",
@@ -1216,6 +1220,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, 
const char *fname)
        if (!allow_widelinks || !allow_symlinks) {
                const char *conn_rootdir;
                size_t rootdir_len;
+               bool matched;
 
                conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
                if (conn_rootdir == NULL) {
@@ -1226,8 +1231,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, 
const char *fname)
                }
 
                rootdir_len = strlen(conn_rootdir);
-               if (strncmp(conn_rootdir, resolved_name,
-                               rootdir_len) != 0) {
+               matched = (strncmp(conn_rootdir, resolved_name,
+                               rootdir_len) == 0);
+               if (!matched || (resolved_name[rootdir_len] != '/' &&
+                                resolved_name[rootdir_len] != '\0')) {
                        DEBUG(2, ("check_reduced_name: Bad access "
                                "attempt: %s is a symlink outside the "
                                "share path\n", fname));
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c 
b/source4/dsdb/samdb/ldb_modules/samldb.c
index fbb392d..153c85e 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -1558,12 +1558,15 @@ static int samldb_check_user_account_control_acl(struct 
samldb_ctx *ac,
        struct security_token *user_token;
        struct security_descriptor *domain_sd;
        struct ldb_dn *domain_dn = 
ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
+       struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
        const struct uac_to_guid {
                uint32_t uac;
+               uint32_t priv_to_change_from;
                const char *oid;
                const char *guid;
                enum sec_privilege privilege;
                bool delete_is_privileged;
+               bool admin_required;
                const char *error_string;
        } map[] = {
                {
@@ -1592,6 +1595,16 @@ static int samldb_check_user_account_control_acl(struct 
samldb_ctx *ac,
                        .error_string = "Adding the UF_PARTIAL_SECRETS_ACCOUNT 
bit in userAccountControl requires the DS-Install-Replica right that was not 
given on the Domain object"
                },
                {
+                       .uac = UF_WORKSTATION_TRUST_ACCOUNT,
+                       .priv_to_change_from = UF_NORMAL_ACCOUNT,
+                       .error_string = "Swapping UF_NORMAL_ACCOUNT to 
UF_WORKSTATION_TRUST_ACCOUNT requires the user to be a member of the domain 
admins group"
+               },
+               {
+                       .uac = UF_NORMAL_ACCOUNT,
+                       .priv_to_change_from = UF_WORKSTATION_TRUST_ACCOUNT,
+                       .error_string = "Swapping UF_WORKSTATION_TRUST_ACCOUNT 
to UF_NORMAL_ACCOUNT requires the user to be a member of the domain admins 
group"
+               },
+               {
                        .uac = UF_INTERDOMAIN_TRUST_ACCOUNT,
                        .oid = DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
                        .error_string = "Updating the 
UF_INTERDOMAIN_TRUST_ACCOUNT bit in userAccountControl is not permitted over 
LDAP.  This bit is restricted to the LSA CreateTrustedDomain interface",
@@ -1643,7 +1656,7 @@ static int samldb_check_user_account_control_acl(struct 
samldb_ctx *ac,
                return ldb_module_operr(ac->module);
        }
 
-       ret = dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module),
+       ret = dsdb_get_sd_from_ldb_message(ldb,
                                           ac, res->msgs[0], &domain_sd);
 
        if (ret != LDB_SUCCESS) {
@@ -1670,12 +1683,19 @@ static int samldb_check_user_account_control_acl(struct 
samldb_ctx *ac,
                                if (have_priv == false) {
                                        ret = 
LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
                                }
-                       } else {
+                       } else if (map[i].priv_to_change_from & 
user_account_control_old) {
+                               bool is_admin = 
security_token_has_builtin_administrators(user_token);
+                               if (is_admin == false) {
+                                       ret = 
LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+                               }
+                       } else if (map[i].guid) {
                                ret = acl_check_extended_right(ac, domain_sd,
                                                               user_token,
                                                               map[i].guid,
                                                               
SEC_ADS_CONTROL_ACCESS,
                                                               sid);
+                       } else {
+                               ret = LDB_SUCCESS;
                        }
                        if (ret != LDB_SUCCESS) {
                                break;
diff --git a/source4/dsdb/tests/python/user_account_control.py 
b/source4/dsdb/tests/python/user_account_control.py
index 16c7f81..a53c4f9 100644
--- a/source4/dsdb/tests/python/user_account_control.py
+++ b/source4/dsdb/tests/python/user_account_control.py
@@ -240,6 +240,16 @@ class UserAccountControlTests(samba.tests.TestCase):
         m.dn = res[0].dn
         m["userAccountControl"] = 
ldb.MessageElement(str(samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT),
                                                      ldb.FLAG_MOD_REPLACE, 
"userAccountControl")
+        try:
+            self.samdb.modify(m)
+            self.fail("Unexpectedly able to set userAccountControl to be an 
Workstation on %s" % m.dn)
+        except LdbError, (enum, estr):
+            self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum)
+
+        m = ldb.Message()
+        m.dn = res[0].dn
+        m["userAccountControl"] = 
ldb.MessageElement(str(samba.dsdb.UF_NORMAL_ACCOUNT),
+                                                     ldb.FLAG_MOD_REPLACE, 
"userAccountControl")
         self.samdb.modify(m)
 
         m = ldb.Message()
@@ -306,7 +316,12 @@ class UserAccountControlTests(samba.tests.TestCase):
         m.dn = res[0].dn
         m["userAccountControl"] = 
ldb.MessageElement(str(samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT),
                                                      ldb.FLAG_MOD_REPLACE, 
"userAccountControl")
-        self.samdb.modify(m)
+        try:
+            self.samdb.modify(m)
+            self.fail("Unexpectedly able to set userAccountControl to be an 
Workstation on %s" % m.dn)
+        except LdbError, (enum, estr):
+            self.assertEqual(ldb.ERR_INSUFFICIENT_ACCESS_RIGHTS, enum)
+
 
     def test_admin_mod_uac(self):
         computername=self.computernames[0]
@@ -382,9 +397,10 @@ class UserAccountControlTests(samba.tests.TestCase):
         priv_to_auth_users_bits = set([UF_PASSWD_NOTREQD, 
UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED,
                                        UF_DONT_EXPIRE_PASSWD])
 
-        # These bits really are privileged
+        # These bits really are privileged, or can't be changed from UF_NORMAL 
as a non-admin
         priv_bits = set([UF_INTERDOMAIN_TRUST_ACCOUNT, UF_SERVER_TRUST_ACCOUNT,
-                         UF_TRUSTED_FOR_DELEGATION, 
UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION])
+                         UF_TRUSTED_FOR_DELEGATION, 
UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION,
+                         UF_WORKSTATION_TRUST_ACCOUNT])
 
         invalid_bits = set([UF_TEMP_DUPLICATE_ACCOUNT, 
UF_PARTIAL_SECRETS_ACCOUNT])
 
@@ -446,7 +462,7 @@ class UserAccountControlTests(samba.tests.TestCase):
                             int("0x10000000", 16), int("0x20000000", 16), 
int("0x40000000", 16), int("0x80000000", 16)])
         super_priv_bits = set([UF_INTERDOMAIN_TRUST_ACCOUNT])
 
-        priv_to_remove_bits = set([UF_TRUSTED_FOR_DELEGATION, 
UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION])
+        priv_to_remove_bits = set([UF_TRUSTED_FOR_DELEGATION, 
UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, UF_WORKSTATION_TRUST_ACCOUNT])
 
         for bit in bits:


-- 
Samba Shared Repository

Reply via email to