summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/libsmb/cliconnect.c149
1 files changed, 114 insertions, 35 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 010aa4d1bb..ca492e0a1c 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -131,6 +131,55 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
}
/****************************************************************************
+ 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)) {