From 6e572d40a913f788f06e4bc7a7047129bc22ad5a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 6 Mar 2009 11:52:15 +0100 Subject: s3:libsmb: remove cli_setup_signing_state() and add struct cli_state *cli_initialise_ex() This prepares the next changes. metze --- source3/libsmb/clidfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clidfs.c') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e642f169f9..1153d8dc89 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -151,7 +151,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, zero_sockaddr(&ss); /* have to open a new connection */ - if (!(c=cli_initialise())) { + if (!(c=cli_initialise_ex(cm_creds.signing_state))) { d_printf("Connection to %s failed\n", server_n); if (c) { cli_shutdown(c); @@ -177,7 +177,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, c->protocol = max_protocol; c->use_kerberos = cm_creds.use_kerberos; c->fallback_after_kerberos = cm_creds.fallback_after_kerberos; - cli_setup_signing_state(c, cm_creds.signing_state); if (!cli_session_request(c, &calling, &called)) { char *p; -- cgit From e5136e984922570ce9992c642c340dd3e937fc4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 12 Mar 2009 17:59:24 -0700 Subject: Remove the static "struct client_connection" mess which is part of the problem that stops libsmbclient being thread safe. Subsidiary DFS connections are now hung off a list inside the cli_state struct. Much more to do in order to get libsmbclient to thread safety, but this is a good start. Jeremy. --- source3/libsmb/clidfs.c | 162 ++++++++++++++++-------------------------------- 1 file changed, 54 insertions(+), 108 deletions(-) (limited to 'source3/libsmb/clidfs.c') 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. */ -- cgit From 8dd1faaa2992851f6852ba7ea4498445af5faadd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Mar 2009 14:53:06 -0700 Subject: Remove the global "struct cm_cred_struct" and associated calls, make callers pass in a struct user_auth_info * instead. This commit causes smbc_set_credentials() to print out a message telling callers to use smbc_set_credentials_with_fallback() instead, as smbc_set_credentials() has a broken API (no SMBCCTX * pointer). No more global variables used in the connection manager API for client dfs calls. Jeremy. --- source3/libsmb/clidfs.c | 143 ++++++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 95 deletions(-) (limited to 'source3/libsmb/clidfs.c') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 8544d5520e..18e7ab1dec 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -32,17 +32,6 @@ as a separator when looking at the pathname part.... JRA. ********************************************************************/ -static struct cm_cred_struct { - char *username; - char *password; - bool got_pass; - bool use_kerberos; - bool fallback_after_kerberos; - int signing_state; -} cm_creds; - -static void cm_set_password(const char *newpass); - static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, struct cli_state *cli, const char *sharename, @@ -96,6 +85,7 @@ NTSTATUS cli_cm_force_encryption(struct cli_state *c, static struct cli_state *do_connect(TALLOC_CTX *ctx, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_sessetup, bool force_encrypt, int max_protocol, @@ -143,7 +133,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, zero_sockaddr(&ss); /* have to open a new connection */ - if (!(c=cli_initialise_ex(cm_creds.signing_state))) { + if (!(c=cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)))) { d_printf("Connection to %s failed\n", server_n); if (c) { cli_shutdown(c); @@ -167,8 +157,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, max_protocol = PROTOCOL_NT1; } c->protocol = max_protocol; - c->use_kerberos = cm_creds.use_kerberos; - c->fallback_after_kerberos = cm_creds.fallback_after_kerberos; + c->use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info); + c->fallback_after_kerberos = + get_cmdline_auth_info_fallback_after_kerberos(auth_info); if (!cli_session_request(c, &calling, &called)) { char *p; @@ -198,20 +189,8 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, return NULL; } - if (!cm_creds.got_pass && !cm_creds.use_kerberos) { - char *label = NULL; - char *pass; - label = talloc_asprintf(ctx, "Enter %s's password: ", - cm_creds.username); - pass = getpass(label); - if (pass) { - cm_set_password(pass); - } - TALLOC_FREE(label); - } - - username = cm_creds.username ? cm_creds.username : ""; - password = cm_creds.password ? cm_creds.password : ""; + username = get_cmdline_auth_info_username(auth_info); + password = get_cmdline_auth_info_password(auth_info); if (!NT_STATUS_IS_OK(cli_session_setup(c, username, password, strlen(password), @@ -219,8 +198,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, lp_workgroup()))) { /* If a password was not supplied then * try again with a null username. */ - if (password[0] || !username[0] || cm_creds.use_kerberos || - !NT_STATUS_IS_OK(cli_session_setup(c, "", + if (password[0] || !username[0] || + get_cmdline_auth_info_use_kerberos(auth_info) || + !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, lp_workgroup()))) { @@ -259,7 +239,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, lp_workgroup())) { cli_shutdown(c); return do_connect(ctx, newserver, - newshare, false, + newshare, auth_info, false, force_encrypt, max_protocol, port, name_type); } @@ -313,6 +293,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_hdr, bool force_encrypt, int max_protocol, @@ -322,6 +303,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, struct cli_state *cli; cli = do_connect(ctx, server, share, + auth_info, show_hdr, force_encrypt, max_protocol, port, name_type); @@ -389,6 +371,7 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, + const struct user_auth_info *auth_info, bool show_hdr, bool force_encrypt, int max_protocol, @@ -402,9 +385,25 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, return c; } - return cli_cm_connect(ctx, referring_cli, - server, share, show_hdr, force_encrypt, - max_protocol, port, name_type); + if (auth_info == NULL) { + /* Can't do a new connection + * without auth info. */ + d_printf("cli_cm_open() Unable to open connection [\\%s\\%s] " + "without auth info\n", + server, share ); + return NULL; + } + + return cli_cm_connect(ctx, + referring_cli, + server, + share, + auth_info, + show_hdr, + force_encrypt, + max_protocol, + port, + name_type); } /**************************************************************************** @@ -423,18 +422,10 @@ void cli_cm_display(const struct cli_state *cli) /**************************************************************************** ****************************************************************************/ -static void cm_set_password(const char *newpass) -{ - SAFE_FREE(cm_creds.password); - cm_creds.password = SMB_STRDUP(newpass); - if (cm_creds.password) { - cm_creds.got_pass = true; - } -} - /**************************************************************************** ****************************************************************************/ +#if 0 void cli_cm_set_credentials(struct user_auth_info *auth_info) { SAFE_FREE(cm_creds.username); @@ -449,51 +440,7 @@ void cli_cm_set_credentials(struct user_auth_info *auth_info) cm_creds.fallback_after_kerberos = false; cm_creds.signing_state = get_cmdline_auth_info_signing_state(auth_info); } - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_signing_state(int state) -{ - cm_creds.signing_state = state; -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_username(const char *username) -{ - SAFE_FREE(cm_creds.username); - cm_creds.username = SMB_STRDUP(username); -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_password(const char *newpass) -{ - SAFE_FREE(cm_creds.password); - cm_creds.password = SMB_STRDUP(newpass); - if (cm_creds.password) { - cm_creds.got_pass = true; - } -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_use_kerberos(void) -{ - cm_creds.use_kerberos = true; -} - -/**************************************************************************** -****************************************************************************/ - -void cli_cm_set_fallback_after_kerberos(void) -{ - cm_creds.fallback_after_kerberos = true; -} +#endif /********************************************************************** split a dfs path into the server, share name, and extrapath components @@ -763,6 +710,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx, bool cli_resolve_path(TALLOC_CTX *ctx, const char *mountpt, + const struct user_auth_info *dfs_auth_info, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, @@ -843,13 +791,16 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* Check for the referral. */ - if (!(cli_ipc = cli_cm_open(ctx, rootcli, - rootcli->desthost, - "IPC$", false, - (rootcli->trans_enc_state != NULL), - rootcli->protocol, - 0, - 0x20))) { + if (!(cli_ipc = cli_cm_open(ctx, + rootcli, + rootcli->desthost, + "IPC$", + dfs_auth_info, + false, + (rootcli->trans_enc_state != NULL), + rootcli->protocol, + 0, + 0x20))) { return false; } @@ -893,6 +844,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx, if ((*targetcli = cli_cm_open(ctx, rootcli, server, share, + dfs_auth_info, false, (rootcli->trans_enc_state != NULL), rootcli->protocol, @@ -952,6 +904,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx, if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) { if (cli_resolve_path(ctx, newmount, + dfs_auth_info, *targetcli, *pp_targetpath, &newcli, -- cgit From 28e03f2011b331ab01b99f9ff6e049f938ec1a00 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Mar 2009 20:56:48 -0700 Subject: Allow DFS client paths to work when POSIX pathnames have been selected (we need to path in pathname /that/look/like/this). Jeremy. --- source3/libsmb/clidfs.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clidfs.c') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 18e7ab1dec..430807eb7f 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -551,13 +551,23 @@ static char *cli_dfs_make_full_path(TALLOC_CTX *ctx, struct cli_state *cli, const char *dir) { + char path_sep = '\\'; + /* Ensure the extrapath doesn't start with a separator. */ while (IS_DIRECTORY_SEP(*dir)) { dir++; } - return talloc_asprintf(ctx, "\\%s\\%s\\%s", - cli->desthost, cli->share, dir); + if (cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) { + path_sep = '/'; + } + return talloc_asprintf(ctx, "%c%s%c%s%c%s", + path_sep, + cli->desthost, + path_sep, + cli->share, + path_sep, + dir); } /******************************************************************** -- cgit