Merge branch 'v3-2-stable' into my_branch
[ira/wip.git] / source3 / libsmb / cliconnect.c
index 15dac093da4438711acbcf5feb5d2367598b45f4..16c3bed4383cc4607b9e02a2c76aaee737cd08ed 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -15,8 +15,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -61,8 +60,8 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
                                          const char *pass, size_t passlen,
                                          const char *workgroup)
 {
-       DATA_BLOB session_key = data_blob(NULL, 0);
-       DATA_BLOB lm_response = data_blob(NULL, 0);
+       DATA_BLOB session_key = data_blob_null;
+       DATA_BLOB lm_response = data_blob_null;
        fstring pword;
        char *p;
 
@@ -299,9 +298,9 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
                                      const char *workgroup)
 {
        uint32 capabilities = cli_session_setup_capabilities(cli);
-       DATA_BLOB lm_response = data_blob(NULL, 0);
-       DATA_BLOB nt_response = data_blob(NULL, 0);
-       DATA_BLOB session_key = data_blob(NULL, 0);
+       DATA_BLOB lm_response = data_blob_null;
+       DATA_BLOB nt_response = data_blob_null;
+       DATA_BLOB session_key = data_blob_null;
        NTSTATUS result;
        char *p;
 
@@ -334,7 +333,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
                        E_md4hash(pass, nt_hash);
 
 #ifdef LANMAN_ONLY
-                       nt_response = data_blob(NULL, 0);
+                       nt_response = data_blob_null;
 #else
                        nt_response = data_blob(NULL, 24);
                        SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
@@ -485,7 +484,7 @@ static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
 
 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
 {
-       DATA_BLOB blob2 = data_blob(NULL, 0);
+       DATA_BLOB blob2 = data_blob_null;
        char *p;
        size_t len;
 
@@ -534,8 +533,9 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B
 {
        int32 remaining = blob.length;
        int32 cur = 0;
-       DATA_BLOB send_blob = data_blob(NULL, 0);
+       DATA_BLOB send_blob = data_blob_null;
        int32 max_blob_size = 0;
+       DATA_BLOB receive_blob = data_blob_null;
 
        if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
                DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
@@ -553,7 +553,7 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B
                        send_blob.length = max_blob_size;
                        remaining -= max_blob_size;
                } else {
-                       DATA_BLOB null_blob = data_blob(NULL, 0);
+                       DATA_BLOB null_blob = data_blob_null;
 
                        send_blob.length = remaining; 
                         remaining = 0;
@@ -575,13 +575,15 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B
                        return False;
                }
 
-               cli_session_setup_blob_receive(cli);
+               receive_blob = cli_session_setup_blob_receive(cli);
+               data_blob_free(&receive_blob);
 
                if (cli_is_error(cli) &&
                                !NT_STATUS_EQUAL( cli_get_nt_error(cli), 
                                        NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                        DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n",
                                nt_errstr(cli_get_nt_error(cli)) ));
+                       cli->vuid = 0;
                        return False;
                }
        }
@@ -654,9 +656,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
        NTSTATUS nt_status;
        int turn = 1;
        DATA_BLOB msg1;
-       DATA_BLOB blob = data_blob(NULL, 0);
-       DATA_BLOB blob_in = data_blob(NULL, 0);
-       DATA_BLOB blob_out = data_blob(NULL, 0);
+       DATA_BLOB blob = data_blob_null;
+       DATA_BLOB blob_in = data_blob_null;
+       DATA_BLOB blob_out = data_blob_null;
 
        cli_temp_set_signing(cli);
 
