X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Flibsmb%2Fcliconnect.c;h=84159e5d62a7af216b9d6132eee338712e336201;hp=32397173da19438cefa28757e5f2f589b3ec73e0;hb=b20f1a95a90033f711a26fdeeb49eaf3059ad91d;hpb=49237d9955628764f8763d20194fb619650663a1 diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 32397173da1..84159e5d62a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -53,6 +53,13 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, if (passlen > sizeof(pword)-1) return False; + /* LANMAN servers predate NT status codes and Unicode and ignore those + smb flags so we must disable the corresponding default capabilities + that would otherwise cause the Unicode and NT Status flags to be + set (and even returned by the server) */ + + cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); + /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) passlen = 0; @@ -190,7 +197,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, char *p; fstring lanman; - snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); @@ -241,13 +248,21 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) +/** + * Set the user session key for a connection + * @param cli The cli structure to add it too + * @param session_key The session key used. (A copy of this is taken for the cli struct) + * + */ + +static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) { - memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); + cli->user_session_key = data_blob(session_key.data, session_key.length); } /**************************************************************************** - do a NT1 NTLM/LM encrypted session setup + do a NT1 NTLM/LM encrypted session setup - for when extended security + is not negotiated. @param cli client state to create do session setup on @param user username @param pass *either* cleartext password (passlen !=24) or LM response. @@ -267,35 +282,50 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, BOOL ret = False; char *p; - if (passlen != 24) { + if (passlen == 0) { + /* do nothing - guest login */ + } else if (passlen != 24) { if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; - + DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); - if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal, + /* note that the 'workgroup' here is a best guess - we don't know + the server's domain at this point. The 'server name' is also + dodgy... + */ + names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup); + + if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal, + &names_blob, &lm_response, &nt_response, &session_key)) { + data_blob_free(&names_blob); data_blob_free(&server_chal); return False; } + data_blob_free(&names_blob); data_blob_free(&server_chal); } else { uchar nt_hash[16]; E_md4hash(pass, nt_hash); + nt_response = data_blob(NULL, 24); + SMBNTencrypt(pass,cli->secblob.data,nt_response.data); + /* non encrypted password supplied. Ignore ntpass. */ if (lp_client_lanman_auth()) { lm_response = data_blob(NULL, 24); - SMBencrypt(pass,cli->secblob.data,lm_response.data); + SMBencrypt(pass,cli->secblob.data, lm_response.data); + } else { + /* LM disabled, place NT# in LM field instead */ + lm_response = data_blob(nt_response.data, nt_response.length); } - nt_response = data_blob(NULL, 24); - SMBNTencrypt(pass,cli->secblob.data,nt_response.data); session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key.data, nt_response); + cli_simple_set_signing(cli, session_key, nt_response, 0); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -338,7 +368,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, goto end; } - show_msg(cli->inbuf); + /* show_msg(cli->inbuf); */ if (cli_is_error(cli)) { ret = False; @@ -357,14 +387,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ - set_cli_session_key(cli, session_key); + cli_set_session_key(cli, session_key); } ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); - data_blob_free(&session_key); + + if (!ret) + data_blob_free(&session_key); return ret; } @@ -440,6 +472,8 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) return blob2; } +#ifdef HAVE_KRB5 + /**************************************************************************** Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ @@ -454,10 +488,10 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return cli_session_setup_blob_receive(cli); } -#ifdef HAVE_KRB5 /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ + static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } @@ -466,40 +500,56 @@ static void use_in_memory_ccache(void) { Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) +static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; + DATA_BLOB session_key_krb5; + DATA_BLOB null_blob = data_blob(NULL, 0); + int rc; DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0); + rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5); - if (!negTokenTarg.data) return False; + if (rc) { + DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); + return ADS_ERROR_KRB5(rc); + } #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif + cli_simple_set_signing(cli, session_key_krb5, null_blob, 0); + blob2 = cli_session_setup_blob(cli, negTokenTarg); /* we don't need this blob for kerberos */ data_blob_free(&blob2); + cli_set_session_key(cli, session_key_krb5); + data_blob_free(&negTokenTarg); - return !cli_is_error(cli); + if (cli_is_error(cli)) { + if (NT_STATUS_IS_OK(cli_nt_error(cli))) { + return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + } + } + return ADS_ERROR_NT(cli_nt_error(cli)); } -#endif +#endif /* HAVE_KRB5 */ + /**************************************************************************** Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, + const char *pass, const char *domain) { - struct ntlmssp_client_state *ntlmssp_state; + struct ntlmssp_state *ntlmssp_state; NTSTATUS nt_status; int turn = 1; DATA_BLOB msg1; @@ -510,23 +560,21 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, cli_temp_set_signing(cli); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - return False; + return nt_status; } - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { - return False; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { - return False; + return nt_status; } - ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(); - do { - nt_status = ntlmssp_client_update(ntlmssp_state, + nt_status = ntlmssp_update(ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -540,15 +588,22 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { - return False; + DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n")); + nt_status = NT_STATUS_UNSUCCESSFUL; + } else { + data_blob_free(&msg1); + + blob = cli_session_setup_blob_receive(cli); + + nt_status = cli_nt_error(cli); + if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { + if (cli->smb_rw_error == READ_BAD_SIG) { + nt_status = NT_STATUS_ACCESS_DENIED; + } else { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } } - data_blob_free(&msg1); - - cli_ntlmssp_set_signing(cli, ntlmssp_state); - - blob = cli_session_setup_blob_receive(cli); - - nt_status = cli_nt_error(cli); } if (!blob.length) { @@ -566,7 +621,6 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } data_blob_free(&tmp_blob); } else { - /* the server might give us back two challenges */ if (!spnego_parse_auth_response(blob, nt_status, &blob_in)) { DEBUG(3,("Failed to parse auth response\n")); @@ -581,25 +635,37 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); if (NT_STATUS_IS_OK(nt_status)) { - set_cli_session_key(cli, ntlmssp_state->session_key); + + DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); + DATA_BLOB null_blob = data_blob(NULL, 0); + + fstrcpy(cli->server_domain, ntlmssp_state->server_domain); + cli_set_session_key(cli, ntlmssp_state->session_key); + + /* Using NTLMSSP session setup, signing on the net only starts + * after a successful authentication and the session key has + * been determined, but with a sequence number of 2. This + * assumes that NTLMSSP needs exactly 2 roundtrips, for any + * other SPNEGO mechanism it needs adapting. */ + + cli_simple_set_signing(cli, key, null_blob, 2); } /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ - if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { - return False; - } + ntlmssp_end(&ntlmssp_state); - return (NT_STATUS_IS_OK(nt_status)); + return nt_status; } /**************************************************************************** Do a spnego encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, + const char *pass, const char *domain) { char *principal; char *OIDs[ASN1_MAX_OIDS]; @@ -607,7 +673,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, BOOL got_kerberos_mechanism = False; DATA_BLOB blob; - DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); + DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length <= 16) { @@ -626,7 +692,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, reply */ if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { data_blob_free(&blob); - return False; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } data_blob_free(&blob); @@ -648,7 +714,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, * and do not store results */ if (got_kerberos_mechanism && cli->use_kerberos) { - if (*pass) { + if (pass && *pass) { int ret; use_in_memory_ccache(); @@ -656,11 +722,11 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return False; + return ADS_ERROR_KRB5(ret); } } - return cli_session_setup_kerberos(cli, principal, workgroup); + return cli_session_setup_kerberos(cli, principal, domain); } #endif @@ -668,7 +734,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - return cli_session_setup_ntlmssp(cli, user, pass, workgroup); + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain)); } /**************************************************************************** @@ -704,8 +770,22 @@ BOOL cli_session_setup(struct cli_state *cli, /* if its an older server then we have to use the older request format */ - if (cli->protocol < PROTOCOL_NT1) + if (cli->protocol < PROTOCOL_NT1) { + if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { + DEBUG(1, ("Server requested LM password but 'client lanman auth'" + " is disabled\n")); + return False; + } + + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && + !lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return False; + } + return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); + } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ @@ -717,21 +797,31 @@ BOOL cli_session_setup(struct cli_state *cli, password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + if (!lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return False; + } return cli_session_setup_plaintext(cli, user, pass, workgroup); + } - /* Indidicate signing */ - /* if the server supports extended security then use SPNEGO */ - if (cli->capabilities & CAP_EXTENDED_SECURITY) - return cli_session_setup_spnego(cli, user, pass, workgroup); + if (cli->capabilities & CAP_EXTENDED_SECURITY) { + ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); + if (!ADS_ERR_OK(status)) { + DEBUG(3, ("SPENGO login failed: %s\n", ads_errstr(status))); + return False; + } + return True; + } /* otherwise do a NT1 style session setup */ @@ -780,6 +870,12 @@ BOOL cli_send_tconX(struct cli_state *cli, } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { + if (!lp_client_lanman_auth()) { + DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'" + " is disabled\n")); + return False; + } + /* * Non-encrypted passwords - convert to DOS codepage before encryption. */ @@ -787,10 +883,17 @@ BOOL cli_send_tconX(struct cli_state *cli, SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { + if (!lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return False; + } + /* * Non-encrypted passwords - convert to DOS codepage before using. */ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + } else { memcpy(pword, pass, passlen); } @@ -810,7 +913,7 @@ BOOL cli_send_tconX(struct cli_state *cli, memcpy(p,pword,passlen); p += passlen; p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER); - fstrcpy(p, dev); p += strlen(dev)+1; + p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII); cli_setup_bcc(cli, p); @@ -823,9 +926,6 @@ BOOL cli_send_tconX(struct cli_state *cli, clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); - if (strcasecmp(share,"IPC$")==0) - fstrcpy(cli->dev, "IPC"); - if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ @@ -938,6 +1038,11 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { + DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); + return False; + } + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); @@ -962,11 +1067,28 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) - cli->sign_info.negotiated_smb_signing = True; + /* + * As signing is slow we only turn it on if either the client or + * the server require it. JRA. + */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && cli->sign_info.allow_smb_signing) + if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { + /* Fail if server says signing is mandatory and we don't want to support it. */ + if (!cli->sign_info.allow_smb_signing) { + DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); + return False; + } cli->sign_info.negotiated_smb_signing = True; + cli->sign_info.mandatory_signing = True; + } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) { + /* Fail if client says signing is mandatory and the server doesn't support it. */ + if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { + DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); + return False; + } + cli->sign_info.negotiated_smb_signing = True; + cli->sign_info.mandatory_signing = True; + } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; @@ -1149,7 +1271,7 @@ 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, const char* username, +void init_creds(struct ntuser_creds *creds, const char* username, const char* domain, const char* password) { ZERO_STRUCTP(creds); @@ -1165,29 +1287,21 @@ static void init_creds(struct ntuser_creds *creds, const char* username, } /** - establishes a connection right up to doing tconX, password specified. + establishes a connection to after the negprot. @param output_cli A fully initialised cli structure, non-null only on success @param dest_host The netbios name of the remote host @param dest_ip (optional) The the destination IP, NULL for name based lookup @param port (optional) The destination port (0 for default) - @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. - @param service_type The 'type' of serivice. - @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, - const char *service, const char *service_type, - const char *user, const char *domain, - const char *password, int flags, - BOOL *retry) +*/ +NTSTATUS cli_start_connection(struct cli_state **output_cli, + const char *my_name, + const char *dest_host, + struct in_addr *dest_ip, int port, + int signing_state, int flags, + BOOL *retry) { - struct ntuser_creds creds; NTSTATUS nt_status; struct nmb_name calling; struct nmb_name called; @@ -1220,7 +1334,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, again: - DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); + DEBUG(3,("Connecting to host=%s\n", dest_host)); if (!cli_connect(cli, dest_host, &ip)) { DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", @@ -1247,6 +1361,8 @@ again: return NT_STATUS_UNSUCCESSFUL; } + cli_setup_signing_state(cli, signing_state); + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) @@ -1259,6 +1375,46 @@ again: return nt_status; } + *output_cli = cli; + return NT_STATUS_OK; +} + + +/** + establishes a connection right up to doing tconX, password specified. + @param output_cli A fully initialised cli structure, non-null only on success + @param dest_host The netbios name of the remote host + @param dest_ip (optional) The the destination IP, NULL for name based lookup + @param port (optional) The destination port (0 for default) + @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. + @param service_type The 'type' of serivice. + @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, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password, int flags, + int signing_state, + BOOL *retry) +{ + struct ntuser_creds creds; + NTSTATUS nt_status; + struct cli_state *cli = NULL; + + nt_status = cli_start_connection(&cli, my_name, dest_host, + dest_ip, port, signing_state, flags, retry); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { @@ -1369,6 +1525,12 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, { char *p; + if (!lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return NT_STATUS_ACCESS_DENIED; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -1411,7 +1573,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, - CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL); + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; @@ -1433,7 +1595,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) { - struct in_addr *ip_list; + struct ip_service *ip_list; struct cli_state *cli; int i, count; struct in_addr server_ip; @@ -1447,7 +1609,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user for (i = 0; i < count; i++) { static fstring name; - if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) + if (!name_status_find("*", 0, 0x1d, ip_list[i].ip, name)) continue; if (!find_master_ip(name, &server_ip)) @@ -1456,7 +1618,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user pstrcpy(workgroup, name); DEBUG(4, ("found master browser %s, %s\n", - name, inet_ntoa(ip_list[i]))); + name, inet_ntoa(ip_list[i].ip))); cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);