Fix client authentication with -P switch in client tools (Bug 5435).
authorGünther Deschner <gd@samba.org>
Mon, 5 May 2008 14:58:24 +0000 (16:58 +0200)
committerGünther Deschner <gd@samba.org>
Mon, 5 May 2008 14:59:53 +0000 (16:59 +0200)
Guenther
(This used to be commit d077ef64cd1d9bbaeb936566c2c70da508de829f)

source3/client/client.c
source3/include/popt_common.h
source3/lib/popt_common.c
source3/lib/util.c
source3/libsmb/cliconnect.c
source3/rpcclient/rpcclient.c
source3/utils/smbcacls.c
source3/utils/smbcquotas.c
source3/utils/smbtree.c

index b4e1985a837b3a14eb1fed04106ff8469c4102d0..cc0da18d4d36c813a390e2b856307f4eb76ad09c 100644 (file)
@@ -4875,6 +4875,11 @@ static int do_message_op(void)
                        argv[0], get_dyn_CONFIGFILE());
        }
 
+       if (get_cmdline_auth_info_use_machine_account() &&
+           !set_cmdline_auth_info_machine_account_creds()) {
+               exit(-1);
+       }
+
        load_interfaces();
 
        if (service_opt && service) {
index 9e5503f2701f09b368edd063c8df09a15d85ff6c..c889d2e6e6a2b3d94c6b93ddb312cf103f5358c5 100644 (file)
@@ -50,6 +50,7 @@ struct user_auth_info {
        bool use_kerberos;
        int signing_state;
        bool smb_encrypt;
+       bool use_machine_account;
 };
 
 #endif /* _POPT_COMMON_H */
index 8f0f7c62bb9e6ace3982774dfd07533ea99ae663..25e41ab5f3c0ce1886190662d385f2d63e0021c4 100644 (file)
@@ -514,35 +514,7 @@ static void popt_common_credentials_callback(poptContext con,
                }
                break;
        case 'P':
-               {
-                       char *opt_password = NULL;
-                       char *pwd = NULL;
-
-                       /* it is very useful to be able to make ads queries as the
-                          machine account for testing purposes and for domain leave */
-
-                       if (!secrets_init()) {
-                               d_printf("ERROR: Unable to open secrets database\n");
-                               exit(1);
-                       }
-
-                       opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
-                       if (!opt_password) {
-                               d_printf("ERROR: Unable to fetch machine password\n");
-                               exit(1);
-                       }
-                       if (asprintf(&pwd, "%s$", global_myname()) < 0) {
-                               exit(ENOMEM);
-                       }
-                       set_cmdline_auth_info_username(pwd);
-                       set_cmdline_auth_info_password(opt_password);
-                       SAFE_FREE(pwd);
-                       SAFE_FREE(opt_password);
-
-                       /* machine accounts only work with kerberos */
-                       set_cmdline_auth_info_use_krb5_ticket();
-               }
+               set_cmdline_auth_info_use_machine_account();
                break;
        case 'N':
                set_cmdline_auth_info_password("");
index 953981e82ade57c85b2b0817a160603f035db373..5f95bcc558ff38462f8003e5e2b0e25bac96e433 100644 (file)
@@ -291,7 +291,8 @@ static struct user_auth_info cmdline_auth_info = {
        false,  /* got_pass */
        false,  /* use_kerberos */
        Undefined, /* signing state */
-       false   /* smb_encrypt */
+       false,  /* smb_encrypt */
+       false   /* use machine account */
 };
 
 const char *get_cmdline_auth_info_username(void)
@@ -370,6 +371,11 @@ void set_cmdline_auth_info_smb_encrypt(void)
        cmdline_auth_info.smb_encrypt = true;
 }
 
+void set_cmdline_auth_info_use_machine_account(void)
+{
+       cmdline_auth_info.use_machine_account = true;
+}
+
 bool get_cmdline_auth_info_got_pass(void)
 {
        return cmdline_auth_info.got_pass;
@@ -380,6 +386,11 @@ bool get_cmdline_auth_info_smb_encrypt(void)
        return cmdline_auth_info.smb_encrypt;
 }
 
+bool get_cmdline_auth_info_use_machine_account(void)
+{
+       return cmdline_auth_info.use_machine_account;
+}
+
 bool get_cmdline_auth_info_copy(struct user_auth_info *info)
 {
        *info = cmdline_auth_info;
@@ -392,6 +403,42 @@ bool get_cmdline_auth_info_copy(struct user_auth_info *info)
        return true;
 }
 
