This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-extern pstring user_socket_options;
-
static const struct {
int prot;
const char *name;
{-1,NULL}
};
+static const char *star_smbserver_name = "*SMBSERVER";
+
/**
* Set the user session key for a connection
* @param cli The cli structure to add it too
const char *pass, size_t passlen,
const char *workgroup)
{
- DATA_BLOB session_key = data_blob(NULL, 0);
- DATA_BLOB lm_response = data_blob(NULL, 0);
+ DATA_BLOB session_key = data_blob_null;
+ DATA_BLOB lm_response = data_blob_null;
fstring pword;
char *p;
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,10, 0, True);
+ cli_set_message(cli->outbuf,10, 0, True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
uint32 capabilities = cli_session_setup_capabilities(cli);
memset(cli->outbuf, '\0', smb_size);
- set_message(cli->outbuf,13,0,True);
+ cli_set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
memset(cli->outbuf, '\0', smb_size);
- set_message(cli->outbuf,13,0,True);
+ cli_set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
const char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
- DATA_BLOB lm_response = data_blob(NULL, 0);
- DATA_BLOB nt_response = data_blob(NULL, 0);
- DATA_BLOB session_key = data_blob(NULL, 0);
+ DATA_BLOB lm_response = data_blob_null;
+ DATA_BLOB nt_response = data_blob_null;
+ DATA_BLOB session_key = data_blob_null;
NTSTATUS result;
char *p;
E_md4hash(pass, nt_hash);
#ifdef LANMAN_ONLY
- nt_response = data_blob(NULL, 0);
+ nt_response = data_blob_null;
#else
nt_response = data_blob(NULL, 24);
SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,13,0,True);
+ cli_set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
Send a extended security session setup blob
****************************************************************************/
-static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
+static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
char *p;
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,12,0,True);
+ cli_set_message(cli->outbuf,12,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
{
- DATA_BLOB blob2 = data_blob(NULL, 0);
+ DATA_BLOB blob2 = data_blob_null;
char *p;
size_t len;
#define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
-static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_BLOB session_key_krb5)
+static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_BLOB session_key_krb5)
{
int32 remaining = blob.length;
int32 cur = 0;
- DATA_BLOB send_blob = data_blob(NULL, 0);
+ DATA_BLOB send_blob = data_blob_null;
int32 max_blob_size = 0;
+ DATA_BLOB receive_blob = data_blob_null;
if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
send_blob.length = max_blob_size;
remaining -= max_blob_size;
} else {
- DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB null_blob = data_blob_null;
send_blob.length = remaining;
remaining = 0;
return False;
}
- cli_session_setup_blob_receive(cli);
+ receive_blob = cli_session_setup_blob_receive(cli);
+ data_blob_free(&receive_blob);
if (cli_is_error(cli) &&
!NT_STATUS_EQUAL( cli_get_nt_error(cli),
NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n",
- nt_errstr(cli_get_nt_error(cli)) ));
+ DEBUG(0, ("cli_session_setup_blob: receive failed "
+ "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
+ cli->vuid = 0;
return False;
}
}
if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) {
data_blob_free(&negTokenTarg);
data_blob_free(&session_key_krb5);
- ADS_ERROR_NT(cli_nt_error(cli));
+ return ADS_ERROR_NT(cli_nt_error(cli));
}
cli_set_session_key(cli, session_key_krb5);
NTSTATUS nt_status;
int turn = 1;
DATA_BLOB msg1;
- DATA_BLOB blob = data_blob(NULL, 0);
- DATA_BLOB blob_in = data_blob(NULL, 0);
- DATA_BLOB blob_out = data_blob(NULL, 0);
+ DATA_BLOB blob = data_blob_null;
+ DATA_BLOB blob_in = data_blob_null;
+ DATA_BLOB blob_out = data_blob_null;
cli_temp_set_signing(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) {
+ if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
nt_status = NT_STATUS_ACCESS_DENIED;
} else {
nt_status = NT_STATUS_UNSUCCESSFUL;
}
} else if ((turn == 1) &&
NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DATA_BLOB tmp_blob = data_blob(NULL, 0);
+ DATA_BLOB tmp_blob = data_blob_null;
/* the server might give us back two challenges */
if (!spnego_parse_challenge(blob, &blob_in,
&tmp_blob)) {
}
data_blob_free(&tmp_blob);
} else {
- if (!spnego_parse_auth_response(blob, nt_status,
+ if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
&blob_in)) {
DEBUG(3,("Failed to parse auth response\n"));
if (NT_STATUS_IS_OK(nt_status)
DATA_BLOB key = data_blob(ntlmssp_state->session_key.data,
ntlmssp_state->session_key.length);
- DATA_BLOB null_blob = data_blob(NULL, 0);
- BOOL res;
+ DATA_BLOB null_blob = data_blob_null;
+ bool res;
fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
cli_set_session_key(cli, ntlmssp_state->session_key);
/* 'resign' the last message, so we get the right sequence numbers
for checking the first reply from the server */
- cli_calculate_sign_mac(cli);
+ cli_calculate_sign_mac(cli, cli->outbuf);
- if (!cli_check_sign_mac(cli)) {
+ if (!cli_check_sign_mac(cli, cli->inbuf)) {
nt_status = NT_STATUS_ACCESS_DENIED;
}
}
}
- /* we have a reference counter on ntlmssp_state, if we are signing
+ /* we have a reference conter on ntlmssp_state, if we are signing
then the state will be kept by the signing engine */
ntlmssp_end(&ntlmssp_state);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ cli->vuid = 0;
+ }
return nt_status;
}
char *principal;
char *OIDs[ASN1_MAX_OIDS];
int i;
- BOOL got_kerberos_mechanism = False;
+ bool got_kerberos_mechanism = False;
DATA_BLOB blob;
DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
}
}
- rc = cli_session_setup_kerberos(cli, principal, domain);
- if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
+ /* If we get a bad principal, try to guess it if
+ we have a valid host NetBIOS name.
+ */
+ if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
SAFE_FREE(principal);
- return rc;
+ }
+
+ if (principal == NULL &&
+ !is_ipaddress(cli->desthost) &&
+ !strequal(star_smbserver_name,
+ cli->desthost)) {
+ char *realm = NULL;
+ char *machine = NULL;
+ char *host = NULL;
+ DEBUG(3,("cli_session_setup_spnego: got a "
+ "bad server principal, trying to guess ...\n"));
+
+ host = strchr_m(cli->desthost, '.');
+ if (host) {
+ machine = SMB_STRNDUP(cli->desthost,
+ host - cli->desthost);
+ } else {
+ machine = SMB_STRDUP(cli->desthost);
+ }
+ if (machine == NULL) {
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ realm = kerberos_get_default_realm_from_ccache();
+ if (realm && *realm) {
+ if (asprintf(&principal, "%s$@%s",
+ machine, realm) < 0) {
+ SAFE_FREE(machine);
+ SAFE_FREE(realm);
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ DEBUG(3,("cli_session_setup_spnego: guessed "
+ "server principal=%s\n",
+ principal ? principal : "<null>"));
+ }
+ SAFE_FREE(machine);
+ SAFE_FREE(realm);
+ }
+
+ if (principal) {
+ rc = cli_session_setup_kerberos(cli, principal, domain);
+ if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
+ SAFE_FREE(principal);
+ return rc;
+ }
}
}
#endif
password is in plaintext, the same should be done.
****************************************************************************/
-NTSTATUS cli_session_setup(struct cli_state *cli,
- const char *user,
+NTSTATUS cli_session_setup(struct cli_state *cli,
+ const char *user,
const char *pass, int passlen,
const char *ntpass, int ntpasslen,
const char *workgroup)
char *p;
fstring user2;
+ if (user) {
+ fstrcpy(user2, user);
+ } else {
+ user2[0] ='\0';
+ }
+
+ if (!workgroup) {
+ workgroup = "";
+ }
+
/* allow for workgroups as part of the username */
- fstrcpy(user2, user);
if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
(p=strchr_m(user2,*lp_winbind_separator()))) {
*p = 0;
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"));
+ DEBUG(1, ("Server requested plaintext password but "
+ "'client plaintext auth' is disabled\n"));
return NT_STATUS_ACCESS_DENIED;
}
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"));
+ DEBUG(1, ("Server requested plaintext password but "
+ "'client plaintext auth' is disabled\n"));
return NT_STATUS_ACCESS_DENIED;
}
return cli_session_setup_plaintext(cli, user, pass, workgroup);
}
return NT_STATUS_OK;
+
}
/****************************************************************************
Send a uloggoff.
*****************************************************************************/
-BOOL cli_ulogoff(struct cli_state *cli)
+bool cli_ulogoff(struct cli_state *cli)
{
memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,2,0,True);
+ cli_set_message(cli->outbuf,2,0,True);
SCVAL(cli->outbuf,smb_com,SMBulogoffX);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
Send a tconX.
****************************************************************************/
-BOOL cli_send_tconX(struct cli_state *cli,
+bool cli_send_tconX(struct cli_state *cli,
const char *share, const char *dev, const char *pass, int passlen)
{
fstring fullshare, 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"));
+ DEBUG(1, ("Server requested plaintext "
+ "password but 'client plaintext "
+ "auth' is disabled\n"));
return False;
}
slprintf(fullshare, sizeof(fullshare)-1,
"\\\\%s\\%s", cli->desthost, share);
- set_message(cli->outbuf,4, 0, True);
+ cli_set_message(cli->outbuf,4, 0, True);
SCVAL(cli->outbuf,smb_com,SMBtconX);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
+ SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
SSVAL(cli->outbuf,smb_vwv3,passlen);
p = smb_buf(cli->outbuf);
Send a tree disconnect.
****************************************************************************/
-BOOL cli_tdis(struct cli_state *cli)
+bool cli_tdis(struct cli_state *cli)
{
memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,0,0,True);
+ cli_set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBtdis);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
memset(cli->outbuf,'\0',smb_size);
/* setup the protocol strings */
- set_message(cli->outbuf,0,0,True);
+ cli_set_message(cli->outbuf,0,0,True);
p = smb_buf(cli->outbuf);
for (numprots=0;
Send a negprot command.
****************************************************************************/
-BOOL cli_negprot(struct cli_state *cli)
+bool cli_negprot(struct cli_state *cli)
{
char *p;
int numprots;
numprots++)
plength += strlen(prots[numprots].name)+2;
- set_message(cli->outbuf,0,plength,True);
+ cli_set_message(cli->outbuf,0,plength,True);
p = smb_buf(cli->outbuf);
for (numprots=0;
Send a session request. See rfc1002.txt 4.3 and 4.3.2.
****************************************************************************/
-BOOL cli_session_request(struct cli_state *cli,
+bool cli_session_request(struct cli_state *cli,
struct nmb_name *calling, struct nmb_name *called)
{
char *p;
int16 port;
};
*/
- int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+ uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+ struct in_addr dest_ip;
+
/* SESSION RETARGET */
- putip((char *)&cli->dest_ip,cli->inbuf+4);
+ putip((char *)&dest_ip,cli->inbuf+4);
+ in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
+ cli->fd = open_socket_out(SOCK_STREAM,
+ &cli->dest_ss,
+ port,
+ LONG_CONNECT_TIMEOUT);
if (cli->fd == -1)
return False;
DEBUG(3,("Retargeted\n"));
- set_socket_options(cli->fd,user_socket_options);
+ set_socket_options(cli->fd, lp_socket_options());
/* Try again */
{
static int depth;
- BOOL ret;
+ bool ret;
if (depth > 4) {
DEBUG(0,("Retarget recursion - failing\n"));
return False;
Open the client sockets.
****************************************************************************/
-BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
+NTSTATUS cli_connect(struct cli_state *cli,
+ const char *host,
+ struct sockaddr_storage *dest_ss)
+
{
int name_type = 0x20;
- char *p;
+ TALLOC_CTX *frame = talloc_stackframe();
+ unsigned int num_addrs = 0;
+ unsigned int i = 0;
+ struct sockaddr_storage *ss_arr = NULL;
+ char *p = NULL;
/* reasonable default hostname */
- if (!host) host = "*SMBSERVER";
+ if (!host) {
+ host = star_smbserver_name;
+ }
fstrcpy(cli->desthost, host);
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ((p = strchr(cli->desthost, '#'))) {
- name_type = strtol(p+1, NULL, 16);
+ name_type = strtol(p+1, NULL, 16);
*p = 0;
}
-
- if (!ip || is_zero_ip(*ip)) {
- if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
- return False;
+
+ if (!dest_ss || is_zero_addr(dest_ss)) {
+ NTSTATUS status =resolve_name_list(frame,
+ cli->desthost,
+ name_type,
+ &ss_arr,
+ &num_addrs);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_BAD_NETWORK_NAME;
}
- if (ip) *ip = cli->dest_ip;
} else {
- cli->dest_ip = *ip;
+ num_addrs = 1;
+ ss_arr = TALLOC_P(frame, struct sockaddr_storage);
+ if (!ss_arr) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ *ss_arr = *dest_ss;
}
- if (getenv("LIBSMB_PROG")) {
- cli->fd = sock_exec(getenv("LIBSMB_PROG"));
- } else {
- /* try 445 first, then 139 */
- int port = cli->port?cli->port:445;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
- port, cli->timeout);
- if (cli->fd == -1 && cli->port == 0) {
- port = 139;
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
+ for (i = 0; i < num_addrs; i++) {
+ cli->dest_ss = ss_arr[i];
+ if (getenv("LIBSMB_PROG")) {
+ cli->fd = sock_exec(getenv("LIBSMB_PROG"));
+ } else {
+ /* try 445 first, then 139 */
+ uint16_t port = cli->port?cli->port:445;
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
port, cli->timeout);
+ if (cli->fd == -1 && cli->port == 0) {
+ port = 139;
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
+ port, cli->timeout);
+ }
+ if (cli->fd != -1) {
+ cli->port = port;
+ }
+ }
+ if (cli->fd == -1) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
+ DEBUG(2,("Error connecting to %s (%s)\n",
+ dest_ss?addr:host,strerror(errno)));
+ } else {
+ /* Exit from loop on first connection. */
+ break;
}
- if (cli->fd != -1)
- cli->port = port;
}
+
if (cli->fd == -1) {
- DEBUG(1,("Error connecting to %s (%s)\n",
- ip?inet_ntoa(*ip):host,strerror(errno)));
- return False;
+ TALLOC_FREE(frame);
+ return map_nt_error_from_unix(errno);
+ }
+
+ if (dest_ss) {
+ *dest_ss = cli->dest_ss;
}
- set_socket_options(cli->fd,user_socket_options);
+ set_socket_options(cli->fd, lp_socket_options());
- return True;
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
}
/**
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 dest_ss (optional) The the destination IP, NULL for name based lookup
@param port (optional) The destination port (0 for default)
- @param retry BOOL. Did this connection fail with a retryable error ?
+ @param retry bool. Did this connection fail with a retryable error ?
*/
NTSTATUS cli_start_connection(struct cli_state **output_cli,
const char *my_name,
const char *dest_host,
- struct in_addr *dest_ip, int port,
+ struct sockaddr_storage *dest_ss, int port,
int signing_state, int flags,
- BOOL *retry)
+ bool *retry)
{
NTSTATUS nt_status;
struct nmb_name calling;
struct nmb_name called;
struct cli_state *cli;
- struct in_addr ip;
+ struct sockaddr_storage ss;
if (retry)
*retry = False;
cli_set_timeout(cli, 10000); /* 10 seconds. */
- if (dest_ip)
- ip = *dest_ip;
- else
- ZERO_STRUCT(ip);
+ if (dest_ss) {
+ ss = *dest_ss;
+ } else {
+ zero_addr(&ss);
+ }
again:
DEBUG(3,("Connecting to host=%s\n", dest_host));
-
- if (!cli_connect(cli, dest_host, &ip)) {
- DEBUG(1,("cli_start_connection: failed to connect to %s (%s)\n",
- nmb_namestr(&called), inet_ntoa(ip)));
+
+ nt_status = cli_connect(cli, dest_host, &ss);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ss);
+ DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
+ nmb_namestr(&called), addr, nt_errstr(nt_status) ));
cli_shutdown(cli);
- if (is_zero_ip(ip)) {
- return NT_STATUS_BAD_NETWORK_NAME;
- } else {
- return NT_STATUS_CONNECTION_REFUSED;
- }
+ return nt_status;
}
if (retry)
if (!cli_session_request(cli, &calling, &called)) {
char *p;
- DEBUG(1,("session request to %s failed (%s)\n",
+ DEBUG(1,("session request to %s failed (%s)\n",
called.name, cli_errstr(cli)));
if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
*p = 0;
goto again;
}
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
+ if (strcmp(called.name, star_smbserver_name)) {
+ make_nmb_name(&called , star_smbserver_name, 0x20);
goto again;
}
return NT_STATUS_BAD_NETWORK_NAME;
@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,
const char *my_name,
const char *dest_host,
- struct in_addr *dest_ip, int port,
+ struct sockaddr_storage *dest_ss, 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)
+ bool *retry)
{
NTSTATUS nt_status;
struct cli_state *cli = NULL;
password = "";
}
- nt_status = cli_start_connection(&cli, my_name, dest_host,
- dest_ip, port, signing_state, flags, retry);
-
+ nt_status = cli_start_connection(&cli, my_name, dest_host,
+ dest_ss, port, signing_state,
+ flags, retry);
+
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
return nt_status;
}
}
-
+
if (service) {
if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
nt_status = cli_nt_error(cli);
Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
****************************************************************************/
-BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
- struct in_addr *pdest_ip)
+bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
+ struct sockaddr_storage *pdest_ss)
{
struct nmb_name calling, called;
*/
if(is_ipaddress(desthost)) {
- make_nmb_name(&called, "*SMBSERVER", 0x20);
+ make_nmb_name(&called, star_smbserver_name, 0x20);
} else {
make_nmb_name(&called, desthost, 0x20);
}
if (!cli_session_request(*ppcli, &calling, &called)) {
+ NTSTATUS status;
struct nmb_name smbservername;
- make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
+ make_nmb_name(&smbservername, star_smbserver_name, 0x20);
/*
* If the name wasn't *SMBSERVER then
return False;
}
- if (!cli_connect(*ppcli, desthost, pdest_ip) ||
+ status = cli_connect(*ppcli, desthost, pdest_ss);
+ if (!NT_STATUS_IS_OK(status) ||
!cli_session_request(*ppcli, &calling, &smbservername)) {
DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
return True;
}
-
-
-
-
/****************************************************************************
Send an old style tcon.
****************************************************************************/
char *p;
if (!lp_client_plaintext_auth() && (*pass)) {
- DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
- " is disabled\n"));
+ DEBUG(1, ("Server requested plaintext password but 'client "
+ "plaintext auth' is disabled\n"));
return NT_STATUS_ACCESS_DENIED;
}
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf, 0, 0, True);
+ cli_set_message(cli->outbuf, 0, 0, True);
SCVAL(cli->outbuf,smb_com,SMBtcon);
cli_setup_packet(cli);
/* Return a cli_state pointing at the IPC$ share for the given server */
-struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
- struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect(char *server,
+ struct sockaddr_storage *server_ss,
+ const struct user_auth_info *user_info)
{
struct cli_state *cli;
- pstring myname;
NTSTATUS nt_status;
- get_myname(myname);
-
- nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC",
- user_info->username, lp_workgroup(), user_info->password,
+ nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
+ user_info->username ? user_info->username : "",
+ lp_workgroup(),
+ user_info->password ? user_info->password : "",
CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
/* windows 9* needs a correct NMB name for connections */
fstring remote_name;
- if (name_status_find("*", 0, 0, *server_ip, remote_name)) {
- cli = get_ipc_connect(remote_name, server_ip, user_info);
+ if (name_status_find("*", 0, 0, server_ss, remote_name)) {
+ cli = get_ipc_connect(remote_name, server_ss, user_info);
if (cli)
return cli;
}
* entire network browse list)
*/
-struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
+ struct ip_service *mb_ip,
+ const struct user_auth_info *user_info,
+ char **pp_workgroup_out)
{
- static fstring name;
+ char addr[INET6_ADDRSTRLEN];
+ fstring name;
struct cli_state *cli;
- struct in_addr server_ip;
+ struct sockaddr_storage server_ss;
+
+ *pp_workgroup_out = NULL;
+ print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
DEBUG(99, ("Looking up name of master browser %s\n",
- inet_ntoa(mb_ip->ip)));
+ addr));
/*
* Do a name status query to find out the name of the master browser.
* the original wildcard query as the first choice and fall back to
* MSBROWSE if the wildcard query fails.
*/
- if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) &&
- !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) {
+ if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
+ !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
DEBUG(99, ("Could not retrieve name status for %s\n",
- inet_ntoa(mb_ip->ip)));
+ addr));
return NULL;
}
- if (!find_master_ip(name, &server_ip)) {
+ if (!find_master_ip(name, &server_ss)) {
DEBUG(99, ("Could not find master ip for %s\n", name));
return NULL;
}
- pstrcpy(workgroup, name);
+ *pp_workgroup_out = talloc_strdup(ctx, name);
- DEBUG(4, ("found master browser %s, %s\n",
- name, inet_ntoa(mb_ip->ip)));
+ DEBUG(4, ("found master browser %s, %s\n", name, addr));
- cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
+ print_sockaddr(addr, sizeof(addr), &server_ss);
+ cli = get_ipc_connect(addr, &server_ss, user_info);
- return cli;
-
+ return cli;
}
/*
* connect to it.
*/
-struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info)
+struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
+ const struct user_auth_info *user_info,
+ char **pp_workgroup_out)
{
struct ip_service *ip_list;
struct cli_state *cli;
int i, count;
+ *pp_workgroup_out = NULL;
+
DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
- /* Go looking for workgroups by broadcasting on the local network */
+ /* Go looking for workgroups by broadcasting on the local network */
- if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) {
+ if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
+ &count))) {
DEBUG(99, ("No master browsers responded\n"));
return False;
}
for (i = 0; i < count; i++) {
- DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
+ char addr[INET6_ADDRSTRLEN];
+ print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
+ DEBUG(99, ("Found master browser %s\n", addr));
- cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info);
- if (cli)
- return(cli);
+ cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
+ user_info, pp_workgroup_out);
+ if (cli)
+ return(cli);
}
return NULL;