@@ -713,7 +715,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
                        }
                } else if ((turn == 1) && 
                           NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-                       DATA_BLOB tmp_blob = data_blob(NULL, 0);
+                       DATA_BLOB tmp_blob = data_blob_null;
                        /* the server might give us back two challenges */
                        if (!spnego_parse_challenge(blob, &blob_in, 
                                                    &tmp_blob)) {
@@ -722,7 +724,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
                        }
                        data_blob_free(&tmp_blob);
                } else {
-                       if (!spnego_parse_auth_response(blob, nt_status, 
+                       if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, 
                                                        &blob_in)) {
                                DEBUG(3,("Failed to parse auth response\n"));
                                if (NT_STATUS_IS_OK(nt_status) 
@@ -741,33 +743,36 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
 
                DATA_BLOB key = data_blob(ntlmssp_state->session_key.data,
                                          ntlmssp_state->session_key.length);
-               DATA_BLOB null_blob = data_blob(NULL, 0);
+               DATA_BLOB null_blob = data_blob_null;
+               BOOL res;
 
                fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
                cli_set_session_key(cli, ntlmssp_state->session_key);
 
-               if (!cli_encryption_on(cli)) {
-                       BOOL res = cli_simple_set_signing(cli, key, null_blob);
+               res = cli_simple_set_signing(cli, key, null_blob);
 
-                       if (res) {
+               data_blob_free(&key);
+
+               if (res) {
                        
-                               /* 'resign' the last message, so we get the right sequence numbers
-                                  for checking the first reply from the server */
-                               cli_calculate_sign_mac(cli);
+                       /* 'resign' the last message, so we get the right sequence numbers
+                          for checking the first reply from the server */
+                       cli_calculate_sign_mac(cli);
                        
-                               if (!cli_check_sign_mac(cli)) {
-                                       nt_status = NT_STATUS_ACCESS_DENIED;
-                               }
+                       if (!cli_check_sign_mac(cli)) {
+                               nt_status = NT_STATUS_ACCESS_DENIED;
                        }
                }
-               data_blob_free(&key);
        }
 
-       /* we have a reference counter on ntlmssp_state, if we are signing
+       /* we have a reference conter on ntlmssp_state, if we are signing
           then the state will be kept by the signing engine */
 
        ntlmssp_end(&ntlmssp_state);
 
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               cli->vuid = 0;
+       }
        return nt_status;
 }
 
@@ -973,6 +978,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
        }
 
        return NT_STATUS_OK;
+
 }
 
 /****************************************************************************
@@ -1064,6 +1070,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
        cli_setup_packet(cli);
 
        SSVAL(cli->outbuf,smb_vwv0,0xFF);
+       SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
        SSVAL(cli->outbuf,smb_vwv3,passlen);
 
        p = smb_buf(cli->outbuf);
@@ -1398,7 +1405,7 @@ BOOL cli_session_request(struct cli_state *cli,
  Open the client sockets.
 ****************************************************************************/
 
-BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
+NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
 {
        int name_type = 0x20;
        char *p;
@@ -1414,9 +1421,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
                *p = 0;
        }
        
-       if (!ip || is_zero_ip(*ip)) {
+       if (!ip || is_zero_ip_v4(*ip)) {
                 if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
-                        return False;
+                       return NT_STATUS_BAD_NETWORK_NAME;
                 }
                if (ip) *ip = cli->dest_ip;
        } else {
@@ -1441,12 +1448,12 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
        if (cli->fd == -1) {
                DEBUG(1,("Error connecting to %s (%s)\n",
                         ip?inet_ntoa(*ip):host,strerror(errno)));
-               return False;
+               return map_nt_error_from_unix(errno);
        }
 
        set_socket_options(cli->fd,user_socket_options);
 
-       return True;
+       return NT_STATUS_OK;
 }
 
 /**
@@ -1500,15 +1507,12 @@ again:
 
        DEBUG(3,("Connecting to host=%s\n", dest_host));
        
-       if (!cli_connect(cli, dest_host, &ip)) {
-               DEBUG(1,("cli_start_connection: failed to connect to %s (%s)\n",
-                        nmb_namestr(&called), inet_ntoa(ip)));
+       nt_status = cli_connect(cli, dest_host, &ip);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
+                        nmb_namestr(&called), inet_ntoa(ip), nt_errstr(nt_status) ));
                cli_shutdown(cli);
-               if (is_zero_ip(ip)) {
-                       return NT_STATUS_BAD_NETWORK_NAME;
-               } else {
-                       return NT_STATUS_CONNECTION_REFUSED;
-               }
+               return nt_status;
        }
 
        if (retry)
@@ -1518,7 +1522,7 @@ again:
                char *p;
                DEBUG(1,("session request to %s failed (%s)\n", 
                         called.name, cli_errstr(cli)));
-               if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
+               if ((p=strchr(called.name, '.')) && !is_ipaddress_v4(called.name)) {
                        *p = 0;
                        goto again;
                }
@@ -1646,13 +1650,14 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho
         * then use *SMBSERVER immediately.
         */
 
-       if(is_ipaddress(desthost)) {
+       if(is_ipaddress_v4(desthost)) {
                make_nmb_name(&called, "*SMBSERVER", 0x20);
        } else {
                make_nmb_name(&called, desthost, 0x20);
        }
 
        if (!cli_session_request(*ppcli, &calling, &called)) {
+               NTSTATUS status;
                struct nmb_name smbservername;
 
                make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
@@ -1682,7 +1687,8 @@ with error %s.\n", desthost, cli_errstr(*ppcli) ));
                        return False;
                }
 
-               if (!cli_connect(*ppcli, desthost, pdest_ip) ||
+               status = cli_connect(*ppcli, desthost, pdest_ip);
+               if (!NT_STATUS_IS_OK(status) ||
                                !cli_session_request(*ppcli, &calling, &smbservername)) {
                        DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
@@ -1758,7 +1764,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return cli;
-       } else if (is_ipaddress(server)) {
+       } else if (is_ipaddress_v4(server)) {
            /* windows 9* needs a correct NMB name for connections */
            fstring remote_name;
 
@@ -1842,7 +1848,8 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
 
         /* Go looking for workgroups by broadcasting on the local network */ 
 
-        if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
+        if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
+                                               &count))) {
                 DEBUG(99, ("No master browsers responded\n"));
                 return False;
         }