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