return old_timeout;
}
-/****************************************************************************
- Change the port number used to call on.
-****************************************************************************/
-
-void cli_set_port(struct cli_state *cli, int port)
-{
- cli->port = port;
-}
-
/****************************************************************************
convenience routine to find if we negotiated ucs2
****************************************************************************/
bool cli_ucs2(struct cli_state *cli)
{
- return ((cli->capabilities & CAP_UNICODE) != 0);
+ return ((cli_state_capabilities(cli) & CAP_UNICODE) != 0);
}
/****************************************************************************
uint16 flags2;
cli->rap_error = 0;
SIVAL(buf,smb_rcls,0);
- SSVAL(buf,smb_pid,cli->pid);
+ SSVAL(buf,smb_pid,cli->smb1.pid);
memset(buf+smb_pidhigh, 0, 12);
- SSVAL(buf,smb_uid,cli->vuid);
- SSVAL(buf,smb_mid,cli->mid);
+ SSVAL(buf,smb_uid, cli_state_get_uid(cli));
+ SSVAL(buf,smb_mid, 0);
- if (cli->protocol <= PROTOCOL_CORE) {
+ if (cli_state_protocol(cli) <= PROTOCOL_CORE) {
return;
}
SCVAL(buf,smb_flg,0x8);
}
flags2 = FLAGS2_LONG_PATH_COMPONENTS;
- if (cli->capabilities & CAP_UNICODE)
+ if (cli_state_capabilities(cli) & CAP_UNICODE)
flags2 |= FLAGS2_UNICODE_STRINGS;
- if ((cli->capabilities & CAP_DFS) && cli->dfsroot)
+ if ((cli_state_capabilities(cli) & CAP_DFS) && cli->dfsroot)
flags2 |= FLAGS2_DFS_PATHNAMES;
- if (cli->capabilities & CAP_STATUS32)
+ if (cli_state_capabilities(cli) & CAP_STATUS32)
flags2 |= FLAGS2_32_BIT_ERROR_CODES;
- if (cli->use_spnego)
+ if (cli_state_capabilities(cli) & CAP_EXTENDED_SECURITY)
flags2 |= FLAGS2_EXTENDED_SECURITY;
SSVAL(buf,smb_flg2, flags2);
}
Set the signing state (used from the command line).
****************************************************************************/
-struct cli_state *cli_initialise_ex(int signing_state)
+struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
+ int fd,
+ const char *remote_name,
+ const char *remote_realm,
+ int signing_state, int flags)
{
struct cli_state *cli = NULL;
- bool allow_smb_signing = false;
- bool mandatory_signing = false;
+ bool allow_smb_signing;
+ bool desire_smb_signing;
+ bool mandatory_signing;
+ socklen_t ss_length;
+ int ret;
+ bool use_spnego = lp_client_use_spnego();
+ bool force_dos_errors = false;
+ bool force_ascii = false;
+ bool use_level_II_oplocks = false;
/* Check the effective uid - make sure we are not setuid */
if (is_setuid_root()) {
return NULL;
}
- cli = talloc_zero(NULL, struct cli_state);
+ cli = talloc_zero(mem_ctx, struct cli_state);
if (!cli) {
return NULL;
}
if (!cli->dfs_mountpoint) {
goto error;
}
- cli->port = 0;
- cli->fd = -1;
cli->raw_status = NT_STATUS_INTERNAL_ERROR;
- cli->cnum = -1;
- cli->pid = (uint16)sys_getpid();
- cli->mid = 1;
- cli->vuid = UID_FIELD_INVALID;
- cli->protocol = PROTOCOL_NT1;
cli->timeout = 20000; /* Timeout is in milliseconds. */
- cli->bufsize = CLI_BUFFER_SIZE+4;
- cli->max_xmit = cli->bufsize;
- cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
- cli->oplock_handler = cli_oplock_ack;
+ cli->max_xmit = CLI_BUFFER_SIZE+4;
cli->case_sensitive = false;
- cli->use_spnego = lp_client_use_spnego();
-
- cli->capabilities = CAP_UNICODE | CAP_STATUS32 | CAP_DFS;
-
/* Set the CLI_FORCE_DOSERR environment variable to test
client routines using DOS errors instead of STATUS32
ones. This intended only as a temporary hack. */
- if (getenv("CLI_FORCE_DOSERR"))
- cli->force_dos_errors = true;
-
- if (lp_client_signing()) {
- allow_smb_signing = true;
+ if (getenv("CLI_FORCE_DOSERR")) {
+ force_dos_errors = true;
+ }
+ if (flags & CLI_FULL_CONNECTION_FORCE_DOS_ERRORS) {
+ force_dos_errors = true;
}
- if (lp_client_signing() == Required) {
- mandatory_signing = true;
+ if (getenv("CLI_FORCE_ASCII")) {
+ force_ascii = true;
+ }
+ if (flags & CLI_FULL_CONNECTION_FORCE_ASCII) {
+ force_ascii = true;
}
- if (signing_state != Undefined) {
- allow_smb_signing = true;
+ if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) {
+ use_spnego = false;
+ } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
+ cli->use_kerberos = true;
+ }
+ if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
+ cli->use_kerberos) {
+ cli->fallback_after_kerberos = true;
}
- if (signing_state == false) {
- allow_smb_signing = false;
- mandatory_signing = false;
+ if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
+ cli->use_ccache = true;
}
- if (signing_state == Required) {
- mandatory_signing = true;
+ if (flags & CLI_FULL_CONNECTION_OPLOCKS) {
+ cli->use_oplocks = true;
+ }
+ if (flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) {
+ use_level_II_oplocks = true;
}
- if (!cli->inbuf)
- goto error;
+ if (signing_state == Undefined) {
+ signing_state = lp_client_signing();
+ }
- memset(cli->inbuf, 0, cli->bufsize);
+ switch (signing_state) {
+ case false:
+ /* never */
+ allow_smb_signing = false;
+ desire_smb_signing = false;
+ mandatory_signing = false;
+ break;
+ case true:
+ /* if the server supports it */
+ allow_smb_signing = true;
+ desire_smb_signing = true;
+ mandatory_signing = false;
+ break;
+ default:
+ case Undefined:
+ case Auto:
+ /* if the server requires it */
+ allow_smb_signing = true;
+ desire_smb_signing = false;
+ mandatory_signing = false;
+ break;
+ case Required:
+ /* always */
+ allow_smb_signing = true;
+ desire_smb_signing = true;
+ mandatory_signing = true;
+ break;
+ }
/* initialise signing */
cli->signing_state = smb_signing_init(cli,
allow_smb_signing,
+ desire_smb_signing,
mandatory_signing);
if (!cli->signing_state) {
goto error;
}
- cli->outgoing = tevent_queue_create(cli, "cli_outgoing");
- if (cli->outgoing == NULL) {
+ cli->conn.smb1.client.capabilities = 0;
+ cli->conn.smb1.client.capabilities |= CAP_LARGE_FILES;
+ cli->conn.smb1.client.capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
+ cli->conn.smb1.client.capabilities |= CAP_LOCK_AND_READ | CAP_NT_FIND;
+ cli->conn.smb1.client.capabilities |= CAP_DFS | CAP_W2K_SMBS;
+ cli->conn.smb1.client.capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX;
+ cli->conn.smb1.client.capabilities |= CAP_LWIO;
+
+ if (!force_dos_errors) {
+ cli->conn.smb1.client.capabilities |= CAP_STATUS32;
+ }
+
+ if (!force_ascii) {
+ cli->conn.smb1.client.capabilities |= CAP_UNICODE;
+ }
+
+ if (use_spnego) {
+ cli->conn.smb1.client.capabilities |= CAP_EXTENDED_SECURITY;
+ }
+
+ if (use_level_II_oplocks) {
+ cli->conn.smb1.client.capabilities |= CAP_LEVEL_II_OPLOCKS;
+ }
+
+ cli->conn.smb1.capabilities = cli->conn.smb1.client.capabilities;
+
+ cli->conn.outgoing = tevent_queue_create(cli, "cli_outgoing");
+ if (cli->conn.outgoing == NULL) {
+ goto error;
+ }
+ cli->conn.pending = NULL;
+
+ cli->conn.remote_name = talloc_strdup(cli, remote_name);
+ if (cli->conn.remote_name == NULL) {
goto error;
}
- cli->pending = NULL;
- cli->initialised = 1;
+ if (remote_realm) {
+ cli->conn.remote_realm = talloc_strdup(cli, remote_realm);
+ if (cli->conn.remote_realm == NULL) {
+ goto error;
+ }
+ }
+
+ cli->conn.fd = fd;
+
+ ss_length = sizeof(cli->conn.local_ss);
+ ret = getsockname(fd,
+ (struct sockaddr *)(void *)&cli->conn.local_ss,
+ &ss_length);
+ if (ret == -1) {
+ goto error;
+ }
+ ss_length = sizeof(cli->conn.remote_ss);
+ ret = getpeername(fd,
+ (struct sockaddr *)(void *)&cli->conn.remote_ss,
+ &ss_length);
+ if (ret == -1) {
+ goto error;
+ }
+ cli->smb1.mid = 1;
+ cli->smb1.pid = (uint16_t)sys_getpid();
+ cli->smb1.vc_num = cli->smb1.pid;
+ cli->smb1.tid = UINT16_MAX;
+ cli->smb1.uid = UID_FIELD_INVALID;
+
+ cli->initialised = 1;
return cli;
/* Clean up after malloc() error */
error:
- SAFE_FREE(cli->inbuf);
TALLOC_FREE(cli);
return NULL;
}
-struct cli_state *cli_initialise(void)
+bool cli_state_encryption_on(struct cli_state *cli)
{
- return cli_initialise_ex(Undefined);
+ return common_encryption_on(cli->trans_enc_state);
}
+
/****************************************************************************
Close all pipes open on this session.
****************************************************************************/
* later. This tree disconnect forces the peer to clean up, since the
* connection will be going away.
*/
- if (cli->cnum != (uint16)-1) {
+ if (cli_state_has_tcon(cli)) {
cli_tdis(cli);
}
- SAFE_FREE(cli->inbuf);
-
data_blob_free(&cli->secblob);
data_blob_free(&cli->user_session_key);
- if (cli->fd != -1) {
- close(cli->fd);
- }
- cli->fd = -1;
+ cli_state_disconnect(cli);
/*
* Need to free pending first, they remove themselves
*/
- while (cli->pending) {
- talloc_free(cli->pending[0]);
+ while (cli->conn.pending) {
+ talloc_free(cli->conn.pending[0]);
}
TALLOC_FREE(cli);
}
void cli_sockopt(struct cli_state *cli, const char *options)
{
- set_socket_options(cli->fd, options);
+ set_socket_options(cli->conn.fd, options);
+}
+
+const struct sockaddr_storage *cli_state_local_sockaddr(struct cli_state *cli)
+{
+ return &cli->conn.local_ss;
+}
+
+const struct sockaddr_storage *cli_state_remote_sockaddr(struct cli_state *cli)
+{
+ return &cli->conn.remote_ss;
+}
+
+const char *cli_state_remote_name(struct cli_state *cli)
+{
+ return cli->conn.remote_name;
+}
+
+const char *cli_state_remote_realm(struct cli_state *cli)
+{
+ return cli->conn.remote_realm;
+}
+
+uint16_t cli_state_get_vc_num(struct cli_state *cli)
+{
+ return cli->smb1.vc_num;
+}
+
+uint32_t cli_state_server_session_key(struct cli_state *cli)
+{
+ return cli->sesskey;
}
/****************************************************************************
uint16 cli_setpid(struct cli_state *cli, uint16 pid)
{
- uint16 ret = cli->pid;
- cli->pid = pid;
+ uint16_t ret = cli->smb1.pid;
+ cli->smb1.pid = pid;
+ return ret;
+}
+
+uint16_t cli_getpid(struct cli_state *cli)
+{
+ return cli->smb1.pid;
+}
+
+bool cli_state_has_tcon(struct cli_state *cli)
+{
+ if (cli->smb1.tid == UINT16_MAX) {
+ return false;
+ }
+
+ return true;
+}
+
+uint16_t cli_state_get_tid(struct cli_state *cli)
+{
+ return cli->smb1.tid;
+}
+
+uint16_t cli_state_set_tid(struct cli_state *cli, uint16_t tid)
+{
+ uint16_t ret = cli->smb1.tid;
+ cli->smb1.tid = tid;
+ return ret;
+}
+
+uint16_t cli_state_get_uid(struct cli_state *cli)
+{
+ return cli->smb1.uid;
+}
+
+uint16_t cli_state_set_uid(struct cli_state *cli, uint16_t uid)
+{
+ uint16_t ret = cli->smb1.uid;
+ cli->smb1.uid = uid;
return ret;
}
return ret;
}
+enum protocol_types cli_state_protocol(struct cli_state *cli)
+{
+ return cli->conn.protocol;
+}
+
+uint32_t cli_state_capabilities(struct cli_state *cli)
+{
+ return cli->conn.smb1.capabilities;
+}
+
+uint32_t cli_state_available_size(struct cli_state *cli, uint32_t ofs)
+{
+ uint32_t ret = cli->max_xmit;
+
+ if (ofs >= ret) {
+ return 0;
+ }
+
+ ret -= ofs;
+
+ return ret;
+}
+
+uint16_t cli_state_max_requests(struct cli_state *cli)
+{
+ return cli->max_mux;
+}
+
+uint16_t cli_state_security_mode(struct cli_state *cli)
+{
+ return cli->sec_mode;
+}
+
+int cli_state_server_time_zone(struct cli_state *cli)
+{
+ return cli->serverzone;
+}
+
+time_t cli_state_server_time(struct cli_state *cli)
+{
+ return cli->servertime;
+}
+
struct cli_echo_state {
uint16_t vwv[1];
DATA_BLOB data;