1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00
samba-mirror/source3/libsmb/libsmb_server.c

677 lines
20 KiB
C
Raw Normal View History

Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
/*
Unix SMB/Netbios implementation.
SMB client library implementation
Copyright (C) Andrew Tridgell 1998
Copyright (C) Richard Sharpe 2000, 2002
Copyright (C) John Terpstra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
Copyright (C) Derrell Lipman 2003-2008
Copyright (C) Jeremy Allison 2007, 2008
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"
#include "libsmbclient.h"
#include "libsmb_internal.h"
/*
* Check a server for being alive and well.
* returns 0 if the server is in shape. Returns 1 on error
*
* Also useable outside libsmbclient to enable external cache
* to do some checks too.
*/
int
SMBC_check_server(SMBCCTX * context,
SMBCSRV * server)
{
socklen_t size;
struct sockaddr addr;
size = sizeof(addr);
return (getpeername(server->cli->fd, &addr, &size) == -1);
}
/*
* Remove a server from the cached server list it's unused.
* On success, 0 is returned. 1 is returned if the server could not be removed.
*
* Also useable outside libsmbclient
*/
int
SMBC_remove_unused_server(SMBCCTX * context,
SMBCSRV * srv)
{
SMBCFILE * file;
/* are we being fooled ? */
if (!context || !context->internal->initialized || !srv) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
return 1;
}
/* Check all open files/directories for a relation with this server */
for (file = context->internal->files; file; file = file->next) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
if (file->srv == srv) {
/* Still used */
DEBUG(3, ("smbc_remove_usused_server: "
"%p still used by %p.\n",
srv, file));
return 1;
}
}
DLIST_REMOVE(context->internal->servers, srv);
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
cli_shutdown(srv->cli);
srv->cli = NULL;
DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
(context->cache.remove_cached_server_fn)(context, srv);
SAFE_FREE(srv);
return 0;
}
/****************************************************************
* Call the auth_fn with fixed size (fstring) buffers.
***************************************************************/
void
SMBC_call_auth_fn(TALLOC_CTX *ctx,
SMBCCTX *context,
const char *server,
const char *share,
char **pp_workgroup,
char **pp_username,
char **pp_password)
{
fstring workgroup;
fstring username;
fstring password;
strlcpy(workgroup, *pp_workgroup, sizeof(workgroup));
strlcpy(username, *pp_username, sizeof(username));
strlcpy(password, *pp_password, sizeof(password));
(context->server.get_auth_data_fn)(
server, share,
workgroup, sizeof(workgroup),
username, sizeof(username),
password, sizeof(password));
TALLOC_FREE(*pp_workgroup);
TALLOC_FREE(*pp_username);
TALLOC_FREE(*pp_password);
*pp_workgroup = talloc_strdup(ctx, workgroup);
*pp_username = talloc_strdup(ctx, username);
*pp_password = talloc_strdup(ctx, password);
}
void
SMBC_get_auth_data(const char *server, const char *share,
char *workgroup_buf, int workgroup_buf_len,
char *username_buf, int username_buf_len,
char *password_buf, int password_buf_len)
{
/* Default function just uses provided data. Nothing to do. */
}
SMBCSRV *
SMBC_find_server(TALLOC_CTX *ctx,
SMBCCTX *context,
const char *server,
const char *share,
char **pp_workgroup,
char **pp_username,
char **pp_password)
{
SMBCSRV *srv;
int auth_called = 0;
check_server_cache:
srv = (context->cache.get_cached_server_fn)(context,
server, share,
*pp_workgroup,
*pp_username);
if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] ||
!*pp_password || !(*pp_password)[0])) {
SMBC_call_auth_fn(ctx, context, server, share,
pp_workgroup, pp_username, pp_password);
if (!pp_workgroup || !pp_username || !pp_password) {
return NULL;
}
/*
* However, smbc_auth_fn may have picked up info relating to
* an existing connection, so try for an existing connection
* again ...
*/
auth_called = 1;
goto check_server_cache;
}
if (srv) {
if ((context->server.check_server_fn)(context, srv)) {
/*
* This server is no good anymore
* Try to remove it and check for more possible
* servers in the cache
*/
if ((context->server.remove_unused_server_fn)(context,
srv)) {
/*
* We could not remove the server completely,
* remove it from the cache so we will not get
* it again. It will be removed when the last
* file/dir is closed.
*/
(context->cache.remove_cached_server_fn)(context,
srv);
}
/*
* Maybe there are more cached connections to this
* server
*/
goto check_server_cache;
}
return srv;
}
return NULL;
}
/*
* Connect to a server, possibly on an existing connection
*
* Here, what we want to do is: If the server and username
* match an existing connection, reuse that, otherwise, establish a
* new connection.
*
* If we have to create a new connection, call the auth_fn to get the
* info we need, unless the username and password were passed in.
*/
SMBCSRV *
SMBC_server(TALLOC_CTX *ctx,
SMBCCTX *context,
bool connect_if_not_found,
const char *server,
const char *share,
char **pp_workgroup,
char **pp_username,
char **pp_password)
{
SMBCSRV *srv=NULL;
struct cli_state *c;
struct nmb_name called, calling;
const char *server_n = server;
struct sockaddr_storage ss;
int tried_reverse = 0;
int port_try_first;
int port_try_next;
const char *username_used;
NTSTATUS status;
zero_addr(&ss);
ZERO_STRUCT(c);
if (server[0] == 0) {
errno = EPERM;
return NULL;
}
/* Look for a cached connection */
srv = SMBC_find_server(ctx, context, server, share,
pp_workgroup, pp_username, pp_password);
/*
* If we found a connection and we're only allowed one share per
* server...
*/
if (srv && *share != '\0' && context->internal->one_share_per_server) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
/*
* ... then if there's no current connection to the share,
* connect to it. SMBC_find_server(), or rather the function
* pointed to by context->cache.get_cached_srv_fn which
* was called by SMBC_find_server(), will have issued a tree
* disconnect if the requested share is not the same as the
* one that was already connected.
*/
if (srv->cli->cnum == (uint16) -1) {
/* Ensure we have accurate auth info */
SMBC_call_auth_fn(ctx, context, server, share,
pp_workgroup, pp_username, pp_password);
if (!*pp_workgroup || !*pp_username || !*pp_password) {
errno = ENOMEM;
cli_shutdown(srv->cli);
srv->cli = NULL;
(context->cache.remove_cached_server_fn)(context,
srv);
return NULL;
}
/*
* We don't need to renegotiate encryption
* here as the encryption context is not per
* tid.
*/
if (!cli_send_tconX(srv->cli, share, "?????",
*pp_password,
strlen(*pp_password)+1)) {
errno = SMBC_errno(context, srv->cli);
cli_shutdown(srv->cli);
srv->cli = NULL;
(context->cache.remove_cached_server_fn)(context,
srv);
srv = NULL;
}
/*
* Regenerate the dev value since it's based on both
* server and share
*/
if (srv) {
srv->dev = (dev_t)(str_checksum(server) ^
str_checksum(share));
}
}
}
/* If we have a connection... */
if (srv) {
/* ... then we're done here. Give 'em what they came for. */
return srv;
}
/* If we're not asked to connect when a connection doesn't exist... */
if (! connect_if_not_found) {
/* ... then we're done here. */
return NULL;
}
if (!*pp_workgroup || !*pp_username || !*pp_password) {
errno = ENOMEM;
return NULL;
}
make_nmb_name(&calling, context->config.netbios_name, 0x0);
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
make_nmb_name(&called , server, 0x20);
DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server));
DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
again:
zero_addr(&ss);
/* have to open a new connection */
if ((c = cli_initialise()) == NULL) {
errno = ENOMEM;
return NULL;
}
if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
c->use_kerberos = True;
}
if (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
c->fallback_after_kerberos = True;
}
c->timeout = context->config.timeout;
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
/*
* Force use of port 139 for first try if share is $IPC, empty, or
* null, so browse lists can work
*/
if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) {
port_try_first = 139;
port_try_next = 445;
} else {
port_try_first = 445;
port_try_next = 139;
}
c->port = port_try_first;
status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
/* First connection attempt failed. Try alternate port. */
c->port = port_try_next;
status = cli_connect(c, server_n, &ss);
if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(c);
errno = ETIMEDOUT;
return NULL;
}
}
if (!cli_session_request(c, &calling, &called)) {
cli_shutdown(c);
if (strcmp(called.name, "*SMBSERVER")) {
make_nmb_name(&called , "*SMBSERVER", 0x20);
goto again;
} else { /* Try one more time, but ensure we don't loop */
/* Only try this if server is an IP address ... */
if (is_ipaddress(server) && !tried_reverse) {
fstring remote_name;
struct sockaddr_storage rem_ss;
if (!interpret_string_addr(&rem_ss, server,
NI_NUMERICHOST)) {
DEBUG(4, ("Could not convert IP address "
"%s to struct sockaddr_storage\n",
server));
errno = ETIMEDOUT;
return NULL;
}
tried_reverse++; /* Yuck */
if (name_status_find("*", 0, 0, &rem_ss, remote_name)) {
make_nmb_name(&called, remote_name, 0x20);
goto again;
}
}
}
errno = ETIMEDOUT;
return NULL;
}
DEBUG(4,(" session request ok\n"));
if (!cli_negprot(c)) {
cli_shutdown(c);
errno = ETIMEDOUT;
return NULL;
}
username_used = *pp_username;
if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
*pp_password, strlen(*pp_password),
*pp_password, strlen(*pp_password),
*pp_workgroup))) {
/* Failed. Try an anonymous login, if allowed by flags. */
username_used = "";
if ((context->flags.bits &
SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
*pp_password, 1,
*pp_password, 0,
*pp_workgroup))) {
cli_shutdown(c);
errno = EPERM;
return NULL;
}
}
DEBUG(4,(" session setup ok\n"));
if (!cli_send_tconX(c, share, "?????",
*pp_password, strlen(*pp_password)+1)) {
errno = SMBC_errno(context, c);
cli_shutdown(c);
return NULL;
}
DEBUG(4,(" tconx ok\n"));
if (context->internal->smb_encryption_level) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
/* Attempt UNIX smb encryption. */
if (!NT_STATUS_IS_OK(cli_force_encryption(c,
username_used,
*pp_password,
*pp_workgroup))) {
/*
* context->smb_encryption_level == 1
* means don't fail if encryption can't be negotiated,
* == 2 means fail if encryption can't be negotiated.
*/
DEBUG(4,(" SMB encrypt failed\n"));
if (context->internal->smb_encryption_level == 2) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
cli_shutdown(c);
errno = EPERM;
return NULL;
}
}
DEBUG(4,(" SMB encrypt ok\n"));
}
/*
* Ok, we have got a nice connection
* Let's allocate a server structure.
*/
srv = SMB_MALLOC_P(SMBCSRV);
if (!srv) {
errno = ENOMEM;
goto failed;
}
ZERO_STRUCTP(srv);
srv->cli = c;
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
srv->no_pathinfo = False;
srv->no_pathinfo2 = False;
srv->no_nt_session = False;
/* now add it to the cache (internal or external) */
/* Let the cache function set errno if it wants to */
errno = 0;
if ((context->cache.add_cached_server_fn)(context, srv,
server, share,
*pp_workgroup,
*pp_username)) {
int saved_errno = errno;
DEBUG(3, (" Failed to add server to cache\n"));
errno = saved_errno;
if (errno == 0) {
errno = ENOMEM;
}
goto failed;
}
DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
server, share, srv));
DLIST_ADD(context->internal->servers, srv);
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
return srv;
failed:
cli_shutdown(c);
if (!srv) {
return NULL;
}
SAFE_FREE(srv);
return NULL;
}
/*
* Connect to a server for getting/setting attributes, possibly on an existing
* connection. This works similarly to SMBC_server().
*/
SMBCSRV *
SMBC_attr_server(TALLOC_CTX *ctx,
SMBCCTX *context,
const char *server,
const char *share,
char **pp_workgroup,
char **pp_username,
char **pp_password)
{
int flags;
struct sockaddr_storage ss;
struct cli_state *ipc_cli;
struct rpc_pipe_client *pipe_hnd;
NTSTATUS nt_status;
SMBCSRV *ipc_srv=NULL;
/*
* See if we've already created this special connection. Reference
* our "special" share name '*IPC$', which is an impossible real share
* name due to the leading asterisk.
*/
ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$",
pp_workgroup, pp_username, pp_password);
if (!ipc_srv) {
/* We didn't find a cached connection. Get the password */
if (!*pp_password || (*pp_password)[0] == '\0') {
/* ... then retrieve it now. */
SMBC_call_auth_fn(ctx, context, server, share,
pp_workgroup, pp_username, pp_password);
if (!*pp_workgroup || !*pp_username || !*pp_password) {
errno = ENOMEM;
return NULL;
}
}
flags = 0;
if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
}
zero_addr(&ss);
nt_status = cli_full_connection(&ipc_cli,
global_myname(), server,
&ss, 0, "IPC$", "?????",
*pp_username,
*pp_workgroup,
*pp_password,
flags,
Undefined, NULL);
if (! NT_STATUS_IS_OK(nt_status)) {
DEBUG(1,("cli_full_connection failed! (%s)\n",
nt_errstr(nt_status)));
errno = ENOTSUP;
return NULL;
}
if (context->internal->smb_encryption_level) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
/* Attempt UNIX smb encryption. */
if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
*pp_username,
*pp_password,
*pp_workgroup))) {
/*
* context->smb_encryption_level ==
* 1 means don't fail if encryption can't be
* negotiated, == 2 means fail if encryption
* can't be negotiated.
*/
DEBUG(4,(" SMB encrypt failed on IPC$\n"));
if (context->internal->smb_encryption_level == 2) {
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
cli_shutdown(ipc_cli);
errno = EPERM;
return NULL;
}
}
DEBUG(4,(" SMB encrypt ok on IPC$\n"));
}
ipc_srv = SMB_MALLOC_P(SMBCSRV);
if (!ipc_srv) {
errno = ENOMEM;
cli_shutdown(ipc_cli);
return NULL;
}
ZERO_STRUCTP(ipc_srv);
ipc_srv->cli = ipc_cli;
pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli,
PI_LSARPC,
&nt_status);
if (!pipe_hnd) {
DEBUG(1, ("cli_nt_session_open fail!\n"));
errno = ENOTSUP;
cli_shutdown(ipc_srv->cli);
free(ipc_srv);
return NULL;
}
/*
* Some systems don't support
* SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000
* so we might as well do it too.
*/
nt_status = rpccli_lsa_open_policy(
pipe_hnd,
talloc_tos(),
True,
GENERIC_EXECUTE_ACCESS,
&ipc_srv->pol);
if (!NT_STATUS_IS_OK(nt_status)) {
errno = SMBC_errno(context, ipc_srv->cli);
cli_shutdown(ipc_srv->cli);
return NULL;
}
/* now add it to the cache (internal or external) */
errno = 0; /* let cache function set errno if it likes */
if ((context->cache.add_cached_server_fn)(context, ipc_srv,
server,
"*IPC$",
*pp_workgroup,
*pp_username)) {
DEBUG(3, (" Failed to add server to cache\n"));
if (errno == 0) {
errno = ENOMEM;
}
cli_shutdown(ipc_srv->cli);
free(ipc_srv);
return NULL;
}
DLIST_ADD(context->internal->servers, ipc_srv);
Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771)
2008-02-28 19:23:20 +03:00
}
return ipc_srv;
}