The branch, master has been updated
       via  531ef64 s3:tests: Add test for changing the local user password 
with smbpasswd
       via  4a4bfcb s3:utils: Remove pointless if-clause for remote_machine
       via  dc129a9 s3:utils: Make sure we authenticate against our SAM name in 
smbpasswd
       via  b483340 s3:utils: Pass domain to password_change() in smbpasswd
       via  41a31a7 s3:utils: Make strings const passed to password_change() in 
smbpasswd
       via  c773844 s3:libsmb: Move prototye of remote_password_change()
       via  7a554ee s3:libsmb: Pass domain to remote_password_change()
      from  95e30b0 s3:utils: Do not report an invalid range for AD DC role

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


- Log -----------------------------------------------------------------
commit 531ef64bf87ac849c24ebf129faec4c4131fde40
Author: Andreas Schneider <[email protected]>
Date:   Mon Aug 21 12:23:56 2017 +0200

    s3:tests: Add test for changing the local user password with smbpasswd
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>
    
    Autobuild-User(master): Andreas Schneider <[email protected]>
    Autobuild-Date(master): Wed Aug 23 17:05:48 CEST 2017 on sn-devel-144

commit 4a4bfcb539b4489f397b2bc9369215b7e03e620e
Author: Andreas Schneider <[email protected]>
Date:   Tue Aug 22 15:46:07 2017 +0200

    s3:utils: Remove pointless if-clause for remote_machine
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Review with: git show -U20
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>

commit dc129a968afdac8be70f9756bd18a7bf1f4c3b02
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 18 16:17:08 2017 +0200

    s3:utils: Make sure we authenticate against our SAM name in smbpasswd
    
    If a local user wants to change his password using smbpasswd and the
    machine is a domain member, we need to make sure we authenticate against
    our SAM and not ask winbind.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>

commit b483340639157fe95777672f5723455c48c3c616
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 18 16:14:57 2017 +0200

    s3:utils: Pass domain to password_change() in smbpasswd
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>

commit 41a31a71abe144362fc7483fabba39aafa866373
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 18 16:13:15 2017 +0200

    s3:utils: Make strings const passed to password_change() in smbpasswd
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>

commit c773844e7529b83b2633671c7bcf1e7b84ad7950
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 18 16:10:06 2017 +0200

    s3:libsmb: Move prototye of remote_password_change()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>

commit 7a554ee7dcefdff599ebc6fbf4e128b33ffccf29
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 18 16:08:46 2017 +0200

    s3:libsmb: Pass domain to remote_password_change()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12975
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Andrew Bartlet <[email protected]>

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

Summary of changes:
 source3/include/proto.h                |   6 --
 source3/libsmb/passchange.c            |   5 +-
 source3/libsmb/proto.h                 |  10 +++
 source3/script/tests/test_smbpasswd.sh | 132 +++++++++++++++++++++++++++++++++
 source3/selftest/tests.py              |   3 +
 source3/utils/smbpasswd.c              |  57 ++++++++++----
 6 files changed, 189 insertions(+), 24 deletions(-)
 create mode 100755 source3/script/tests/test_smbpasswd.sh


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index c8f6c28..b2c3a03 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -821,12 +821,6 @@ bool get_dc_name(const char *domain,
                fstring srv_name,
                struct sockaddr_storage *ss_out);
 
-/* The following definitions come from libsmb/passchange.c  */
-
-NTSTATUS remote_password_change(const char *remote_machine, const char 
*user_name, 
-                               const char *old_passwd, const char *new_passwd,
-                               char **err_str);
-
 /* The following definitions come from libsmb/smberr.c  */
 
 const char *smb_dos_err_name(uint8_t e_class, uint16_t num);
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index c89b7ca..48ffba8 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -30,7 +30,8 @@
  Change a password on a remote machine using IPC calls.
 *************************************************************/
 
