Fixed "object picker can't determine if object in domain" bug seen from W2K
[amitay/samba.git] / source3 / rpc_server / srv_lsa.c
1 #define OLD_NTDOMAIN 1
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.
10  *
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.
15  *  
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.
20  *  
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.
24  */
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29 extern DOM_SID global_sam_sid;
30 extern fstring global_myworkgroup;
31 extern pstring global_myname;
32
33 /***************************************************************************
34  lsa_reply_open_policy2
35  ***************************************************************************/
36
37 static BOOL lsa_reply_open_policy2(prs_struct *rdata)
38 {
39         int i;
40         LSA_R_OPEN_POL2 r_o;
41
42         ZERO_STRUCT(r_o);
43
44         /* set up the LSA QUERY INFO response */
45
46         for (i = 4; i < POL_HND_SIZE; i++)
47                 r_o.pol.data[i] = i;
48         r_o.status = 0x0;
49
50         /* store the response in the SMB stream */
51         if(!lsa_io_r_open_pol2("", &r_o, rdata, 0)) {
52                 DEBUG(0,("lsa_reply_open_policy2: unable to marshall LSA_R_OPEN_POL2.\n"));
53                 return False;
54         }
55
56         return True;
57 }
58
59 /***************************************************************************
60 lsa_reply_open_policy
61  ***************************************************************************/
62
63 static BOOL lsa_reply_open_policy(prs_struct *rdata)
64 {
65         int i;
66         LSA_R_OPEN_POL r_o;
67
68         ZERO_STRUCT(r_o);
69
70         /* set up the LSA QUERY INFO response */
71
72         for (i = 4; i < POL_HND_SIZE; i++)
73                 r_o.pol.data[i] = i;
74         r_o.status = 0x0;
75
76         /* store the response in the SMB stream */
77         if(!lsa_io_r_open_pol("", &r_o, rdata, 0)) {
78                 DEBUG(0,("lsa_reply_open_policy: unable to marshall LSA_R_OPEN_POL.\n"));
79                 return False;
80         }
81
82         return True;
83 }
84
85 /***************************************************************************
86 Init dom_query
87  ***************************************************************************/
88
89 static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
90 {
91         int domlen = (dom_name != NULL) ? strlen(dom_name) : 0;
92
93         d_q->uni_dom_max_len = domlen * 2;
94         d_q->uni_dom_str_len = domlen * 2;
95
96         d_q->buffer_dom_name = dom_name ? 1 : 0;
97         d_q->buffer_dom_sid  = dom_sid ? 1 : 0;
98
99         /* this string is supposed to be character short */
100         init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
101         if (dom_sid != NULL)
102                 init_dom_sid2(&d_q->dom_sid, dom_sid);
103 }
104
105 /***************************************************************************
106  lsa_reply_enum_trust_dom
107  ***************************************************************************/
108
109 static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
110                                 prs_struct *rdata,
111                                 uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
112 {
113         LSA_R_ENUM_TRUST_DOM r_e;
114
115         ZERO_STRUCT(r_e);
116
117         /* set up the LSA QUERY INFO response */
118         init_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
119               dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
120
121         /* store the response in the SMB stream */
122         lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
123 }
124
125 /***************************************************************************
126 lsa_reply_query_info
127  ***************************************************************************/
128
129 static BOOL lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata, LSA_R_QUERY_INFO *r_q)
130 {
131         /* set up the LSA QUERY INFO response */
132
133         if(r_q->status == 0) {
134                 r_q->undoc_buffer = 0x22000000; /* bizarre */
135                 r_q->info_class = q_q->info_class;
136         }
137
138         /* store the response in the SMB stream */
139         if(!lsa_io_r_query("", r_q, rdata, 0)) {
140                 DEBUG(0,("lsa_reply_query_info: failed to marshall LSA_R_QUERY_INFO.\n"));
141                 return False;
142         }
143
144         return True;
145 }
146
147 /***************************************************************************
148  init_dom_ref - adds a domain if it's not already in, returns the index.
149 ***************************************************************************/
150
151 static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
152 {
153         int num = 0;
154         int len;
155
156         if (dom_name != NULL) {
157                 for (num = 0; num < ref->num_ref_doms_1; num++) {
158                         fstring domname;
159                         fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
160                         if (strequal(domname, dom_name))
161                                 return num;
162                 }
163         } else {
164                 num = ref->num_ref_doms_1;
165         }
166
167         if (num >= MAX_REF_DOMAINS) {
168                 /* index not found, already at maximum domain limit */
169                 return -1;
170         }
171
172         ref->num_ref_doms_1 = num+1;
173         ref->ptr_ref_dom  = 1;
174         ref->max_entries = MAX_REF_DOMAINS;
175         ref->num_ref_doms_2 = num+1;
176
177         len = (dom_name != NULL) ? strlen(dom_name) : 0;
178         if(dom_name != NULL && len == 0)
179                 len = 1;
180
181         init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
182         ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
183
184         init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
185         init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
186
187         return num;
188 }
189
190 /***************************************************************************
191  init_lsa_rid2s
192  ***************************************************************************/
193
194 static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
195                                 int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
196                                 uint32 *mapped_count)
197 {
198         int i;
199         int total = 0;
200         *mapped_count = 0;
201
202         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
203
204         for (i = 0; i < num_entries; i++) {
205                 BOOL status = False;
206                 DOM_SID sid;
207                 uint32 rid = 0xffffffff;
208                 int dom_idx = -1;
209                 pstring full_name;
210                 fstring dom_name, user;
211                 enum SID_NAME_USE name_type = SID_NAME_UNKNOWN;
212
213                 /* Split name into domain and user component */
214
215                 pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
216                 split_domain_name(full_name, dom_name, user);
217
218                 /* Lookup name */
219
220                 DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
221
222                 status = lookup_name(full_name, &sid, &name_type);
223
224                 DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : 
225                           "not found"));
226
227                 if (status) {
228                         sid_split_rid(&sid, &rid);
229                         dom_idx = init_dom_ref(ref, dom_name, &sid);
230                         (*mapped_count)++;
231                 } else {
232                         dom_idx = -1;
233                         rid = 0xffffffff;
234                         name_type = SID_NAME_UNKNOWN;
235                 }
236
237                 init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
238                 total++;
239         }
240 }
241
242 /***************************************************************************
243  init_reply_lookup_names
244  ***************************************************************************/
245
246 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
247                 DOM_R_REF *ref, uint32 num_entries,
248                 DOM_RID2 *rid2, uint32 mapped_count)
249 {
250         r_l->ptr_dom_ref  = 1;
251         r_l->dom_ref      = ref;
252
253         r_l->num_entries  = num_entries;
254         r_l->ptr_entries  = 1;
255         r_l->num_entries2 = num_entries;
256         r_l->dom_rid      = rid2;
257
258         r_l->mapped_count = mapped_count;
259
260         if (mapped_count == 0)
261                 r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
262         else
263                 r_l->status = 0x0;
264 }
265
266 /***************************************************************************
267  Init lsa_trans_names.
268  ***************************************************************************/
269
270 static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
271                                  int num_entries, DOM_SID2 *sid,
272                                  uint32 *mapped_count)
273 {
274         int i;
275         int total = 0;
276         *mapped_count = 0;
277
278         /* Allocate memory for list of names */
279
280         if (num_entries > 0) {
281                 if (!(trn->name = (LSA_TRANS_NAME *)talloc(ctx, sizeof(LSA_TRANS_NAME) *
282                                                           num_entries))) {
283                         DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
284                         return;
285                 }
286
287                 if (!(trn->uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2) * 
288                                                         num_entries))) {
289                         DEBUG(0, ("init_lsa_trans_names(): out of memory\n"));
290                         return;
291                 }
292         }
293
294         for (i = 0; i < num_entries; i++) {
295                 BOOL status = False;
296                 DOM_SID find_sid = sid[i].sid;
297                 uint32 rid = 0xffffffff;
298                 int dom_idx = -1;
299                 fstring name, dom_name;
300                 enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0;
301
302                 sid_to_string(name, &find_sid);
303                 DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name));
304
305                 /* Lookup sid from winbindd */
306
307                 memset(dom_name, '\0', sizeof(dom_name));
308                 memset(name, '\0', sizeof(name));
309
310                 status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
311
312                 DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" : 
313                           "not found"));
314
315                 if (!status) {
316                         sid_name_use = SID_NAME_UNKNOWN;
317                 }
318
319                 /* Store domain sid in ref array */
320
321                 if (find_sid.num_auths == 5) {
322                         sid_split_rid(&find_sid, &rid);
323                 }
324
325                 dom_idx = init_dom_ref(ref, dom_name, &find_sid);
326
327                 DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
328                           "referenced list.\n", dom_name, name ));
329
330                 (*mapped_count)++;
331
332                 init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
333                                         sid_name_use, name, dom_idx);
334                 total++;
335         }
336
337         trn->num_entries = total;
338         trn->ptr_trans_names = 1;
339         trn->num_entries2 = total;
340 }
341
342 /***************************************************************************
343  Init_reply_lookup_sids.
344  ***************************************************************************/
345
346 static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
347                 DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
348                 uint32 mapped_count)
349 {
350         r_l->ptr_dom_ref  = 1;
351         r_l->dom_ref      = ref;
352         r_l->names        = names;
353         r_l->mapped_count = mapped_count;
354
355         if (mapped_count == 0)
356                 r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
357         else
358                 r_l->status = 0x0;
359 }
360
361 /***************************************************************************
362 lsa_reply_lookup_sids
363  ***************************************************************************/
364
365 static BOOL lsa_reply_lookup_sids(prs_struct *rdata, DOM_SID2 *sid, int num_entries)
366 {
367         LSA_R_LOOKUP_SIDS r_l;
368         DOM_R_REF ref;
369         LSA_TRANS_NAME_ENUM names;
370         uint32 mapped_count = 0;
371         TALLOC_CTX *ctx = talloc_init();
372
373         ZERO_STRUCT(r_l);
374         ZERO_STRUCT(ref);
375         ZERO_STRUCT(names);
376
377         /* set up the LSA Lookup SIDs response */
378         init_lsa_trans_names(ctx, &ref, &names, num_entries, sid, &mapped_count);
379         init_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
380
381         /* store the response in the SMB stream */
382         if(!lsa_io_r_lookup_sids("", &r_l, rdata, 0)) {
383                 DEBUG(0,("lsa_reply_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n"));
384                 talloc_destroy(ctx);
385                 return False;
386         }
387
388         talloc_destroy(ctx);
389         return True;
390 }
391
392 /***************************************************************************
393 lsa_reply_lookup_names
394  ***************************************************************************/
395
396 static BOOL lsa_reply_lookup_names(prs_struct *rdata, UNISTR2 *names, 
397                                    int num_entries)
398 {
399         LSA_R_LOOKUP_NAMES r_l;
400         DOM_R_REF ref;
401         DOM_RID2 rids[MAX_LOOKUP_SIDS];
402         uint32 mapped_count = 0;
403         BOOL result = True;
404
405         ZERO_STRUCT(r_l);
406         ZERO_STRUCT(ref);
407         ZERO_ARRAY(rids);
408
409         /* set up the LSA Lookup RIDs response */
410         init_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
411         init_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
412
413         /* store the response in the SMB stream */
414         if(!lsa_io_r_lookup_names("", &r_l, rdata, 0)) {
415                 DEBUG(0,("lsa_reply_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n"));
416                 result = False;
417         }
418
419         return result;
420 }
421
422 /***************************************************************************
423  api_lsa_open_policy2
424  ***************************************************************************/
425
426 static BOOL api_lsa_open_policy2(pipes_struct *p)
427 {
428         prs_struct *data = &p->in_data.data;
429         prs_struct *rdata = &p->out_data.rdata;
430
431         LSA_Q_OPEN_POL2 q_o;
432
433         ZERO_STRUCT(q_o);
434
435         /* grab the server, object attributes and desired access flag...*/
436         if(!lsa_io_q_open_pol2("", &q_o, data, 0)) {
437                 DEBUG(0,("api_lsa_open_policy2: unable to unmarshall LSA_Q_OPEN_POL2.\n"));
438                 return False;
439         }
440
441         /* lkclXXXX having decoded it, ignore all fields in the open policy! */
442
443         /* return a 20 byte policy handle */
444         if(!lsa_reply_open_policy2(rdata))
445                 return False;
446
447         return True;
448 }
449
450 /***************************************************************************
451 api_lsa_open_policy
452  ***************************************************************************/
453 static BOOL api_lsa_open_policy(pipes_struct *p)
454 {
455         prs_struct *data = &p->in_data.data;
456         prs_struct *rdata = &p->out_data.rdata;
457
458         LSA_Q_OPEN_POL q_o;
459
460         ZERO_STRUCT(q_o);
461
462         /* grab the server, object attributes and desired access flag...*/
463         if(!lsa_io_q_open_pol("", &q_o, data, 0)) {
464                 DEBUG(0,("api_lsa_open_policy: unable to unmarshall LSA_Q_OPEN_POL.\n"));
465                 return False;
466         }
467
468         /* lkclXXXX having decoded it, ignore all fields in the open policy! */
469
470         /* return a 20 byte policy handle */
471         if(!lsa_reply_open_policy(rdata))
472                 return False;
473
474         return True;
475 }
476
477 /***************************************************************************
478 api_lsa_enum_trust_dom
479  ***************************************************************************/
480 static BOOL api_lsa_enum_trust_dom(pipes_struct *p)
481 {
482         LSA_Q_ENUM_TRUST_DOM q_e;
483         prs_struct *data = &p->in_data.data;
484         prs_struct *rdata = &p->out_data.rdata;
485
486         ZERO_STRUCT(q_e);
487
488         /* grab the enum trust domain context etc. */
489         if(!lsa_io_q_enum_trust_dom("", &q_e, data, 0))
490                 return False;
491
492         /* construct reply.  return status is always 0x0 */
493         lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
494
495         return True;
496 }
497
498 /***************************************************************************
499 api_lsa_query_info
500  ***************************************************************************/
501 static BOOL api_lsa_query_info(pipes_struct *p)
502 {
503         LSA_Q_QUERY_INFO q_i;
504         LSA_R_QUERY_INFO r_q;
505         LSA_INFO_UNION *info = &r_q.dom;
506         DOM_SID domain_sid;
507         char *name = NULL;
508         DOM_SID *sid = NULL;
509         prs_struct *data = &p->in_data.data;
510         prs_struct *rdata = &p->out_data.rdata;
511
512         ZERO_STRUCT(q_i);
513         ZERO_STRUCT(r_q);
514
515         /* grab the info class and policy handle */
516         if(!lsa_io_q_query("", &q_i, data, 0)) {
517                 DEBUG(0,("api_lsa_query_info: failed to unmarshall LSA_Q_QUERY_INFO.\n"));
518                 return False;
519         }
520
521         switch (q_i.info_class) {
522         case 0x02:
523                 {
524                         unsigned int i;
525                         /* fake info: We audit everything. ;) */
526                         info->id2.auditing_enabled = 1;
527             info->id2.count1 = 7;
528             info->id2.count2 = 7;
529                         if ((info->id2.auditsettings = (uint32 *)talloc(prs_get_mem_context(rdata),7*sizeof(uint32))) == NULL)
530                                 return False;
531             for (i = 0; i < 7; i++)
532                 info->id2.auditsettings[i] = 3;
533             break;
534                 }
535         case 0x03:
536                 switch (lp_server_role())
537                 {
538                         case ROLE_DOMAIN_PDC:
539                         case ROLE_DOMAIN_BDC:
540                                 name = global_myworkgroup;
541                                 sid = &global_sam_sid;
542                                 break;
543                         case ROLE_DOMAIN_MEMBER:
544                                 if (secrets_fetch_domain_sid(global_myworkgroup,
545                                         &domain_sid))
546                                 {
547                                         name = global_myworkgroup;
548                                         sid = &domain_sid;
549                                 }
550                         default:
551                                 break;
552                 }
553                 init_dom_query(&r_q.dom.id3, name, sid);
554                 break;
555         case 0x05:
556                 name = global_myname;
557                 sid = &global_sam_sid;
558                 init_dom_query(&r_q.dom.id5, name, sid);
559                 break;
560         case 0x06:
561                 switch (lp_server_role())
562                 {
563                         case ROLE_DOMAIN_BDC:
564                                 /*
565                                  * only a BDC is a backup controller
566                                  * of the domain, it controls.
567                                  */
568                                 info->id6.server_role = 2;
569                                 break;
570                         default:
571                                 /*
572                                  * any other role is a primary
573                                  * of the domain, it controls.
574                                  */
575                                 info->id6.server_role = 3;
576                                 break; 
577                 }
578                 break;
579         default:
580                 DEBUG(0,("api_lsa_query_info: unknown info level in Lsa Query: %d\n", q_i.info_class));
581                 r_q.status = (NT_STATUS_INVALID_INFO_CLASS | 0xC0000000);
582                 break;
583         }
584
585         /* construct reply.  return status is always 0x0 */
586         if(!lsa_reply_query_info(&q_i, rdata, &r_q))
587                 return False;
588
589         return True;
590 }
591
592 /***************************************************************************
593  api_lsa_lookup_sids
594  ***************************************************************************/
595
596 static BOOL api_lsa_lookup_sids(pipes_struct *p)
597 {
598         LSA_Q_LOOKUP_SIDS q_l;
599         prs_struct *data = &p->in_data.data;
600         prs_struct *rdata = &p->out_data.rdata;
601         BOOL result = True;
602
603         ZERO_STRUCT(q_l);
604
605         /* grab the info class and policy handle */
606         if(!lsa_io_q_lookup_sids("", &q_l, data, 0)) {
607                 DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n"));
608                 result = False;
609         }
610
611         /* construct reply.  return status is always 0x0 */
612         if(!lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries)) {
613                 result = False;
614         }
615
616         return result;
617 }
618
619 /***************************************************************************
620  api_lsa_lookup_names
621  ***************************************************************************/
622
623 static BOOL api_lsa_lookup_names(pipes_struct *p)
624 {
625         LSA_Q_LOOKUP_NAMES q_l;
626         prs_struct *data = &p->in_data.data;
627         prs_struct *rdata = &p->out_data.rdata;
628
629         ZERO_STRUCT(q_l);
630
631         /* grab the info class and policy handle */
632         if(!lsa_io_q_lookup_names("", &q_l, data, 0)) {
633                 DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n"));
634                 return False;
635         }
636
637         return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
638 }
639
640 /***************************************************************************
641  api_lsa_close
642  ***************************************************************************/
643 static BOOL api_lsa_close(pipes_struct *p)
644 {
645         LSA_R_CLOSE r_c;
646         prs_struct *rdata = &p->out_data.rdata;
647
648         ZERO_STRUCT(r_c);
649
650         /* store the response in the SMB stream */
651         if (!lsa_io_r_close("", &r_c, rdata, 0)) {
652                 DEBUG(0,("api_lsa_close: lsa_io_r_close failed.\n"));
653                 return False;
654         }
655
656         return True;
657 }
658
659 /***************************************************************************
660  api_lsa_open_secret
661  ***************************************************************************/
662 static BOOL api_lsa_open_secret(pipes_struct *p)
663 {
664         /* XXXX this is NOT good */
665         size_t i;
666         uint32 dummy = 0;
667         prs_struct *rdata = &p->out_data.rdata;
668
669         for(i =0; i < 4; i++) {
670                 if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
671                         DEBUG(0,("api_lsa_open_secret: prs_uint32 %d failed.\n",
672                                 (int)i ));
673                         return False;
674                 }
675         }
676
677         dummy = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
678         if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
679                 DEBUG(0,("api_lsa_open_secret: prs_uint32 status failed.\n"));
680                 return False;
681         }
682
683         return True;
684 }
685
686 /***************************************************************************
687  \PIPE\ntlsa commands
688  ***************************************************************************/
689 static struct api_struct api_lsa_cmds[] =
690 {
691         { "LSA_OPENPOLICY2"     , LSA_OPENPOLICY2     , api_lsa_open_policy2   },
692         { "LSA_OPENPOLICY"      , LSA_OPENPOLICY      , api_lsa_open_policy    },
693         { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info     },
694         { "LSA_ENUMTRUSTDOM"    , LSA_ENUMTRUSTDOM    , api_lsa_enum_trust_dom },
695         { "LSA_CLOSE"           , LSA_CLOSE           , api_lsa_close          },
696         { "LSA_OPENSECRET"      , LSA_OPENSECRET      , api_lsa_open_secret    },
697         { "LSA_LOOKUPSIDS"      , LSA_LOOKUPSIDS      , api_lsa_lookup_sids    },
698         { "LSA_LOOKUPNAMES"     , LSA_LOOKUPNAMES     , api_lsa_lookup_names   },
699         { NULL                  , 0                   , NULL                   }
700 };
701
702 /***************************************************************************
703  api_ntLsarpcTNP
704  ***************************************************************************/
705 BOOL api_ntlsa_rpc(pipes_struct *p)
706 {
707         return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds);
708 }
709
710 #undef OLD_NTDOMAIN