fix for CR-636. Kill connection to NETLOGON cli_connection
[Samba.git] / source / rpc_client / cli_connect.c
blob2714a59397a5c11a85b8e46dea4a56e568ea394c
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"
27 #include "rpc_client.h"
29 struct user_creds *usr_creds = NULL;
30 vuser_key *user_key = NULL;
32 extern int DEBUGLEVEL;
34 enum
35 { MSRPC_NONE, MSRPC_LOCAL, MSRPC_SMB };
37 struct cli_connection
39 char *srv_name;
40 char *pipe_name;
41 struct user_creds usr_creds;
43 int type;
45 union
47 struct ncacn_np *smb;
48 struct msrpc_local *local;
49 void *cli;
51 msrpc;
53 cli_auth_fns *auth;
54 void *auth_info;
55 void *auth_creds;
58 static struct cli_connection **con_list = NULL;
59 static uint32 num_cons = 0;
61 void init_connections(void)
63 con_list = NULL;
64 num_cons = 0;
66 init_cli_use();
69 static void free_con_array(uint32 num_entries,
70 struct cli_connection **entries)
72 void (*fn) (void *) = (void (*)(void *))&cli_connection_free;
73 free_void_array(num_entries, (void **)entries, *fn);
76 static struct cli_connection *add_con_to_array(uint32 *len,
77 struct cli_connection ***array,
78 struct cli_connection *con)
80 return (struct cli_connection *)add_item_to_array(len,
81 (void ***)array,
82 (void *)con);
85 void free_connections(void)
87 DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
88 free_con_array(num_cons, con_list);
89 free_cli_use();
91 init_connections();
94 static struct cli_connection *cli_con_get(const char *srv_name,
95 const char *pipe_name,
96 cli_auth_fns * auth,
97 void *auth_creds, BOOL reuse)
99 struct cli_connection *con = NULL;
100 BOOL is_new_connection = False;
102 vuser_key key;
104 con = (struct cli_connection *)malloc(sizeof(*con));
106 if (con == NULL)
108 return NULL;
111 memset(con, 0, sizeof(*con));
112 con->type = MSRPC_NONE;
114 copy_user_creds(&con->usr_creds, NULL);
115 con->usr_creds.reuse = reuse;
117 if (srv_name != NULL)
119 con->srv_name = strdup(srv_name);
121 if (pipe_name != NULL)
123 con->pipe_name = strdup(pipe_name);
126 if (strequal(srv_name, "\\\\."))
128 con->type = MSRPC_LOCAL;
129 become_root(False);
130 con->msrpc.local = ncalrpc_l_use_add(pipe_name, user_key,
131 reuse,
132 &is_new_connection);
134 * XXX - this rebinds on the same pipe,
135 * only necessary, when the loopback connection
136 * was first iniated as a forward
138 is_new_connection = True;
139 unbecome_root(False);
141 else
143 struct ntuser_creds *ntc = NULL;
144 if (usr_creds != NULL)
146 ntc = &usr_creds->ntc;
148 con->type = MSRPC_SMB;
149 con->msrpc.smb =
150 ncacn_np_use_add(pipe_name, user_key, srv_name,
151 ntc, reuse,
152 &is_new_connection);
154 if (con->msrpc.smb == NULL)
156 cli_connection_free(con);
157 return NULL;
160 key = con->msrpc.smb->smb->nt.key;
161 con->msrpc.smb->smb->nt.key.pid = 0;
162 con->msrpc.smb->smb->nt.key.vuid = UID_FIELD_INVALID;
163 copy_nt_creds(&con->usr_creds.ntc,
164 &con->msrpc.smb->smb->usr);
167 if (con->msrpc.cli != NULL)
169 if (is_new_connection)
171 RPC_IFACE abstract;
172 RPC_IFACE transfer;
174 con->auth_info = NULL;
175 con->auth_creds = auth_creds;
177 if (auth != NULL)
179 con->auth = auth;
181 else
183 extern cli_auth_fns cli_noauth_fns;
184 con->auth = &cli_noauth_fns;
187 if (!rpc_pipe_bind(con, pipe_name, &abstract,
188 &transfer))
190 DEBUG(0, ("rpc_pipe_bind failed\n"));
191 cli_connection_free(con);
192 return NULL;
195 else
197 con->auth_info = cli_conn_get_auth_creds(con);
198 con->auth = cli_conn_get_authfns(con);
199 if (con->auth_info != NULL)
201 DEBUG(1, ("cli_con_get: TODO: auth reuse\n"));
202 cli_connection_free(con);
203 return NULL;
205 else
207 extern cli_auth_fns cli_noauth_fns;
208 con->auth = &cli_noauth_fns;
213 if (con->msrpc.cli == NULL)
215 cli_connection_free(con);
216 return NULL;
219 if (con->type == MSRPC_SMB)
221 con->msrpc.smb->smb->nt.key = key;
223 add_con_to_array(&num_cons, &con_list, con);
224 return con;
227 /****************************************************************************
228 terminate client connection
229 ****************************************************************************/
230 void cli_connection_free(struct cli_connection *con)
232 BOOL closed = False;
233 int i;
235 DEBUG(10, ("cli_connection_free: %d\n", __LINE__));
237 if (con->msrpc.cli != NULL)
239 switch (con->type)
241 case MSRPC_LOCAL:
243 DEBUG(10, ("msrpc local connection\n"));
244 ncalrpc_l_use_del(con->pipe_name,
245 &con->msrpc.local->nt.key,
246 False, &closed);
247 con->msrpc.local = NULL;
248 break;
250 case MSRPC_SMB:
252 DEBUG(10, ("msrpc smb connection\n"));
253 ncacn_np_use_del(con->srv_name,
254 con->pipe_name,
255 &con->msrpc.smb->smb->nt.key,
256 False, &closed);
257 con->msrpc.smb = NULL;
258 break;
263 DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed)));
265 if (con->msrpc.cli != NULL)
267 free(con->msrpc.cli);
269 con->msrpc.cli = NULL;
271 if (con->srv_name != NULL)
273 free(con->srv_name);
274 con->srv_name = NULL;
276 if (con->pipe_name != NULL)
278 free(con->pipe_name);
279 con->pipe_name = NULL;
282 if (con->auth_info != NULL)
284 free(con->auth_info);
285 con->auth_info = NULL;
288 memset(&con->usr_creds, 0, sizeof(con->usr_creds));
290 for (i = 0; i < num_cons; i++)
292 if (con == con_list[i])
294 con_list[i] = NULL;
298 free(con);
301 /****************************************************************************
302 terminate client state
303 ****************************************************************************/
304 void cli_connection_unlink(struct cli_connection *con)
306 if (con != NULL)
308 cli_connection_free(con);
310 return;
313 /****************************************************************************
314 init client state
315 ****************************************************************************/
316 BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
317 struct cli_connection **con)
319 return cli_connection_init_auth(srv_name, pipe_name, con, NULL, NULL);
322 /****************************************************************************
323 init client state
324 ****************************************************************************/
325 BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
326 struct cli_connection **con,
327 cli_auth_fns * auth, void *auth_creds)
329 BOOL reuse = True;
332 * allocate
335 DEBUG(10, ("cli_connection_init_auth: %s %s\n",
336 srv_name != NULL ? srv_name : "<null>", pipe_name));
338 *con = cli_con_get(srv_name, pipe_name, auth, auth_creds, reuse);
340 return (*con) != NULL;
343 /****************************************************************************
344 obtain client state
345 ****************************************************************************/
346 BOOL cli_connection_getsrv(const char *srv_name, const char *pipe_name,
347 struct cli_connection **con)
349 int i;
350 struct cli_connection *auth_con = NULL;
352 if (con_list == NULL || num_cons == 0)
354 return False;
357 (*con) = NULL;
359 for (i = 0; i < num_cons; i++)
361 if (con_list[i] != NULL &&
362 strequal(con_list[i]->srv_name, srv_name) &&
363 strequal(con_list[i]->pipe_name, pipe_name))
365 extern cli_auth_fns cli_noauth_fns;
366 (*con) = con_list[i];
367 /* authenticated connections take priority. HACK! */
368 if ((*con)->auth != &cli_noauth_fns)
370 auth_con = (*con);
373 /* Check for an invalid fd */
375 if (((*con)->type == MSRPC_SMB)
376 && (*con)->msrpc.smb
377 && (*con)->msrpc.smb->smb
378 && (*con)->msrpc.smb->smb->fd == -1)
380 /* remove this connection and force us to reestablish */
381 DEBUG(2,("cli_connection_getsrv: fd == -1 ! Closing cli_connection to [%s:%s]!\n",
382 (*con)->srv_name, (*con)->pipe_name));
383 con_list[i] = NULL;
384 cli_connection_free(*con);
385 *con = NULL;
387 return False;
392 if (auth_con != NULL)
394 (*con) = auth_con;
397 return (*con) != NULL;
400 /****************************************************************************
401 obtain client state
402 ****************************************************************************/
403 BOOL cli_connection_get(const POLICY_HND *pol, struct cli_connection **con)
405 return get_policy_con(get_global_hnd_cache(), pol, con);
408 /****************************************************************************
409 link a child policy handle to a parent one
410 ****************************************************************************/
411 BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from)
413 struct cli_connection *con = NULL;
415 if (!cli_connection_get(from, &con))
417 DEBUG(0, ("cli_pol_link: no connection\n"));
418 return False;
421 /* fix this when access masks are actually working! */
422 DEBUG(10, ("cli_pol_link: lkclXXXX - MAXIMUM_ALLOWED access_mask\n"));
424 return dup_policy_hnd(get_global_hnd_cache(), to, from) &&
425 set_policy_con(get_global_hnd_cache(), to, con, NULL);
428 /****************************************************************************
429 set a user session key associated with a connection
430 ****************************************************************************/
431 BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar usr_sess_key[16])
433 struct ntdom_info *nt;
434 struct cli_connection *con;
435 if (!cli_connection_get(pol, &con))
437 return False;
439 if (con == NULL)
441 DEBUG(0, ("cli_get_usr_sesskey: no connection\n"));
442 return False;
444 nt = cli_conn_get_ntinfo(con);
445 if (nt == NULL)
447 DEBUG(0, ("cli_get_usr_sesskey: no ntdom_info\n"));
448 return False;
451 memcpy(usr_sess_key, nt->usr_sess_key, sizeof(nt->usr_sess_key));
453 return True;
456 /****************************************************************************
457 set a user session key associated with a connection
458 ****************************************************************************/
459 BOOL cli_set_con_usr_sesskey(struct cli_connection *con,
460 const uchar usr_sess_key[16])
462 struct ntdom_info *nt;
463 if (con == NULL)
465 return False;
467 nt = cli_conn_get_ntinfo(con);
468 if (nt != NULL)
470 memcpy(nt->usr_sess_key, usr_sess_key,
471 sizeof(nt->usr_sess_key));
475 return True;
478 /****************************************************************************
479 get auth functions associated with an msrpc session.
480 ****************************************************************************/
481 const vuser_key *cli_con_sec_ctx(struct cli_connection *con)
483 struct ntdom_info *nt;
484 if (con == NULL)
486 return False;
488 nt = cli_conn_get_ntinfo(con);
489 if (nt != NULL && nt->key.vuid != UID_FIELD_INVALID)
491 return &nt->key;
493 return NULL;
496 /****************************************************************************
497 get auth functions associated with an msrpc session.
498 ****************************************************************************/
499 struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con)
501 return con != NULL ? con->auth : NULL;
504 /****************************************************************************
505 get auth info associated with an msrpc session.
506 ****************************************************************************/
507 void *cli_conn_get_auth_creds(struct cli_connection *con)
509 return con != NULL ? con->auth_creds : NULL;
512 /****************************************************************************
513 get auth info associated with an msrpc session.
514 ****************************************************************************/
515 void *cli_conn_get_auth_info(struct cli_connection *con)
517 return con != NULL ? con->auth_info : NULL;
520 /****************************************************************************
521 set auth info associated with an msrpc session.
522 ****************************************************************************/
523 BOOL cli_conn_set_auth_info(struct cli_connection *con, void *auth_info)
525 con->auth_info = auth_info;
526 return auth_info != NULL;
529 /****************************************************************************
530 get nt creds (HACK ALERT!) associated with an msrpc session.
531 ****************************************************************************/
532 struct ntdom_info *cli_conn_get_ntinfo(struct cli_connection *con)
534 if (con == NULL)
536 return NULL;
538 if (con->msrpc.cli == NULL)
540 DEBUG(1, ("cli_conn_get_ntinfo: NULL msrpc (closed)\n"));
541 return NULL;
544 switch (con->type)
546 case MSRPC_LOCAL:
548 return &con->msrpc.local->nt;
550 case MSRPC_SMB:
552 return &con->msrpc.smb->smb->nt;
555 return NULL;
558 /****************************************************************************
559 get a user session key associated with a connection associated with a
560 policy handle.
561 ****************************************************************************/
562 BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16])
564 struct ntdom_info *nt;
565 if (con == NULL)
567 return False;
569 nt = cli_conn_get_ntinfo(con);
570 memcpy(sess_key, nt->sess_key, sizeof(nt->sess_key));
572 dump_data_pw("sess_key:", sess_key, 16);
574 return True;
577 /****************************************************************************
578 get a server name associated with a connection associated with a
579 policy handle.
580 ****************************************************************************/
581 BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name)
583 const char *desthost = NULL;
585 if (con == NULL)
587 return False;
590 switch (con->type)
592 case MSRPC_SMB:
594 desthost = con->msrpc.smb->smb->desthost;
595 break;
597 case MSRPC_LOCAL:
599 desthost = con->srv_name;
600 break;
604 if (strnequal("\\\\", desthost, 2))
606 fstrcpy(srv_name, desthost);
608 else
610 fstrcpy(srv_name, "\\\\");
611 fstrcat(srv_name, desthost);
614 return True;
617 /****************************************************************************
618 get a user session key associated with a connection associated with a
619 policy handle.
620 ****************************************************************************/
621 BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16])
623 struct cli_connection *con = NULL;
625 if (!cli_connection_get(pol, &con))
627 return False;
630 return cli_get_con_sesskey(con, sess_key);
633 /****************************************************************************
634 get a user session key associated with a connection associated with a
635 policy handle.
636 ****************************************************************************/
637 BOOL cli_get_sesskey_srv(const char *srv_name, uchar sess_key[16])
639 struct cli_connection *con = NULL;
641 if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
643 return False;
646 return cli_get_con_sesskey(con, sess_key);
649 /****************************************************************************
650 get a user session key associated with a connection associated with a
651 policy handle.
652 ****************************************************************************/
653 void cli_con_gen_next_creds(struct cli_connection *con,
654 DOM_CRED * new_clnt_cred)
656 struct ntdom_info *nt = cli_conn_get_ntinfo(con);
657 gen_next_creds(nt, new_clnt_cred);
660 /****************************************************************************
661 get a user session key associated with a connection associated with a
662 policy handle.
663 ****************************************************************************/
664 void cli_con_get_cli_cred(struct cli_connection *con, DOM_CRED * clnt_cred)
666 struct ntdom_info *nt = cli_conn_get_ntinfo(con);
667 memcpy(clnt_cred, &nt->clnt_cred, sizeof(*clnt_cred));
670 /****************************************************************************
671 get a user session key associated with a connection associated with a
672 policy handle.
673 ****************************************************************************/
674 BOOL cli_con_deal_with_creds(struct cli_connection *con,
675 DOM_CRED * rcv_srv_cred)
677 struct ntdom_info *nt = cli_conn_get_ntinfo(con);
678 return clnt_deal_with_creds(nt->sess_key, &nt->clnt_cred,
679 rcv_srv_cred);
682 /****************************************************************************
683 get a user session key associated with a connection associated with a
684 policy handle.
685 ****************************************************************************/
686 BOOL cli_con_set_creds(const char *srv_name, const uchar sess_key[16],
687 DOM_CRED * cred)
689 struct cli_connection *con = NULL;
690 struct ntdom_info *nt;
692 if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
694 return False;
697 nt = cli_conn_get_ntinfo(con);
699 memcpy(nt->sess_key, sess_key, 16);
700 memcpy(&nt->clnt_cred, cred, sizeof(*cred));
702 return True;
705 /****************************************************************************
706 send a request on an rpc pipe.
707 ****************************************************************************/
708 BOOL rpc_hnd_ok(const POLICY_HND *hnd)
710 struct cli_connection *con = NULL;
712 return cli_connection_get(hnd, &con) && rpc_con_ok(con);
715 /****************************************************************************
716 send a request on an rpc pipe.
717 ****************************************************************************/
718 BOOL rpc_hnd_pipe_req(const POLICY_HND *hnd, uint8 op_num,
719 prs_struct *data, prs_struct *rdata)
721 struct cli_connection *con = NULL;
723 if (!cli_connection_get(hnd, &con))
725 return False;
728 if (!rpc_con_ok(con))
729 return False;
731 return rpc_con_pipe_req(con, op_num, data, rdata);
734 /****************************************************************************
735 send a request on an rpc pipe.
736 ****************************************************************************/
737 BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
738 prs_struct *data, prs_struct *rdata)
740 BOOL ret;
741 DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
742 op_num, prs_offset(data), prs_data_size(data)));
743 prs_dump("in_rpcclient", (int)op_num, data);
744 prs_realloc_data(data, data->offset);
745 ret = rpc_api_pipe_req(con, op_num, data, rdata);
746 prs_dump("out_rpcclient", (int)op_num, rdata);
747 return ret;
750 /****************************************************************************
751 write a full PDU to a pipe
752 ****************************************************************************/
753 BOOL rpc_api_write(struct cli_connection *con, prs_struct *data)
755 switch (con->type)
757 case MSRPC_SMB:
759 struct cli_state *cli = con->msrpc.smb->smb;
760 int fnum = con->msrpc.smb->fnum;
761 return cli_write(cli, fnum, 0x0008,
762 data->data, 0,
763 prs_data_size(data),
764 prs_data_size(data)) > 0;
766 case MSRPC_LOCAL:
768 data->offset = prs_data_size(data);
769 prs_link(NULL, data, NULL);
770 return msrpc_send(con->msrpc.local->fd, data);
773 return False;
776 /****************************************************************************
777 read a full PDU from a pipe
778 ****************************************************************************/
779 BOOL rpc_api_rcv_pdu(struct cli_connection *con, prs_struct *rdata)
781 switch (con->type)
783 case MSRPC_SMB:
785 struct cli_state *cli = con->msrpc.smb->smb;
786 int fnum = con->msrpc.smb->fnum;
787 return cli_rcv_pdu(con, cli, fnum, rdata);
789 case MSRPC_LOCAL:
791 BOOL ret;
792 ret = msrpc_send(con->msrpc.local->fd, NULL);
793 ret = msrpc_receive(con->msrpc.local->fd, rdata);
794 rdata->io = True;
795 rdata->offset = 0;
796 rdata->start = 0;
797 rdata->end = prs_data_size(rdata);
798 return ret;
801 return False;
804 /****************************************************************************
805 this allows us to detect dead servers.
806 ****************************************************************************/
807 BOOL rpc_con_ok(struct cli_connection *con)
809 if (!con) return False;
811 switch (con->type)
813 case MSRPC_SMB:
815 struct cli_state *cli;
816 if (!con->msrpc.smb) return False;
817 cli = con->msrpc.smb->smb;
818 /* check for NULL pointers or invalid sockets */
819 if (!cli || cli->fd == -1) return False;
820 return True;
822 break;
824 case MSRPC_LOCAL:
825 return True;
827 return False;
831 /****************************************************************************
832 write full PDU to pipe then read full PDU from pipe.
833 ****************************************************************************/
834 BOOL rpc_api_send_rcv_pdu(struct cli_connection *con, prs_struct *data,
835 prs_struct *rdata)
837 switch (con->type)
839 case MSRPC_SMB:
841 struct ntdom_info *nt = cli_conn_get_ntinfo(con);
842 struct cli_state *cli = con->msrpc.smb->smb;
843 int fnum = con->msrpc.smb->fnum;
844 if (cli->fd == -1) return False;
845 return cli_send_and_rcv_pdu(con, cli, fnum, data,
846 rdata, nt->max_xmit_frag);
848 case MSRPC_LOCAL:
850 BOOL ret;
851 data->offset = prs_data_size(data);
852 prs_link(NULL, data, NULL);
853 ret = msrpc_send(con->msrpc.local->fd, data) &&
854 msrpc_receive(con->msrpc.local->fd, rdata);
855 rdata->io = True;
856 rdata->offset = 0;
857 rdata->start = 0;
858 rdata->end = prs_data_size(rdata);
859 return ret;
862 return False;
865 /* connection policy state-info */
867 struct con_info
869 struct cli_connection *con;
870 void (*free_con) (struct cli_connection *);
873 static void free_policy_con(void *dev)
875 struct con_info *con = (struct con_info *)dev;
876 DEBUG(10, ("free policy connection\n"));
877 if (con->free_con != NULL)
879 con->free_con(con->con);
881 free(dev);
884 /****************************************************************************
885 set con state
886 ****************************************************************************/
887 BOOL set_policy_con(struct policy_cache *cache, POLICY_HND *hnd,
888 struct cli_connection *con,
889 void (*free_fn) (struct cli_connection *))
891 struct con_info *dev = (struct con_info *)malloc(sizeof(*dev));
893 if (dev != NULL)
895 dev->con = con;
896 dev->free_con = free_fn;
897 if (set_policy_state(cache, hnd,
898 free_policy_con, (void *)dev))
900 DEBUG(5, ("setting policy con\n"));
901 return True;
903 free(dev);
906 DEBUG(3, ("Error setting policy con state\n"));
907 return False;
910 /****************************************************************************
911 get con state
912 ****************************************************************************/
913 BOOL get_policy_con(struct policy_cache *cache, const POLICY_HND *hnd,
914 struct cli_connection **con)
916 struct con_info *dev;
917 dev = (struct con_info *)get_policy_state_info(cache, hnd);
919 if (dev != NULL)
921 DEBUG(5, ("Getting policy con state\n"));
922 (*con) = dev->con;
923 return True;
926 DEBUG(3, ("Error getting policy con state\n"));
927 return False;