final part of "first" phase converting over to msrpc daemon architecture.
[kai/samba-autobuild/.git] / source3 / rpc_client / cli_connect.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    SMB client generic functions
5    Copyright (C) Andrew Tridgell 1994-1999
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1999
7    
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.
12    
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.
17    
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.
21 */
22
23 #define NO_SYSLOG
24
25 #include "includes.h"
26
27 struct ntuser_creds *usr_creds = NULL;
28
29 extern int DEBUGLEVEL;
30 extern pstring scope;
31 extern pstring global_myname;
32
33 struct cli_connection
34 {
35         uint32 num_connections;
36         char *srv_name;
37         char *pipe_name;
38         struct ntuser_creds usr_creds;
39         struct cli_state *cli;
40         uint16 fnum;
41 };
42
43 static struct cli_connection **con_list = NULL;
44 uint32 num_cons = 0;
45
46 void init_connections(void)
47 {
48         con_list = NULL;
49         num_cons = 0;
50
51         init_cli_use();
52 }
53
54 static void free_con_array(uint32 num_entries, struct cli_connection **entries)
55 {
56         void(*fn)(void*) = (void(*)(void*))&cli_connection_free;
57         free_void_array(num_entries, (void**)entries, *fn);
58 }
59
60 static struct cli_connection* add_con_to_array(uint32 *len,
61                                 struct cli_connection ***array,
62                                 struct cli_connection *con)
63 {
64         return (struct cli_connection*)add_item_to_array(len,
65                              (void***)array, (void*)con);
66                                 
67 }
68 void free_connections(void)
69 {
70         free_con_array(num_cons, con_list);
71         free_cli_use();
72
73         init_connections();
74 }
75
76 static struct cli_connection *cli_con_get(const char* srv_name,
77                                 const char* pipe_name, BOOL reuse)
78 {
79         struct cli_connection *con = NULL;
80
81         con = (struct cli_connection*)malloc(sizeof(*con));
82
83         if (con == NULL)
84         {
85                 return NULL;
86         }
87
88         memset(con, 0, sizeof(*con));
89
90         if (srv_name != NULL)
91         {
92                 con->srv_name = strdup(srv_name);
93         }
94         if (pipe_name != NULL)
95         {
96                 con->pipe_name = strdup(pipe_name);
97         }
98
99         con->cli = cli_net_use_add(srv_name, usr_creds, True, reuse);
100
101         if (con->cli == NULL)
102         {
103                 cli_connection_free(con);
104                 return NULL;
105         }
106         add_con_to_array(&num_cons, &con_list, con);
107         return con;
108 }
109
110 /****************************************************************************
111 terminate client connection
112 ****************************************************************************/
113 void cli_connection_free(struct cli_connection *con)
114 {
115         BOOL closed;
116         int i;
117
118         if (con->cli != NULL)
119         {
120                 cli_nt_session_close(con->cli, con->fnum);
121                 cli_net_use_del(con->srv_name, &con->usr_creds, False, &closed);
122         }
123
124         if (closed)
125         {
126                 for (i = 0; i < num_cons; i++)
127                 {
128                         if (con_list[i] != NULL &&
129                             con != con_list[i] &&
130                             con_list[i]->cli == con->cli)
131                         {
132                                 /* WHOOPS! fnum already open: too bad!!! */
133                                 con_list[i]->cli = NULL;
134                                 con_list[i]->fnum = 0xffff;
135                         }
136                 }
137         }
138
139         con->cli = NULL;
140
141         if (con->srv_name != NULL)
142         {
143                 free(con->srv_name);
144                 con->srv_name = NULL;
145         }
146         if (con->pipe_name != NULL)
147         {
148                 free(con->pipe_name);
149                 con->pipe_name = NULL;
150         }
151
152         memset(&con->usr_creds, 0, sizeof(con->usr_creds));
153
154         for (i = 0; i < num_cons; i++)
155         {
156                 if (con == con_list[i])
157                 {
158                         con_list[i] = NULL;
159                 }
160         }
161
162         free(con);
163 }
164
165 /****************************************************************************
166 terminate client state
167 ****************************************************************************/
168 void cli_connection_unlink(struct cli_connection *con)
169 {
170         if (con != NULL)
171         {
172                 cli_connection_free(con);
173         }
174         return;
175 }
176
177 /****************************************************************************
178 init client state
179 ****************************************************************************/
180 BOOL cli_connection_init(const char* srv_name, const char* pipe_name,
181                                 struct cli_connection **con)
182 {
183         BOOL res = True;
184         BOOL reuse = False;
185
186         /*
187          * allocate
188          */
189
190         *con = cli_con_get(srv_name, pipe_name, reuse);
191
192         if ((*con) == NULL)
193         {
194                 return False;
195         }
196
197         res = res ? cli_nt_session_open((*con)->cli, pipe_name,
198                                        &(*con)->fnum) : False;
199
200         return res;
201 }
202
203 /****************************************************************************
204 obtain client state
205 ****************************************************************************/
206 BOOL cli_connection_getsrv(const char* srv_name, const char* pipe_name,
207                                 struct cli_connection **con)
208 {
209         int i;
210         if (con_list == NULL || num_cons == 0)
211         {
212                 return False;
213         }
214
215         for (i = 0; i < num_cons; i++)
216         {
217                 if (con_list[i] != NULL &&
218                     strequal(con_list[i]->srv_name , srv_name ) &&
219                     strequal(con_list[i]->pipe_name, pipe_name))
220                 {
221                         (*con) = con_list[i];
222                         return True;
223                 }
224         }
225         return False;
226 }
227
228 /****************************************************************************
229 obtain client state
230 ****************************************************************************/
231 BOOL cli_connection_get(const POLICY_HND *pol, struct cli_connection **con)
232 {
233         return get_policy_con(pol, con);
234 }
235
236 /****************************************************************************
237 link a child policy handle to a parent one
238 ****************************************************************************/
239 BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from)
240 {
241         struct cli_connection *con = NULL;
242
243         if (!cli_connection_get(from, &con))
244         {
245                 return False;
246         }
247
248         return register_policy_hnd(to) && set_policy_con(to, con, NULL);
249 }
250
251 /****************************************************************************
252 get a user session key associated with a connection associated with a
253 policy handle.
254 ****************************************************************************/
255 BOOL cli_get_con_usr_sesskey(struct cli_connection *con, uchar usr_sess_key[16])
256 {
257         if (con == NULL)
258         {
259                 return False;
260         }
261         memcpy(usr_sess_key, con->cli->usr.pwd.sess_key, 16);
262
263         return True;
264 }
265
266 /****************************************************************************
267 get a user session key associated with a connection associated with a
268 policy handle.
269 ****************************************************************************/
270 BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16])
271 {
272         if (con == NULL)
273         {
274                 return False;
275         }
276         memcpy(sess_key, con->cli->sess_key, sizeof(con->cli->sess_key));
277
278         return True;
279 }
280
281 /****************************************************************************
282 get a user session key associated with a connection associated with a
283 policy handle.
284 ****************************************************************************/
285 BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name)
286 {
287         if (con == NULL)
288         {
289                 return False;
290         }
291
292         if (strnequal("\\\\", con->cli->desthost, 2))
293         {
294                 fstrcpy(srv_name, con->cli->desthost);
295         }
296         else
297         {
298                 fstrcpy(srv_name, "\\\\");
299                 fstrcat(srv_name, con->cli->desthost);
300         }
301         
302         return True;
303 }
304
305 /****************************************************************************
306 get a user session key associated with a connection associated with a
307 policy handle.
308 ****************************************************************************/
309 BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar usr_sess_key[16])
310 {
311         struct cli_connection *con = NULL;
312
313         if (!cli_connection_get(pol, &con))
314         {
315                 return False;
316         }
317
318         return cli_get_con_usr_sesskey(con, usr_sess_key);
319 }
320
321 /****************************************************************************
322 get a user session key associated with a connection associated with a
323 policy handle.
324 ****************************************************************************/
325 BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16])
326 {
327         struct cli_connection *con = NULL;
328
329         if (!cli_connection_get(pol, &con))
330         {
331                 return False;
332         }
333
334         return cli_get_con_sesskey(con, sess_key);
335 }
336
337 /****************************************************************************
338 get a user session key associated with a connection associated with a
339 policy handle.
340 ****************************************************************************/
341 BOOL cli_get_sesskey_srv(const char* srv_name, uchar sess_key[16])
342 {
343         struct cli_connection *con = NULL;
344
345         if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
346         {
347                 return False;
348         }
349
350         return cli_get_con_sesskey(con, sess_key);
351 }
352
353 /****************************************************************************
354 get a user session key associated with a connection associated with a
355 policy handle.
356 ****************************************************************************/
357 void cli_con_gen_next_creds(struct cli_connection *con,
358                                 DOM_CRED *new_clnt_cred)
359 {
360         gen_next_creds(con->cli, new_clnt_cred);
361 }
362
363 /****************************************************************************
364 get a user session key associated with a connection associated with a
365 policy handle.
366 ****************************************************************************/
367 void cli_con_get_cli_cred(struct cli_connection *con,
368                                 DOM_CRED *clnt_cred)
369 {
370         memcpy(clnt_cred, &con->cli->clnt_cred, sizeof(*clnt_cred));
371 }
372
373 /****************************************************************************
374 get a user session key associated with a connection associated with a
375 policy handle.
376 ****************************************************************************/
377 BOOL cli_con_deal_with_creds(struct cli_connection *con,
378                                 DOM_CRED *rcv_srv_cred)
379 {
380         return clnt_deal_with_creds(con->cli->sess_key, &con->cli->clnt_cred,
381                                 rcv_srv_cred);
382 }
383
384 /****************************************************************************
385 get a user session key associated with a connection associated with a
386 policy handle.
387 ****************************************************************************/
388 BOOL cli_con_set_creds(const char* srv_name, const uchar sess_key[16],
389                                 DOM_CRED *cred)
390 {
391         struct cli_connection *con = NULL;
392
393         if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
394         {
395                 return False;
396         }
397
398         memcpy(con->cli->sess_key, sess_key, 16);
399         memcpy(&con->cli->clnt_cred, cred, sizeof(*cred));
400
401         return True;
402 }
403
404 /****************************************************************************
405  send a request on an rpc pipe.
406  ****************************************************************************/
407 BOOL rpc_hnd_pipe_req(const POLICY_HND *hnd, uint8 op_num,
408                       prs_struct *data, prs_struct *rdata)
409 {
410         struct cli_connection *con = NULL;
411
412         if (!cli_connection_get(hnd, &con))
413         {
414                 return False;
415         }
416
417         return rpc_con_pipe_req(con, op_num, data, rdata);
418 }
419
420 /****************************************************************************
421  send a request on an rpc pipe.
422  ****************************************************************************/
423 BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
424                       prs_struct *data, prs_struct *rdata)
425 {
426         return rpc_api_pipe_req(con->cli, con->fnum, op_num, data, rdata);
427 }