diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/libsmb_server.c | 196 |
1 files changed, 98 insertions, 98 deletions
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 0a3287bc82..aeec255350 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -7,17 +7,17 @@ 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/>. */ @@ -40,7 +40,7 @@ SMBC_check_server(SMBCCTX * context, { socklen_t size; struct sockaddr addr; - + size = sizeof(addr); return (getpeername(server->cli->fd, &addr, &size) == -1); } @@ -56,12 +56,12 @@ SMBC_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) { SMBCFILE * file; - + /* are we being fooled ? */ if (!context || !context->internal->initialized || !srv) { return 1; } - + /* Check all open files/directories for a relation with this server */ for (file = context->internal->files; file; file = file->next) { if (file->srv == srv) { @@ -72,16 +72,16 @@ SMBC_remove_unused_server(SMBCCTX * context, return 1; } } - + DLIST_REMOVE(context->internal->servers, srv); - + cli_shutdown(srv->cli); srv->cli = NULL; - + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - + smbc_getFunctionRemoveCachedServer(context)(context, srv); - + SAFE_FREE(srv); return 0; } @@ -102,11 +102,11 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, fstring username; fstring password; smbc_get_auth_data_with_context_fn auth_with_context_fn; - + strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); strlcpy(username, *pp_username, sizeof(username)); strlcpy(password, *pp_password, sizeof(password)); - + /* See if there's an authentication with context function provided */ auth_with_context_fn = smbc_getFunctionAuthDataWithContext(context); if (auth_with_context_fn) @@ -124,11 +124,11 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, 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); @@ -157,23 +157,23 @@ SMBC_find_server(TALLOC_CTX *ctx, { SMBCSRV *srv; int auth_called = 0; - + if (!pp_workgroup || !pp_username || !pp_password) { return NULL; } - + check_server_cache: - + srv = smbc_getFunctionGetCachedServer(context)(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); - + /* * However, smbc_auth_fn may have picked up info relating to * an existing connection, so try for an existing connection @@ -181,9 +181,9 @@ check_server_cache: */ auth_called = 1; goto check_server_cache; - + } - + if (srv) { if (smbc_getFunctionCheckServer(context)(context, srv)) { /* @@ -202,17 +202,17 @@ check_server_cache: smbc_getFunctionRemoveCachedServer(context)(context, srv); } - + /* * Maybe there are more cached connections to this * server */ goto check_server_cache; } - + return srv; } - + return NULL; } @@ -247,19 +247,19 @@ SMBC_server(TALLOC_CTX *ctx, 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... @@ -267,7 +267,7 @@ SMBC_server(TALLOC_CTX *ctx, if (srv && *share != '\0' && smbc_getOptionOneSharePerServer(context)) { - + /* * ... then if there's no current connection to the share, * connect to it. SMBC_find_server(), or rather the function @@ -282,7 +282,7 @@ SMBC_server(TALLOC_CTX *ctx, pp_workgroup, pp_username, pp_password); - + if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; cli_shutdown(srv->cli); @@ -291,17 +291,17 @@ SMBC_server(TALLOC_CTX *ctx, 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; @@ -309,7 +309,7 @@ SMBC_server(TALLOC_CTX *ctx, srv); srv = NULL; } - + /* * Regenerate the dev value since it's based on both * server and share @@ -320,42 +320,42 @@ SMBC_server(TALLOC_CTX *ctx, } } } - + /* 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, smbc_getNetbiosName(context), 0x0); 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 (smbc_getOptionUseKerberos(context)) { c->use_kerberos = True; } @@ -363,9 +363,9 @@ again: if (smbc_getOptionFallbackAfterKerberos(context)) { c->fallback_after_kerberos = True; } - + c->timeout = smbc_getTimeout(context); - + /* * Force use of port 139 for first try if share is $IPC, empty, or * null, so browse lists can work @@ -377,15 +377,15 @@ again: 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); @@ -393,20 +393,20 @@ again: 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 " @@ -415,9 +415,9 @@ again: errno = ETIMEDOUT; return NULL; } - + tried_reverse++; /* Yuck */ - + if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { make_nmb_name(&called, @@ -430,65 +430,65 @@ 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 (smbc_getOptionNoAutoAnonymousLogin(context) || !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) { /* 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) { cli_shutdown(c); errno = EPERM; @@ -497,25 +497,25 @@ again: } 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; @@ -531,19 +531,19 @@ again: } goto failed; } - + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); - + DLIST_ADD(context->internal->servers, srv); return srv; - + failed: cli_shutdown(c); if (!srv) { return NULL; } - + SAFE_FREE(srv); return NULL; } @@ -567,7 +567,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, 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 @@ -576,7 +576,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, 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. */ @@ -589,12 +589,12 @@ SMBC_attr_server(TALLOC_CTX *ctx, return NULL; } } - + flags = 0; if (smbc_getOptionUseKerberos(context)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } - + zero_addr(&ss); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, @@ -610,23 +610,23 @@ SMBC_attr_server(TALLOC_CTX *ctx, errno = ENOTSUP; return NULL; } - + if (context->internal->smb_encryption_level) { /* 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) { cli_shutdown(ipc_cli); errno = EPERM; @@ -635,17 +635,17 @@ SMBC_attr_server(TALLOC_CTX *ctx, } 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; - + nt_status = cli_rpc_pipe_open_noauth( ipc_srv->cli, &ndr_table_lsarpc.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(nt_status)) { @@ -655,28 +655,28 @@ SMBC_attr_server(TALLOC_CTX *ctx, 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 (smbc_getFunctionAddCachedServer(context)(context, ipc_srv, server, @@ -691,9 +691,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, free(ipc_srv); return NULL; } - + DLIST_ADD(context->internal->servers, ipc_srv); } - + return ipc_srv; } |