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"
27 #include "rpc_client.h"
29 struct user_creds
*usr_creds
= NULL
;
30 vuser_key
*user_key
= NULL
;
32 extern int DEBUGLEVEL
;
35 { MSRPC_NONE
, MSRPC_LOCAL
, MSRPC_SMB
};
41 struct user_creds usr_creds
;
48 struct msrpc_local
*local
;
58 static struct cli_connection
**con_list
= NULL
;
59 static uint32 num_cons
= 0;
61 void init_connections(void)
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
,
85 void free_connections(void)
87 DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
88 free_con_array(num_cons
, con_list
);
94 static struct cli_connection
*cli_con_get(const char *srv_name
,
95 const char *pipe_name
,
97 void *auth_creds
, BOOL reuse
)
99 struct cli_connection
*con
= NULL
;
100 BOOL is_new_connection
= False
;
104 con
= (struct cli_connection
*)malloc(sizeof(*con
));
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
;
130 con
->msrpc
.local
= ncalrpc_l_use_add(pipe_name
, user_key
,
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
);
143 struct ntuser_creds
*ntc
= NULL
;
144 if (usr_creds
!= NULL
)
146 ntc
= &usr_creds
->ntc
;
148 con
->type
= MSRPC_SMB
;
150 ncacn_np_use_add(pipe_name
, user_key
, srv_name
,
154 if (con
->msrpc
.smb
== NULL
)
156 cli_connection_free(con
);
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
)
174 con
->auth_info
= NULL
;
175 con
->auth_creds
= auth_creds
;
183 extern cli_auth_fns cli_noauth_fns
;
184 con
->auth
= &cli_noauth_fns
;
187 if (!rpc_pipe_bind(con
, pipe_name
, &abstract
,
190 DEBUG(0, ("rpc_pipe_bind failed\n"));
191 cli_connection_free(con
);
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
);
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
);
219 if (con
->type
== MSRPC_SMB
)
221 con
->msrpc
.smb
->smb
->nt
.key
= key
;
223 add_con_to_array(&num_cons
, &con_list
, con
);
227 /****************************************************************************
228 terminate client connection
229 ****************************************************************************/
230 void cli_connection_free(struct cli_connection
*con
)
235 DEBUG(10, ("cli_connection_free: %d\n", __LINE__
));
237 if (con
->msrpc
.cli
!= NULL
)
243 DEBUG(10, ("msrpc local connection\n"));
244 ncalrpc_l_use_del(con
->pipe_name
,
245 &con
->msrpc
.local
->nt
.key
,
247 con
->msrpc
.local
= NULL
;
252 DEBUG(10, ("msrpc smb connection\n"));
253 ncacn_np_use_del(con
->srv_name
,
255 &con
->msrpc
.smb
->smb
->nt
.key
,
257 con
->msrpc
.smb
= NULL
;
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
)
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
])
301 /****************************************************************************
302 terminate client state
303 ****************************************************************************/
304 void cli_connection_unlink(struct cli_connection
*con
)
308 cli_connection_free(con
);
313 /****************************************************************************
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 /****************************************************************************
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
)
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 /****************************************************************************
345 ****************************************************************************/
346 BOOL
cli_connection_getsrv(const char *srv_name
, const char *pipe_name
,
347 struct cli_connection
**con
)
350 struct cli_connection
*auth_con
= NULL
;
352 if (con_list
== NULL
|| num_cons
== 0)
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
)
373 /* Check for an invalid fd */
375 if (((*con
)->type
== 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
));
384 cli_connection_free(*con
);
392 if (auth_con
!= NULL
)
397 return (*con
) != NULL
;
400 /****************************************************************************
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"));
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
))
441 DEBUG(0, ("cli_get_usr_sesskey: no connection\n"));
444 nt
= cli_conn_get_ntinfo(con
);
447 DEBUG(0, ("cli_get_usr_sesskey: no ntdom_info\n"));
451 memcpy(usr_sess_key
, nt
->usr_sess_key
, sizeof(nt
->usr_sess_key
));
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
;
467 nt
= cli_conn_get_ntinfo(con
);
470 memcpy(nt
->usr_sess_key
, usr_sess_key
,
471 sizeof(nt
->usr_sess_key
));
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
;
488 nt
= cli_conn_get_ntinfo(con
);
489 if (nt
!= NULL
&& nt
->key
.vuid
!= UID_FIELD_INVALID
)
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
)
538 if (con
->msrpc
.cli
== NULL
)
540 DEBUG(1, ("cli_conn_get_ntinfo: NULL msrpc (closed)\n"));
548 return &con
->msrpc
.local
->nt
;
552 return &con
->msrpc
.smb
->smb
->nt
;
558 /****************************************************************************
559 get a user session key associated with a connection associated with a
561 ****************************************************************************/
562 BOOL
cli_get_con_sesskey(struct cli_connection
*con
, uchar sess_key
[16])
564 struct ntdom_info
*nt
;
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);
577 /****************************************************************************
578 get a server name associated with a connection associated with a
580 ****************************************************************************/
581 BOOL
cli_con_get_srvname(struct cli_connection
*con
, char *srv_name
)
583 const char *desthost
= NULL
;
594 desthost
= con
->msrpc
.smb
->smb
->desthost
;
599 desthost
= con
->srv_name
;
604 if (strnequal("\\\\", desthost
, 2))
606 fstrcpy(srv_name
, desthost
);
610 fstrcpy(srv_name
, "\\\\");
611 fstrcat(srv_name
, desthost
);
617 /****************************************************************************
618 get a user session key associated with a connection associated with a
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
))
630 return cli_get_con_sesskey(con
, sess_key
);
633 /****************************************************************************
634 get a user session key associated with a connection associated with a
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
))
646 return cli_get_con_sesskey(con
, sess_key
);
649 /****************************************************************************
650 get a user session key associated with a connection associated with a
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
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
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
,
682 /****************************************************************************
683 get a user session key associated with a connection associated with a
685 ****************************************************************************/
686 BOOL
cli_con_set_creds(const char *srv_name
, const uchar sess_key
[16],
689 struct cli_connection
*con
= NULL
;
690 struct ntdom_info
*nt
;
692 if (!cli_connection_getsrv(srv_name
, PIPE_NETLOGON
, &con
))
697 nt
= cli_conn_get_ntinfo(con
);
699 memcpy(nt
->sess_key
, sess_key
, 16);
700 memcpy(&nt
->clnt_cred
, cred
, sizeof(*cred
));
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
))
728 if (!rpc_con_ok(con
))
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
)
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
);
750 /****************************************************************************
751 write a full PDU to a pipe
752 ****************************************************************************/
753 BOOL
rpc_api_write(struct cli_connection
*con
, prs_struct
*data
)
759 struct cli_state
*cli
= con
->msrpc
.smb
->smb
;
760 int fnum
= con
->msrpc
.smb
->fnum
;
761 return cli_write(cli
, fnum
, 0x0008,
764 prs_data_size(data
)) > 0;
768 data
->offset
= prs_data_size(data
);
769 prs_link(NULL
, data
, NULL
);
770 return msrpc_send(con
->msrpc
.local
->fd
, data
);
776 /****************************************************************************
777 read a full PDU from a pipe
778 ****************************************************************************/
779 BOOL
rpc_api_rcv_pdu(struct cli_connection
*con
, prs_struct
*rdata
)
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
);
792 ret
= msrpc_send(con
->msrpc
.local
->fd
, NULL
);
793 ret
= msrpc_receive(con
->msrpc
.local
->fd
, rdata
);
797 rdata
->end
= prs_data_size(rdata
);
804 /****************************************************************************
805 this allows us to detect dead servers.
806 ****************************************************************************/
807 BOOL
rpc_con_ok(struct cli_connection
*con
)
809 if (!con
) return False
;
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
;
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
,
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
);
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
);
858 rdata
->end
= prs_data_size(rdata
);
865 /* connection policy state-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
);
884 /****************************************************************************
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
));
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"));
906 DEBUG(3, ("Error setting policy con state\n"));
910 /****************************************************************************
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
);
921 DEBUG(5, ("Getting policy con state\n"));
926 DEBUG(3, ("Error getting policy con state\n"));