summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cliconnect.c35
-rw-r--r--source3/libsmb/clidfs.c162
-rw-r--r--source3/libsmb/clientgen.c88
-rw-r--r--source3/libsmb/clilist.c5
-rw-r--r--source3/libsmb/clireadwrite.c33
-rw-r--r--source3/libsmb/passchange.c18
-rw-r--r--source3/libsmb/pwd_cache.c61
7 files changed, 185 insertions, 217 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index ec2932488e..43326e912c 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -61,6 +61,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
{
DATA_BLOB session_key = data_blob_null;
DATA_BLOB lm_response = data_blob_null;
+ NTSTATUS status;
fstring pword;
char *p;
@@ -129,7 +130,10 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
- fstrcpy(cli->user_name, user);
+ status = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if (session_key.data) {
/* Have plaintext orginal */
@@ -237,7 +241,10 @@ NTSTATUS cli_session_setup_guest_recv(struct async_req *req)
cli->is_samba = True;
}
- fstrcpy(cli->user_name, "");
+ status = cli_set_username(cli, "");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
return NT_STATUS_OK;
}
@@ -289,6 +296,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
{
uint32 capabilities = cli_session_setup_capabilities(cli);
char *p;
+ NTSTATUS status;
fstring lanman;
fstr_sprintf( lanman, "Samba %s", samba_version_string());
@@ -349,8 +357,10 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
-1, STR_TERMINATE);
p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
-1, STR_TERMINATE);
- fstrcpy(cli->user_name, user);
-
+ status = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
}
@@ -520,7 +530,10 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
cli->is_samba = True;
}
- fstrcpy(cli->user_name, user);
+ result = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto end;
+ }
if (session_key.data) {
/* Have plaintext orginal */
@@ -898,6 +911,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
DATA_BLOB blob;
const char *p = NULL;
char *account = NULL;
+ NTSTATUS status;
DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
@@ -936,7 +950,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
- fstrcpy(cli->user_name, user);
+ status = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ADS_ERROR_NT(status);
+ }
#ifdef HAVE_KRB5
/* If password is set we reauthenticate to kerberos server
@@ -2101,7 +2118,11 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
}
}
- cli_init_creds(cli, user, domain, password);
+ nt_status = cli_init_creds(cli, user, domain, password);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ cli_shutdown(cli);
+ return nt_status;
+ }
*output_cli = cli;
return NT_STATUS_OK;
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 1153d8dc89..8544d5520e 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -3,7 +3,7 @@
client connect/disconnect routines
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Gerald (Jerry) Carter 2004
- Copyright (C) Jeremy Allison 2007
+ Copyright (C) Jeremy Allison 2007-2009
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
@@ -32,12 +32,6 @@
as a separator when looking at the pathname part.... JRA.
********************************************************************/
-struct client_connection {
- struct client_connection *prev, *next;
- struct cli_state *cli;
- char *mount;
-};
-
static struct cm_cred_struct {
char *username;
char *password;
@@ -49,8 +43,6 @@ static struct cm_cred_struct {
static void cm_set_password(const char *newpass);
-static struct client_connection *connections;
-
static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *sharename,
@@ -96,7 +88,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c,
return status;
}
-
+
/********************************************************************
Return a connection to a server.
********************************************************************/
@@ -301,52 +293,20 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
/****************************************************************************
****************************************************************************/
-static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt)
-{
- struct client_connection *p;
- int i;
-
- for (p=connections,i=0; p; p=p->next,i++) {
- if (strequal(p->cli->desthost, c->desthost) &&
- strequal(p->cli->share, c->share)) {
- break;
- }
- }
-
- if (p) {
- char *name = clean_name(NULL, mnt);
- if (!name) {
- return;
- }
- TALLOC_FREE(p->mount);
- p->mount = talloc_strdup(p, name);
- TALLOC_FREE(name);
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-
-const char *cli_cm_get_mntpoint(struct cli_state *c)
+static void cli_set_mntpoint(struct cli_state *cli, const char *mnt)
{
- struct client_connection *p;
- int i;
-
- for (p=connections,i=0; p; p=p->next,i++) {
- if (strequal(p->cli->desthost, c->desthost) &&
- strequal(p->cli->share, c->share)) {
- break;
- }
- }
-
- if (p) {
- return p->mount;
+ char *name = clean_name(NULL, mnt);
+ if (!name) {
+ return;
}
- return NULL;
+ TALLOC_FREE(cli->dfs_mountpoint);
+ cli->dfs_mountpoint = talloc_strdup(cli, name);
+ TALLOC_FREE(name);
}
/********************************************************************
- Add a new connection to the list
+ Add a new connection to the list.
+ referring_cli == NULL means a new initial connection.
********************************************************************/
static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
@@ -359,53 +319,62 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
int port,
int name_type)
{
- struct client_connection *node;
-
- /* NB This must be the null context here... JRA. */
- node = TALLOC_ZERO_ARRAY(NULL, struct client_connection, 1);
- if (!node) {
- return NULL;
- }
+ struct cli_state *cli;
- node->cli = do_connect(ctx, server, share,
+ cli = do_connect(ctx, server, share,
show_hdr, force_encrypt, max_protocol,
port, name_type);
- if ( !node->cli ) {
- TALLOC_FREE( node );
+ if (!cli ) {
return NULL;
}
- DLIST_ADD( connections, node );
-
- cli_cm_set_mntpoint(node->cli, "");
+ /* Enter into the list. */
+ if (referring_cli) {
+ DLIST_ADD_END(referring_cli, cli, struct cli_state *);
+ }
if (referring_cli && referring_cli->posix_capabilities) {
uint16 major, minor;
uint32 caplow, caphigh;
- if (cli_unix_extensions_version(node->cli, &major,
+ if (cli_unix_extensions_version(cli, &major,
&minor, &caplow, &caphigh)) {
- cli_set_unix_extensions_capabilities(node->cli,
+ cli_set_unix_extensions_capabilities(cli,
major, minor,
caplow, caphigh);
}
}
- return node->cli;
+ return cli;
}
/********************************************************************
- Return a connection to a server.
+ Return a connection to a server on a particular share.
********************************************************************/
-static struct cli_state *cli_cm_find(const char *server, const char *share)
+static struct cli_state *cli_cm_find(struct cli_state *cli,
+ const char *server,
+ const char *share)
{
- struct client_connection *p;
+ struct cli_state *p;
- for (p=connections; p; p=p->next) {
- if ( strequal(server, p->cli->desthost) &&
- strequal(share,p->cli->share)) {
- return p->cli;
+ if (cli == NULL) {
+ return NULL;
+ }
+
+ /* Search to the start of the list. */
+ for (p = cli; p; p = p->prev) {
+ if (strequal(server, p->desthost) &&
+ strequal(share,p->share)) {
+ return p;
+ }
+ }
+
+ /* Search to the end of the list. */
+ for (p = cli->next; p; p = p->next) {
+ if (strequal(server, p->desthost) &&
+ strequal(share,p->share)) {
+ return p;
}
}
@@ -413,8 +382,7 @@ static struct cli_state *cli_cm_find(const char *server, const char *share)
}
/****************************************************************************
- Open a client connection to a \\server\share. Set's the current *cli
- global variable as a side-effect (but only if the connection is successful).
+ Open a client connection to a \\server\share.
****************************************************************************/
struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
@@ -427,50 +395,28 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
int port,
int name_type)
{
- struct cli_state *c;
+ /* Try to reuse an existing connection in this list. */
+ struct cli_state *c = cli_cm_find(referring_cli, server, share);
- /* try to reuse an existing connection */
+ if (c) {
+ return c;
+ }
- c = cli_cm_find(server, share);
- if (!c) {
- c = cli_cm_connect(ctx, referring_cli,
+ return cli_cm_connect(ctx, referring_cli,
server, share, show_hdr, force_encrypt,
max_protocol, port, name_type);
- }
-
- return c;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_shutdown(void)
-{
- struct client_connection *p, *x;
-
- for (p=connections; p;) {
- cli_shutdown(p->cli);
- x = p;
- p = p->next;
-
- TALLOC_FREE(x);
- }
-
- connections = NULL;
- return;
}
/****************************************************************************
****************************************************************************/
-void cli_cm_display(void)
+void cli_cm_display(const struct cli_state *cli)
{
- struct client_connection *p;
int i;
- for ( p=connections,i=0; p; p=p->next,i++ ) {
+ for (i=0; cli; cli = cli->next,i++ ) {
d_printf("%d:\tserver=%s, share=%s\n",
- i, p->cli->desthost, p->cli->share );
+ i, cli->desthost, cli->share );
}
}
@@ -998,7 +944,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
return false;
}
- cli_cm_set_mntpoint(*targetcli, newmount);
+ cli_set_mntpoint(*targetcli, newmount);
/* Check for another dfs referral, note that we are not
checking for loops here. */
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 2983f7771a..c1ba4e5c4f 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -409,23 +409,68 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
}
/****************************************************************************
+ Initialize Domain, user or password.
+****************************************************************************/
+
+NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain)
+{
+ TALLOC_FREE(cli->domain);
+ cli->domain = talloc_strdup(cli, domain ? domain : "");
+ if (cli->domain == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_set_username(struct cli_state *cli, const char *username)
+{
+ TALLOC_FREE(cli->user_name);
+ cli->user_name = talloc_strdup(cli, username ? username : "");
+ if (cli->user_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_set_password(struct cli_state *cli, const char *password)
+{
+ TALLOC_FREE(cli->password);
+
+ /* Password can be NULL. */
+ if (password) {
+ cli->password = talloc_strdup(cli, password);
+ if (cli->password == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ /* Use zero NTLMSSP hashes and session key. */
+ cli->password = NULL;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
Initialise credentials of a client structure.
****************************************************************************/
-void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
+NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
{
- fstrcpy(cli->domain, domain);
- fstrcpy(cli->user_name, username);
- pwd_set_cleartext(&cli->pwd, password);
- if (!*username) {
- cli->pwd.null_pwd = true;
+ NTSTATUS status = cli_set_username(cli, username);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = cli_set_domain(cli, domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
+ DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
- DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
+ return cli_set_password(cli, password);
}
/****************************************************************************
- Initialise a client structure. Always returns a malloc'ed struct.
+ Initialise a client structure. Always returns a talloc'ed struct.
Set the signing state (used from the command line).
****************************************************************************/
@@ -446,6 +491,10 @@ struct cli_state *cli_initialise_ex(int signing_state)
return NULL;
}
+ cli->dfs_mountpoint = talloc_strdup(cli, "");
+ if (!cli->dfs_mountpoint) {
+ goto error;
+ }
cli->port = 0;
cli->fd = -1;
cli->cnum = -1;
@@ -521,7 +570,7 @@ struct cli_state *cli_initialise_ex(int signing_state)
SAFE_FREE(cli->inbuf);
SAFE_FREE(cli->outbuf);
- SAFE_FREE(cli);
+ TALLOC_FREE(cli);
return NULL;
}
@@ -550,6 +599,27 @@ void cli_nt_pipes_close(struct cli_state *cli)
void cli_shutdown(struct cli_state *cli)
{
+ if (cli->prev == NULL) {
+ /*
+ * Possible head of a DFS list,
+ * shutdown all subsidiary DFS
+ * connections.
+ */
+ struct cli_state *p, *next;
+
+ for (p = cli->next; p; p = next) {
+ next = p->next;
+ cli_shutdown(p);
+ }
+ } else {
+ /*
+ * We're a subsidiary connection.
+ * Just remove ourselves from the
+ * DFS list.
+ */
+ DLIST_REMOVE(cli->prev, cli);
+ }
+
cli_nt_pipes_close(cli);
/*
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index e604725493..a84a64794b 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -244,7 +244,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
unsigned int param_len, data_len;
uint16 setup;
char *param;
- const char *mnt;
uint32 resume_key = 0;
TALLOC_CTX *frame = talloc_stackframe();
DATA_BLOB last_name_raw = data_blob(NULL, 0);
@@ -457,8 +456,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
First = False;
}
- mnt = cli_cm_get_mntpoint( cli );
-
/* see if the server disconnected or the connection otherwise failed */
if (cli_is_error(cli)) {
total_received = -1;
@@ -479,7 +476,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
info_level));
break;
}
- fn(mnt,&finfo, Mask, state);
+ fn(cli->dfs_mountpoint, &finfo, Mask, state);
}
}
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 7e7cf0d682..f2f447b4c9 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -930,11 +930,8 @@ struct cli_push_state {
uint16_t mode;
off_t start_offset;
size_t window_size;
- bool caller_buffers;
- size_t (*source)(uint8_t *inbuf, size_t n,
- const uint8_t **outbuf,
- void *priv);
+ size_t (*source)(uint8_t *buf, size_t n, void *priv);
void *priv;
bool eof;
@@ -966,21 +963,13 @@ static bool cli_push_write_setup(struct async_req *req,
substate->req = req;
substate->idx = idx;
substate->ofs = state->next_offset;
- if (state->caller_buffers) {
- substate->buf = NULL;
- } else {
- substate->buf = talloc_array(substate, uint8_t,
- state->chunk_size);
- if (!substate->buf) {
- talloc_free(substate);
- return false;
- }
+ substate->buf = talloc_array(substate, uint8_t, state->chunk_size);
+ if (!substate->buf) {
+ talloc_free(substate);
+ return false;
}
-
- /* source function can overwrite substate->buf... */
substate->size = state->source(substate->buf,
state->chunk_size,
- (const uint8_t **)&substate->buf,
state->priv);
if (substate->size == 0) {
state->eof = true;
@@ -1013,9 +1002,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct cli_state *cli,
uint16_t fnum, uint16_t mode,
off_t start_offset, size_t window_size,
- bool caller_buffers,
- size_t (*source)(uint8_t *inbuf, size_t n,
- const uint8_t **outbuf,
+ size_t (*source)(uint8_t *buf, size_t n,
void *priv),
void *priv)
{
@@ -1032,7 +1019,6 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
state->fnum = fnum;
state->start_offset = start_offset;
state->mode = mode;
- state->caller_buffers = caller_buffers;
state->source = source;
state->priv = priv;
state->eof = false;
@@ -1122,10 +1108,7 @@ NTSTATUS cli_push_recv(struct async_req *req)
NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode,
off_t start_offset, size_t window_size,
- bool caller_buffers,
- size_t (*source)(uint8_t *inbuf, size_t n,
- const uint8_t **outbuf,
- void *priv),
+ size_t (*source)(uint8_t *buf, size_t n, void *priv),
void *priv)
{
TALLOC_CTX *frame = talloc_stackframe();
@@ -1146,7 +1129,7 @@ NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode,
}
req = cli_push_send(frame, ev, cli, fnum, mode, start_offset,
- window_size, caller_buffers, source, priv);
+ window_size, source, priv);
if (req == NULL) {
goto nomem;
}
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index f9ff4b3191..45cd392a5a 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -133,9 +133,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
return result;
}
- cli_init_creds(cli, "", "", NULL);
+ result = cli_init_creds(cli, "", "", NULL);
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_shutdown(cli);
+ return result;
+ }
} else {
- cli_init_creds(cli, user_name, "", old_passwd);
+ result = cli_init_creds(cli, user_name, "", old_passwd);
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_shutdown(cli);
+ return result;
+ }
}
result = cli_tcon_andx(cli, "IPC$", "IPC", "", 1);
@@ -222,7 +230,11 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
TALLOC_FREE(pipe_hnd);
/* Try anonymous NTLMSSP... */
- cli_init_creds(cli, "", "", NULL);
+ result = cli_init_creds(cli, "", "", NULL);
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_shutdown(cli);
+ return result;
+ }
result = NT_STATUS_UNSUCCESSFUL;
diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c
deleted file mode 100644
index 071e729e8c..0000000000
--- a/source3/libsmb/pwd_cache.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Password cacheing. obfuscation is planned
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
-
- 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 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-/****************************************************************************
- Initialises a password structure.
-****************************************************************************/
-
-static void pwd_init(struct pwd_info *pwd)
-{
- memset((char *)pwd->password , '\0', sizeof(pwd->password ));
-
- pwd->null_pwd = True; /* safest option... */
-}
-
-/****************************************************************************
- Stores a cleartext password.
-****************************************************************************/
-
-void pwd_set_cleartext(struct pwd_info *pwd, const char *clr)
-{
- pwd_init(pwd);
- if (clr) {
- fstrcpy(pwd->password, clr);
- pwd->null_pwd = False;
- } else {
- pwd->null_pwd = True;
- }
-
- pwd->cleartext = True;
-}
-
-/****************************************************************************
- Gets a cleartext password.
-****************************************************************************/
-
-void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
-{
- if (pwd->cleartext)
- fstrcpy(clr, pwd->password);
- else
- clr[0] = 0;
-
-}