2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 * Copyright (C) Jeremy Allison 1998.
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.
27 extern int DEBUGLEVEL;
28 extern DOM_SID global_sam_sid;
29 extern fstring global_myworkgroup;
30 extern pstring global_myname;
32 /***************************************************************************
33 lsa_reply_open_policy2
34 ***************************************************************************/
36 static BOOL lsa_reply_open_policy2(prs_struct *rdata)
43 /* set up the LSA QUERY INFO response */
45 for (i = 4; i < POL_HND_SIZE; i++)
49 /* store the response in the SMB stream */
50 if(!lsa_io_r_open_pol2("", &r_o, rdata, 0)) {
51 DEBUG(0,("lsa_reply_open_policy2: unable to marshall LSA_R_OPEN_POL2.\n"));
58 /***************************************************************************
60 ***************************************************************************/
62 static BOOL lsa_reply_open_policy(prs_struct *rdata)
69 /* set up the LSA QUERY INFO response */
71 for (i = 4; i < POL_HND_SIZE; i++)
75 /* store the response in the SMB stream */
76 if(!lsa_io_r_open_pol("", &r_o, rdata, 0)) {
77 DEBUG(0,("lsa_reply_open_policy: unable to marshall LSA_R_OPEN_POL.\n"));
84 /***************************************************************************
86 ***************************************************************************/
88 static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
91 int domlen = strlen(dom_name);
95 d_q->uni_dom_max_len = domlen * 2;
96 d_q->uni_dom_str_len = domlen * 2;
98 d_q->buffer_dom_name = domlen != 0 ? 1 : 0; /* domain buffer pointer */
99 d_q->buffer_dom_sid = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
101 /* this string is supposed to be character short */
102 init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
105 sid_to_string(sid_str, dom_sid);
106 init_dom_sid2(&d_q->dom_sid, dom_sid);
110 /***************************************************************************
111 lsa_reply_enum_trust_dom
112 ***************************************************************************/
114 static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
116 uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
118 LSA_R_ENUM_TRUST_DOM r_e;
122 /* set up the LSA QUERY INFO response */
123 init_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
124 dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
126 /* store the response in the SMB stream */
127 lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
130 /***************************************************************************
132 ***************************************************************************/
134 static BOOL lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
135 char *dom_name, DOM_SID *dom_sid, uint32 status_code)
137 LSA_R_QUERY_INFO r_q;
141 /* set up the LSA QUERY INFO response */
143 if(status_code == 0) {
144 r_q.undoc_buffer = 0x22000000; /* bizarre */
145 r_q.info_class = q_q->info_class;
147 init_dom_query(&r_q.dom.id5, dom_name, dom_sid);
150 r_q.status = status_code;
152 /* store the response in the SMB stream */
153 if(!lsa_io_r_query("", &r_q, rdata, 0)) {
154 DEBUG(0,("lsa_reply_query_info: failed to marshall LSA_R_QUERY_INFO.\n"));
161 /***************************************************************************
162 init_dom_ref - adds a domain if it's not already in, returns the index.
163 ***************************************************************************/
165 static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
170 if (dom_name != NULL) {
171 for (num = 0; num < ref->num_ref_doms_1; num++) {
173 fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
174 if (strequal(domname, dom_name))
178 num = ref->num_ref_doms_1;
181 if (num >= MAX_REF_DOMAINS) {
182 /* index not found, already at maximum domain limit */
186 ref->num_ref_doms_1 = num+1;
187 ref->ptr_ref_dom = 1;
188 ref->max_entries = MAX_REF_DOMAINS;
189 ref->num_ref_doms_2 = num+1;
191 len = (dom_name != NULL) ? strlen(dom_name) : 0;
192 if(dom_name != NULL && len == 0)
195 init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
196 ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
198 init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
199 init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
204 /***************************************************************************
206 ***************************************************************************/
208 static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
209 int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
210 uint32 *mapped_count)
216 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
218 for (i = 0; i < num_entries; i++) {
222 uint32 rid = 0xffffffff;
227 uint8 sid_name_use = SID_NAME_UNKNOWN;
229 pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
232 * Try and split the name into a DOMAIN and
236 split_domain_name(full_name, dom_name, user);
239 * We only do anything with this name if we
240 * can map the Domain into a SID we know.
243 if (map_domain_name_to_sid(&dom_sid, dom_name)) {
244 dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
246 if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
255 sid_name_use = SID_NAME_UNKNOWN;
258 init_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
263 /***************************************************************************
264 init_reply_lookup_names
265 ***************************************************************************/
267 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
268 DOM_R_REF *ref, uint32 num_entries,
269 DOM_RID2 *rid2, uint32 mapped_count)
271 r_l->ptr_dom_ref = 1;
274 r_l->num_entries = num_entries;
275 r_l->ptr_entries = 1;
276 r_l->num_entries2 = num_entries;
279 r_l->mapped_count = mapped_count;
281 if (mapped_count == 0)
282 r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
287 /***************************************************************************
288 Init lsa_trans_names.
289 ***************************************************************************/
291 static void init_lsa_trans_names(DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
292 int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS], uint32 *mapped_count)
294 extern DOM_SID global_sid_S_1_5_0x20; /* BUILTIN sid. */
299 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
301 for (i = 0; i < num_entries; i++) {
303 DOM_SID find_sid = sid[i].sid;
304 uint32 rid = 0xffffffff;
308 uint8 sid_name_use = 0;
310 memset(dom_name, '\0', sizeof(dom_name));
311 memset(name, '\0', sizeof(name));
314 * First, check to see if the SID is one of the well
315 * known ones (this includes our own domain SID).
316 * Next, check if the domain prefix is one of the
317 * well known ones. If so and the domain prefix was
318 * either BUILTIN or our own global sid, then lookup
319 * the RID as a user or group id and translate to
323 if (map_domain_sid_to_name(&find_sid, dom_name)) {
324 sid_name_use = SID_NAME_DOMAIN;
325 } else if (sid_split_rid(&find_sid, &rid) && map_domain_sid_to_name(&find_sid, dom_name)) {
326 if (sid_equal(&find_sid, &global_sam_sid) ||
327 sid_equal(&find_sid, &global_sid_S_1_5_0x20)) {
328 status = lookup_local_rid(rid, name, &sid_name_use);
330 status = lookup_known_rid(&find_sid, rid, name, &sid_name_use);
334 DEBUG(10,("init_lsa_trans_names: adding domain '%s' sid %s to referenced list.\n",
337 dom_idx = init_dom_ref(ref, dom_name, &find_sid);
340 slprintf(name, sizeof(name)-1, "unix.%08x", rid);
341 sid_name_use = SID_NAME_UNKNOWN;
344 DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to referenced list.\n", dom_name, name ));
348 init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
349 sid_name_use, name, dom_idx);
353 trn->num_entries = total;
354 trn->ptr_trans_names = 1;
355 trn->num_entries2 = total;
358 /***************************************************************************
359 Init_reply_lookup_sids.
360 ***************************************************************************/
362 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
363 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
366 r_l->ptr_dom_ref = 1;
369 r_l->mapped_count = mapped_count;
371 if (mapped_count == 0)
372 r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
377 /***************************************************************************
378 lsa_reply_lookup_sids
379 ***************************************************************************/
381 static BOOL lsa_reply_lookup_sids(prs_struct *rdata, DOM_SID2 *sid, int num_entries)
383 LSA_R_LOOKUP_SIDS r_l;
385 LSA_TRANS_NAME_ENUM names;
386 uint32 mapped_count = 0;
392 /* set up the LSA Lookup SIDs response */
393 init_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
394 init_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
396 /* store the response in the SMB stream */
397 if(!lsa_io_r_lookup_sids("", &r_l, rdata, 0)) {
398 DEBUG(0,("lsa_reply_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n"));
405 /***************************************************************************
406 lsa_reply_lookup_names
407 ***************************************************************************/
409 static BOOL lsa_reply_lookup_names(prs_struct *rdata,
410 UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
412 LSA_R_LOOKUP_NAMES r_l;
414 DOM_RID2 rids[MAX_LOOKUP_SIDS];
415 uint32 mapped_count = 0;
421 /* set up the LSA Lookup RIDs response */
422 init_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
423 init_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
425 /* store the response in the SMB stream */
426 if(!lsa_io_r_lookup_names("", &r_l, rdata, 0)) {
427 DEBUG(0,("lsa_reply_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n"));
434 /***************************************************************************
436 ***************************************************************************/
438 static BOOL api_lsa_open_policy2(prs_struct *data, prs_struct *rdata)
444 /* grab the server, object attributes and desired access flag...*/
445 if(!lsa_io_q_open_pol2("", &q_o, data, 0)) {
446 DEBUG(0,("api_lsa_open_policy2: unable to unmarshall LSA_Q_OPEN_POL2.\n"));
450 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
452 /* return a 20 byte policy handle */
453 if(!lsa_reply_open_policy2(rdata))
459 /***************************************************************************
461 ***************************************************************************/
462 static BOOL api_lsa_open_policy(prs_struct *data, prs_struct *rdata)
468 /* grab the server, object attributes and desired access flag...*/
469 if(!lsa_io_q_open_pol("", &q_o, data, 0)) {
470 DEBUG(0,("api_lsa_open_policy: unable to unmarshall LSA_Q_OPEN_POL.\n"));
474 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
476 /* return a 20 byte policy handle */
477 if(!lsa_reply_open_policy(rdata))
483 /***************************************************************************
484 api_lsa_enum_trust_dom
485 ***************************************************************************/
486 static BOOL api_lsa_enum_trust_dom(prs_struct *data, prs_struct *rdata)
488 LSA_Q_ENUM_TRUST_DOM q_e;
492 /* grab the enum trust domain context etc. */
493 if(!lsa_io_q_enum_trust_dom("", &q_e, data, 0))
496 /* construct reply. return status is always 0x0 */
497 lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
502 /***************************************************************************
504 ***************************************************************************/
505 static BOOL api_lsa_query_info(prs_struct *data, prs_struct *rdata)
507 LSA_Q_QUERY_INFO q_i;
510 uint32 status_code = 0;
512 memset(name, 0, sizeof(name));
516 /* grab the info class and policy handle */
517 if(!lsa_io_q_query("", &q_i, data, 0)) {
518 DEBUG(0,("api_lsa_query_info: failed to unmarshall LSA_Q_QUERY_INFO.\n"));
522 switch (q_i.info_class) {
524 if(lp_domain_logons()) {
525 fstrcpy(name, global_myworkgroup);
526 sid = &global_sam_sid;
532 fstrcpy(name, global_myname);
533 sid = &global_sam_sid;
536 DEBUG(0,("api_lsa_query_info: unknown info level in Lsa Query: %d\n", q_i.info_class));
537 status_code = (NT_STATUS_INVALID_INFO_CLASS | 0xC0000000);
541 /* construct reply. return status is always 0x0 */
542 if(!lsa_reply_query_info(&q_i, rdata, name, sid, status_code))
548 /***************************************************************************
550 ***************************************************************************/
552 static BOOL api_lsa_lookup_sids(prs_struct *data, prs_struct *rdata)
554 LSA_Q_LOOKUP_SIDS q_l;
557 /* grab the info class and policy handle */
558 if(!lsa_io_q_lookup_sids("", &q_l, data, 0)) {
559 DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n"));
563 /* construct reply. return status is always 0x0 */
564 if(!lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries))
570 /***************************************************************************
572 ***************************************************************************/
574 static BOOL api_lsa_lookup_names(prs_struct *data, prs_struct *rdata)
576 LSA_Q_LOOKUP_NAMES q_l;
579 /* grab the info class and policy handle */
580 if(!lsa_io_q_lookup_names("", &q_l, data, 0)) {
581 DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n"));
585 SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
587 return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
590 /***************************************************************************
592 ***************************************************************************/
593 static BOOL api_lsa_close(prs_struct *data, prs_struct *rdata)
599 /* store the response in the SMB stream */
600 if (!lsa_io_r_close("", &r_c, rdata, 0)) {
601 DEBUG(0,("api_lsa_close: lsa_io_r_close failed.\n"));
608 /***************************************************************************
610 ***************************************************************************/
611 static BOOL api_lsa_open_secret(prs_struct *data, prs_struct *rdata)
613 /* XXXX this is NOT good */
617 for(i =0; i < 4; i++) {
618 if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
619 DEBUG(0,("api_lsa_open_secret: prs_uint32 %d failed.\n",
625 dummy = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
626 if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
627 DEBUG(0,("api_lsa_open_secret: prs_uint32 status failed.\n"));
634 /***************************************************************************
636 ***************************************************************************/
637 static struct api_struct api_lsa_cmds[] =
639 { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
640 { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
641 { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
642 { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
643 { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
644 { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
645 { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
646 { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
650 /***************************************************************************
652 ***************************************************************************/
653 BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
655 return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);