/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- libnetapi_open_ipc_connection
- libnetapi_shutdown_cm
- pipe_cm_find
- pipe_cm_connect
- pipe_cm_open
- libnetapi_open_pipe
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi Support
4 * Copyright (C) Guenther Deschner 2008
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20 #include "includes.h"
21
22 #include "lib/netapi/netapi.h"
23 #include "lib/netapi/netapi_private.h"
24
25 /********************************************************************
26 ********************************************************************/
27
28 static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
/* [<][>][^][v][top][bottom][index][help] */
29 const char *server_name,
30 struct cli_state **cli)
31 {
32 struct user_auth_info *auth_info = NULL;
33 struct cli_state *cli_ipc = NULL;
34
35 if (!ctx || !cli || !server_name) {
36 return WERR_INVALID_PARAM;
37 }
38
39 auth_info = user_auth_info_init(NULL);
40 if (!auth_info) {
41 return WERR_NOMEM;
42 }
43 auth_info->signing_state = Undefined;
44 set_cmdline_auth_info_use_kerberos(auth_info, ctx->use_kerberos);
45 set_cmdline_auth_info_username(auth_info, ctx->username);
46 if (ctx->password) {
47 set_cmdline_auth_info_password(auth_info, ctx->password);
48 } else {
49 set_cmdline_auth_info_getpass(auth_info);
50 }
51
52 if (ctx->username && ctx->username[0] &&
53 ctx->password && ctx->password[0] &&
54 ctx->use_kerberos) {
55 set_cmdline_auth_info_fallback_after_kerberos(auth_info, true);
56 }
57
58 cli_ipc = cli_cm_open(ctx, NULL,
59 server_name, "IPC$",
60 auth_info,
61 false, false,
62 PROTOCOL_NT1,
63 0, 0x20);
64 if (cli_ipc) {
65 cli_set_username(cli_ipc, ctx->username);
66 cli_set_password(cli_ipc, ctx->password);
67 cli_set_domain(cli_ipc, ctx->workgroup);
68 }
69 TALLOC_FREE(auth_info);
70
71 if (!cli_ipc) {
72 libnetapi_set_error_string(ctx,
73 "Failed to connect to IPC$ share on %s", server_name);
74 return WERR_CAN_NOT_COMPLETE;
75 }
76
77 *cli = cli_ipc;
78
79 return WERR_OK;
80 }
81
82 /********************************************************************
83 ********************************************************************/
84
85 struct client_pipe_connection {
86 struct client_pipe_connection *prev, *next;
87 struct rpc_pipe_client *pipe;
88 struct cli_state *cli;
89 };
90
91 static struct client_pipe_connection *pipe_connections;
92
93 /********************************************************************
94 ********************************************************************/
95
96 WERROR libnetapi_shutdown_cm(struct libnetapi_ctx *ctx)
/* [<][>][^][v][top][bottom][index][help] */
97 {
98 struct client_pipe_connection *p;
99
100 for (p = pipe_connections; p; p = p->next) {
101 cli_shutdown(p->cli);
102 }
103
104 return WERR_OK;
105 }
106
107 /********************************************************************
108 ********************************************************************/
109
110 static NTSTATUS pipe_cm_find(struct cli_state *cli,
/* [<][>][^][v][top][bottom][index][help] */
111 const struct ndr_syntax_id *interface,
112 struct rpc_pipe_client **presult)
113 {
114 struct client_pipe_connection *p;
115
116 for (p = pipe_connections; p; p = p->next) {
117
118 if (!rpc_pipe_np_smb_conn(p->pipe)) {
119 return NT_STATUS_PIPE_EMPTY;
120 }
121
122 if (strequal(cli->desthost, p->pipe->desthost)
123 && ndr_syntax_id_equal(&p->pipe->abstract_syntax,
124 interface)) {
125 *presult = p->pipe;
126 return NT_STATUS_OK;
127 }
128 }
129
130 return NT_STATUS_PIPE_NOT_AVAILABLE;
131 }
132
133 /********************************************************************
134 ********************************************************************/
135
136 static NTSTATUS pipe_cm_connect(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
137 struct cli_state *cli,
138 const struct ndr_syntax_id *interface,
139 struct rpc_pipe_client **presult)
140 {
141 struct client_pipe_connection *p;
142 NTSTATUS status;
143
144 p = TALLOC_ZERO_ARRAY(mem_ctx, struct client_pipe_connection, 1);
145 if (!p) {
146 return NT_STATUS_NO_MEMORY;
147 }
148
149 status = cli_rpc_pipe_open_noauth(cli, interface, &p->pipe);
150 if (!NT_STATUS_IS_OK(status)) {
151 TALLOC_FREE(p);
152 return status;
153 }
154
155 p->cli = cli;
156 DLIST_ADD(pipe_connections, p);
157
158 *presult = p->pipe;
159 return NT_STATUS_OK;
160 }
161
162 /********************************************************************
163 ********************************************************************/
164
165 static NTSTATUS pipe_cm_open(TALLOC_CTX *ctx,
/* [<][>][^][v][top][bottom][index][help] */
166 struct cli_state *cli,
167 const struct ndr_syntax_id *interface,
168 struct rpc_pipe_client **presult)
169 {
170 if (NT_STATUS_IS_OK(pipe_cm_find(cli, interface, presult))) {
171 return NT_STATUS_OK;
172 }
173
174 return pipe_cm_connect(ctx, cli, interface, presult);
175 }
176
177 /********************************************************************
178 ********************************************************************/
179
180 WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx,
/* [<][>][^][v][top][bottom][index][help] */
181 const char *server_name,
182 const struct ndr_syntax_id *interface,
183 struct rpc_pipe_client **presult)
184 {
185 struct rpc_pipe_client *result = NULL;
186 NTSTATUS status;
187 WERROR werr;
188 struct cli_state *cli = NULL;
189
190 if (!presult) {
191 return WERR_INVALID_PARAM;
192 }
193
194 werr = libnetapi_open_ipc_connection(ctx, server_name, &cli);
195 if (!W_ERROR_IS_OK(werr)) {
196 return werr;
197 }
198
199 status = pipe_cm_open(ctx, cli, interface, &result);
200 if (!NT_STATUS_IS_OK(status)) {
201 libnetapi_set_error_string(ctx, "failed to open PIPE %s: %s",
202 get_pipe_name_from_iface(interface),
203 get_friendly_nt_error_msg(status));
204 return WERR_DEST_NOT_FOUND;
205 }
206
207 *presult = result;
208
209 return WERR_OK;
210 }