2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "popt_common.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/netapi_private.h"
26 /********************************************************************
27 ********************************************************************/
29 static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
30 const char *server_name,
31 struct cli_state **cli)
33 struct user_auth_info *auth_info = NULL;
34 struct cli_state *cli_ipc = NULL;
36 if (!ctx || !cli || !server_name) {
37 return WERR_INVALID_PARAM;
40 auth_info = user_auth_info_init(NULL);
44 auth_info->signing_state = Undefined;
45 set_cmdline_auth_info_use_kerberos(auth_info, ctx->use_kerberos);
46 set_cmdline_auth_info_username(auth_info, ctx->username);
48 set_cmdline_auth_info_password(auth_info, ctx->password);
50 set_cmdline_auth_info_getpass(auth_info);
53 if (ctx->username && ctx->username[0] &&
54 ctx->password && ctx->password[0] &&
56 set_cmdline_auth_info_fallback_after_kerberos(auth_info, true);
59 if (ctx->use_ccache) {
60 set_cmdline_auth_info_use_ccache(auth_info, true);
63 cli_ipc = cli_cm_open(ctx, NULL,
70 cli_set_username(cli_ipc, ctx->username);
71 cli_set_password(cli_ipc, ctx->password);
72 cli_set_domain(cli_ipc, ctx->workgroup);
74 TALLOC_FREE(auth_info);
77 libnetapi_set_error_string(ctx,
78 "Failed to connect to IPC$ share on %s", server_name);
79 return WERR_CAN_NOT_COMPLETE;
87 /********************************************************************
88 ********************************************************************/
90 struct client_pipe_connection {
91 struct client_pipe_connection *prev, *next;
92 struct rpc_pipe_client *pipe;
93 struct cli_state *cli;
96 static struct client_pipe_connection *pipe_connections;
98 /********************************************************************
99 ********************************************************************/
101 WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx)
103 struct client_pipe_connection *p;
105 for (p = pipe_connections; p; p = p->next) {
106 cli_shutdown(p->cli);
112 /********************************************************************
113 ********************************************************************/
115 static NTSTATUS pipe_cm_find(struct cli_state *cli,
116 const struct ndr_syntax_id *interface,
117 struct rpc_pipe_client **presult)
119 struct client_pipe_connection *p;
121 for (p = pipe_connections; p; p = p->next) {
123 if (!rpc_pipe_np_smb_conn(p->pipe)) {
124 return NT_STATUS_PIPE_EMPTY;
127 if (strequal(cli->desthost, p->pipe->desthost)
128 && ndr_syntax_id_equal(&p->pipe->abstract_syntax,
135 return NT_STATUS_PIPE_NOT_AVAILABLE;
138 /********************************************************************
139 ********************************************************************/
141 static NTSTATUS pipe_cm_connect(TALLOC_CTX *mem_ctx,
142 struct cli_state *cli,
143 const struct ndr_syntax_id *interface,
144 struct rpc_pipe_client **presult)
146 struct client_pipe_connection *p;
149 p = TALLOC_ZERO_ARRAY(mem_ctx, struct client_pipe_connection, 1);
151 return NT_STATUS_NO_MEMORY;
154 status = cli_rpc_pipe_open_noauth(cli, interface, &p->pipe);
155 if (!NT_STATUS_IS_OK(status)) {
161 DLIST_ADD(pipe_connections, p);
167 /********************************************************************
168 ********************************************************************/
170 static NTSTATUS pipe_cm_open(TALLOC_CTX *ctx,
171 struct cli_state *cli,
172 const struct ndr_syntax_id *interface,
173 struct rpc_pipe_client **presult)
175 if (NT_STATUS_IS_OK(pipe_cm_find(cli, interface, presult))) {
179 return pipe_cm_connect(ctx, cli, interface, presult);
182 /********************************************************************
183 ********************************************************************/
185 WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx,
186 const char *server_name,
187 const struct ndr_syntax_id *interface,
188 struct rpc_pipe_client **presult)
190 struct rpc_pipe_client *result = NULL;
193 struct cli_state *cli = NULL;
196 return WERR_INVALID_PARAM;
199 werr = libnetapi_open_ipc_connection(ctx, server_name, &cli);
200 if (!W_ERROR_IS_OK(werr)) {
204 status = pipe_cm_open(ctx, cli, interface, &result);
205 if (!NT_STATUS_IS_OK(status)) {
206 libnetapi_set_error_string(ctx, "failed to open PIPE %s: %s",
207 get_pipe_name_from_syntax(talloc_tos(), interface),
208 get_friendly_nt_error_msg(status));
209 return WERR_DEST_NOT_FOUND;