summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cliconnect.c308
1 files changed, 266 insertions, 42 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 0fc532dd0f..3678ec80c3 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -47,6 +47,40 @@ static const struct {
#define STAR_SMBSERVER "*SMBSERVER"
+/********************************************************
+ Utility function to ensure we always return at least
+ a valid char * pointer to an empty string for the
+ cli->server_os, cli->server_type and cli->server_domain
+ strings.
+*******************************************************/
+
+static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
+ char *inbuf,
+ char **dest,
+ uint8_t *src,
+ size_t srclen,
+ ssize_t *destlen)
+{
+ *destlen = clistr_pull_talloc(cli,
+ inbuf,
+ SVAL(inbuf, smb_flg2),
+ dest,
+ (char *)src,
+ srclen,
+ STR_TERMINATE);
+ if (*destlen == -1) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (*dest == NULL) {
+ *dest = talloc_strdup(cli, "");
+ if (*dest == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
/**
* Set the user session key for a connection
* @param cli The cli structure to add it too
@@ -220,6 +254,7 @@ static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
uint8_t *bytes;
uint8_t *p;
NTSTATUS status;
+ ssize_t ret;
status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
&num_bytes, &bytes);
@@ -234,12 +269,44 @@ static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
cli->vuid = SVAL(inbuf, smb_uid);
- p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_os,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_type,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_domain,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
@@ -415,6 +482,7 @@ static void cli_session_setup_guest_done(struct tevent_req *subreq)
uint8_t *bytes;
uint8_t *p;
NTSTATUS status;
+ ssize_t ret;
status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
&num_bytes, &bytes);
@@ -429,12 +497,44 @@ static void cli_session_setup_guest_done(struct tevent_req *subreq)
cli->vuid = SVAL(inbuf, smb_uid);
- p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_os,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_type,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_domain,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
@@ -590,6 +690,7 @@ static void cli_session_setup_plain_done(struct tevent_req *subreq)
uint8_t *bytes;
uint8_t *p;
NTSTATUS status;
+ ssize_t ret;
status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
&num_bytes, &bytes);
@@ -603,12 +704,44 @@ static void cli_session_setup_plain_done(struct tevent_req *subreq)
cli->vuid = SVAL(inbuf, smb_uid);
- p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_os,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_type,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_domain,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
status = cli_set_username(cli, state->user);
if (tevent_req_nterror(req, status)) {
@@ -913,6 +1046,7 @@ static void cli_session_setup_nt1_done(struct tevent_req *subreq)
uint8_t *bytes;
uint8_t *p;
NTSTATUS status;
+ ssize_t ret;
status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL,
&num_bytes, &bytes);
@@ -927,12 +1061,41 @@ static void cli_session_setup_nt1_done(struct tevent_req *subreq)
cli->vuid = SVAL(inbuf, smb_uid);
- p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_os,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_type,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ inbuf,
+ &cli->server_domain,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
@@ -1122,6 +1285,7 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq)
uint8_t *p;
uint16_t blob_length;
uint8_t *inbuf;
+ ssize_t ret;
status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
&num_bytes, &bytes);
@@ -1147,15 +1311,44 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq)
p = bytes + blob_length;
- p += clistr_pull(state->inbuf, cli->server_os,
- (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(state->inbuf, cli->server_type,
- (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(state->inbuf, cli->server_domain,
- (char *)p, sizeof(fstring),
- bytes+num_bytes-p, STR_TERMINATE);
+ status = smb_bytes_talloc_string(cli,
+ (char *)inbuf,
+ &cli->server_os,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ (char *)inbuf,
+ &cli->server_type,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
+
+ status = smb_bytes_talloc_string(cli,
+ (char *)inbuf,
+ &cli->server_domain,
+ p,
+ bytes+num_bytes-p,
+ &ret);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ p += ret;
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
@@ -1456,8 +1649,14 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
if (NT_STATUS_IS_OK(status)) {
if (state->cli->server_domain[0] == '\0') {
- fstrcpy(state->cli->server_domain,
- state->ntlmssp_state->server.netbios_domain);
+ TALLOC_FREE(state->cli->server_domain);
+ state->cli->server_domain = talloc_strdup(state->cli,
+ state->ntlmssp_state->server.netbios_domain);
+ if (state->cli->server_domain == NULL) {
+ TALLOC_FREE(subreq);
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
}
cli_set_session_key(
state->cli, state->ntlmssp_state->session_key);
@@ -1754,12 +1953,15 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
const char *workgroup)
{
char *p;
- fstring user2;
+ char *user2;
if (user) {
- fstrcpy(user2, user);
+ user2 = talloc_strdup(talloc_tos(), user);
} else {
- user2[0] ='\0';
+ user2 = talloc_strdup(talloc_tos(), "");
+ }
+ if (user2 == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
if (!workgroup) {
@@ -1979,7 +2181,10 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
state->cli = cli;
vwv = state->vwv;
- fstrcpy(cli->share, share);
+ cli->share = talloc_strdup(cli, share);
+ if (!cli->share) {
+ return NULL;
+ }
/* in user level security don't send a password now */
if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
@@ -2143,8 +2348,24 @@ static void cli_tcon_andx_done(struct tevent_req *subreq)
inbuf = (char *)in;
- clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes,
- STR_TERMINATE|STR_ASCII);
+ if (num_bytes) {
+ if (clistr_pull_talloc(cli,
+ inbuf,
+ SVAL(inbuf, smb_flg2),
+ &cli->dev,
+ bytes,
+ num_bytes,
+ STR_TERMINATE|STR_ASCII) == -1) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ } else {
+ cli->dev = talloc_strdup(cli, "");
+ if (cli->dev == NULL) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ }
if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
/* almost certainly win95 - enable bug fixes */
@@ -2777,7 +2998,10 @@ NTSTATUS cli_connect(struct cli_state *cli,
host = STAR_SMBSERVER;
}
- fstrcpy(cli->desthost, host);
+ cli->desthost = talloc_strdup(cli, host);
+ if (cli->desthost == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ((p = strchr(cli->desthost, '#'))) {