mirror of
https://github.com/samba-team/samba.git
synced 2025-10-23 11:33:16 +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:
@@ -130,6 +130,55 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
|
|||||||
return capabilities;
|
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.
|
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 cli client state to create do session setup on
|
||||||
@param user username
|
@param user username
|
||||||
@param pass *either* cleartext password (passlen !=24) or LM response.
|
@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) {
|
if (passlen == 0) {
|
||||||
/* do nothing - guest login */
|
/* do nothing - guest login */
|
||||||
} else if (passlen != 24) {
|
} 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 server_chal;
|
||||||
DATA_BLOB names_blob;
|
DATA_BLOB names_blob;
|
||||||
server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
|
server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
|
||||||
@@ -581,7 +634,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
|
|||||||
Do a spnego encrypted session setup.
|
Do a spnego encrypted session setup.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user,
|
BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user,
|
||||||
const char *pass, const char *workgroup)
|
const char *pass, const char *workgroup)
|
||||||
{
|
{
|
||||||
char *principal;
|
char *principal;
|
||||||
@@ -704,6 +757,12 @@ BOOL cli_session_setup(struct cli_state *cli,
|
|||||||
return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup);
|
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
|
/* if the server is share level then send a plaintext null
|
||||||
password at this point. The password is sent in the tree
|
password at this point. The password is sent in the tree
|
||||||
connect */
|
connect */
|
||||||
@@ -711,17 +770,6 @@ BOOL cli_session_setup(struct cli_state *cli,
|
|||||||
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);
|
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
|
/* if the server doesn't support encryption then we have to use
|
||||||
plaintext. The second password is ignored */
|
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.
|
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)
|
const char* domain, const char* password)
|
||||||
{
|
{
|
||||||
ZERO_STRUCTP(creds);
|
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 output_cli A fully initialised cli structure, non-null only on success
|
||||||
@param dest_host The netbios name of the remote host
|
@param dest_host The netbios name of the remote host
|
||||||
@param dest_ip (optional) The the destination IP, NULL for name based lookup
|
@param dest_ip (optional) The the destination IP, NULL for name based lookup
|
||||||
@param port (optional) The destination port (0 for default)
|
@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 ?
|
@param retry BOOL. Did this connection fail with a retryable error ?
|
||||||
*/
|
|
||||||
|
|
||||||
NTSTATUS cli_full_connection(struct cli_state **output_cli,
|
*/
|
||||||
|
NTSTATUS cli_start_connection(struct cli_state **output_cli,
|
||||||
const char *my_name,
|
const char *my_name,
|
||||||
const char *dest_host,
|
const char *dest_host,
|
||||||
struct in_addr *dest_ip, int port,
|
struct in_addr *dest_ip, int port,
|
||||||
const char *service, const char *service_type,
|
int signing_state, int flags,
|
||||||
const char *user, const char *domain,
|
|
||||||
const char *password, int flags,
|
|
||||||
int signing_state,
|
|
||||||
BOOL *retry)
|
BOOL *retry)
|
||||||
{
|
{
|
||||||
struct ntuser_creds creds;
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
struct nmb_name calling;
|
struct nmb_name calling;
|
||||||
struct nmb_name called;
|
struct nmb_name called;
|
||||||
@@ -1259,7 +1298,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
|
|||||||
|
|
||||||
again:
|
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)) {
|
if (!cli_connect(cli, dest_host, &ip)) {
|
||||||
DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n",
|
DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n",
|
||||||
@@ -1300,6 +1339,46 @@ again:
|
|||||||
return nt_status;
|
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,
|
if (!cli_session_setup(cli, user, password, strlen(password)+1,
|
||||||
password, strlen(password)+1,
|
password, strlen(password)+1,
|
||||||
domain)) {
|
domain)) {
|
||||||
|
Reference in New Issue
Block a user