2
Unix SMB/Netbios implementation.
3
SMB client library implementation
4
Copyright (C) Andrew Tridgell 1998
5
Copyright (C) Richard Sharpe 2000, 2002
6
Copyright (C) John Terpstra 2000
7
Copyright (C) Tom Jansen (Ninja ISD) 2002
8
Copyright (C) Derrell Lipman 2003-2008
9
Copyright (C) Jeremy Allison 2007, 2008
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 3 of the License, or
14
(at your option) any later version.
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
GNU General Public License for more details.
21
You should have received a copy of the GNU General Public License
22
along with this program. If not, see <http://www.gnu.org/licenses/>.
26
#include "libsmbclient.h"
27
#include "libsmb_internal.h"
31
* Check a server for being alive and well.
32
* returns 0 if the server is in shape. Returns 1 on error
34
* Also useable outside libsmbclient to enable external cache
35
* to do some checks too.
38
SMBC_check_server(SMBCCTX * context,
45
return (getpeername(server->cli->fd, &addr, &size) == -1);
49
* Remove a server from the cached server list it's unused.
50
* On success, 0 is returned. 1 is returned if the server could not be removed.
52
* Also useable outside libsmbclient
55
SMBC_remove_unused_server(SMBCCTX * context,
60
/* are we being fooled ? */
61
if (!context || !context->internal->initialized || !srv) {
65
/* Check all open files/directories for a relation with this server */
66
for (file = context->internal->files; file; file = file->next) {
67
if (file->srv == srv) {
69
DEBUG(3, ("smbc_remove_usused_server: "
70
"%p still used by %p.\n",
76
DLIST_REMOVE(context->internal->servers, srv);
78
cli_shutdown(srv->cli);
81
DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
83
smbc_getFunctionRemoveCachedServer(context)(context, srv);
89
/****************************************************************
90
* Call the auth_fn with fixed size (fstring) buffers.
91
***************************************************************/
93
SMBC_call_auth_fn(TALLOC_CTX *ctx,
104
smbc_get_auth_data_with_context_fn auth_with_context_fn;
106
strlcpy(workgroup, *pp_workgroup, sizeof(workgroup));
107
strlcpy(username, *pp_username, sizeof(username));
108
strlcpy(password, *pp_password, sizeof(password));
110
/* See if there's an authentication with context function provided */
111
auth_with_context_fn = smbc_getFunctionAuthDataWithContext(context);
112
if (auth_with_context_fn)
114
(* auth_with_context_fn)(context,
116
workgroup, sizeof(workgroup),
117
username, sizeof(username),
118
password, sizeof(password));
122
smbc_getFunctionAuthData(context)(server, share,
123
workgroup, sizeof(workgroup),
124
username, sizeof(username),
125
password, sizeof(password));
128
TALLOC_FREE(*pp_workgroup);
129
TALLOC_FREE(*pp_username);
130
TALLOC_FREE(*pp_password);
132
*pp_workgroup = talloc_strdup(ctx, workgroup);
133
*pp_username = talloc_strdup(ctx, username);
134
*pp_password = talloc_strdup(ctx, password);
139
SMBC_get_auth_data(const char *server, const char *share,
140
char *workgroup_buf, int workgroup_buf_len,
141
char *username_buf, int username_buf_len,
142
char *password_buf, int password_buf_len)
144
/* Default function just uses provided data. Nothing to do. */
150
SMBC_find_server(TALLOC_CTX *ctx,
161
if (!pp_workgroup || !pp_username || !pp_password) {
167
srv = smbc_getFunctionGetCachedServer(context)(context,
172
if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] ||
173
!*pp_password || !(*pp_password)[0])) {
174
SMBC_call_auth_fn(ctx, context, server, share,
175
pp_workgroup, pp_username, pp_password);
178
* However, smbc_auth_fn may have picked up info relating to
179
* an existing connection, so try for an existing connection
183
goto check_server_cache;
188
if (smbc_getFunctionCheckServer(context)(context, srv)) {
190
* This server is no good anymore
191
* Try to remove it and check for more possible
192
* servers in the cache
194
if (smbc_getFunctionRemoveUnusedServer(context)(context,
197
* We could not remove the server completely,
198
* remove it from the cache so we will not get
199
* it again. It will be removed when the last
200
* file/dir is closed.
202
smbc_getFunctionRemoveCachedServer(context)(context,
207
* Maybe there are more cached connections to this
210
goto check_server_cache;
220
* Connect to a server, possibly on an existing connection
222
* Here, what we want to do is: If the server and username
223
* match an existing connection, reuse that, otherwise, establish a
226
* If we have to create a new connection, call the auth_fn to get the
227
* info we need, unless the username and password were passed in.
231
SMBC_server(TALLOC_CTX *ctx,
233
bool connect_if_not_found,
241
char *workgroup = NULL;
243
struct nmb_name called, calling;
244
const char *server_n = server;
245
struct sockaddr_storage ss;
246
int tried_reverse = 0;
249
int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0);
251
const char *username_used;
257
if (server[0] == 0) {
262
/* Look for a cached connection */
263
srv = SMBC_find_server(ctx, context, server, share,
264
pp_workgroup, pp_username, pp_password);
267
* If we found a connection and we're only allowed one share per
272
smbc_getOptionOneSharePerServer(context)) {
275
* ... then if there's no current connection to the share,
276
* connect to it. SMBC_find_server(), or rather the function
277
* pointed to by context->get_cached_srv_fn which
278
* was called by SMBC_find_server(), will have issued a tree
279
* disconnect if the requested share is not the same as the
280
* one that was already connected.
282
if (srv->cli->cnum == (uint16) -1) {
283
/* Ensure we have accurate auth info */
284
SMBC_call_auth_fn(ctx, context, server, share,
289
if (!*pp_workgroup || !*pp_username || !*pp_password) {
291
cli_shutdown(srv->cli);
293
smbc_getFunctionRemoveCachedServer(context)(context,
299
* We don't need to renegotiate encryption
300
* here as the encryption context is not per
304
status = cli_tcon_andx(srv->cli, share, "?????",
306
strlen(*pp_password)+1);
307
if (!NT_STATUS_IS_OK(status)) {
308
errno = map_errno_from_nt_status(status);
309
cli_shutdown(srv->cli);
311
smbc_getFunctionRemoveCachedServer(context)(context,
316
/* Determine if this share supports case sensitivity */
319
("IPC$ so ignore case sensitivity\n"));
320
} else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
321
DEBUG(4, ("Could not retrieve "
322
"case sensitivity flag: %s.\n",
326
* We can't determine the case sensitivity of
327
* the share. We have no choice but to use the
328
* user-specified case sensitivity setting.
330
if (smbc_getOptionCaseSensitive(context)) {
331
cli_set_case_sensitive(c, True);
333
cli_set_case_sensitive(c, False);
337
("Case sensitive: %s\n",
338
(fs_attrs & FILE_CASE_SENSITIVE_SEARCH
341
cli_set_case_sensitive(
343
(fs_attrs & FILE_CASE_SENSITIVE_SEARCH
349
* Regenerate the dev value since it's based on both
353
srv->dev = (dev_t)(str_checksum(server) ^
354
str_checksum(share));
359
/* If we have a connection... */
362
/* ... then we're done here. Give 'em what they came for. */
366
/* If we're not asked to connect when a connection doesn't exist... */
367
if (! connect_if_not_found) {
368
/* ... then we're done here. */
372
if (!*pp_workgroup || !*pp_username || !*pp_password) {
377
make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0);
378
make_nmb_name(&called , server, 0x20);
380
DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server));
382
DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
388
/* have to open a new connection */
389
if ((c = cli_initialise()) == NULL) {
394
if (smbc_getOptionUseKerberos(context)) {
395
c->use_kerberos = True;
398
if (smbc_getOptionFallbackAfterKerberos(context)) {
399
c->fallback_after_kerberos = True;
402
c->timeout = smbc_getTimeout(context);
405
* Force use of port 139 for first try if share is $IPC, empty, or
406
* null, so browse lists can work
408
if (share == NULL || *share == '\0' || is_ipc) {
409
port_try_first = 139;
412
port_try_first = 445;
416
c->port = port_try_first;
418
status = cli_connect(c, server_n, &ss);
419
if (!NT_STATUS_IS_OK(status)) {
421
/* First connection attempt failed. Try alternate port. */
422
c->port = port_try_next;
424
status = cli_connect(c, server_n, &ss);
425
if (!NT_STATUS_IS_OK(status)) {
432
if (!cli_session_request(c, &calling, &called)) {
434
if (strcmp(called.name, "*SMBSERVER")) {
435
make_nmb_name(&called , "*SMBSERVER", 0x20);
437
} else { /* Try one more time, but ensure we don't loop */
439
/* Only try this if server is an IP address ... */
441
if (is_ipaddress(server) && !tried_reverse) {
443
struct sockaddr_storage rem_ss;
445
if (!interpret_string_addr(&rem_ss, server,
447
DEBUG(4, ("Could not convert IP address "
448
"%s to struct sockaddr_storage\n",
454
tried_reverse++; /* Yuck */
456
if (name_status_find("*", 0, 0,
457
&rem_ss, remote_name)) {
458
make_nmb_name(&called,
469
DEBUG(4,(" session request ok\n"));
471
status = cli_negprot(c);
473
if (!NT_STATUS_IS_OK(status)) {
479
username_used = *pp_username;
481
if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
483
strlen(*pp_password),
485
strlen(*pp_password),
488
/* Failed. Try an anonymous login, if allowed by flags. */
491
if (smbc_getOptionNoAutoAnonymousLogin(context) ||
492
!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
503
status = cli_init_creds(c, username_used,
504
*pp_workgroup, *pp_password);
505
if (!NT_STATUS_IS_OK(status)) {
506
errno = map_errno_from_nt_status(status);
511
DEBUG(4,(" session setup ok\n"));
513
status = cli_tcon_andx(c, share, "?????", *pp_password,
514
strlen(*pp_password)+1);
515
if (!NT_STATUS_IS_OK(status)) {
516
errno = map_errno_from_nt_status(status);
521
DEBUG(4,(" tconx ok\n"));
523
/* Determine if this share supports case sensitivity */
525
DEBUG(4, ("IPC$ so ignore case sensitivity\n"));
526
} else if (!cli_get_fs_attr_info(c, &fs_attrs)) {
527
DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n",
531
* We can't determine the case sensitivity of the share. We
532
* have no choice but to use the user-specified case
533
* sensitivity setting.
535
if (smbc_getOptionCaseSensitive(context)) {
536
cli_set_case_sensitive(c, True);
538
cli_set_case_sensitive(c, False);
541
DEBUG(4, ("Case sensitive: %s\n",
542
(fs_attrs & FILE_CASE_SENSITIVE_SEARCH
545
cli_set_case_sensitive(c,
546
(fs_attrs & FILE_CASE_SENSITIVE_SEARCH
551
if (context->internal->smb_encryption_level) {
552
/* Attempt UNIX smb encryption. */
553
if (!NT_STATUS_IS_OK(cli_force_encryption(c,
559
* context->smb_encryption_level == 1
560
* means don't fail if encryption can't be negotiated,
561
* == 2 means fail if encryption can't be negotiated.
564
DEBUG(4,(" SMB encrypt failed\n"));
566
if (context->internal->smb_encryption_level == 2) {
572
DEBUG(4,(" SMB encrypt ok\n"));
576
* Ok, we have got a nice connection
577
* Let's allocate a server structure.
580
srv = SMB_MALLOC_P(SMBCSRV);
588
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
589
srv->no_pathinfo = False;
590
srv->no_pathinfo2 = False;
591
srv->no_nt_session = False;
593
/* now add it to the cache (internal or external) */
594
/* Let the cache function set errno if it wants to */
596
if (smbc_getFunctionAddCachedServer(context)(context, srv,
600
int saved_errno = errno;
601
DEBUG(3, (" Failed to add server to cache\n"));
609
DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
610
server, share, srv));
612
DLIST_ADD(context->internal->servers, srv);
614
if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
615
workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
617
workgroup = *pp_workgroup;
623
/* set the credentials to make DFS work */
624
smbc_set_credentials_with_fallback(context,
642
* Connect to a server for getting/setting attributes, possibly on an existing
643
* connection. This works similarly to SMBC_server().
646
SMBC_attr_server(TALLOC_CTX *ctx,
655
struct sockaddr_storage ss;
656
struct cli_state *ipc_cli;
657
struct rpc_pipe_client *pipe_hnd;
659
SMBCSRV *ipc_srv=NULL;
662
* See if we've already created this special connection. Reference
663
* our "special" share name '*IPC$', which is an impossible real share
664
* name due to the leading asterisk.
666
ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$",
667
pp_workgroup, pp_username, pp_password);
670
/* We didn't find a cached connection. Get the password */
671
if (!*pp_password || (*pp_password)[0] == '\0') {
672
/* ... then retrieve it now. */
673
SMBC_call_auth_fn(ctx, context, server, share,
677
if (!*pp_workgroup || !*pp_username || !*pp_password) {
684
if (smbc_getOptionUseKerberos(context)) {
685
flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
689
nt_status = cli_full_connection(&ipc_cli,
690
global_myname(), server,
691
&ss, 0, "IPC$", "?????",
697
if (! NT_STATUS_IS_OK(nt_status)) {
698
DEBUG(1,("cli_full_connection failed! (%s)\n",
699
nt_errstr(nt_status)));
704
if (context->internal->smb_encryption_level) {
705
/* Attempt UNIX smb encryption. */
706
if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
712
* context->smb_encryption_level ==
713
* 1 means don't fail if encryption can't be
714
* negotiated, == 2 means fail if encryption
715
* can't be negotiated.
718
DEBUG(4,(" SMB encrypt failed on IPC$\n"));
720
if (context->internal->smb_encryption_level == 2) {
721
cli_shutdown(ipc_cli);
726
DEBUG(4,(" SMB encrypt ok on IPC$\n"));
729
ipc_srv = SMB_MALLOC_P(SMBCSRV);
732
cli_shutdown(ipc_cli);
736
ZERO_STRUCTP(ipc_srv);
737
ipc_srv->cli = ipc_cli;
739
nt_status = cli_rpc_pipe_open_noauth(
740
ipc_srv->cli, &ndr_table_lsarpc.syntax_id, &pipe_hnd);
741
if (!NT_STATUS_IS_OK(nt_status)) {
742
DEBUG(1, ("cli_nt_session_open fail!\n"));
744
cli_shutdown(ipc_srv->cli);
750
* Some systems don't support
751
* SEC_FLAG_MAXIMUM_ALLOWED, but NT sends 0x2000000
752
* so we might as well do it too.
755
nt_status = rpccli_lsa_open_policy(
759
GENERIC_EXECUTE_ACCESS,
762
if (!NT_STATUS_IS_OK(nt_status)) {
763
errno = SMBC_errno(context, ipc_srv->cli);
764
cli_shutdown(ipc_srv->cli);
768
/* now add it to the cache (internal or external) */
770
errno = 0; /* let cache function set errno if it likes */
771
if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv,
776
DEBUG(3, (" Failed to add server to cache\n"));
780
cli_shutdown(ipc_srv->cli);
785
DLIST_ADD(context->internal->servers, ipc_srv);