+bool set_cmdline_auth_info_machine_account_creds(void)
+{
+       char *pass = NULL;
+       char *account = NULL;
+
+       if (!get_cmdline_auth_info_use_machine_account()) {
+               return false;
+       }
+
+       if (!secrets_init()) {
+               d_printf("ERROR: Unable to open secrets database\n");
+               return false;
+       }
+
+       if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
+               return false;
+       }
+
+       pass = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+       if (!pass) {
+               d_printf("ERROR: Unable to fetch machine password for "
+                       "%s in domain %s\n",
+                       account, lp_workgroup());
+               SAFE_FREE(account);
+               return false;
+       }
+
+       set_cmdline_auth_info_username(account);
+       set_cmdline_auth_info_password(pass);
+
+       SAFE_FREE(account);
+       SAFE_FREE(pass);
+
+       return true;
+}
+
 /**************************************************************************n
  Find a suitable temporary directory. The result should be copied immediately
  as it may be overwritten by a subsequent call.
index 7d3d246da507dbce25fada49e21438d1d2ab1977..671f0e7bc5fb81ad92ee68892ce0d0fd69f5e991 100644 (file)
@@ -795,6 +795,8 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
        int i;
        bool got_kerberos_mechanism = False;
        DATA_BLOB blob;
+       const char *p = NULL;
+       char *account = NULL;
 
        DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
 
@@ -925,7 +927,17 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
 
 ntlmssp:
 
-       return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain));
+       account = talloc_strdup(talloc_tos(), user);
+       ADS_ERROR_HAVE_NO_MEMORY(account);
+
+       /* when falling back to ntlmssp while authenticating with a machine
+        * account strip off the realm - gd */
+
+       if ((p = strchr_m(user, '@')) != NULL) {
+               account[PTR_DIFF(p,user)] = '\0';
+       }
+
+       return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, domain));
 }
 
 /****************************************************************************
@@ -1867,12 +1879,18 @@ struct cli_state *get_ipc_connect(char *server,
 {
         struct cli_state *cli;
        NTSTATUS nt_status;
+       uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
+
+       if (user_info->use_kerberos) {
+               flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+       }
 
        nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", 
                                        user_info->username ? user_info->username : "",
                                        lp_workgroup(),
                                        user_info->password ? user_info->password : "",
-                                       CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL);
+                                       flags,
+                                       Undefined, NULL);
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return cli;
index 10a17412070c70901755077498c610865913b88f..c4be970ac34383fe66ac1dafeeb84f8ab5c7bcf3 100644 (file)
@@ -736,6 +736,7 @@ out_free:
        fstring new_workgroup;
        int result = 0;
        TALLOC_CTX *frame = talloc_stackframe();
+       uint32_t flags = 0;
 
        /* make sure the vars that get altered (4th field) are in
           a fixed location or certain compilers complain */
@@ -827,6 +828,12 @@ out_free:
         * from stdin if necessary
         */
 
+       if (get_cmdline_auth_info_use_machine_account() &&
+           !set_cmdline_auth_info_machine_account_creds()) {
+               result = 1;
+               goto done;
+       }
+
        if (!get_cmdline_auth_info_got_pass()) {
                char *pass = getpass("Password:");
                if (pass) {
@@ -839,13 +846,19 @@ out_free:
                server += 2;
        }
 
+       if (get_cmdline_auth_info_use_kerberos()) {
+               flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
+                        CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+       }
+
+
        nt_status = cli_full_connection(&cli, global_myname(), server,
                                        opt_ipaddr ? &server_ss : NULL, opt_port,
                                        "IPC$", "IPC",
                                        get_cmdline_auth_info_username(),
                                        lp_workgroup(),
                                        get_cmdline_auth_info_password(),
-                                       get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
+                                       flags,
                                        get_cmdline_auth_info_signing_state(),NULL);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
index af14c622dc9616e685945eded431f88b97c84a58..95ef6190e83d976bbdeb7461e671471df5628c7d 100644 (file)
@@ -821,8 +821,20 @@ static struct cli_state *connect_one(const char *server, const char *share)
        struct cli_state *c = NULL;
        struct sockaddr_storage ss;
        NTSTATUS nt_status;
+       uint32_t flags = 0;
+
        zero_addr(&ss);
 
+       if (get_cmdline_auth_info_use_kerberos()) {
+               flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
+                        CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+       }
+
+       if (get_cmdline_auth_info_use_machine_account() &&
+           !set_cmdline_auth_info_machine_account_creds()) {
+               return NULL;
+       }
+
        if (!get_cmdline_auth_info_got_pass()) {
                char *pass = getpass("Password: ");
                if (pass) {
@@ -836,7 +848,7 @@ static struct cli_state *connect_one(const char *server, const char *share)
                                get_cmdline_auth_info_username(),
                                lp_workgroup(),
                                get_cmdline_auth_info_password(),
-                               get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
+                               flags,
                                get_cmdline_auth_info_signing_state(),
                                NULL);
        if (!NT_STATUS_IS_OK(nt_status)) {
index 508a2dc8ca625dc2d49ed466f786454ff2997890..a73c3b49df1f27970486cbb0037c761c1bc359d3 100644 (file)
@@ -371,8 +371,21 @@ static struct cli_state *connect_one(const char *share)
        struct cli_state *c;
        struct sockaddr_storage ss;
        NTSTATUS nt_status;
+       uint32_t flags = 0;
+
        zero_addr(&ss);
 
+       if (get_cmdline_auth_info_use_machine_account() &&
+           !set_cmdline_auth_info_machine_account_creds()) {
+               return NULL;
+       }
+
+       if (get_cmdline_auth_info_use_kerberos()) {
+               flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
+                        CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+
+       }
+
        if (!get_cmdline_auth_info_got_pass()) {
                char *pass = getpass("Password: ");
                if (pass) {
@@ -386,7 +399,7 @@ static struct cli_state *connect_one(const char *share)
                                            get_cmdline_auth_info_username(),
                                            lp_workgroup(),
                                            get_cmdline_auth_info_password(),
-                                           0,
+                                           flags,
                                            get_cmdline_auth_info_signing_state(),
                                            NULL);
        if (!NT_STATUS_IS_OK(nt_status)) {
index c2b364d1e9ac80250dbb3d60ab97bbf36f361933..e975a1c8a27b63160323f2c3b77d504c268af65e 100644 (file)
@@ -302,6 +302,12 @@ static bool print_tree(struct user_auth_info *user_info)
 
        /* Parse command line args */
 
+       if (get_cmdline_auth_info_use_machine_account() &&
+           !set_cmdline_auth_info_machine_account_creds()) {
+               TALLOC_FREE(frame);
+               return 1;
+       }
+
        if (!get_cmdline_auth_info_got_pass()) {
                char *pass = getpass("Password: ");
                if (pass) {