Refactor the NTLMSSP code again - this time we use function pointers to
[kai/samba.git] / source3 / libsmb / cliconnect.c
index 695c6506b5de5d637c2f24e0f28ace8ecd2b110a..389b7a1733218222b0a3f1413bd20f6e567ee15c 100644 (file)
@@ -44,8 +44,8 @@ static const struct {
  Do an old lanman2 style session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, 
-                                     char *pass, int passlen, const char *workgroup)
+static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, 
+                                     const char *pass, int passlen, const char *workgroup)
 {
        fstring pword;
        char *p;
@@ -124,6 +124,9 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
        if (cli->capabilities & CAP_UNICODE)
                capabilities |= CAP_UNICODE;
 
+       if (cli->capabilities & CAP_LARGE_FILES)
+               capabilities |= CAP_LARGE_FILES;
+
        return capabilities;
 }
 
@@ -180,17 +183,11 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
  Do a NT1 plaintext session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, 
-                                       char *pass, char *workgroup)
+static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, 
+                                       const char *pass, const char *workgroup)
 {
        uint32 capabilities = cli_session_setup_capabilities(cli);
        char *p;
-       int push_flags = STR_TERMINATE;
-
-       if (capabilities & CAP_UNICODE)
-               push_flags |= STR_UNICODE;
-       else
-               push_flags |= STR_ASCII;
 
        set_message(cli->outbuf,13,0,True);
        SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
@@ -204,7 +201,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
        SSVAL(cli->outbuf,smb_vwv8,0);
        SIVAL(cli->outbuf,smb_vwv11,capabilities); 
        p = smb_buf(cli->outbuf);
-       p += clistr_push(cli, p, pass, -1, push_flags); /* password */
+       p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
        SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
        p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
        p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
@@ -231,7 +228,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
        return True;
 }
 
-static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) 
+static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 response[24]) 
 {
        uint8 zero_sig[8];
        ZERO_STRUCT(zero_sig);
@@ -267,10 +264,10 @@ static void set_temp_signing_on_cli(struct cli_state *cli)
    @param workgroup The user's domain.
 ****************************************************************************/
 
-static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, 
-                                 char *pass, int passlen,
-                                 char *ntpass, int ntpasslen,
-                                 char *workgroup)
+static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, 
+                                 const char *pass, int passlen,
+                                 const char *ntpass, int ntpasslen,
+                                 const char *workgroup)
 {
        uint32 capabilities = cli_session_setup_capabilities(cli);
        uchar pword[24];
@@ -350,7 +347,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
                /* Have plaintext orginal */
                set_signing_on_cli(cli, pass, ntpword);
        }
-
+       
        return True;
 }
 
@@ -426,7 +423,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
  Do a spnego/kerberos encrypted session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup)
+static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
 {
        DATA_BLOB blob2, negTokenTarg;
 
@@ -456,8 +453,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c
  Do a spnego/NTLMSSP encrypted session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, 
-                                     char *pass, char *workgroup)
+static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, 
+                                     const char *pass, const char *workgroup)
 {
        DATA_BLOB msg1, struct_blob;
        DATA_BLOB blob, chal1, chal2, auth, challenge_blob;
@@ -468,7 +465,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user,
 
        neg_flags = NTLMSSP_NEGOTIATE_UNICODE | 
                NTLMSSP_NEGOTIATE_128 | 
-               NTLMSSP_NEGOTIATE_NTLM;
+               NTLMSSP_NEGOTIATE_NTLM |
+               NTLMSSP_REQUEST_TARGET;
 
        memset(sess_key, 0, 16);
 
@@ -479,8 +477,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user,
                  "NTLMSSP",
                  NTLMSSP_NEGOTIATE,
                  neg_flags,
-                 workgroup, strlen(workgroup),
-                 cli->calling.name, strlen(cli->calling.name) + 1);
+                 workgroup, 
+                 cli->calling.name);
        DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n",
                  neg_flags, workgroup, cli->calling.name));
        /* and wrap it in a SPNEGO wrapper */
@@ -584,8 +582,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user,
  Do a spnego encrypted session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, 
-                                    char *pass, char *workgroup)
+static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, 
+                                    const char *pass, const char *workgroup)
 {
        char *principal;
        char *OIDs[ASN1_MAX_OIDS];
@@ -649,10 +647,10 @@ ntlmssp:
 ****************************************************************************/
 
 BOOL cli_session_setup(struct cli_state *cli, 
-                      char *user, 
-                      char *pass, int passlen,
-                      char *ntpass, int ntpasslen,
-                      char *workgroup)
+                      const char *user, 
+                      const char *pass, int passlen,
+                      const char *ntpass, int ntpasslen,
+                      const char *workgroup)
 {
        char *p;
        fstring user2;
@@ -1133,8 +1131,8 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
  Initialise client credentials for authenticated pipe access.
 ****************************************************************************/
 
-static void init_creds(struct ntuser_creds *creds, char* username,
-                      char* domain, char* password)
+static void init_creds(struct ntuser_creds *creds, const char* username,
+                      const char* domain, const char* password)
 {
        ZERO_STRUCTP(creds);
 
@@ -1159,15 +1157,17 @@ static void init_creds(struct ntuser_creds *creds, char* username,
    @param user Username, unix string
    @param domain User's domain
    @param password User's password, unencrypted unix string.
+   @param retry BOOL. Did this connection fail with a retryable error ?
 */
 
 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
                             const char *my_name, 
                             const char *dest_host, 
                             struct in_addr *dest_ip, int port,
-                            char *service, char *service_type,
-                            char *user, char *domain, 
-                            char *password, int flags) 
+                            const char *service, const char *service_type,
+                            const char *user, const char *domain, 
+                            const char *password, int flags,
+                            BOOL *retry) 
 {
        struct ntuser_creds creds;
        NTSTATUS nt_status;
@@ -1175,10 +1175,12 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
        struct nmb_name called;
        struct cli_state *cli;
        struct in_addr ip;
-       extern pstring global_myname;
+
+       if (retry)
+               *retry = False;
 
        if (!my_name) 
-               my_name = global_myname;
+               my_name = global_myname();
        
        if (!(cli = cli_initialise(NULL)))
                return NT_STATUS_NO_MEMORY;
@@ -1191,6 +1193,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
+       cli_set_timeout(cli, 10000); /* 10 seconds. */
+
        if (dest_ip)
                ip = *dest_ip;
        else
@@ -1207,6 +1211,9 @@ again:
                return NT_STATUS_UNSUCCESSFUL;
        }
 
+       if (retry)
+               *retry = True;
+
        if (!cli_session_request(cli, &calling, &called)) {
                char *p;
                DEBUG(1,("session request to %s failed (%s)\n", 
@@ -1251,9 +1258,9 @@ again:
 
        if (service) {
                if (!cli_send_tconX(cli, service, service_type,
-                                   (char*)password, strlen(password)+1)) {
-                       DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
+                                   password, strlen(password)+1)) {
                        nt_status = cli_nt_error(cli);
+                       DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
                        cli_shutdown(cli);
                        if (NT_STATUS_IS_OK(nt_status)) {
                                nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -1273,7 +1280,7 @@ again:
  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
 ****************************************************************************/
 
-BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
+BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost,
                                      struct in_addr *pdest_ip)
 {
        struct nmb_name calling, called;