s4-auth: Use kerberos util functions in srv_keytab
[Samba.git] / source3 / libsmb / libsmb_server.c
blob07d51ea00cb0e551711d6264b24c97b4ef090ad3
1 /*
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
10 Copyright (C) SATOH Fumiyasu <fumiyas@osstech.co.jp> 2009.
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "includes.h"
27 #include "libsmb/libsmb.h"
28 #include "libsmbclient.h"
29 #include "libsmb_internal.h"
30 #include "../librpc/gen_ndr/ndr_lsa.h"
31 #include "rpc_client/cli_pipe.h"
32 #include "rpc_client/cli_lsarpc.h"
33 #include "libcli/security/security.h"
34 #include "libsmb/nmblib.h"
35 #include "../libcli/smb/smbXcli_base.h"
38 * Check a server for being alive and well.
39 * returns 0 if the server is in shape. Returns 1 on error
41 * Also useable outside libsmbclient to enable external cache
42 * to do some checks too.
44 int
45 SMBC_check_server(SMBCCTX * context,
46 SMBCSRV * server)
48 time_t now;
50 if (!cli_state_is_connected(server->cli)) {
51 return 1;
54 now = time_mono(NULL);
56 if (server->last_echo_time == (time_t)0 ||
57 now > server->last_echo_time +
58 (server->cli->timeout/1000)) {
59 unsigned char data[16] = {0};
60 NTSTATUS status = cli_echo(server->cli,
62 data_blob_const(data, sizeof(data)));
63 if (!NT_STATUS_IS_OK(status)) {
64 return 1;
66 server->last_echo_time = now;
68 return 0;
72 * Remove a server from the cached server list it's unused.
73 * On success, 0 is returned. 1 is returned if the server could not be removed.
75 * Also useable outside libsmbclient
77 int
78 SMBC_remove_unused_server(SMBCCTX * context,
79 SMBCSRV * srv)
81 SMBCFILE * file;
83 /* are we being fooled ? */
84 if (!context || !context->internal->initialized || !srv) {
85 return 1;
88 /* Check all open files/directories for a relation with this server */
89 for (file = context->internal->files; file; file = file->next) {
90 if (file->srv == srv) {
91 /* Still used */
92 DEBUG(3, ("smbc_remove_usused_server: "
93 "%p still used by %p.\n",
94 srv, file));
95 return 1;
99 DLIST_REMOVE(context->internal->servers, srv);
101 cli_shutdown(srv->cli);
102 srv->cli = NULL;
104 DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
106 smbc_getFunctionRemoveCachedServer(context)(context, srv);
108 SAFE_FREE(srv);
109 return 0;
112 /****************************************************************
113 * Call the auth_fn with fixed size (fstring) buffers.
114 ***************************************************************/
115 static void
116 SMBC_call_auth_fn(TALLOC_CTX *ctx,
117 SMBCCTX *context,
118 const char *server,
119 const char *share,
120 char **pp_workgroup,
121 char **pp_username,
122 char **pp_password)
124 fstring workgroup;
125 fstring username;
126 fstring password;
127 smbc_get_auth_data_with_context_fn auth_with_context_fn;
129 strlcpy(workgroup, *pp_workgroup, sizeof(workgroup));
130 strlcpy(username, *pp_username, sizeof(username));
131 strlcpy(password, *pp_password, sizeof(password));
133 /* See if there's an authentication with context function provided */
134 auth_with_context_fn = smbc_getFunctionAuthDataWithContext(context);
135 if (auth_with_context_fn)
137 (* auth_with_context_fn)(context,
138 server, share,
139 workgroup, sizeof(workgroup),
140 username, sizeof(username),
141 password, sizeof(password));
143 else
145 smbc_getFunctionAuthData(context)(server, share,
146 workgroup, sizeof(workgroup),
147 username, sizeof(username),
148 password, sizeof(password));
151 TALLOC_FREE(*pp_workgroup);
152 TALLOC_FREE(*pp_username);
153 TALLOC_FREE(*pp_password);
155 *pp_workgroup = talloc_strdup(ctx, workgroup);
156 *pp_username = talloc_strdup(ctx, username);
157 *pp_password = talloc_strdup(ctx, password);
161 void
162 SMBC_get_auth_data(const char *server, const char *share,
163 char *workgroup_buf, int workgroup_buf_len,
164 char *username_buf, int username_buf_len,
165 char *password_buf, int password_buf_len)
167 /* Default function just uses provided data. Nothing to do. */
172 SMBCSRV *
173 SMBC_find_server(TALLOC_CTX *ctx,
174 SMBCCTX *context,
175 const char *server,
176 const char *share,
177 char **pp_workgroup,
178 char **pp_username,
179 char **pp_password)
181 SMBCSRV *srv;
182 int auth_called = 0;
184 if (!pp_workgroup || !pp_username || !pp_password) {
185 return NULL;
188 check_server_cache:
190 srv = smbc_getFunctionGetCachedServer(context)(context,
191 server, share,
192 *pp_workgroup,
193 *pp_username);
195 if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] ||
196 !*pp_password || !(*pp_password)[0])) {
197 SMBC_call_auth_fn(ctx, context, server, share,
198 pp_workgroup, pp_username, pp_password);
201 * However, smbc_auth_fn may have picked up info relating to
202 * an existing connection, so try for an existing connection
203 * again ...
205 auth_called = 1;
206 goto check_server_cache;
210 if (srv) {
211 if (smbc_getFunctionCheckServer(context)(context, srv)) {
213 * This server is no good anymore
214 * Try to remove it and check for more possible
215 * servers in the cache
217 if (smbc_getFunctionRemoveUnusedServer(context)(context,
218 srv)) {
220 * We could not remove the server completely,
221 * remove it from the cache so we will not get
222 * it again. It will be removed when the last
223 * file/dir is closed.
225 smbc_getFunctionRemoveCachedServer(context)(context,
226 srv);
230 * Maybe there are more cached connections to this
231 * server
233 goto check_server_cache;
236 return srv;
239 return NULL;
243 * Connect to a server, possibly on an existing connection
245 * Here, what we want to do is: If the server and username
246 * match an existing connection, reuse that, otherwise, establish a
247 * new connection.
249 * If we have to create a new connection, call the auth_fn to get the
250 * info we need, unless the username and password were passed in.
253 static SMBCSRV *
254 SMBC_server_internal(TALLOC_CTX *ctx,
255 SMBCCTX *context,
256 bool connect_if_not_found,
257 const char *server,
258 uint16_t port,
259 const char *share,
260 char **pp_workgroup,
261 char **pp_username,
262 char **pp_password,
263 bool *in_cache)
265 SMBCSRV *srv=NULL;
266 char *workgroup = NULL;
267 struct cli_state *c = NULL;
268 const char *server_n = server;
269 int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0);
270 uint32_t fs_attrs = 0;
271 const char *username_used;
272 NTSTATUS status;
273 char *newserver, *newshare;
274 int flags = 0;
275 struct smbXcli_tcon *tcon = NULL;
277 ZERO_STRUCT(c);
278 *in_cache = false;
280 if (server[0] == 0) {
281 errno = EPERM;
282 return NULL;
285 /* Look for a cached connection */
286 srv = SMBC_find_server(ctx, context, server, share,
287 pp_workgroup, pp_username, pp_password);
290 * If we found a connection and we're only allowed one share per
291 * server...
293 if (srv &&
294 share != NULL && *share != '\0' &&
295 smbc_getOptionOneSharePerServer(context)) {
298 * ... then if there's no current connection to the share,
299 * connect to it. SMBC_find_server(), or rather the function
300 * pointed to by context->get_cached_srv_fn which
301 * was called by SMBC_find_server(), will have issued a tree
302 * disconnect if the requested share is not the same as the
303 * one that was already connected.
307 * Use srv->cli->desthost and srv->cli->share instead of
308 * server and share below to connect to the actual share,
309 * i.e., a normal share or a referred share from
310 * 'msdfs proxy' share.
312 if (!cli_state_has_tcon(srv->cli)) {
313 /* Ensure we have accurate auth info */
314 SMBC_call_auth_fn(ctx, context,
315 smbXcli_conn_remote_name(srv->cli->conn),
316 srv->cli->share,
317 pp_workgroup,
318 pp_username,
319 pp_password);
321 if (!*pp_workgroup || !*pp_username || !*pp_password) {
322 errno = ENOMEM;
323 cli_shutdown(srv->cli);
324 srv->cli = NULL;
325 smbc_getFunctionRemoveCachedServer(context)(context,
326 srv);
327 return NULL;
331 * We don't need to renegotiate encryption
332 * here as the encryption context is not per
333 * tid.
336 status = cli_tree_connect(srv->cli,
337 srv->cli->share,
338 "?????",
339 *pp_password,
340 strlen(*pp_password)+1);
341 if (!NT_STATUS_IS_OK(status)) {
342 errno = map_errno_from_nt_status(status);
343 cli_shutdown(srv->cli);
344 srv->cli = NULL;
345 smbc_getFunctionRemoveCachedServer(context)(context,
346 srv);
347 srv = NULL;
350 /* Determine if this share supports case sensitivity */
351 if (is_ipc) {
352 DEBUG(4,
353 ("IPC$ so ignore case sensitivity\n"));
354 status = NT_STATUS_OK;
355 } else {
356 status = cli_get_fs_attr_info(c, &fs_attrs);
359 if (!NT_STATUS_IS_OK(status)) {
360 DEBUG(4, ("Could not retrieve "
361 "case sensitivity flag: %s.\n",
362 nt_errstr(status)));
365 * We can't determine the case sensitivity of
366 * the share. We have no choice but to use the
367 * user-specified case sensitivity setting.
369 if (smbc_getOptionCaseSensitive(context)) {
370 cli_set_case_sensitive(c, True);
371 } else {
372 cli_set_case_sensitive(c, False);
374 } else if (!is_ipc) {
375 DEBUG(4,
376 ("Case sensitive: %s\n",
377 (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
378 ? "True"
379 : "False")));
380 cli_set_case_sensitive(
382 (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
383 ? True
384 : False));
388 * Regenerate the dev value since it's based on both
389 * server and share
391 if (srv) {
392 const char *remote_name =
393 smbXcli_conn_remote_name(srv->cli->conn);
395 srv->dev = (dev_t)(str_checksum(remote_name) ^
396 str_checksum(srv->cli->share));
401 /* If we have a connection... */
402 if (srv) {
404 /* ... then we're done here. Give 'em what they came for. */
405 *in_cache = true;
406 goto done;
409 /* If we're not asked to connect when a connection doesn't exist... */
410 if (! connect_if_not_found) {
411 /* ... then we're done here. */
412 return NULL;
415 if (!*pp_workgroup || !*pp_username || !*pp_password) {
416 errno = ENOMEM;
417 return NULL;
420 DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server));
422 DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
424 status = NT_STATUS_UNSUCCESSFUL;
426 if (smbc_getOptionUseKerberos(context)) {
427 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
430 if (smbc_getOptionFallbackAfterKerberos(context)) {
431 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
434 if (smbc_getOptionUseCCache(context)) {
435 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
438 if (smbc_getOptionUseNTHash(context)) {
439 flags |= CLI_FULL_CONNECTION_USE_NT_HASH;
442 if (port == 0) {
443 if (share == NULL || *share == '\0' || is_ipc) {
445 * Try 139 first for IPC$
447 status = cli_connect_nb(server_n, NULL, NBT_SMB_PORT, 0x20,
448 smbc_getNetbiosName(context),
449 SMB_SIGNING_DEFAULT, flags, &c);
453 if (!NT_STATUS_IS_OK(status)) {
455 * No IPC$ or 139 did not work
457 status = cli_connect_nb(server_n, NULL, port, 0x20,
458 smbc_getNetbiosName(context),
459 SMB_SIGNING_DEFAULT, flags, &c);
462 if (!NT_STATUS_IS_OK(status)) {
463 errno = map_errno_from_nt_status(status);
464 return NULL;
467 cli_set_timeout(c, smbc_getTimeout(context));
469 status = smbXcli_negprot(c->conn, c->timeout,
470 lp_client_min_protocol(),
471 lp_client_max_protocol());
472 if (!NT_STATUS_IS_OK(status)) {
473 cli_shutdown(c);
474 errno = ETIMEDOUT;
475 return NULL;
478 if (smbXcli_conn_protocol(c->conn) >= PROTOCOL_SMB2_02) {
479 /* Ensure we ask for some initial credits. */
480 smb2cli_conn_set_max_credits(c->conn, DEFAULT_SMB2_MAX_CREDITS);
483 username_used = *pp_username;
485 if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
486 *pp_password,
487 strlen(*pp_password),
488 *pp_password,
489 strlen(*pp_password),
490 *pp_workgroup))) {
492 /* Failed. Try an anonymous login, if allowed by flags. */
493 username_used = "";
495 if (smbc_getOptionNoAutoAnonymousLogin(context) ||
496 !NT_STATUS_IS_OK(cli_session_setup(c, username_used,
497 *pp_password, 1,
498 *pp_password, 0,
499 *pp_workgroup))) {
501 cli_shutdown(c);
502 errno = EPERM;
503 return NULL;
507 DEBUG(4,(" session setup ok\n"));
509 /* here's the fun part....to support 'msdfs proxy' shares
510 (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL
511 here before trying to connect to the original share.
512 cli_check_msdfs_proxy() will fail if it is a normal share. */
514 if (smbXcli_conn_dfs_supported(c->conn) &&
515 cli_check_msdfs_proxy(ctx, c, share,
516 &newserver, &newshare,
517 /* FIXME: cli_check_msdfs_proxy() does
518 not support smbc_smb_encrypt_level type */
519 context->internal->smb_encryption_level ?
520 true : false,
521 *pp_username,
522 *pp_password,
523 *pp_workgroup)) {
524 cli_shutdown(c);
525 srv = SMBC_server_internal(ctx, context, connect_if_not_found,
526 newserver, port, newshare, pp_workgroup,
527 pp_username, pp_password, in_cache);
528 TALLOC_FREE(newserver);
529 TALLOC_FREE(newshare);
530 return srv;
533 /* must be a normal share */
535 status = cli_tree_connect(c, share, "?????", *pp_password,
536 strlen(*pp_password)+1);
537 if (!NT_STATUS_IS_OK(status)) {
538 errno = map_errno_from_nt_status(status);
539 cli_shutdown(c);
540 return NULL;
543 DEBUG(4,(" tconx ok\n"));
545 if (smbXcli_conn_protocol(c->conn) >= PROTOCOL_SMB2_02) {
546 tcon = c->smb2.tcon;
547 } else {
548 tcon = c->smb1.tcon;
551 /* Determine if this share supports case sensitivity */
552 if (is_ipc) {
553 DEBUG(4, ("IPC$ so ignore case sensitivity\n"));
554 status = NT_STATUS_OK;
555 } else {
556 status = cli_get_fs_attr_info(c, &fs_attrs);
559 if (!NT_STATUS_IS_OK(status)) {
560 DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n",
561 nt_errstr(status)));
564 * We can't determine the case sensitivity of the share. We
565 * have no choice but to use the user-specified case
566 * sensitivity setting.
568 if (smbc_getOptionCaseSensitive(context)) {
569 cli_set_case_sensitive(c, True);
570 } else {
571 cli_set_case_sensitive(c, False);
573 } else if (!is_ipc) {
574 DEBUG(4, ("Case sensitive: %s\n",
575 (fs_attrs & FILE_CASE_SENSITIVE_SEARCH
576 ? "True"
577 : "False")));
578 smbXcli_tcon_set_fs_attributes(tcon, fs_attrs);
581 if (context->internal->smb_encryption_level) {
582 /* Attempt UNIX smb encryption. */
583 if (!NT_STATUS_IS_OK(cli_force_encryption(c,
584 username_used,
585 *pp_password,
586 *pp_workgroup))) {
589 * context->smb_encryption_level == 1
590 * means don't fail if encryption can't be negotiated,
591 * == 2 means fail if encryption can't be negotiated.
594 DEBUG(4,(" SMB encrypt failed\n"));
596 if (context->internal->smb_encryption_level == 2) {
597 cli_shutdown(c);
598 errno = EPERM;
599 return NULL;
602 DEBUG(4,(" SMB encrypt ok\n"));
606 * Ok, we have got a nice connection
607 * Let's allocate a server structure.
610 srv = SMB_MALLOC_P(SMBCSRV);
611 if (!srv) {
612 cli_shutdown(c);
613 errno = ENOMEM;
614 return NULL;
617 ZERO_STRUCTP(srv);
618 srv->cli = c;
619 srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
620 srv->no_pathinfo = False;
621 srv->no_pathinfo2 = False;
622 srv->no_pathinfo3 = False;
623 srv->no_nt_session = False;
625 done:
626 if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
627 workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
628 } else {
629 workgroup = *pp_workgroup;
631 if(!workgroup) {
632 if (c != NULL) {
633 cli_shutdown(c);
635 SAFE_FREE(srv);
636 return NULL;
639 /* set the credentials to make DFS work */
640 smbc_set_credentials_with_fallback(context,
641 workgroup,
642 *pp_username,
643 *pp_password);
645 return srv;
648 SMBCSRV *
649 SMBC_server(TALLOC_CTX *ctx,
650 SMBCCTX *context,
651 bool connect_if_not_found,
652 const char *server,
653 uint16_t port,
654 const char *share,
655 char **pp_workgroup,
656 char **pp_username,
657 char **pp_password)
659 SMBCSRV *srv=NULL;
660 bool in_cache = false;
662 srv = SMBC_server_internal(ctx, context, connect_if_not_found,
663 server, port, share, pp_workgroup,
664 pp_username, pp_password, &in_cache);
666 if (!srv) {
667 return NULL;
669 if (in_cache) {
670 return srv;
673 /* Now add it to the cache (internal or external) */
674 /* Let the cache function set errno if it wants to */
675 errno = 0;
676 if (smbc_getFunctionAddCachedServer(context)(context, srv,
677 server, share,
678 *pp_workgroup,
679 *pp_username)) {
680 int saved_errno = errno;
681 DEBUG(3, (" Failed to add server to cache\n"));
682 errno = saved_errno;
683 if (errno == 0) {
684 errno = ENOMEM;
686 SAFE_FREE(srv);
687 return NULL;
690 DEBUG(2, ("Server connect ok: //%s/%s: %p\n",
691 server, share, srv));
693 DLIST_ADD(context->internal->servers, srv);
694 return srv;
698 * Connect to a server for getting/setting attributes, possibly on an existing
699 * connection. This works similarly to SMBC_server().
701 SMBCSRV *
702 SMBC_attr_server(TALLOC_CTX *ctx,
703 SMBCCTX *context,
704 const char *server,
705 uint16_t port,
706 const char *share,
707 char **pp_workgroup,
708 char **pp_username,
709 char **pp_password)
711 int flags;
712 struct cli_state *ipc_cli = NULL;
713 struct rpc_pipe_client *pipe_hnd = NULL;
714 NTSTATUS nt_status;
715 SMBCSRV *srv=NULL;
716 SMBCSRV *ipc_srv=NULL;
719 * Use srv->cli->desthost and srv->cli->share instead of
720 * server and share below to connect to the actual share,
721 * i.e., a normal share or a referred share from
722 * 'msdfs proxy' share.
724 srv = SMBC_server(ctx, context, true, server, port, share,
725 pp_workgroup, pp_username, pp_password);
726 if (!srv) {
727 return NULL;
729 server = smbXcli_conn_remote_name(srv->cli->conn);
730 share = srv->cli->share;
733 * See if we've already created this special connection. Reference
734 * our "special" share name '*IPC$', which is an impossible real share
735 * name due to the leading asterisk.
737 ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$",
738 pp_workgroup, pp_username, pp_password);
739 if (!ipc_srv) {
741 /* We didn't find a cached connection. Get the password */
742 if (!*pp_password || (*pp_password)[0] == '\0') {
743 /* ... then retrieve it now. */
744 SMBC_call_auth_fn(ctx, context, server, share,
745 pp_workgroup,
746 pp_username,
747 pp_password);
748 if (!*pp_workgroup || !*pp_username || !*pp_password) {
749 errno = ENOMEM;
750 return NULL;
754 flags = 0;
755 if (smbc_getOptionUseKerberos(context)) {
756 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
758 if (smbc_getOptionUseCCache(context)) {
759 flags |= CLI_FULL_CONNECTION_USE_CCACHE;
762 nt_status = cli_full_connection(&ipc_cli,
763 lp_netbios_name(), server,
764 NULL, 0, "IPC$", "?????",
765 *pp_username,
766 *pp_workgroup,
767 *pp_password,
768 flags,
769 SMB_SIGNING_DEFAULT);
770 if (! NT_STATUS_IS_OK(nt_status)) {
771 DEBUG(1,("cli_full_connection failed! (%s)\n",
772 nt_errstr(nt_status)));
773 errno = ENOTSUP;
774 return NULL;
777 if (context->internal->smb_encryption_level) {
778 /* Attempt UNIX smb encryption. */
779 if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
780 *pp_username,
781 *pp_password,
782 *pp_workgroup))) {
785 * context->smb_encryption_level ==
786 * 1 means don't fail if encryption can't be
787 * negotiated, == 2 means fail if encryption
788 * can't be negotiated.
791 DEBUG(4,(" SMB encrypt failed on IPC$\n"));
793 if (context->internal->smb_encryption_level == 2) {
794 cli_shutdown(ipc_cli);
795 errno = EPERM;
796 return NULL;
799 DEBUG(4,(" SMB encrypt ok on IPC$\n"));
802 ipc_srv = SMB_MALLOC_P(SMBCSRV);
803 if (!ipc_srv) {
804 errno = ENOMEM;
805 cli_shutdown(ipc_cli);
806 return NULL;
809 ZERO_STRUCTP(ipc_srv);
810 ipc_srv->cli = ipc_cli;
812 nt_status = cli_rpc_pipe_open_noauth(
813 ipc_srv->cli, &ndr_table_lsarpc, &pipe_hnd);
814 if (!NT_STATUS_IS_OK(nt_status)) {
815 DEBUG(1, ("cli_nt_session_open fail!\n"));
816 errno = ENOTSUP;
817 cli_shutdown(ipc_srv->cli);
818 free(ipc_srv);
819 return NULL;
823 * Some systems don't support
824 * SEC_FLAG_MAXIMUM_ALLOWED, but NT sends 0x2000000
825 * so we might as well do it too.
828 nt_status = rpccli_lsa_open_policy(
829 pipe_hnd,
830 talloc_tos(),
831 True,
832 GENERIC_EXECUTE_ACCESS,
833 &ipc_srv->pol);
835 if (!NT_STATUS_IS_OK(nt_status)) {
836 errno = SMBC_errno(context, ipc_srv->cli);
837 cli_shutdown(ipc_srv->cli);
838 free(ipc_srv);
839 return NULL;
842 /* now add it to the cache (internal or external) */
844 errno = 0; /* let cache function set errno if it likes */
845 if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv,
846 server,
847 "*IPC$",
848 *pp_workgroup,
849 *pp_username)) {
850 DEBUG(3, (" Failed to add server to cache\n"));
851 if (errno == 0) {
852 errno = ENOMEM;
854 cli_shutdown(ipc_srv->cli);
855 free(ipc_srv);
856 return NULL;
859 DLIST_ADD(context->internal->servers, ipc_srv);
862 return ipc_srv;