s3:netlookup: make use of cli_credentials_init_anon()
[bbaumbach/samba-autobuild/.git] / source3 / utils / smbpasswd.c
index b8a8e9c71b6d8b894e9a81ecc47725581727b113..40131205265b57707ceb1fc25e97f38d848f1073 100644 (file)
@@ -23,6 +23,8 @@
 #include "../lib/util/util_pw.h"
 #include "libsmb/proto.h"
 #include "passdb.h"
+#include "cmdline_contexts.h"
+#include "passwd_proto.h"
 
 /*
  * Next two lines needed for SunOS and don't
@@ -58,7 +60,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");
@@ -95,7 +97,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) {
@@ -294,7 +296,7 @@ static bool store_ldap_admin_pw (char* pw)
        if (!secrets_init())
                return False;
 
-       return secrets_store_ldap_pw(lp_ldap_admin_dn(talloc_tos()), pw);
+       return secrets_store_ldap_pw(lp_ldap_admin_dn(), pw);
 }
 
 
@@ -309,7 +311,7 @@ static int process_root(int local_flags)
        char *old_passwd = NULL;
 
        if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) {
-               char *ldap_admin_dn = lp_ldap_admin_dn(talloc_tos());
+               const char *ldap_admin_dn = lp_ldap_admin_dn();
                if ( ! *ldap_admin_dn ) {
                        DEBUG(0,("ERROR: 'ldap admin dn' not defined! Please check your smb.conf\n"));
                        goto done;
@@ -368,36 +370,44 @@ static int process_root(int local_flags)
 
        if (local_flags & LOCAL_TRUST_ACCOUNT) {
                /* add the $ automatically */
-               static fstring buf;
+               size_t user_name_len = strlen(user_name);
 
-               /*
-                * Remove any trailing '$' before we
-                * generate the initial machine password.
-                */
-
-               if (user_name[strlen(user_name)-1] == '$') {
-                       user_name[strlen(user_name)-1] = 0;
+               if (user_name[user_name_len - 1] == '$') {
+                       user_name_len--;
+               } else {
+                       if (user_name_len + 2 > sizeof(user_name)) {
+                               fprintf(stderr, "machine name too long\n");
+                               exit(1);
+                       }
+                       user_name[user_name_len] = '$';
+                       user_name[user_name_len + 1] = '\0';
                }
 
                if (local_flags & LOCAL_ADD_USER) {
                        SAFE_FREE(new_passwd);
-                       new_passwd = smb_xstrdup(user_name);
+
+                       /*
+                        * Remove any trailing '$' before we
+                        * generate the initial machine password.
+                        */
+                       new_passwd = smb_xstrndup(user_name, user_name_len);
                        if (!strlower_m(new_passwd)) {
                                fprintf(stderr, "strlower_m %s failed\n",
                                        new_passwd);
                                exit(1);
                        }
                }
-
-               /*
-                * Now ensure the username ends in '$' for
-                * the machine add.
-                */
-
-               slprintf(buf, sizeof(buf)-1, "%s$", user_name);
-               strlcpy(user_name, buf, sizeof(user_name));
        } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
-               static fstring buf;
+               size_t user_name_len = strlen(user_name);
+
+               if (user_name[user_name_len - 1] != '$') {
+                       if (user_name_len + 2 > sizeof(user_name)) {
+                               fprintf(stderr, "machine name too long\n");
+                               exit(1);
+                       }
+                       user_name[user_name_len] = '$';
+                       user_name[user_name_len + 1] = '\0';
+               }
 
                if ((local_flags & LOCAL_ADD_USER) && (new_passwd == NULL)) {
                        /*
@@ -409,11 +419,6 @@ static int process_root(int local_flags)
                                exit(1);
                        }
                }
-
-               /* prepare uppercased and '$' terminated username */
-               slprintf(buf, sizeof(buf) - 1, "%s$", user_name);
-               strlcpy(user_name, buf, sizeof(user_name));
-
        } else {
 
                if (remote_machine != NULL) {
@@ -519,6 +524,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 */
@@ -536,6 +544,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
@@ -544,16 +561,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) {
@@ -568,13 +593,13 @@ static int process_nonroot(int local_flags)
        }
 
        if (!NT_STATUS_IS_OK(password_change(remote_machine,
-                                            NULL, user_name,
+                                            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);
@@ -591,7 +616,6 @@ static int process_nonroot(int local_flags)
 int main(int argc, char **argv)
 {      
        TALLOC_CTX *frame = talloc_stackframe();
-       struct messaging_context *msg_ctx = NULL;
        int local_flags = 0;
        int ret;
 
@@ -609,19 +633,6 @@ int main(int argc, char **argv)
 
        setup_logging("smbpasswd", DEBUG_STDERR);
 
-       msg_ctx = server_messaging_context();
-       if (msg_ctx == NULL) {
-               if (geteuid() != 0) {
-                       DBG_NOTICE("Unable to initialize messaging context. "
-                                  "Must be root to do that.\n");
-               } else {
-                       fprintf(stderr,
-                               "smbpasswd is not able to initialize the "
-                               "messaging context!\n");
-                       return 1;
-               }
-       }
-
        /*
         * Set the machine NETBIOS name if not already
         * set from the config file.