3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8 * Copyright (C) Paul Ashton 1997.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 extern int DEBUGLEVEL;
34 /****************************************************************************
35 obtain the sid from the PDC. do some verification along the way...
36 ****************************************************************************/
37 BOOL get_domain_sids(const char *domain, DOM_SID *sid3, DOM_SID *sid5)
41 struct cli_connection *con = NULL;
46 extern struct ntuser_creds *usr_creds;
47 struct ntuser_creds usr;
51 pwd_set_nullpwd(&usr.pwd);
53 if (sid3 == NULL && sid5 == NULL)
55 /* don't waste my time... */
59 if (!get_any_dc_name(domain, srv_name))
65 * Ok - we have an anonymous connection to the IPC$ share.
66 * Now start the NT Domain stuff :-).
80 /* lookup domain controller; receive a policy handle */
81 res = res ? lsa_open_policy(srv_name, &pol, False) : False;
85 /* send client info query, level 3. receive domain name and sid */
86 res1 = res ? lsa_query_info_pol(&pol, 3, dom3, sid3) : False;
91 /* send client info query, level 5. receive domain name and sid */
92 res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, sid5) : False;
95 /* close policy handle */
96 res = res ? lsa_close(&pol) : False;
98 /* close the session */
99 cli_connection_unlink(con);
104 DEBUG(2,("LSA Query Info Policy\n"));
107 sid_to_string(sid, sid3);
108 DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid));
112 sid_to_string(sid, sid5);
113 DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid));
118 DEBUG(1,("lsa query info failed\n"));
125 /****************************************************************************
126 obtain a sid and domain name from a Domain Controller.
127 ****************************************************************************/
128 BOOL get_trust_sid_and_domain(const char* myname, char *server,
130 char *domain, size_t len)
134 struct cli_connection *con = NULL;
142 extern struct ntuser_creds *usr_creds;
143 struct ntuser_creds usr;
147 pwd_set_nullpwd(&usr.pwd);
149 if (!cli_connection_init_list(server, PIPE_LSARPC, &con))
151 DEBUG(0,("get_trust_sid: unable to initialise client connection.\n"));
160 fstrcpy(srv_name, "\\\\");
161 fstrcat(srv_name, myname);
164 /* lookup domain controller; receive a policy handle */
165 res = res ? lsa_open_policy(srv_name, &pol, False) : False;
167 /* send client info query, level 3. receive domain name and sid */
168 res1 = res ? lsa_query_info_pol(&pol, 3, dom3, &sid3) : False;
170 /* send client info query, level 5. receive domain name and sid */
171 res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, &sid5) : False;
173 /* close policy handle */
174 res = res ? lsa_close(&pol) : False;
176 /* close the session */
177 cli_connection_unlink(con);
182 DEBUG(2,("LSA Query Info Policy\n"));
183 sid_to_string(sid_str, &sid3);
184 DEBUG(2,("Domain Member - Domain: %s SID: %s\n",
186 sid_to_string(sid_str, &sid5);
187 DEBUG(2,("Domain Controller - Domain: %s SID: %s\n",
190 if (dom5[0] != 0 && sid_equal(&sid3, &sid5))
192 safe_strcpy(domain, dom5, len);
193 sid_copy(sid, &sid5);
197 DEBUG(2,("Server %s is not a PDC\n", server));
204 DEBUG(1,("lsa query info failed\n"));
211 /****************************************************************************
213 ****************************************************************************/
214 BOOL lsa_open_policy(const char *server_name, POLICY_HND *hnd,
221 BOOL valid_pol = False;
222 struct cli_connection *con = NULL;
224 if (!cli_connection_init(server_name, PIPE_LSARPC, &con))
229 if (hnd == NULL) return False;
231 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
232 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
234 /* create and send a MSRPC command with api LSA_OPENPOLICY */
236 DEBUG(4,("LSA Open Policy\n"));
238 /* store the parameters */
241 make_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000);
242 make_q_open_pol(&q_o, 0x5c, 0, 0x02000000, &qos);
246 make_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL);
249 /* turn parameters into data stream */
250 lsa_io_q_open_pol("", &q_o, &buf, 0);
252 /* send the data on \PIPE\ */
253 if (rpc_con_pipe_req(con, LSA_OPENPOLICY, &buf, &rbuf))
258 lsa_io_r_open_pol("", &r_o, &rbuf, 0);
259 p = rbuf.offset != 0;
261 if (p && r_o.status != 0)
263 /* report error code */
264 DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status)));
270 /* ok, at last: we're happy. return the policy handle */
271 memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
273 valid_pol = register_policy_hnd(hnd) &&
274 set_policy_con(hnd, con,
275 cli_connection_unlink);
285 /****************************************************************************
286 do a LSA Open Policy2
287 ****************************************************************************/
288 BOOL lsa_open_policy2( const char *server_name, POLICY_HND *hnd,
295 BOOL valid_pol = False;
297 struct cli_connection *con = NULL;
299 if (!cli_connection_init(server_name, PIPE_LSARPC, &con))
304 if (hnd == NULL) return False;
306 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
307 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
309 /* create and send a MSRPC command with api LSA_OPENPOLICY2 */
311 DEBUG(4,("LSA Open Policy2\n"));
313 /* store the parameters */
316 make_lsa_sec_qos(&qos, 2, 1, 0, 0x02000000);
317 make_q_open_pol2(&q_o, server_name, 0, 0x02000000, &qos);
321 make_q_open_pol2(&q_o, server_name, 0, 0x02000000, NULL);
324 /* turn parameters into data stream */
325 lsa_io_q_open_pol2("", &q_o, &buf, 0);
327 /* send the data on \PIPE\ */
328 if (rpc_hnd_pipe_req(hnd, LSA_OPENPOLICY2, &buf, &rbuf))
333 lsa_io_r_open_pol2("", &r_o, &rbuf, 0);
334 p = rbuf.offset != 0;
336 if (p && r_o.status != 0)
338 /* report error code */
339 DEBUG(0,("LSA_OPENPOLICY2: %s\n", get_nt_error_msg(r_o.status)));
345 /* ok, at last: we're happy. return the policy handle */
346 memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
347 valid_pol = register_policy_hnd(hnd) &&
348 set_policy_con(hnd, con,
349 cli_connection_unlink);
359 /****************************************************************************
361 ****************************************************************************/
362 BOOL lsa_open_secret( const POLICY_HND *hnd,
363 const char *secret_name,
365 POLICY_HND *hnd_secret)
369 LSA_Q_OPEN_SECRET q_o;
370 BOOL valid_pol = False;
372 if (hnd == NULL) return False;
374 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
375 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
377 /* create and send a MSRPC command with api LSA_OPENSECRET */
379 DEBUG(4,("LSA Open Secret\n"));
381 make_q_open_secret(&q_o, hnd, secret_name, des_access);
383 /* turn parameters into data stream */
384 lsa_io_q_open_secret("", &q_o, &buf, 0);
386 /* send the data on \PIPE\ */
387 if (rpc_hnd_pipe_req(hnd, LSA_OPENSECRET, &buf, &rbuf))
389 LSA_R_OPEN_SECRET r_o;
392 lsa_io_r_open_secret("", &r_o, &rbuf, 0);
393 p = rbuf.offset != 0;
395 if (p && r_o.status != 0)
397 /* report error code */
398 DEBUG(0,("LSA_OPENSECRET: %s\n", get_nt_error_msg(r_o.status)));
404 /* ok, at last: we're happy. return the policy handle */
405 memcpy(hnd_secret, r_o.pol.data, sizeof(hnd_secret->data));
416 /****************************************************************************
417 do a LSA Query Secret
418 ****************************************************************************/
419 BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 *secret,
424 LSA_Q_QUERY_SECRET q_q;
425 BOOL valid_info = False;
427 if (hnd == NULL) return False;
429 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
430 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
432 /* create and send a MSRPC command with api LSA_QUERYSECRET */
434 DEBUG(4,("LSA Query Secret\n"));
436 make_q_query_secret(&q_q, hnd);
438 /* turn parameters into data stream */
439 lsa_io_q_query_secret("", &q_q, &buf, 0);
441 /* send the data on \PIPE\ */
442 if (rpc_hnd_pipe_req(hnd, LSA_QUERYSECRET, &buf, &rbuf))
444 LSA_R_QUERY_SECRET r_q;
447 lsa_io_r_query_secret("", &r_q, &rbuf, 0);
448 p = rbuf.offset != 0;
450 if (p && r_q.status != 0)
452 /* report error code */
453 DEBUG(0,("LSA_QUERYSECRET: %s\n", get_nt_error_msg(r_q.status)));
457 if (p && (r_q.info.ptr_value != 0) &&
458 (r_q.info.value.ptr_secret != 0) &&
459 (r_q.info.ptr_update != 0))
463 memcpy(&enc_secret, &(r_q.info.value.enc_secret), sizeof(STRING2));
464 memcpy(last_update, &(r_q.info.last_update), sizeof(NTTIME));
465 if (!cli_get_sesskey(hnd, sess_key))
469 #ifdef DEBUG_PASSWORD
470 dump_data(100, sess_key, 16);
472 valid_info = nt_decrypt_string2(secret, &enc_secret,
484 /****************************************************************************
485 do a LSA Lookup Names
486 ****************************************************************************/
487 BOOL lsa_lookup_names( POLICY_HND *hnd,
496 LSA_Q_LOOKUP_NAMES q_l;
497 BOOL valid_response = False;
499 if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
501 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
502 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
504 /* create and send a MSRPC command with api LSA_LOOKUP_NAMES */
506 DEBUG(4,("LSA Lookup NAMEs\n"));
508 /* store the parameters */
509 make_q_lookup_names(&q_l, hnd, num_names, names);
511 /* turn parameters into data stream */
512 lsa_io_q_lookup_names("", &q_l, &buf, 0);
514 /* send the data on \PIPE\ */
515 if (rpc_hnd_pipe_req(hnd, LSA_LOOKUPNAMES, &buf, &rbuf))
517 LSA_R_LOOKUP_NAMES r_l;
519 DOM_RID2 t_rids[MAX_LOOKUP_SIDS];
526 r_l.dom_rid = t_rids;
528 lsa_io_r_lookup_names("", &r_l, &rbuf, 0);
529 p = rbuf.offset != 0;
531 if (p && r_l.status != 0)
533 /* report error code */
534 DEBUG(1,("LSA_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_l.status)));
540 if (r_l.ptr_dom_ref != 0 && r_l.ptr_entries != 0)
542 valid_response = True;
546 if (num_sids != NULL && valid_response)
548 (*num_sids) = r_l.num_entries;
553 for (i = 0; i < r_l.num_entries; i++)
555 if (t_rids[i].rid_idx >= ref.num_ref_doms_1 &&
556 t_rids[i].rid_idx != 0xffffffff)
558 DEBUG(0,("LSA_LOOKUP_NAMES: domain index %d out of bounds\n",
560 valid_response = False;
566 if (types != NULL && valid_response && r_l.num_entries != 0)
568 (*types) = (uint8*)malloc((*num_sids) * sizeof(uint8));
571 if (sids != NULL && valid_response && r_l.num_entries != 0)
573 (*sids) = (DOM_SID*)malloc((*num_sids) * sizeof(DOM_SID));
576 if (sids != NULL && (*sids) != NULL)
579 /* take each name, construct a SID */
580 for (i = 0; i < (*num_sids); i++)
582 uint32 dom_idx = t_rids[i].rid_idx;
583 uint32 dom_rid = t_rids[i].rid;
584 DOM_SID *sid = &(*sids)[i];
585 if (dom_idx != 0xffffffff)
587 sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
588 if (dom_rid != 0xffffffff)
590 sid_append_rid(sid, dom_rid);
592 if (types != NULL && (*types) != NULL)
594 (*types)[i] = t_rids[i].type;
600 if (types != NULL && (*types) != NULL)
602 (*types)[i] = SID_NAME_UNKNOWN;
612 return valid_response;
615 /****************************************************************************
617 ****************************************************************************/
618 BOOL lsa_lookup_sids(POLICY_HND *hnd,
627 LSA_Q_LOOKUP_SIDS q_l;
628 BOOL valid_response = False;
632 if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
634 if (num_names != NULL)
647 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
648 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
650 /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
652 DEBUG(4,("LSA Lookup SIDs\n"));
654 /* store the parameters */
655 make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
657 /* turn parameters into data stream */
658 lsa_io_q_lookup_sids("", &q_l, &buf, 0);
660 /* send the data on \PIPE\ */
661 if (rpc_hnd_pipe_req(hnd, LSA_LOOKUPSIDS, &buf, &rbuf))
663 LSA_R_LOOKUP_SIDS r_l;
665 LSA_TRANS_NAME_ENUM t_names;
669 r_l.names = &t_names;
671 lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
672 p = rbuf.offset != 0;
674 if (p && r_l.status != 0 &&
675 r_l.status != 0x107 &&
676 r_l.status != (0xC0000000 | NT_STATUS_NONE_MAPPED))
678 /* report error code */
679 DEBUG(1,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
685 if (t_names.ptr_trans_names != 0 && r_l.ptr_dom_ref != 0)
687 valid_response = True;
691 if (num_names != NULL && valid_response)
693 (*num_names) = t_names.num_entries;
698 for (i = 0; i < t_names.num_entries; i++)
700 if (t_names.name[i].domain_idx >= ref.num_ref_doms_1)
702 DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
703 valid_response = False;
709 if (types != NULL && valid_response && (*num_names) != 0)
711 (*types) = (uint8*)malloc((*num_names) * sizeof(uint8));
714 if (names != NULL && valid_response && (*num_names) != 0)
716 (*names) = (char**)malloc((*num_names) * sizeof(char*));
719 if (names != NULL && (*names) != NULL)
722 /* take each name, construct a \DOMAIN\name string */
723 for (i = 0; i < (*num_names); i++)
728 uint32 dom_idx = t_names.name[i].domain_idx;
730 if (dom_idx != 0xffffffff)
732 unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)-1);
733 unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name)-1);
735 memset(full_name, 0, sizeof(full_name));
737 slprintf(full_name, sizeof(full_name)-1, "%s\\%s",
740 (*names)[i] = strdup(full_name);
741 if (types != NULL && (*types) != NULL)
743 (*types)[i] = t_names.name[i].sid_name_use;
749 if (types != NULL && (*types) != NULL)
751 (*types)[i] = SID_NAME_UNKNOWN;
761 return valid_response;
764 /****************************************************************************
765 do a LSA Query Info Policy
766 ****************************************************************************/
767 BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
768 fstring domain_name, DOM_SID *domain_sid)
772 LSA_Q_QUERY_INFO q_q;
773 BOOL valid_response = False;
775 ZERO_STRUCTP(domain_sid);
778 if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False;
780 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
781 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
783 /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
785 DEBUG(4,("LSA Query Info Policy\n"));
787 /* store the parameters */
788 make_q_query(&q_q, hnd, info_class);
790 /* turn parameters into data stream */
791 lsa_io_q_query("", &q_q, &buf, 0);
793 /* send the data on \PIPE\ */
794 if (rpc_hnd_pipe_req(hnd, LSA_QUERYINFOPOLICY, &buf, &rbuf))
796 LSA_R_QUERY_INFO r_q;
799 lsa_io_r_query("", &r_q, &rbuf, 0);
800 p = rbuf.offset != 0;
802 if (p && r_q.status != 0)
804 /* report error code */
805 DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
809 if (p && r_q.info_class != q_q.info_class)
811 /* report different info classes */
812 DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
813 q_q.info_class, r_q.info_class));
820 /* ok, at last: we're happy. */
821 switch (r_q.info_class)
825 if (r_q.dom.id3.buffer_dom_name != 0)
827 unistr2_to_ascii(domain_name, &r_q.dom.id3.uni_domain_name, sizeof(fstring)-1);
829 if (r_q.dom.id3.buffer_dom_sid != 0)
831 *domain_sid = r_q.dom.id3.dom_sid.sid;
834 valid_response = True;
839 if (r_q.dom.id5.buffer_dom_name != 0)
841 unistr2_to_ascii(domain_name, &r_q.dom.id5.uni_domain_name, sizeof(fstring)-1);
843 if (r_q.dom.id5.buffer_dom_sid != 0)
845 *domain_sid = r_q.dom.id5.dom_sid.sid;
848 valid_response = True;
853 DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
860 sid_to_string(sid_str, domain_sid);
861 DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n",
862 r_q.info_class, domain_name, sid_str));
869 return valid_response;
872 /****************************************************************************
873 do a LSA Enumerate Trusted Domain
874 ****************************************************************************/
875 BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 *enum_ctx,
876 uint32 *num_doms, char ***names,
881 LSA_Q_ENUM_TRUST_DOM q_q;
882 BOOL valid_response = False;
884 if (hnd == NULL || num_doms == NULL || names == NULL) return False;
886 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
887 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
889 /* create and send a MSRPC command with api LSA_ENUMTRUSTDOM */
891 DEBUG(4,("LSA Enum Trusted Domains\n"));
893 /* store the parameters */
894 make_q_enum_trust_dom(&q_q, hnd, *enum_ctx, 0xffffffff);
896 /* turn parameters into data stream */
897 lsa_io_q_enum_trust_dom("", &q_q, &buf, 0);
899 /* send the data on \PIPE\ */
900 if (rpc_hnd_pipe_req(hnd, LSA_ENUMTRUSTDOM, &buf, &rbuf))
902 LSA_R_ENUM_TRUST_DOM r_q;
905 lsa_io_r_enum_trust_dom("", &r_q, &rbuf, 0);
906 p = rbuf.offset != 0;
908 if (p && r_q.status != 0)
910 /* report error code */
911 DEBUG(0,("LSA_ENUMTRUSTDOM: %s\n", get_nt_error_msg(r_q.status)));
912 p = r_q.status == 0x8000001a;
919 valid_response = True;
921 for (i = 0; i < r_q.num_domains; i++)
924 unistr2_to_ascii(tmp, &r_q.uni_domain_name[i],
926 add_chars_to_array(num_doms, names, tmp);
927 add_sid_to_array(&num_sids, sids,
928 &r_q.domain_sid[i].sid);
931 if (r_q.status == 0x0)
933 *enum_ctx = r_q.enum_context;
945 return valid_response;
948 /****************************************************************************
950 ****************************************************************************/
951 BOOL lsa_close(POLICY_HND *hnd)
956 BOOL valid_close = False;
958 if (hnd == NULL) return False;
960 /* create and send a MSRPC command with api LSA_OPENPOLICY */
962 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
963 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
965 DEBUG(4,("LSA Close\n"));
967 /* store the parameters */
968 make_lsa_q_close(&q_c, hnd);
970 /* turn parameters into data stream */
971 lsa_io_q_close("", &q_c, &buf, 0);
973 /* send the data on \PIPE\ */
974 if (rpc_hnd_pipe_req(hnd, LSA_CLOSE, &buf, &rbuf))
979 lsa_io_r_close("", &r_c, &rbuf, 0);
980 p = rbuf.offset != 0;
982 if (p && r_c.status != 0)
984 /* report error code */
985 DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
991 /* check that the returned policy handle is all zeros */
995 for (i = 0; i < sizeof(r_c.pol.data); i++)
997 if (r_c.pol.data[i] != 0)
1005 DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
1010 prs_mem_free(&rbuf);
1011 prs_mem_free(&buf );
1013 close_policy_hnd(hnd);