- removed smb.conf.5.html as it now comes as part of htmldocs
[Samba/gbeck.git] / source / rpc_server / srv_lsa.c
blobabbe4ccd936970d3669fdb991c165b684640a2bf
2 /*
3 * Unix SMB/Netbios implementation.
4 * Version 1.9.
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.
9 * Copyright (C) Jeremy Allison 1998.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "includes.h"
28 #include "nterr.h"
30 extern int DEBUGLEVEL;
31 extern DOM_SID global_sam_sid;
32 extern fstring global_sam_name;
33 extern DOM_SID global_member_sid;
34 extern fstring global_myworkgroup;
35 extern DOM_SID global_sid_S_1_1;
36 extern DOM_SID global_sid_S_1_3;
37 extern DOM_SID global_sid_S_1_5;
39 /***************************************************************************
40 lsa_reply_open_policy2
41 ***************************************************************************/
42 static void lsa_reply_open_policy2(prs_struct *rdata)
44 int i;
45 LSA_R_OPEN_POL2 r_o;
47 ZERO_STRUCT(r_o);
49 /* set up the LSA QUERY INFO response */
51 for (i = 4; i < POL_HND_SIZE; i++)
53 r_o.pol.data[i] = i;
55 r_o.status = 0x0;
57 /* store the response in the SMB stream */
58 lsa_io_r_open_pol2("", &r_o, rdata, 0);
61 /***************************************************************************
62 lsa_reply_open_policy
63 ***************************************************************************/
64 static void lsa_reply_open_policy(prs_struct *rdata)
66 int i;
67 LSA_R_OPEN_POL r_o;
69 ZERO_STRUCT(r_o);
71 /* set up the LSA QUERY INFO response */
73 for (i = 4; i < POL_HND_SIZE; i++)
75 r_o.pol.data[i] = i;
77 r_o.status = 0x0;
79 /* store the response in the SMB stream */
80 lsa_io_r_open_pol("", &r_o, rdata, 0);
83 /***************************************************************************
84 make_dom_query
85 ***************************************************************************/
86 static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
88 fstring sid_str;
89 int domlen = strlen(dom_name);
91 d_q->uni_dom_max_len = domlen * 2;
92 d_q->uni_dom_str_len = domlen * 2;
94 d_q->buffer_dom_name = domlen != 0 ? 1 : 0; /* domain buffer pointer */
95 d_q->buffer_dom_sid = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
97 /* this string is supposed to be character short */
98 make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
100 sid_to_string(sid_str, dom_sid);
101 make_dom_sid2(&(d_q->dom_sid), dom_sid);
104 /***************************************************************************
105 lsa_reply_query_info
106 ***************************************************************************/
107 static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
108 prs_struct *rdata,
109 uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
111 LSA_R_ENUM_TRUST_DOM r_e;
113 ZERO_STRUCT(r_e);
115 /* set up the LSA QUERY INFO response */
116 make_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
117 dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
119 /* store the response in the SMB stream */
120 lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
123 /***************************************************************************
124 lsa_reply_query_info
125 ***************************************************************************/
126 static void lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
127 char *dom_name, DOM_SID *dom_sid)
129 LSA_R_QUERY_INFO r_q;
131 ZERO_STRUCT(r_q);
133 /* set up the LSA QUERY INFO response */
135 r_q.undoc_buffer = 0x22000000; /* bizarre */
136 r_q.info_class = q_q->info_class;
138 make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
140 r_q.status = 0x0;
142 /* store the response in the SMB stream */
143 lsa_io_r_query("", &r_q, rdata, 0);
147 /***************************************************************************
148 make_dom_ref - adds a domain if it's not already in, returns the index
149 ***************************************************************************/
150 static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
153 int num = 0;
154 int len;
156 if (dom_name != NULL)
158 for (num = 0; num < ref->num_ref_doms_1; num++)
160 fstring domname;
161 fstrcpy(domname, unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
162 if (strequal(domname, dom_name))
164 return num;
169 else
171 num = ref->num_ref_doms_1;
174 if (num >= MAX_REF_DOMAINS)
176 /* index not found, already at maximum domain limit */
177 return -1;
180 ref->undoc_buffer = 1;
181 ref->num_ref_doms_1 = num+1;
182 ref->undoc_buffer2 = 1;
183 ref->max_entries = MAX_REF_DOMAINS;
184 ref->num_ref_doms_2 = num+1;
186 len = dom_name != NULL ? strlen(dom_name) : 0;
188 make_uni_hdr(&(ref->hdr_ref_dom[num].hdr_dom_name), len, len, len != 0 ? 1 : 0);
189 ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
191 make_unistr2 (&(ref->ref_dom[num].uni_dom_name), dom_name, len);
192 make_dom_sid2(&(ref->ref_dom[num].ref_dom ), dom_sid );
194 return num;
197 /***************************************************************************
198 make_reply_lookup_names
199 ***************************************************************************/
200 static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
201 int num_entries,
202 DOM_SID dom_sids [MAX_LOOKUP_SIDS],
203 uint8 dom_types[MAX_LOOKUP_SIDS])
205 int i;
207 r_l->num_entries = 0;
208 r_l->undoc_buffer = 0;
209 r_l->num_entries2 = 0;
211 #if 0
212 r_l->num_entries = num_entries;
213 r_l->undoc_buffer = 1;
214 r_l->num_entries2 = num_entries;
216 SMB_ASSERT_ARRAY(r_l->dom_rid, num_entries);
218 for (i = 0; i < num_entries; i++)
220 DOM_SID sid = dom_sids[i];
221 uint32 rid;
222 sid_split_rid(&sid, &rid);
223 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid);
224 make_dom_rid2(&(r_l->dom_rid[i]), rid, dom_types[i]);
227 r_l->num_entries3 = num_entries;
228 #endif
231 /***************************************************************************
232 make_lsa_trans_names
233 ***************************************************************************/
234 static void make_lsa_trans_names(DOM_R_REF *ref,
235 LSA_TRANS_NAME_ENUM *trn,
236 int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
237 uint32 *mapped_count)
239 int i;
240 int total = 0;
241 (*mapped_count) = 0;
243 SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
245 for (i = 0; i < num_entries; i++)
247 uint32 status = 0x0;
248 DOM_SID find_sid = sid[i].sid;
249 DOM_SID tmp_sid = sid[i].sid;
250 uint32 rid = 0xffffffff;
251 int dom_idx = -1;
252 fstring name;
253 fstring dom_name;
254 uint8 sid_name_use = 0;
256 memset(dom_name, 0, sizeof(dom_name));
257 memset(name , 0, sizeof(name ));
259 if (map_domain_sid_to_name(&find_sid, dom_name))
261 sid_name_use = SID_NAME_DOMAIN;
262 dom_idx = make_dom_ref(ref, dom_name, &find_sid);
264 else if (sid_split_rid (&find_sid, &rid) &&
265 map_domain_sid_to_name(&find_sid, dom_name))
267 if (sid_equal(&find_sid, &global_sam_sid))
269 status = lookup_sid(&tmp_sid, name, &sid_name_use);
271 else
273 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
276 else
278 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
281 dom_idx = make_dom_ref(ref, dom_name, &find_sid);
283 if (status == 0x0)
285 (*mapped_count)++;
287 else
289 snprintf(name, sizeof(name), "%08x", rid);
290 sid_name_use = SID_NAME_UNKNOWN;
293 make_lsa_trans_name(&(trn->name [total]),
294 &(trn->uni_name[total]),
295 sid_name_use, name, dom_idx);
296 total++;
299 trn->num_entries = total;
300 trn->ptr_trans_names = 1;
301 trn->num_entries2 = total;
304 /***************************************************************************
305 make_reply_lookup_sids
306 ***************************************************************************/
307 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
308 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
309 uint32 mapped_count, uint32 status)
311 r_l->dom_ref = ref;
312 r_l->names = names;
313 r_l->mapped_count = mapped_count;
314 r_l->status = status;
317 /***************************************************************************
318 lsa_reply_lookup_sids
319 ***************************************************************************/
320 static void lsa_reply_lookup_sids(prs_struct *rdata,
321 DOM_SID2 *sid, int num_entries)
323 LSA_R_LOOKUP_SIDS r_l;
324 DOM_R_REF ref;
325 LSA_TRANS_NAME_ENUM names;
326 uint32 mapped_count = 0;
328 ZERO_STRUCT(r_l);
329 ZERO_STRUCT(ref);
330 ZERO_STRUCT(names);
332 /* set up the LSA Lookup SIDs response */
333 make_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
334 make_reply_lookup_sids(&r_l, &ref, &names, mapped_count, 0x0);
336 /* store the response in the SMB stream */
337 lsa_io_r_lookup_sids("", &r_l, rdata, 0);
340 /***************************************************************************
341 lsa_reply_lookup_names
342 ***************************************************************************/
343 static void lsa_reply_lookup_names(prs_struct *rdata,
344 int num_entries,
345 DOM_SID dom_sids [MAX_LOOKUP_SIDS],
346 uint8 dom_types[MAX_LOOKUP_SIDS])
348 LSA_R_LOOKUP_NAMES r_l;
350 ZERO_STRUCT(r_l);
352 /* set up the LSA Lookup RIDs response */
353 make_reply_lookup_names(&r_l, num_entries, dom_sids, dom_types);
355 r_l.status = 0x0;
357 /* store the response in the SMB stream */
358 lsa_io_r_lookup_names("", &r_l, rdata, 0);
361 /***************************************************************************
362 api_lsa_open_policy
363 ***************************************************************************/
364 static void api_lsa_open_policy2( uint16 vuid, prs_struct *data,
365 prs_struct *rdata )
367 LSA_Q_OPEN_POL2 q_o;
369 ZERO_STRUCT(q_o);
371 /* grab the server, object attributes and desired access flag...*/
372 lsa_io_q_open_pol2("", &q_o, data, 0);
374 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
376 /* return a 20 byte policy handle */
377 lsa_reply_open_policy2(rdata);
380 /***************************************************************************
381 api_lsa_open_policy
382 ***************************************************************************/
383 static void api_lsa_open_policy( uint16 vuid, prs_struct *data,
384 prs_struct *rdata )
386 LSA_Q_OPEN_POL q_o;
388 ZERO_STRUCT(q_o);
390 /* grab the server, object attributes and desired access flag...*/
391 lsa_io_q_open_pol("", &q_o, data, 0);
393 /* lkclXXXX having decoded it, ignore all fields in the open policy! */
395 /* return a 20 byte policy handle */
396 lsa_reply_open_policy(rdata);
399 /***************************************************************************
400 api_lsa_enum_trust_dom
401 ***************************************************************************/
402 static void api_lsa_enum_trust_dom( uint16 vuid, prs_struct *data,
403 prs_struct *rdata )
405 LSA_Q_ENUM_TRUST_DOM q_e;
407 ZERO_STRUCT(q_e);
409 /* grab the enum trust domain context etc. */
410 lsa_io_q_enum_trust_dom("", &q_e, data, 0);
412 /* construct reply. return status is always 0x0 */
413 lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
416 /***************************************************************************
417 api_lsa_query_info
418 ***************************************************************************/
419 static void api_lsa_query_info( uint16 vuid, prs_struct *data,
420 prs_struct *rdata )
422 LSA_Q_QUERY_INFO q_i;
423 fstring name;
424 DOM_SID *sid = NULL;
425 memset(name, 0, sizeof(name));
427 ZERO_STRUCT(q_i);
429 /* grab the info class and policy handle */
430 lsa_io_q_query("", &q_i, data, 0);
432 switch (q_i.info_class)
434 case 0x03:
436 fstrcpy(name, global_myworkgroup);
437 sid = &global_member_sid;
438 break;
440 case 0x05:
442 fstrcpy(name, global_sam_name);
443 sid = &global_sam_sid;
444 break;
446 default:
448 DEBUG(5,("unknown info level in Lsa Query: %d\n",
449 q_i.info_class));
450 break;
454 /* construct reply. return status is always 0x0 */
455 lsa_reply_query_info(&q_i, rdata, name, sid);
458 /***************************************************************************
459 api_lsa_lookup_sids
460 ***************************************************************************/
461 static void api_lsa_lookup_sids( uint16 vuid, prs_struct *data,
462 prs_struct *rdata )
464 LSA_Q_LOOKUP_SIDS q_l;
465 ZERO_STRUCT(q_l);
467 /* grab the info class and policy handle */
468 lsa_io_q_lookup_sids("", &q_l, data, 0);
470 /* construct reply. return status is always 0x0 */
471 lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries);
474 /***************************************************************************
475 api_lsa_lookup_names
476 ***************************************************************************/
477 static void api_lsa_lookup_names( uint16 vuid, prs_struct *data,
478 prs_struct *rdata )
480 int i;
481 LSA_Q_LOOKUP_NAMES q_l;
482 DOM_SID dom_sids [MAX_LOOKUP_SIDS];
483 uint8 dom_types[MAX_LOOKUP_SIDS];
485 ZERO_STRUCT(q_l);
486 ZERO_ARRAY(dom_sids);
488 /* grab the info class and policy handle */
489 lsa_io_q_lookup_names("", &q_l, data, 0);
491 SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
493 /* convert received RIDs to strings, so we can do them. */
494 for (i = 0; i < q_l.num_entries; i++)
496 fstring name;
497 fstrcpy(name, unistr2_to_str(&q_l.uni_name[i]));
499 if (!lookup_name(name, &dom_sids[i], &dom_types[i]))
501 dom_types[i] = SID_NAME_UNKNOWN;
505 /* construct reply. return status is always 0x0 */
506 lsa_reply_lookup_names(rdata,
507 q_l.num_entries,
508 dom_sids, /* text-converted SIDs */
509 dom_types); /* SID_NAME_USE types */
512 /***************************************************************************
513 api_lsa_close
514 ***************************************************************************/
515 static void api_lsa_close( uint16 vuid, prs_struct *data,
516 prs_struct *rdata)
518 /* XXXX this is NOT good */
519 char *q = mem_data(&(rdata->data), rdata->offset);
521 SIVAL(q, 0, 0);
522 q += 4;
523 SIVAL(q, 0, 0);
524 q += 4;
525 SIVAL(q, 0, 0);
526 q += 4;
527 SIVAL(q, 0, 0);
528 q += 4;
529 SIVAL(q, 0, 0);
530 q += 4;
531 SIVAL(q, 0, 0);
532 q += 4;
534 rdata->offset += 24;
537 /***************************************************************************
538 api_lsa_open_secret
539 ***************************************************************************/
540 static void api_lsa_open_secret( uint16 vuid, prs_struct *data,
541 prs_struct *rdata)
543 /* XXXX this is NOT good */
544 char *q = mem_data(&(rdata->data), rdata->offset);
546 SIVAL(q, 0, 0);
547 q += 4;
548 SIVAL(q, 0, 0);
549 q += 4;
550 SIVAL(q, 0, 0);
551 q += 4;
552 SIVAL(q, 0, 0);
553 q += 4;
554 SIVAL(q, 0, 0);
555 q += 4;
556 SIVAL(q, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND);
557 q += 4;
559 rdata->offset += 24;
562 /***************************************************************************
563 \PIPE\ntlsa commands
564 ***************************************************************************/
565 static struct api_struct api_lsa_cmds[] =
567 { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
568 { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
569 { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
570 { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
571 { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
572 { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
573 { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
574 { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
575 { NULL , 0 , NULL }
578 /***************************************************************************
579 api_ntLsarpcTNP
580 ***************************************************************************/
581 BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
583 return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);