-NTSTATUS remote_password_change(const char *remote_machine, const char 
*user_name, 
+NTSTATUS remote_password_change(const char *remote_machine,
+                               const char *domain, const char *user_name,
                                const char *old_passwd, const char *new_passwd,
                                char **err_str)
 {
@@ -55,7 +56,7 @@ NTSTATUS remote_password_change(const char *remote_machine, 
const char *user_nam
 
        creds = cli_session_creds_init(cli,
                                       user_name,
-                                      NULL, /* domain */
+                                      domain,
                                       NULL, /* realm */
                                       old_passwd,
                                       false, /* use_kerberos */
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 05d91f7..a74433f 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -30,6 +30,9 @@
 
 struct smb_trans_enc_state;
 struct cli_credentials;
+struct cli_state;
+struct file_info;
+struct print_job_info;
 
 /* The following definitions come from libsmb/cliconnect.c  */
 
@@ -970,4 +973,11 @@ NTSTATUS cli_readlink(struct cli_state *cli, const char 
*fname,
                       TALLOC_CTX *mem_ctx, char **psubstitute_name,
                      char **pprint_name, uint32_t *pflags);
 
+/* The following definitions come from libsmb/passchange.c  */
+
+NTSTATUS remote_password_change(const char *remote_machine,
+                               const char *domain, const char *user_name,
+                               const char *old_passwd, const char *new_passwd,
+                               char **err_str);
+
 #endif /* _LIBSMB_PROTO_H_ */
diff --git a/source3/script/tests/test_smbpasswd.sh 
b/source3/script/tests/test_smbpasswd.sh
new file mode 100755
index 0000000..62b37a0
--- /dev/null
+++ b/source3/script/tests/test_smbpasswd.sh
@@ -0,0 +1,132 @@
+#!/bin/sh
+#
+# Blackbox tests for smbpasswd
+#
+# Copyright (c) 2015-2016 Andreas Schneider <[email protected]>
+#
+
+if [ $# -lt 4 ]; then
+cat <<EOF
+Usage: test_smbpasswd.sh SERVER USERNAME PASSWORD
+EOF
+exit 1;
+fi
+
+SERVER=$1
+SERVER_IP=$2
+USERNAME=$3
+PASSWORD=$4
+shift 4
+
+incdir=$(dirname $0)/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+failed=0
+
+samba_bindir="$BINDIR"
+samba_srcdir="$SRCDIR"
+
+samba_texpect="$samba_bindir/texpect"
+samba_smbpasswd="$samba_bindir/smbpasswd"
+
+samba_test_user="alice_smbpasswd"
+samba_test_user_pwd="Secret007"
+samba_test_user_new_pwd="Secret008"
+
+create_local_smb_user()
+{
+       user=$1
+       password=$2
+
+       tmpfile=$PREFIX/smbpasswd_create_user_script
+       cat > $tmpfile <<EOF
+expect New SMB password:
+send $password\n
+expect Retype new SMB password:
+send $password\n
+EOF
+
+       cmd='UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 
$samba_texpect $tmpfile $samba_smbpasswd -c $SMB_CONF_PATH -a $user 2>&1'
+       eval echo "$cmd"
+       out=$(eval $cmd)
+       ret=$?
+
+       rm -f $tmpfile
+
+       if [ $ret -ne 0 ]; then
+               echo "Failed to create smb user $user"
+               return 1
+       fi
+
+       getent passwd $user
+       ret=$?
+       if [ $ret -ne 0 ]; then
+               echo "Failed to create smb user $user"
+               return 1
+       fi
+}
+
+delete_local_smb_user()
+{
+       user=$1
+
+       # This also deletes the unix account!
+       UID_WRAPPER_INITIAL_RUID=0 UID_WRAPPER_INITIAL_EUID=0 $samba_smbpasswd 
-c $SMB_CONF_PATH -x $user
+       ret=$?
+       if [ $ret -ne 0 ]; then
+               echo "Failed to delete smb user $user"
+               return 1
+       fi
+}
+
+test_smbpasswd()
+{
+       user=$1
+       oldpwd=$2
+       newpwd=$3
+
+       user_id=$(id -u $user)
+
+       tmpfile=$PREFIX/smbpasswd_change_password_script
+       cat > $tmpfile <<EOF
+expect Old SMB password:
+send $oldpwd\n
+expect New SMB password:
+send $newpwd\n
+expect Retype new SMB password:
+send $newpwd\n
+EOF
+
+       cmd='UID_WRAPPER_INITIAL_RUID=$user_id 
UID_WRAPPER_INITIAL_EUID=$user_id $samba_texpect $tmpfile $samba_smbpasswd -c 
$SMB_CONF_PATH -r $SERVER 2>&1'
+       eval echo "$cmd"
+       out=$(eval $cmd)
+       ret=$?
+       rm -f $tmpfile
+       if [ $ret -ne 0 ]; then
+               echo "Failed to change user password $user"
+               return 1
+       fi
+
+       prompt="Password changed for user $user"
+       echo "$out" | grep "$prompt" >/dev/null 2>&1
+       ret=$?
+       if [ $ret -ne 0 ]; then
+               echo "Failed to change password for user $user"
+               echo "$out"
+               return 1
+       fi
+}
+
+testit "Create user $samba_test_user" \
+       create_local_smb_user $samba_test_user $samba_test_user_pwd \
+       || failed=$(expr $failed + 1)
+
+testit "Change user password" \
+       test_smbpasswd $samba_test_user $samba_test_user_pwd 
$samba_test_user_new_pwd \
+       || failed=$(expr $failed + 1)
+
+testit "Delete user $samba_test_user" \
+       delete_local_smb_user $samba_test_user \
+       || failed=$(expr $failed + 1)
+
+exit $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index a624f85..7e1f213 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -188,6 +188,9 @@ for options in ["--option=clientntlmv2auth=no", 
"--option=clientusespnego=no --o
 env="ad_dc"
 plantestsuite("samba3.blackbox.smbspool", env, [os.path.join(samba3srcdir, 
"script/tests/test_smbspool.sh"), '$SERVER', '$SERVER_IP', '$DC_USERNAME', 
'$DC_PASSWORD', env])
 
+for env in ["ad_member:local", "nt4_dc:local"]:
+    plantestsuite("samba3.blackbox.smbpasswd", env, 
[os.path.join(samba3srcdir, "script/tests/test_smbpasswd.sh"), '$SERVER', 
'$SERVER_IP', '$DC_USERNAME', '$DC_PASSWORD'])
+
 env="nt4_dc"
 plantestsuite("samba3.blackbox.smbclient_auth.plain (%s) ipv6" % env, env, 
[os.path.join(samba3srcdir, "script/tests/test_smbclient_auth.sh"), '$SERVER', 
'$SERVER_IPV6', '$SERVER/$USERNAME', '$PASSWORD', smbclient3, configuration])
 
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index ae98626..3136de6 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -21,6 +21,7 @@
 #include "secrets.h"
 #include "../librpc/gen_ndr/samr.h"
 #include "../lib/util/util_pw.h"
+#include "libsmb/proto.h"
 #include "passdb.h"
 
 /*
@@ -57,7 +58,7 @@ static void usage(void)
        printf("  -c smb.conf file     Use the given path to the smb.conf 
file\n");
        printf("  -D LEVEL             debug level\n");
        printf("  -r MACHINE           remote machine\n");
-       printf("  -U USER              remote username\n");
+       printf("  -U USER              remote username (e.g. SAM/user)\n");
 
        printf("extra options when run by root or in local mode:\n");
        printf("  -a                   add user\n");
@@ -94,7 +95,7 @@ static int process_options(int argc, char **argv, int 
local_flags)
 
        user_name[0] = '\0';
 
-       while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:LW")) != EOF) {
+       while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:LWS:")) != EOF) {
                switch(ch) {
                case 'L':
                        if (getuid() != 0) {
@@ -242,8 +243,9 @@ static char *prompt_for_new_password(bool stdin_get)
  Change a password either locally or remotely.
 *************************************************************/
 
-static NTSTATUS password_change(const char *remote_mach, char *username, 
-                               char *old_passwd, char *new_pw,
+static NTSTATUS password_change(const char *remote_mach,
+                               const char *domain, const char *username,
+                               const char *old_passwd, const char *new_pw,
                                int local_flags)
 {
        NTSTATUS ret;
@@ -258,7 +260,8 @@ static NTSTATUS password_change(const char *remote_mach, 
char *username,
                        fprintf(stderr, "Invalid remote operation!\n");
                        return NT_STATUS_UNSUCCESSFUL;
                }
-               ret = remote_password_change(remote_mach, username,
+               ret = remote_password_change(remote_mach,
+                                            domain, username,
                                             old_passwd, new_pw, &err_str);
        } else {
                ret = local_password_change(username, local_flags, new_pw,
@@ -463,7 +466,8 @@ static int process_root(int local_flags)
                }
        }
 
-       if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name,
+       if (!NT_STATUS_IS_OK(password_change(remote_machine,
+                                            NULL, user_name,
                                             old_passwd, new_passwd,
                                             local_flags))) {
                result = 1;
@@ -515,6 +519,9 @@ static int process_nonroot(int local_flags)
        int result = 0;
        char *old_pw = NULL;
        char *new_pw = NULL;
+       const char *username = user_name;
+       const char *domain = NULL;
+       char *p = NULL;
 
        if (local_flags & ~(LOCAL_AM_ROOT | LOCAL_SET_PASSWORD)) {
                /* Extra flags that we can't honor non-root */
@@ -532,6 +539,15 @@ static int process_nonroot(int local_flags)
                }
        }
 
+       /* Allow domain as part of the username */
+       if ((p = strchr_m(user_name, '\\')) ||
+           (p = strchr_m(user_name, '/')) ||
+           (p = strchr_m(user_name, *lp_winbind_separator()))) {
+               *p = '\0';
+               username = p + 1;
+               domain = user_name;
+       }
+
        /*
         * A non-root user is always setting a password
         * via a remote machine (even if that machine is
@@ -540,16 +556,24 @@ static int process_nonroot(int local_flags)
 
        load_interfaces(); /* Delayed from main() */
 
-       if (remote_machine == NULL) {
+       if (remote_machine != NULL) {
+               if (!is_ipaddress(remote_machine)) {
+                       domain = remote_machine;
+               }
+       } else {
                remote_machine = "127.0.0.1";
+
+               /*
+                * If we deal with a local user, change the password for the
+                * user in our SAM.
+                */
+               domain = get_global_sam_name();
        }
 
-       if (remote_machine != NULL) {
-               old_pw = get_pass("Old SMB password:",stdin_passwd_get);
-               if (old_pw == NULL) {
-                       fprintf(stderr, "Unable to get old password.\n");
-                       exit(1);
-               }
+       old_pw = get_pass("Old SMB password:",stdin_passwd_get);
+       if (old_pw == NULL) {
+               fprintf(stderr, "Unable to get old password.\n");
+               exit(1);
        }
 
        if (!new_passwd) {
@@ -563,13 +587,14 @@ static int process_nonroot(int local_flags)
                exit(1);
        }
 
-       if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, old_pw,
-                                            new_pw, 0))) {
+       if (!NT_STATUS_IS_OK(password_change(remote_machine,
+                                            domain, username,
+                                            old_pw, new_pw, 0))) {
                result = 1;
                goto done;
        }
 
-       printf("Password changed for user %s\n", user_name);
+       printf("Password changed for user %s\n", username);
 
  done:
        SAFE_FREE(old_pw);


-- 
Samba Shared Repository

Reply via email to