2 Unix SMB/Netbios implementation.
4 SMB client generic functions
5 Copyright (C) Andrew Tridgell 1994-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "rpc_parse.h"
29 static struct cli_connection **con_list = NULL;
30 static uint32 num_cons = 0;
32 struct user_creds *usr_creds = NULL;
33 vuser_key *user_key = NULL;
35 extern pstring global_myname;
37 * needed for the struct cli_connection
38 * none of these functions are implemented in HEAD currently
39 * rpc_client/cli_connect.c for details
41 * the 'typedef struct _cli_auth_fns cli_auth_fns;' is in
44 struct _cli_auth_fns {
46 /* these three will do for now. they *should* match with server-side */
47 BOOL (*create_bind_req) (struct cli_connection *, prs_struct *,
48 uint32, RPC_IFACE *, RPC_IFACE *);
49 BOOL (*decode_bind_resp) (struct cli_connection *, prs_struct *);
50 BOOL (*create_bind_cont) (struct cli_connection *, prs_struct *, uint32);
52 /* creates an authenticated PDU */
53 BOOL (*cli_create_pdu) (struct cli_connection *, uint8, prs_struct *,
54 int, int *, prs_struct *, uint8 *);
56 /* decodes an authenticated PDU */
57 BOOL (*cli_decode_pdu) (struct cli_connection *, prs_struct *, int, int);
61 cli_auth_fns cli_noauth_fns =
73 void init_connections(void)
81 static void free_con_array(uint32 num_entries,
82 struct cli_connection **entries)
84 void (*fn) (void *) = (void (*)(void *))&cli_connection_free;
85 free_void_array(num_entries, (void **)entries, *fn);
89 static struct cli_connection *add_con_to_array(uint32 * len,
90 struct cli_connection ***array,
91 struct cli_connection *con)
93 return (struct cli_connection *)add_item_to_array(len,
99 void free_connections(void)
101 DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
102 free_con_array(num_cons, con_list);
108 static struct cli_connection *cli_con_get(const char *srv_name,
111 void *auth_creds, BOOL reuse)
113 struct cli_connection *con = NULL;
114 BOOL is_new_connection = False;
116 struct ntuser_creds *ntc = NULL;
117 struct ncacn_np *pNcacn;
120 * initialization stuff
122 con = (struct cli_connection *)malloc(sizeof(*con));
127 memset(con, 0, sizeof(*con));
129 copy_user_creds(&con->usr_creds, NULL);
130 con->usr_creds.reuse = reuse;
132 if (srv_name != NULL)
134 con->srv_name = strdup(srv_name);
136 if (pipe_name != NULL)
138 con->pipe_name = strdup(pipe_name);
140 if (usr_creds != NULL)
142 ntc = &usr_creds->ntc;
145 /* fix me XXXX **WHAT** a hack. The cli_state* is malloc'd
146 deep within the call stack, so we can grab that pointer.
147 ncacn_np* is stored in an array which is currently handled
148 by underlying systems. --jerry */
149 pNcacn = ncacn_np_use_add(pipe_name, user_key, srv_name,
155 con->pCli_state = pNcacn->smb;
157 if (con->pCli_state == NULL)
160 con->pCli_state->key.pid = 0;
161 con->pCli_state->key.vuid = UID_FIELD_INVALID;
162 create_ntc_from_cli_state ( &usr, con->pCli_state );
163 copy_nt_creds(&con->usr_creds.ntc, &usr);
165 if (is_new_connection)
167 con->auth_info = NULL;
168 con->auth_creds = auth_creds;
176 con->auth = &cli_noauth_fns;
179 if (!rpc_pipe_bind(con->pCli_state, pipe_name, global_myname))
181 DEBUG(0, ("rpc_pipe_bind failed\n"));
182 cli_connection_free(con);
188 con->auth_info = cli_conn_get_auth_creds(con);
189 con->auth = cli_conn_get_authfns(con);
190 if (con->auth_info != NULL)
192 DEBUG(1,("cli_con_get: TODO: auth reuse\n"));
193 cli_connection_free(con);
198 con->auth = &cli_noauth_fns;
202 add_con_to_array(&num_cons, &con_list, con);
207 /****************************************************************************
208 terminate client connection
209 ****************************************************************************/
210 void cli_connection_free(struct cli_connection *con)
213 struct cli_state *oldcli = NULL;
216 DEBUG(10, ("cli_connection_free: %d\n", __LINE__));
218 if (con->pCli_state != NULL)
220 DEBUG(10, ("msrpc smb connection\n"));
221 ncacn_np_use_del(con->srv_name, con->pipe_name,
222 &con->pCli_state->key, False, &closed);
223 oldcli = con->pCli_state;
224 con->pCli_state = NULL;
227 DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed)));
231 for (i = 0; i < num_cons; i++)
233 struct cli_connection *c = con_list[i];
234 if (c != NULL && con != c && c->pCli_state == oldcli)
236 /* WHOOPS! fnum already open: too bad!!!
237 get rid of all other connections that
238 were using that connection
240 c->pCli_state = NULL;
245 /* don't free the cli_state since it is being handled
246 by the *clis list in rpc_client/cli_use.c.
247 This code needs to be fixed badly. It is **way**
248 to complicated. --jerry */
249 /* if (oldcli != NULL)
254 SAFE_FREE(con->srv_name);
255 SAFE_FREE(con->pipe_name);
256 SAFE_FREE(con->auth_info);
258 memset(&con->usr_creds, 0, sizeof(con->usr_creds));
260 for (i = 0; i < num_cons; i++)
262 if (con == con_list[i])
271 void cli_connection_unlink(struct cli_connection *con)
275 cli_connection_free(con);
280 /****************************************************************************
282 ****************************************************************************/
283 BOOL cli_connection_init(const char *srv_name, char *pipe_name,
284 struct cli_connection **con)
286 return cli_connection_init_auth(srv_name, pipe_name, con, NULL, NULL);
289 /****************************************************************************
291 ****************************************************************************/
292 BOOL cli_connection_init_auth(const char *srv_name, char *pipe_name,
293 struct cli_connection **con,
294 cli_auth_fns * auth, void *auth_creds)
302 DEBUG(10, ("cli_connection_init_auth: %s %s\n",
303 srv_name != NULL ? srv_name : "<null>", pipe_name));
305 *con = cli_con_get(srv_name, pipe_name, auth, auth_creds, reuse);
307 return (*con) != NULL;
310 /****************************************************************************
311 get auth functions associated with an msrpc session.
312 ****************************************************************************/
313 struct _cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con)
315 return con != NULL ? con->auth : NULL;
319 /****************************************************************************
320 get auth info associated with an msrpc session.
321 ****************************************************************************/
322 void *cli_conn_get_auth_creds(struct cli_connection *con)
324 return con != NULL ? con->auth_creds : NULL;
328 /****************************************************************************
329 send a request on an rpc pipe.
330 ****************************************************************************/
331 BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
332 prs_struct * data, prs_struct * rdata)
334 struct cli_connection *con = NULL;
336 /* we need this to locate the cli_connection associated
337 with the POLICY_HND */
338 if ((con=RpcHndList_get_connection(hnd)) == NULL)
341 if (!rpc_con_ok(con)) return False;
343 return rpc_con_pipe_req(con, op_num, data, rdata);
346 /****************************************************************************
347 send a request on an rpc pipe.
348 ****************************************************************************/
349 BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
350 prs_struct * data, prs_struct * rdata)
353 DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
354 op_num, data->data_offset, data->buffer_size));
355 prs_dump("in_rpcclient", (int)op_num, data);
357 /* Why does this use prs->data_offset? --jerry */
358 /* prs_realloc_data(data, data->data_offset); */
360 ret = rpc_api_pipe_req(con->pCli_state, op_num, data, rdata);
361 prs_dump("out_rpcclient", (int)op_num, rdata);
365 /****************************************************************************
366 this allows us to detect dead servers. The cli->fd is set to -1 when
368 *****************************************************************************/
369 BOOL rpc_con_ok(struct cli_connection *con)
374 if (!con->pCli_state)
376 if (con->pCli_state->fd == -1)