few cleanups to bring in line with 2.2
[Samba/gbeck.git] / source / rpc_client / cli_connect.c
blobed0112238368c99aec7cc7594803441db6eb6a5c
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
23 #define NO_SYSLOG
25 #include "includes.h"
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 int DEBUGLEVEL;
36 extern pstring global_myname;
38 * needed for the struct cli_connection
39 * none of these functions are implemented in HEAD currently
40 * rpc_client/cli_connect.c for details
42 * the 'typedef struct _cli_auth_fns cli_auth_fns;' is in
43 * rpc_misc.h
45 struct _cli_auth_fns {
47 /* these three will do for now. they *should* match with server-side */
48 BOOL (*create_bind_req) (struct cli_connection *, prs_struct *,
49 uint32, RPC_IFACE *, RPC_IFACE *);
50 BOOL (*decode_bind_resp) (struct cli_connection *, prs_struct *);
51 BOOL (*create_bind_cont) (struct cli_connection *, prs_struct *, uint32);
53 /* creates an authenticated PDU */
54 BOOL (*cli_create_pdu) (struct cli_connection *, uint8, prs_struct *,
55 int, int *, prs_struct *, uint8 *);
57 /* decodes an authenticated PDU */
58 BOOL (*cli_decode_pdu) (struct cli_connection *, prs_struct *, int, int);
62 cli_auth_fns cli_noauth_fns =
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 NULL
74 void init_connections(void)
76 con_list = NULL;
77 num_cons = 0;
79 init_cli_use();
82 static void free_con_array(uint32 num_entries,
83 struct cli_connection **entries)
85 void (*fn) (void *) = (void (*)(void *))&cli_connection_free;
86 free_void_array(num_entries, (void **)entries, *fn);
90 static struct cli_connection *add_con_to_array(uint32 * len,
91 struct cli_connection ***array,
92 struct cli_connection *con)
94 return (struct cli_connection *)add_item_to_array(len,
95 (void ***)array,
96 (void *)con);
100 void free_connections(void)
102 DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
103 free_con_array(num_cons, con_list);
104 free_cli_use();
106 init_connections();
109 static struct cli_connection *cli_con_get(const char *srv_name,
110 char *pipe_name,
111 cli_auth_fns * auth,
112 void *auth_creds, BOOL reuse)
114 struct cli_connection *con = NULL;
115 BOOL is_new_connection = False;
116 CREDS_NT usr;
117 struct ntuser_creds *ntc = NULL;
118 struct ncacn_np *pNcacn;
121 * initialization stuff
123 con = (struct cli_connection *)malloc(sizeof(*con));
124 if (con == NULL)
126 return NULL;
128 memset(con, 0, sizeof(*con));
130 copy_user_creds(&con->usr_creds, NULL);
131 con->usr_creds.reuse = reuse;
133 if (srv_name != NULL)
135 con->srv_name = strdup(srv_name);
137 if (pipe_name != NULL)
139 con->pipe_name = strdup(pipe_name);
141 if (usr_creds != NULL)
143 ntc = &usr_creds->ntc;
146 /* fix me XXXX **WHAT** a hack. The cli_state* is malloc'd
147 deep within the call stack, so we can grab that pointer.
148 ncacn_np* is stored in an array which is currently handled
149 by underlying systems. --jerry */
150 pNcacn = ncacn_np_use_add(pipe_name, user_key, srv_name,
151 ntc, reuse,
152 &is_new_connection);
153 if (pNcacn == NULL)
154 return NULL;
156 con->pCli_state = pNcacn->smb;
158 if (con->pCli_state == NULL)
159 return NULL;
161 con->pCli_state->key.pid = 0;
162 con->pCli_state->key.vuid = UID_FIELD_INVALID;
163 create_ntc_from_cli_state ( &usr, con->pCli_state );
164 copy_nt_creds(&con->usr_creds.ntc, &usr);
166 if (is_new_connection)
168 con->auth_info = NULL;
169 con->auth_creds = auth_creds;
171 if (auth != NULL)
173 con->auth = auth;
175 else
177 con->auth = &cli_noauth_fns;
180 if (!rpc_pipe_bind(con->pCli_state, pipe_name, global_myname))
182 DEBUG(0, ("rpc_pipe_bind failed\n"));
183 cli_connection_free(con);
184 return NULL;
187 else
189 con->auth_info = cli_conn_get_auth_creds(con);
190 con->auth = cli_conn_get_authfns(con);
191 if (con->auth_info != NULL)
193 DEBUG(1,("cli_con_get: TODO: auth reuse\n"));
194 cli_connection_free(con);
195 return NULL;
197 else
199 con->auth = &cli_noauth_fns;
203 add_con_to_array(&num_cons, &con_list, con);
204 return con;
208 /****************************************************************************
209 terminate client connection
210 ****************************************************************************/
211 void cli_connection_free(struct cli_connection *con)
213 BOOL closed = False;
214 struct cli_state *oldcli = NULL;
215 int i;
217 DEBUG(10, ("cli_connection_free: %d\n", __LINE__));
219 if (con->pCli_state != NULL)
221 DEBUG(10, ("msrpc smb connection\n"));
222 ncacn_np_use_del(con->srv_name, con->pipe_name,
223 &con->pCli_state->key, False, &closed);
224 oldcli = con->pCli_state;
225 con->pCli_state = NULL;
228 DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed)));
230 if (closed)
232 for (i = 0; i < num_cons; i++)
234 struct cli_connection *c = con_list[i];
235 if (c != NULL && con != c && c->pCli_state == oldcli)
237 /* WHOOPS! fnum already open: too bad!!!
238 get rid of all other connections that
239 were using that connection
241 c->pCli_state = NULL;
246 /* don't free the cli_state since it is being handled
247 by the *clis list in rpc_client/cli_use.c.
248 This code needs to be fixed badly. It is **way**
249 to complicated. --jerry */
250 /* if (oldcli != NULL)
252 free(oldcli);
253 } */
255 if (con->srv_name != NULL)
257 free(con->srv_name);
258 con->srv_name = NULL;
260 if (con->pipe_name != NULL)
262 free(con->pipe_name);
263 con->pipe_name = NULL;
266 if (con->auth_info != NULL)
268 free(con->auth_info);
269 con->auth_info = NULL;
272 memset(&con->usr_creds, 0, sizeof(con->usr_creds));
274 for (i = 0; i < num_cons; i++)
276 if (con == con_list[i])
278 con_list[i] = NULL;
282 free(con);
285 void cli_connection_unlink(struct cli_connection *con)
287 if (con != NULL)
289 cli_connection_free(con);
291 return;
294 /****************************************************************************
295 init client state
296 ****************************************************************************/
297 BOOL cli_connection_init(const char *srv_name, char *pipe_name,
298 struct cli_connection **con)
300 return cli_connection_init_auth(srv_name, pipe_name, con, NULL, NULL);
303 /****************************************************************************
304 init client state
305 ****************************************************************************/
306 BOOL cli_connection_init_auth(const char *srv_name, char *pipe_name,
307 struct cli_connection **con,
308 cli_auth_fns * auth, void *auth_creds)
310 BOOL reuse = True;
313 * allocate
316 DEBUG(10, ("cli_connection_init_auth: %s %s\n",
317 srv_name != NULL ? srv_name : "<null>", pipe_name));
319 *con = cli_con_get(srv_name, pipe_name, auth, auth_creds, reuse);
321 return (*con) != NULL;
324 /****************************************************************************
325 get auth functions associated with an msrpc session.
326 ****************************************************************************/
327 struct _cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con)
329 return con != NULL ? con->auth : NULL;
333 /****************************************************************************
334 get auth info associated with an msrpc session.
335 ****************************************************************************/
336 void *cli_conn_get_auth_creds(struct cli_connection *con)
338 return con != NULL ? con->auth_creds : NULL;
342 /****************************************************************************
343 send a request on an rpc pipe.
344 ****************************************************************************/
345 BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
346 prs_struct * data, prs_struct * rdata)
348 struct cli_connection *con = NULL;
350 /* we need this to locate the cli_connection associated
351 with the POLICY_HND */
352 if ((con=RpcHndList_get_connection(hnd)) == NULL)
353 return False;
355 if (!rpc_con_ok(con)) return False;
357 return rpc_con_pipe_req(con, op_num, data, rdata);
360 /****************************************************************************
361 send a request on an rpc pipe.
362 ****************************************************************************/
363 BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
364 prs_struct * data, prs_struct * rdata)
366 BOOL ret;
367 DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
368 op_num, data->data_offset, data->buffer_size));
369 prs_dump("in_rpcclient", (int)op_num, data);
371 /* Why does this use prs->data_offset? --jerry */
372 /* prs_realloc_data(data, data->data_offset); */
374 ret = rpc_api_pipe_req(con->pCli_state, op_num, data, rdata);
375 prs_dump("out_rpcclient", (int)op_num, rdata);
376 return ret;
379 /****************************************************************************
380 this allows us to detect dead servers. The cli->fd is set to -1 when
381 we get an error
382 *****************************************************************************/
383 BOOL rpc_con_ok(struct cli_connection *con)
385 if (!con)
386 return False;
388 if (!con->pCli_state)
389 return False;
390 if (con->pCli_state->fd == -1)
391 return False;
393 return True;