mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
Break up 'cli_full_connection' to allow for the session setups to be done
elsewhere in the code. This will allow us to try kerberos, then another user then guest in the winbindd code. Also, re-introduce the seperate, NT1 'guest' session setup code, as I found some problems with doing guest under NTLMSSP. Andrew Bartlett
This commit is contained in:
parent
5be5151568
commit
33109fefe7
@ -130,6 +130,55 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Do a NT1 guest session setup.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL cli_session_setup_guest(struct cli_state *cli)
|
||||
{
|
||||
char *p;
|
||||
uint32 capabilities = cli_session_setup_capabilities(cli);
|
||||
|
||||
set_message(cli->outbuf,13,0,True);
|
||||
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
|
||||
cli_setup_packet(cli);
|
||||
|
||||
SCVAL(cli->outbuf,smb_vwv0,0xFF);
|
||||
SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
|
||||
SSVAL(cli->outbuf,smb_vwv3,2);
|
||||
SSVAL(cli->outbuf,smb_vwv4,cli->pid);
|
||||
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
|
||||
SSVAL(cli->outbuf,smb_vwv7,0);
|
||||
SSVAL(cli->outbuf,smb_vwv8,0);
|
||||
SIVAL(cli->outbuf,smb_vwv11,capabilities);
|
||||
p = smb_buf(cli->outbuf);
|
||||
p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
|
||||
p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
|
||||
p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
|
||||
p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
|
||||
cli_setup_bcc(cli, p);
|
||||
|
||||
cli_send_smb(cli);
|
||||
if (!cli_receive_smb(cli))
|
||||
return False;
|
||||
|
||||
show_msg(cli->inbuf);
|
||||
|
||||
if (cli_is_error(cli))
|
||||
return False;
|
||||
|
||||
cli->vuid = SVAL(cli->inbuf,smb_uid);
|
||||
|
||||
p = smb_buf(cli->inbuf);
|
||||
p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
|
||||
p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
|
||||
p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
|
||||
|
||||
fstrcpy(cli->user_name, "");
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Do a NT1 plaintext session setup.
|
||||
****************************************************************************/
|
||||
@ -198,7 +247,8 @@ static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
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.
|
||||
@ -221,7 +271,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
|
||||
if (passlen == 0) {
|
||||
/* do nothing - guest login */
|
||||
} else if (passlen != 24) {
|
||||
if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) {
|
||||
/* if client ntlmv2 auth is set, then don't use it on a
|
||||
connection without extended security. This isn't a very
|
||||
good check, but it is a start */
|
||||
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));
|
||||
@ -573,7 +626,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
|
||||
if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) {
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
return (NT_STATUS_IS_OK(nt_status));
|
||||
}
|
||||
|
||||
@ -581,8 +634,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
|
||||
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)
|
||||
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];
|
||||
@ -704,6 +757,12 @@ BOOL cli_session_setup(struct cli_state *cli,
|
||||
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 */
|
||||
|
||||
if (!user || !*user)
|
||||
return cli_session_setup_guest(cli);
|
||||
|
||||
/* if the server is share level then send a plaintext null
|
||||
password at this point. The password is sent in the tree
|
||||
connect */
|
||||
@ -711,17 +770,6 @@ BOOL cli_session_setup(struct cli_state *cli,
|
||||
if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
|
||||
return cli_session_setup_plaintext(cli, user, "", workgroup);
|
||||
|
||||
/* if no user is supplied then we have to do an anonymous connection.
|
||||
passwords are ignored */
|
||||
|
||||
if (!user || !*user) {
|
||||
user = "";
|
||||
pass = NULL;
|
||||
ntpass = NULL;
|
||||
passlen = 0;
|
||||
ntpasslen = 0;
|
||||
}
|
||||
|
||||
/* if the server doesn't support encryption then we have to use
|
||||
plaintext. The second password is ignored */
|
||||
|
||||
@ -1187,7 +1235,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);
|
||||
@ -1203,30 +1251,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,
|
||||
int signing_state,
|
||||
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;
|
||||
@ -1259,7 +1298,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",
|
||||
@ -1300,6 +1339,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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user