r24784: Initialize uninitalized data to prevent segfaults.
[nivanova/samba-autobuild/.git] / source3 / rpc_client / cli_lsarpc.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4    Copyright (C) Tim Potter                        2000-2001,
5    Copyright (C) Andrew Tridgell              1992-1997,2000,
6    Copyright (C) Rafal Szczesniak                       2002
7    Copyright (C) Jeremy Allison                         2005.
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24
25 /** @defgroup lsa LSA - Local Security Architecture
26  *  @ingroup rpc_client
27  *
28  * @{
29  **/
30
31 /**
32  * @file cli_lsarpc.c
33  *
34  * RPC client routines for the LSA RPC pipe.  LSA means "local
35  * security authority", which is half of a password database.
36  **/
37
38 /** Open a LSA policy handle
39  *
40  * @param cli Handle on an initialised SMB connection */
41
42 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
43                                 TALLOC_CTX *mem_ctx,
44                                 BOOL sec_qos, uint32 des_access,
45                                 POLICY_HND *pol)
46 {
47         prs_struct qbuf, rbuf;
48         LSA_Q_OPEN_POL q;
49         LSA_R_OPEN_POL r;
50         LSA_SEC_QOS qos;
51         NTSTATUS result;
52
53         ZERO_STRUCT(q);
54         ZERO_STRUCT(r);
55
56         /* Initialise input parameters */
57
58         if (sec_qos) {
59                 init_lsa_sec_qos(&qos, 2, 1, 0);
60                 init_q_open_pol(&q, '\\', 0, des_access, &qos);
61         } else {
62                 init_q_open_pol(&q, '\\', 0, des_access, NULL);
63         }
64
65         /* Marshall data and send request */
66
67         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY,
68                         q, r,
69                         qbuf, rbuf,
70                         lsa_io_q_open_pol,
71                         lsa_io_r_open_pol,
72                         NT_STATUS_UNSUCCESSFUL );
73
74         /* Return output parameters */
75
76         result = r.status;
77
78         if (NT_STATUS_IS_OK(result)) {
79                 *pol = r.pol;
80         }
81
82         return result;
83 }
84
85 /** Open a LSA policy handle
86   *
87   * @param cli Handle on an initialised SMB connection 
88   */
89
90 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
91                                  TALLOC_CTX *mem_ctx, BOOL sec_qos,
92                                  uint32 des_access, POLICY_HND *pol)
93 {
94         prs_struct qbuf, rbuf;
95         LSA_Q_OPEN_POL2 q;
96         LSA_R_OPEN_POL2 r;
97         LSA_SEC_QOS qos;
98         NTSTATUS result;
99         char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
100
101         ZERO_STRUCT(q);
102         ZERO_STRUCT(r);
103
104         if (sec_qos) {
105                 init_lsa_sec_qos(&qos, 2, 1, 0);
106                 init_q_open_pol2(&q, srv_name_slash, 0, des_access, &qos);
107         } else {
108                 init_q_open_pol2(&q, srv_name_slash, 0, des_access, NULL);
109         }
110
111         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY2,
112                         q, r,
113                         qbuf, rbuf,
114                         lsa_io_q_open_pol2,
115                         lsa_io_r_open_pol2,
116                         NT_STATUS_UNSUCCESSFUL );
117
118         /* Return output parameters */
119
120         result = r.status;
121
122         if (NT_STATUS_IS_OK(result)) {
123                 *pol = r.pol;
124         }
125
126         return result;
127 }
128
129 /* Lookup a list of sids
130  *
131  * internal version withOUT memory allocation of the target arrays.
132  * this assumes suffciently sized arrays to store domains, names and types. */
133
134 static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli,
135                                                TALLOC_CTX *mem_ctx,
136                                                POLICY_HND *pol,
137                                                int num_sids,
138                                                const DOM_SID *sids,
139                                                char **domains,
140                                                char **names,
141                                                enum lsa_SidType *types)
142 {
143         prs_struct qbuf, rbuf;
144         LSA_Q_LOOKUP_SIDS q;
145         LSA_R_LOOKUP_SIDS r;
146         DOM_R_REF ref;
147         NTSTATUS result = NT_STATUS_OK;
148         TALLOC_CTX *tmp_ctx = NULL;
149         int i;
150
151         tmp_ctx = talloc_new(mem_ctx);
152         if (!tmp_ctx) {
153                 DEBUG(0, ("rpccli_lsa_lookup_sids_noalloc: out of memory!\n"));
154                 result = NT_STATUS_UNSUCCESSFUL;
155                 goto done;
156         }
157
158         ZERO_STRUCT(q);
159         ZERO_STRUCT(r);
160
161         init_q_lookup_sids(tmp_ctx, &q, pol, num_sids, sids, 1);
162
163         ZERO_STRUCT(ref);
164
165         r.dom_ref = &ref;
166
167         CLI_DO_RPC( cli, tmp_ctx, PI_LSARPC, LSA_LOOKUPSIDS,
168                         q, r,
169                         qbuf, rbuf,
170                         lsa_io_q_lookup_sids,
171                         lsa_io_r_lookup_sids,
172                         NT_STATUS_UNSUCCESSFUL );
173
174         if (!NT_STATUS_IS_OK(r.status) &&
175             !NT_STATUS_EQUAL(r.status, STATUS_SOME_UNMAPPED)) 
176         {
177                 /* An actual error occured */
178                 result = r.status;
179                 goto done;
180         }
181
182         /* Return output parameters */
183
184         if (r.mapped_count == 0) {
185                 for (i = 0; i < num_sids; i++) {
186                         (names)[i] = NULL;
187                         (domains)[i] = NULL;
188                         (types)[i] = SID_NAME_UNKNOWN;
189                 }
190                 result = NT_STATUS_NONE_MAPPED;
191                 goto done;
192         }
193
194         for (i = 0; i < num_sids; i++) {
195                 fstring name, dom_name;
196                 uint32 dom_idx = r.names.name[i].domain_idx;
197
198                 /* Translate optimised name through domain index array */
199
200                 if (dom_idx != 0xffffffff) {
201
202                         rpcstr_pull_unistr2_fstring(
203                                 dom_name, &ref.ref_dom[dom_idx].uni_dom_name);
204                         rpcstr_pull_unistr2_fstring(
205                                 name, &r.names.uni_name[i]);
206
207                         (names)[i] = talloc_strdup(mem_ctx, name);
208                         (domains)[i] = talloc_strdup(mem_ctx, dom_name);
209                         (types)[i] = (enum lsa_SidType)r.names.name[i].sid_name_use;
210                         
211                         if (((names)[i] == NULL) || ((domains)[i] == NULL)) {
212                                 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
213                                 result = NT_STATUS_UNSUCCESSFUL;
214                                 goto done;
215                         }
216
217                 } else {
218                         (names)[i] = NULL;
219                         (domains)[i] = NULL;
220                         (types)[i] = SID_NAME_UNKNOWN;
221                 }
222         }
223
224 done:
225         TALLOC_FREE(tmp_ctx);
226         return result;
227 }
228
229 /* Lookup a list of sids 
230  *
231  * do it the right way: there is a limit (of 20480 for w2k3) entries
232  * returned by this call. when the sids list contains more entries,
233  * empty lists are returned. This version of lsa_lookup_sids passes
234  * the list of sids in hunks of LOOKUP_SIDS_HUNK_SIZE to the lsa call. */
235
236 /* This constant defines the limit of how many sids to look up
237  * in one call (maximum). the limit from the server side is
238  * at 20480 for win2k3, but we keep it at a save 1000 for now. */
239 #define LOOKUP_SIDS_HUNK_SIZE 1000
240
241 NTSTATUS rpccli_lsa_lookup_sids_all(struct rpc_pipe_client *cli,
242                                     TALLOC_CTX *mem_ctx,
243                                     POLICY_HND *pol, 
244                                     int num_sids,
245                                     const DOM_SID *sids, 
246                                     char ***domains,
247                                     char ***names,
248                                     enum lsa_SidType **types)
249 {
250         NTSTATUS result = NT_STATUS_OK;
251         int sids_left = 0;
252         int sids_processed = 0;
253         const DOM_SID *hunk_sids = sids;
254         char **hunk_domains = NULL;
255         char **hunk_names = NULL;
256         enum lsa_SidType *hunk_types = NULL;
257
258         if (num_sids) {
259                 if (!((*domains) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
260                         DEBUG(0, ("rpccli_lsa_lookup_sids_all(): out of memory\n"));
261                         result = NT_STATUS_NO_MEMORY;
262                         goto done;
263                 }
264
265                 if (!((*names) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
266                         DEBUG(0, ("rpccli_lsa_lookup_sids_all(): out of memory\n"));
267                         result = NT_STATUS_NO_MEMORY;
268                         goto done;
269                 }
270
271                 if (!((*types) = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
272                         DEBUG(0, ("rpccli_lsa_lookup_sids_all(): out of memory\n"));
273                         result = NT_STATUS_NO_MEMORY;
274                         goto done;
275                 }
276         } else {
277                 (*domains) = NULL;
278                 (*names) = NULL;
279                 (*types) = NULL;
280         }
281         
282         sids_left = num_sids;
283         hunk_domains = *domains;
284         hunk_names = *names;
285         hunk_types = *types;
286
287         while (sids_left > 0) {
288                 int hunk_num_sids;
289                 NTSTATUS hunk_result = NT_STATUS_OK;
290
291                 hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE) 
292                                 ? LOOKUP_SIDS_HUNK_SIZE 
293                                 : sids_left);
294
295                 DEBUG(10, ("rpccli_lsa_lookup_sids_all: processing items "
296                            "%d -- %d of %d.\n", 
297                            sids_processed, 
298                            sids_processed + hunk_num_sids - 1,
299                            num_sids));
300
301                 hunk_result = rpccli_lsa_lookup_sids_noalloc(cli,
302                                                              mem_ctx,
303                                                              pol,
304                                                              hunk_num_sids, 
305                                                              hunk_sids,
306                                                              hunk_domains,
307                                                              hunk_names,
308                                                              hunk_types);
309
310                 if (!NT_STATUS_IS_OK(hunk_result) &&
311                     !NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED) &&
312                     !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) 
313                 {
314                         /* An actual error occured */
315                         goto done;
316                 }
317
318                 /* adapt overall result */
319                 if (( NT_STATUS_IS_OK(result) && 
320                      !NT_STATUS_IS_OK(hunk_result)) 
321                     ||
322                     ( NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) &&
323                      !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)))
324                 {
325                         result = STATUS_SOME_UNMAPPED;
326                 }
327
328                 sids_left -= hunk_num_sids;
329                 sids_processed += hunk_num_sids; /* only used in DEBUG */
330                 hunk_sids += hunk_num_sids;
331                 hunk_domains += hunk_num_sids;
332                 hunk_names += hunk_num_sids;
333                 hunk_types += hunk_num_sids;
334         }
335
336 done:
337         return result;
338 }
339
340 /** Lookup a list of sids */
341
342 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
343                                 TALLOC_CTX *mem_ctx,
344                                 POLICY_HND *pol, int num_sids,
345                                 const DOM_SID *sids, 
346                                 char ***domains,
347                                 char ***names,
348                                 enum lsa_SidType **types)
349 {
350         prs_struct qbuf, rbuf;
351         LSA_Q_LOOKUP_SIDS q;
352         LSA_R_LOOKUP_SIDS r;
353         DOM_R_REF ref;
354         NTSTATUS result = NT_STATUS_OK;
355         int i;
356
357         ZERO_STRUCT(q);
358         ZERO_STRUCT(r);
359
360         init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);
361
362         ZERO_STRUCT(ref);
363
364         r.dom_ref = &ref;
365
366         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPSIDS,
367                         q, r,
368                         qbuf, rbuf,
369                         lsa_io_q_lookup_sids,
370                         lsa_io_r_lookup_sids,
371                         NT_STATUS_UNSUCCESSFUL );
372
373         if (!NT_STATUS_IS_OK(r.status) &&
374             !NT_STATUS_EQUAL(r.status, STATUS_SOME_UNMAPPED)) {
375           
376                 /* An actual error occured */
377                 result = r.status;
378
379                 goto done;
380         }
381
382         /* Return output parameters */
383
384         if (r.mapped_count == 0) {
385                 result = NT_STATUS_NONE_MAPPED;
386                 goto done;
387         }
388
389         if (num_sids) {
390                 if (!((*domains) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
391                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
392                         result = NT_STATUS_NO_MEMORY;
393                         goto done;
394                 }
395
396                 if (!((*names) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
397                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
398                         result = NT_STATUS_NO_MEMORY;
399                         goto done;
400                 }
401
402                 if (!((*types) = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) {
403                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
404                         result = NT_STATUS_NO_MEMORY;
405                         goto done;
406                 }
407         } else {
408                 (*domains) = NULL;
409                 (*names) = NULL;
410                 (*types) = NULL;
411         }
412                 
413         for (i = 0; i < num_sids; i++) {
414                 fstring name, dom_name;
415                 uint32 dom_idx = r.names.name[i].domain_idx;
416
417                 /* Translate optimised name through domain index array */
418
419                 if (dom_idx != 0xffffffff) {
420
421                         rpcstr_pull_unistr2_fstring(
422                                 dom_name, &ref.ref_dom[dom_idx].uni_dom_name);
423                         rpcstr_pull_unistr2_fstring(
424                                 name, &r.names.uni_name[i]);
425
426                         (*names)[i] = talloc_strdup(mem_ctx, name);
427                         (*domains)[i] = talloc_strdup(mem_ctx, dom_name);
428                         (*types)[i] = (enum lsa_SidType)r.names.name[i].sid_name_use;
429                         
430                         if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) {
431                                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
432                                 result = NT_STATUS_UNSUCCESSFUL;
433                                 goto done;
434                         }
435
436                 } else {
437                         (*names)[i] = NULL;
438                         (*domains)[i] = NULL;
439                         (*types)[i] = SID_NAME_UNKNOWN;
440                 }
441         }
442
443  done:
444
445         return result;
446 }
447
448 /** Lookup a list of names */
449
450 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
451                                  TALLOC_CTX *mem_ctx,
452                                  POLICY_HND *pol, int num_names, 
453                                  const char **names,
454                                  const char ***dom_names,
455                                  int level,
456                                  DOM_SID **sids,
457                                  enum lsa_SidType **types)
458 {
459         prs_struct qbuf, rbuf;
460         LSA_Q_LOOKUP_NAMES q;
461         LSA_R_LOOKUP_NAMES r;
462         DOM_R_REF ref;
463         NTSTATUS result;
464         int i;
465         
466         ZERO_STRUCT(q);
467         ZERO_STRUCT(r);
468
469         ZERO_STRUCT(ref);
470         r.dom_ref = &ref;
471
472         init_q_lookup_names(mem_ctx, &q, pol, num_names, names, level);
473
474         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPNAMES,
475                         q, r,
476                         qbuf, rbuf,
477                         lsa_io_q_lookup_names,
478                         lsa_io_r_lookup_names,
479                         NT_STATUS_UNSUCCESSFUL);
480
481         result = r.status;
482
483         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
484             NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
485
486                 /* An actual error occured */
487
488                 goto done;
489         }
490
491         /* Return output parameters */
492
493         if (r.mapped_count == 0) {
494                 result = NT_STATUS_NONE_MAPPED;
495                 goto done;
496         }
497
498         if (num_names) {
499                 if (!((*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_names)))) {
500                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
501                         result = NT_STATUS_NO_MEMORY;
502                         goto done;
503                 }
504
505                 if (!((*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_names)))) {
506                         DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
507                         result = NT_STATUS_NO_MEMORY;
508                         goto done;
509                 }
510
511                 if (dom_names != NULL) {
512                         *dom_names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
513                         if (*dom_names == NULL) {
514                                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
515                                 result = NT_STATUS_NO_MEMORY;
516                                 goto done;
517                         }
518                 }
519         } else {
520                 *sids = NULL;
521                 *types = NULL;
522                 if (dom_names != NULL) {
523                         *dom_names = NULL;
524                 }
525         }
526
527         for (i = 0; i < num_names; i++) {
528                 DOM_RID *t_rids = r.dom_rid;
529                 uint32 dom_idx = t_rids[i].rid_idx;
530                 uint32 dom_rid = t_rids[i].rid;
531                 DOM_SID *sid = &(*sids)[i];
532
533                 /* Translate optimised sid through domain index array */
534
535                 if (dom_idx == 0xffffffff) {
536                         /* Nothing to do, this is unknown */
537                         ZERO_STRUCTP(sid);
538                         (*types)[i] = SID_NAME_UNKNOWN;
539                         continue;
540                 }
541
542                 sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
543
544                 if (dom_rid != 0xffffffff) {
545                         sid_append_rid(sid, dom_rid);
546                 }
547
548                 (*types)[i] = (enum lsa_SidType)t_rids[i].type;
549
550                 if (dom_names == NULL) {
551                         continue;
552                 }
553
554                 (*dom_names)[i] = rpcstr_pull_unistr2_talloc(
555                         *dom_names, &ref.ref_dom[dom_idx].uni_dom_name);
556         }
557
558  done:
559
560         return result;
561 }
562
563 NTSTATUS rpccli_lsa_query_info_policy_new(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
564                                           POLICY_HND *pol, uint16 info_class,
565                                           LSA_INFO_CTR *ctr) 
566 {
567         prs_struct qbuf, rbuf;
568         LSA_Q_QUERY_INFO q;
569         LSA_R_QUERY_INFO r;
570         NTSTATUS result;
571
572         ZERO_STRUCT(q);
573         ZERO_STRUCT(r);
574
575         init_q_query(&q, pol, info_class);
576
577         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
578                 q, r,
579                 qbuf, rbuf,
580                 lsa_io_q_query,
581                 lsa_io_r_query,
582                 NT_STATUS_UNSUCCESSFUL);
583
584         result = r.status;
585
586         if (!NT_STATUS_IS_OK(result)) {
587                 goto done;
588         }
589
590  done:
591
592         *ctr = r.ctr;
593         
594         return result;
595 }
596
597 NTSTATUS rpccli_lsa_query_info_policy2_new(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
598                                           POLICY_HND *pol, uint16 info_class,
599                                           LSA_INFO_CTR2 *ctr) 
600 {
601         prs_struct qbuf, rbuf;
602         LSA_Q_QUERY_INFO2 q;
603         LSA_R_QUERY_INFO2 r;
604         NTSTATUS result;
605
606         ZERO_STRUCT(q);
607         ZERO_STRUCT(r);
608
609         init_q_query2(&q, pol, info_class);
610
611         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
612                 q, r,
613                 qbuf, rbuf,
614                 lsa_io_q_query_info2,
615                 lsa_io_r_query_info2,
616                 NT_STATUS_UNSUCCESSFUL);
617
618         result = r.status;
619
620         if (!NT_STATUS_IS_OK(result)) {
621                 goto done;
622         }
623
624  done:
625
626         *ctr = r.ctr;
627         
628         return result;
629 }
630
631
632
633 /** Query info policy
634  *
635  *  @param domain_sid - returned remote server's domain sid */
636
637 NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
638                                       TALLOC_CTX *mem_ctx,
639                                       POLICY_HND *pol, uint16 info_class, 
640                                       char **domain_name, DOM_SID **domain_sid)
641 {
642         prs_struct qbuf, rbuf;
643         LSA_Q_QUERY_INFO q;
644         LSA_R_QUERY_INFO r;
645         NTSTATUS result;
646
647         ZERO_STRUCT(q);
648         ZERO_STRUCT(r);
649
650         init_q_query(&q, pol, info_class);
651
652         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
653                 q, r,
654                 qbuf, rbuf,
655                 lsa_io_q_query,
656                 lsa_io_r_query,
657                 NT_STATUS_UNSUCCESSFUL);
658
659         result = r.status;
660
661         if (!NT_STATUS_IS_OK(result)) {
662                 goto done;
663         }
664
665         /* Return output parameters */
666
667         switch (info_class) {
668
669         case 3:
670                 if (domain_name && (r.ctr.info.id3.buffer_dom_name != 0)) {
671                         *domain_name = unistr2_tdup(mem_ctx, 
672                                                    &r.ctr.info.id3.
673                                                    uni_domain_name);
674                         if (!*domain_name) {
675                                 return NT_STATUS_NO_MEMORY;
676                         }
677                 }
678
679                 if (domain_sid && (r.ctr.info.id3.buffer_dom_sid != 0)) {
680                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
681                         if (!*domain_sid) {
682                                 return NT_STATUS_NO_MEMORY;
683                         }
684                         sid_copy(*domain_sid, &r.ctr.info.id3.dom_sid.sid);
685                 }
686
687                 break;
688
689         case 5:
690                 
691                 if (domain_name && (r.ctr.info.id5.buffer_dom_name != 0)) {
692                         *domain_name = unistr2_tdup(mem_ctx, 
693                                                    &r.ctr.info.id5.
694                                                    uni_domain_name);
695                         if (!*domain_name) {
696                                 return NT_STATUS_NO_MEMORY;
697                         }
698                 }
699                         
700                 if (domain_sid && (r.ctr.info.id5.buffer_dom_sid != 0)) {
701                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
702                         if (!*domain_sid) {
703                                 return NT_STATUS_NO_MEMORY;
704                         }
705                         sid_copy(*domain_sid, &r.ctr.info.id5.dom_sid.sid);
706                 }
707                 break;
708                         
709         default:
710                 DEBUG(3, ("unknown info class %d\n", info_class));
711                 break;                
712         }
713         
714  done:
715
716         return result;
717 }
718
719 /** Query info policy2
720  *
721  *  @param domain_name - returned remote server's domain name
722  *  @param dns_name - returned remote server's dns domain name
723  *  @param forest_name - returned remote server's forest name
724  *  @param domain_guid - returned remote server's domain guid
725  *  @param domain_sid - returned remote server's domain sid */
726
727 NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
728                                        TALLOC_CTX *mem_ctx,
729                                        POLICY_HND *pol, uint16 info_class, 
730                                        char **domain_name, char **dns_name,
731                                        char **forest_name,
732                                        struct GUID **domain_guid,
733                                        DOM_SID **domain_sid)
734 {
735         prs_struct qbuf, rbuf;
736         LSA_Q_QUERY_INFO2 q;
737         LSA_R_QUERY_INFO2 r;
738         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
739
740         if (info_class != 12)
741                 goto done;
742
743         ZERO_STRUCT(q);
744         ZERO_STRUCT(r);
745
746         init_q_query2(&q, pol, info_class);
747
748         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
749                 q, r,
750                 qbuf, rbuf,
751                 lsa_io_q_query_info2,
752                 lsa_io_r_query_info2,
753                 NT_STATUS_UNSUCCESSFUL);
754
755         result = r.status;
756
757         if (!NT_STATUS_IS_OK(result)) {
758                 goto done;
759         }
760
761         /* Return output parameters */
762
763         ZERO_STRUCTP(domain_guid);
764
765         if (domain_name && r.ctr.info.id12.hdr_nb_dom_name.buffer) {
766                 *domain_name = unistr2_tdup(mem_ctx, 
767                                             &r.ctr.info.id12
768                                             .uni_nb_dom_name);
769                 if (!*domain_name) {
770                         return NT_STATUS_NO_MEMORY;
771                 }
772         }
773         if (dns_name && r.ctr.info.id12.hdr_dns_dom_name.buffer) {
774                 *dns_name = unistr2_tdup(mem_ctx, 
775                                          &r.ctr.info.id12
776                                          .uni_dns_dom_name);
777                 if (!*dns_name) {
778                         return NT_STATUS_NO_MEMORY;
779                 }
780         }
781         if (forest_name && r.ctr.info.id12.hdr_forest_name.buffer) {
782                 *forest_name = unistr2_tdup(mem_ctx, 
783                                             &r.ctr.info.id12
784                                             .uni_forest_name);
785                 if (!*forest_name) {
786                         return NT_STATUS_NO_MEMORY;
787                 }
788         }
789         
790         if (domain_guid) {
791                 *domain_guid = TALLOC_P(mem_ctx, struct GUID);
792                 if (!*domain_guid) {
793                         return NT_STATUS_NO_MEMORY;
794                 }
795                 memcpy(*domain_guid, 
796                        &r.ctr.info.id12.dom_guid, 
797                        sizeof(struct GUID));
798         }
799
800         if (domain_sid && r.ctr.info.id12.ptr_dom_sid != 0) {
801                 *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
802                 if (!*domain_sid) {
803                         return NT_STATUS_NO_MEMORY;
804                 }
805                 sid_copy(*domain_sid, 
806                          &r.ctr.info.id12.dom_sid.sid);
807         }
808         
809  done:
810
811         return result;
812 }
813
814 NTSTATUS rpccli_lsa_set_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
815                                     POLICY_HND *pol, uint16 info_class,
816                                     LSA_INFO_CTR ctr) 
817 {
818         prs_struct qbuf, rbuf;
819         LSA_Q_SET_INFO q;
820         LSA_R_SET_INFO r;
821         NTSTATUS result;
822
823         ZERO_STRUCT(q);
824         ZERO_STRUCT(r);
825
826         init_q_set(&q, pol, info_class, ctr);
827
828         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_SETINFOPOLICY,
829                 q, r,
830                 qbuf, rbuf,
831                 lsa_io_q_set,
832                 lsa_io_r_set,
833                 NT_STATUS_UNSUCCESSFUL);
834
835         result = r.status;
836
837         if (!NT_STATUS_IS_OK(result)) {
838                 goto done;
839         }
840
841         /* Return output parameters */
842
843  done:
844
845         return result;
846 }
847
848
849 /**
850  * Enumerate list of trusted domains
851  *
852  * @param cli client state (cli_state) structure of the connection
853  * @param mem_ctx memory context
854  * @param pol opened lsa policy handle
855  * @param enum_ctx enumeration context ie. index of first returned domain entry
856  * @param pref_num_domains preferred max number of entries returned in one response
857  * @param num_domains total number of trusted domains returned by response
858  * @param domain_names returned trusted domain names
859  * @param domain_sids returned trusted domain sids
860  *
861  * @return nt status code of response
862  **/
863
864 NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
865                                    TALLOC_CTX *mem_ctx,
866                                    POLICY_HND *pol, uint32 *enum_ctx, 
867                                    uint32 *num_domains,
868                                    char ***domain_names, DOM_SID **domain_sids)
869 {
870         prs_struct qbuf, rbuf;
871         LSA_Q_ENUM_TRUST_DOM in;
872         LSA_R_ENUM_TRUST_DOM out;
873         int i;
874         fstring tmp;
875
876         ZERO_STRUCT(in);
877         ZERO_STRUCT(out);
878
879         /* 64k is enough for about 2000 trusted domains */
880         
881         init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
882
883         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM, 
884                     in, out, 
885                     qbuf, rbuf,
886                     lsa_io_q_enum_trust_dom,
887                     lsa_io_r_enum_trust_dom, 
888                     NT_STATUS_UNSUCCESSFUL );
889
890
891         /* check for an actual error */
892
893         if ( !NT_STATUS_IS_OK(out.status) 
894                 && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES) 
895                 && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
896         {
897                 return out.status;
898         }
899                 
900         /* Return output parameters */
901
902         *num_domains  = out.count;
903         *enum_ctx     = out.enum_context;
904         
905         if ( out.count ) {
906
907                 /* Allocate memory for trusted domain names and sids */
908
909                 if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
910                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
911                         return NT_STATUS_NO_MEMORY;
912                 }
913
914                 if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
915                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
916                         return NT_STATUS_NO_MEMORY;
917                 }
918
919                 /* Copy across names and sids */
920
921                 for (i = 0; i < out.count; i++) {
922
923                         rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer, 
924                                 sizeof(tmp), out.domlist->domains[i].name.length, 0);
925                         (*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
926
927                         sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
928                 }
929         }
930
931         return out.status;
932 }
933
934 /** Enumerate privileges*/
935
936 NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
937                                 POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
938                                 uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
939 {
940         prs_struct qbuf, rbuf;
941         LSA_Q_ENUM_PRIVS q;
942         LSA_R_ENUM_PRIVS r;
943         NTSTATUS result;
944         int i;
945
946         ZERO_STRUCT(q);
947         ZERO_STRUCT(r);
948
949         init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
950
951         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,
952                 q, r,
953                 qbuf, rbuf,
954                 lsa_io_q_enum_privs,
955                 lsa_io_r_enum_privs,
956                 NT_STATUS_UNSUCCESSFUL);
957
958         result = r.status;
959
960         if (!NT_STATUS_IS_OK(result)) {
961                 goto done;
962         }
963
964         /* Return output parameters */
965
966         *enum_context = r.enum_context;
967         *count = r.count;
968
969         if (r.count) {
970                 if (!((*privs_name = TALLOC_ARRAY(mem_ctx, char *, r.count)))) {
971                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
972                         result = NT_STATUS_UNSUCCESSFUL;
973                         goto done;
974                 }
975
976                 if (!((*privs_high = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
977                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
978                         result = NT_STATUS_UNSUCCESSFUL;
979                         goto done;
980                 }
981
982                 if (!((*privs_low = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
983                         DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
984                         result = NT_STATUS_UNSUCCESSFUL;
985                         goto done;
986                 }
987         } else {
988                 *privs_name = NULL;
989                 *privs_high = NULL;
990                 *privs_low = NULL;
991         }
992
993         for (i = 0; i < r.count; i++) {
994                 fstring name;
995
996                 rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
997
998                 (*privs_name)[i] = talloc_strdup(mem_ctx, name);
999
1000                 (*privs_high)[i] = r.privs[i].luid_high;
1001                 (*privs_low)[i] = r.privs[i].luid_low;
1002         }
1003
1004  done:
1005
1006         return result;
1007 }
1008
1009 /** Get privilege name */
1010
1011 NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1012                               POLICY_HND *pol, const char *name, 
1013                               uint16 lang_id, uint16 lang_id_sys,
1014                               fstring description, uint16 *lang_id_desc)
1015 {
1016         prs_struct qbuf, rbuf;
1017         LSA_Q_PRIV_GET_DISPNAME q;
1018         LSA_R_PRIV_GET_DISPNAME r;
1019         NTSTATUS result;
1020
1021         ZERO_STRUCT(q);
1022         ZERO_STRUCT(r);
1023
1024         init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
1025
1026         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_PRIV_GET_DISPNAME,
1027                 q, r,
1028                 qbuf, rbuf,
1029                 lsa_io_q_priv_get_dispname,
1030                 lsa_io_r_priv_get_dispname,
1031                 NT_STATUS_UNSUCCESSFUL);
1032
1033         result = r.status;
1034
1035         if (!NT_STATUS_IS_OK(result)) {
1036                 goto done;
1037         }
1038
1039         /* Return output parameters */
1040         
1041         rpcstr_pull_unistr2_fstring(description , &r.desc);
1042         *lang_id_desc = r.lang_id;
1043
1044  done:
1045
1046         return result;
1047 }
1048
1049 /** Enumerate list of SIDs  */
1050
1051 NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1052                                 POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, 
1053                                 uint32 *num_sids, DOM_SID **sids)
1054 {
1055         prs_struct qbuf, rbuf;
1056         LSA_Q_ENUM_ACCOUNTS q;
1057         LSA_R_ENUM_ACCOUNTS r;
1058         NTSTATUS result;
1059         int i;
1060
1061         ZERO_STRUCT(q);
1062         ZERO_STRUCT(r);
1063
1064         init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
1065
1066         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS,
1067                 q, r,
1068                 qbuf, rbuf,
1069                 lsa_io_q_enum_accounts,
1070                 lsa_io_r_enum_accounts,
1071                 NT_STATUS_UNSUCCESSFUL);
1072
1073         result = r.status;
1074
1075         if (!NT_STATUS_IS_OK(result)) {
1076                 goto done;
1077         }
1078
1079         if (r.sids.num_entries==0)
1080                 goto done;
1081
1082         /* Return output parameters */
1083
1084         *sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.sids.num_entries);
1085         if (!*sids) {
1086                 DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
1087                 result = NT_STATUS_UNSUCCESSFUL;
1088                 goto done;
1089         }
1090
1091         /* Copy across names and sids */
1092
1093         for (i = 0; i < r.sids.num_entries; i++) {
1094                 sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
1095         }
1096
1097         *num_sids= r.sids.num_entries;
1098         *enum_ctx = r.enum_context;
1099
1100  done:
1101
1102         return result;
1103 }
1104
1105 /** Create a LSA user handle
1106  *
1107  * @param cli Handle on an initialised SMB connection
1108  *
1109  * FIXME: The code is actually identical to open account
1110  * TODO: Check and code what the function should exactly do
1111  *
1112  * */
1113
1114 NTSTATUS rpccli_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1115                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access, 
1116                              POLICY_HND *user_pol)
1117 {
1118         prs_struct qbuf, rbuf;
1119         LSA_Q_CREATEACCOUNT q;
1120         LSA_R_CREATEACCOUNT r;
1121         NTSTATUS result;
1122
1123         ZERO_STRUCT(q);
1124         ZERO_STRUCT(r);
1125
1126         /* Initialise input parameters */
1127
1128         init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
1129
1130         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CREATEACCOUNT,
1131                 q, r,
1132                 qbuf, rbuf,
1133                 lsa_io_q_create_account,
1134                 lsa_io_r_create_account,
1135                 NT_STATUS_UNSUCCESSFUL);
1136
1137         /* Return output parameters */
1138
1139         result = r.status;
1140
1141         if (NT_STATUS_IS_OK(result)) {
1142                 *user_pol = r.pol;
1143         }
1144
1145         return result;
1146 }
1147
1148 /** Open a LSA user handle
1149  *
1150  * @param cli Handle on an initialised SMB connection */
1151
1152 NTSTATUS rpccli_lsa_open_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1153                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, 
1154                              POLICY_HND *user_pol)
1155 {
1156         prs_struct qbuf, rbuf;
1157         LSA_Q_OPENACCOUNT q;
1158         LSA_R_OPENACCOUNT r;
1159         NTSTATUS result;
1160
1161         ZERO_STRUCT(q);
1162         ZERO_STRUCT(r);
1163
1164         /* Initialise input parameters */
1165
1166         init_lsa_q_open_account(&q, dom_pol, sid, des_access);
1167
1168         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENACCOUNT,
1169                 q, r,
1170                 qbuf, rbuf,
1171                 lsa_io_q_open_account,
1172                 lsa_io_r_open_account,
1173                 NT_STATUS_UNSUCCESSFUL);
1174
1175         /* Return output parameters */
1176
1177         result = r.status;
1178
1179         if (NT_STATUS_IS_OK(result)) {
1180                 *user_pol = r.pol;
1181         }
1182
1183         return result;
1184 }
1185
1186 /** Enumerate user privileges
1187  *
1188  * @param cli Handle on an initialised SMB connection */
1189
1190 NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1191                              POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
1192 {
1193         prs_struct qbuf, rbuf;
1194         LSA_Q_ENUMPRIVSACCOUNT q;
1195         LSA_R_ENUMPRIVSACCOUNT r;
1196         NTSTATUS result;
1197         int i;
1198
1199         ZERO_STRUCT(q);
1200         ZERO_STRUCT(r);
1201
1202         /* Initialise input parameters */
1203
1204         init_lsa_q_enum_privsaccount(&q, pol);
1205
1206         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT,
1207                 q, r,
1208                 qbuf, rbuf,
1209                 lsa_io_q_enum_privsaccount,
1210                 lsa_io_r_enum_privsaccount,
1211                 NT_STATUS_UNSUCCESSFUL);
1212
1213         /* Return output parameters */
1214
1215         result = r.status;
1216
1217         if (!NT_STATUS_IS_OK(result)) {
1218                 goto done;
1219         }
1220
1221         if (r.count == 0)
1222                 goto done;
1223
1224         if (!((*set = TALLOC_ARRAY(mem_ctx, LUID_ATTR, r.count)))) {
1225                 DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
1226                 result = NT_STATUS_UNSUCCESSFUL;
1227                 goto done;
1228         }
1229
1230         for (i=0; i<r.count; i++) {
1231                 (*set)[i].luid.low = r.set.set[i].luid.low;
1232                 (*set)[i].luid.high = r.set.set[i].luid.high;
1233                 (*set)[i].attr = r.set.set[i].attr;
1234         }
1235
1236         *count=r.count;
1237  done:
1238
1239         return result;
1240 }
1241
1242 /** Get a privilege value given its name */
1243
1244 NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1245                                  POLICY_HND *pol, const char *name, LUID *luid)
1246 {
1247         prs_struct qbuf, rbuf;
1248         LSA_Q_LOOKUP_PRIV_VALUE q;
1249         LSA_R_LOOKUP_PRIV_VALUE r;
1250         NTSTATUS result;
1251
1252         ZERO_STRUCT(q);
1253         ZERO_STRUCT(r);
1254
1255         /* Marshall data and send request */
1256
1257         init_lsa_q_lookup_priv_value(&q, pol, name);
1258
1259         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE,
1260                 q, r,
1261                 qbuf, rbuf,
1262                 lsa_io_q_lookup_priv_value,
1263                 lsa_io_r_lookup_priv_value,
1264                 NT_STATUS_UNSUCCESSFUL);
1265
1266         result = r.status;
1267
1268         if (!NT_STATUS_IS_OK(result)) {
1269                 goto done;
1270         }
1271
1272         /* Return output parameters */
1273
1274         (*luid).low=r.luid.low;
1275         (*luid).high=r.luid.high;
1276
1277  done:
1278
1279         return result;
1280 }
1281
1282 /** Query LSA security object */
1283
1284 NTSTATUS rpccli_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1285                               POLICY_HND *pol, uint32 sec_info, 
1286                               SEC_DESC_BUF **psdb)
1287 {
1288         prs_struct qbuf, rbuf;
1289         LSA_Q_QUERY_SEC_OBJ q;
1290         LSA_R_QUERY_SEC_OBJ r;
1291         NTSTATUS result;
1292
1293         ZERO_STRUCT(q);
1294         ZERO_STRUCT(r);
1295
1296         /* Marshall data and send request */
1297
1298         init_q_query_sec_obj(&q, pol, sec_info);
1299
1300         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYSECOBJ,
1301                 q, r,
1302                 qbuf, rbuf,
1303                 lsa_io_q_query_sec_obj,
1304                 lsa_io_r_query_sec_obj,
1305                 NT_STATUS_UNSUCCESSFUL);
1306
1307         result = r.status;
1308
1309         if (!NT_STATUS_IS_OK(result)) {
1310                 goto done;
1311         }
1312
1313         /* Return output parameters */
1314
1315         if (psdb)
1316                 *psdb = r.buf;
1317
1318  done:
1319
1320         return result;
1321 }
1322
1323
1324 /* Enumerate account rights This is similar to enum_privileges but
1325    takes a SID directly, avoiding the open_account call.
1326 */
1327
1328 NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1329                                      POLICY_HND *pol, DOM_SID *sid,
1330                                      uint32 *count, char ***priv_names)
1331 {
1332         prs_struct qbuf, rbuf;
1333         LSA_Q_ENUM_ACCT_RIGHTS q;
1334         LSA_R_ENUM_ACCT_RIGHTS r;
1335         NTSTATUS result;
1336         int i;
1337         fstring *privileges;
1338         char **names;
1339
1340         ZERO_STRUCT(q);
1341         ZERO_STRUCT(r);
1342
1343         /* Marshall data and send request */
1344         init_q_enum_acct_rights(&q, pol, 2, sid);
1345
1346         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS,
1347                 q, r,
1348                 qbuf, rbuf,
1349                 lsa_io_q_enum_acct_rights,
1350                 lsa_io_r_enum_acct_rights,
1351                 NT_STATUS_UNSUCCESSFUL);
1352
1353         result = r.status;
1354
1355         if (!NT_STATUS_IS_OK(result)) {
1356                 goto done;
1357         }
1358
1359         *count = r.count;
1360         if (! *count) {
1361                 goto done;
1362         }
1363
1364         
1365         privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
1366         names      = TALLOC_ARRAY( mem_ctx, char *, *count );
1367
1368         if ((privileges == NULL) || (names == NULL)) {
1369                 TALLOC_FREE(privileges);
1370                 TALLOC_FREE(names);
1371                 return NT_STATUS_NO_MEMORY;
1372         }
1373
1374         for ( i=0; i<*count; i++ ) {
1375                 UNISTR4 *uni_string = &r.rights->strings[i];
1376
1377                 if ( !uni_string->string )
1378                         continue;
1379
1380                 rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
1381                         
1382                 /* now copy to the return array */
1383                 names[i] = talloc_strdup( mem_ctx, privileges[i] );
1384         }
1385         
1386         *priv_names = names;
1387
1388 done:
1389
1390         return result;
1391 }
1392
1393
1394
1395 /* add account rights to an account. */
1396
1397 NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1398                                     POLICY_HND *pol, DOM_SID sid,
1399                                         uint32 count, const char **privs_name)
1400 {
1401         prs_struct qbuf, rbuf;
1402         LSA_Q_ADD_ACCT_RIGHTS q;
1403         LSA_R_ADD_ACCT_RIGHTS r;
1404         NTSTATUS result;
1405
1406         ZERO_STRUCT(q);
1407         ZERO_STRUCT(r);
1408
1409         /* Marshall data and send request */
1410         init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
1411
1412         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS,
1413                 q, r,
1414                 qbuf, rbuf,
1415                 lsa_io_q_add_acct_rights,
1416                 lsa_io_r_add_acct_rights,
1417                 NT_STATUS_UNSUCCESSFUL);
1418
1419         result = r.status;
1420
1421         if (!NT_STATUS_IS_OK(result)) {
1422                 goto done;
1423         }
1424 done:
1425
1426         return result;
1427 }
1428
1429
1430 /* remove account rights for an account. */
1431
1432 NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1433                                        POLICY_HND *pol, DOM_SID sid, BOOL removeall,
1434                                        uint32 count, const char **privs_name)
1435 {
1436         prs_struct qbuf, rbuf;
1437         LSA_Q_REMOVE_ACCT_RIGHTS q;
1438         LSA_R_REMOVE_ACCT_RIGHTS r;
1439         NTSTATUS result;
1440
1441         ZERO_STRUCT(q);
1442         ZERO_STRUCT(r);
1443
1444         /* Marshall data and send request */
1445         init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
1446
1447         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS,
1448                 q, r,
1449                 qbuf, rbuf,
1450                 lsa_io_q_remove_acct_rights,
1451                 lsa_io_r_remove_acct_rights,
1452                 NT_STATUS_UNSUCCESSFUL);
1453
1454         result = r.status;
1455
1456         if (!NT_STATUS_IS_OK(result)) {
1457                 goto done;
1458         }
1459 done:
1460
1461         return result;
1462 }
1463
1464
1465 #if 0
1466
1467 /** An example of how to use the routines in this file.  Fetch a DOMAIN
1468     sid. Does complete cli setup / teardown anonymously. */
1469
1470 BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
1471 {
1472         extern pstring global_myname;
1473         struct cli_state *cli;
1474         NTSTATUS result;
1475         POLICY_HND lsa_pol;
1476         BOOL ret = False;
1477  
1478         ZERO_STRUCT(cli);
1479         if((cli = cli_initialise()) == NULL) {
1480                 DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
1481                 return False;
1482         }
1483  
1484         if(!resolve_name( remote_machine, &cli->dest_ip, 0x20)) {
1485                 DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
1486                 goto done;
1487         }
1488  
1489         if (!cli_connect(cli, remote_machine, &cli->dest_ip)) {
1490                 DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
1491 machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1492                 goto done;
1493         }
1494
1495         if (!attempt_netbios_session_request(cli, global_myname, remote_machine, &cli->dest_ip)) {
1496                 DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n", 
1497                         remote_machine));
1498                 goto done;
1499         }
1500  
1501         cli->protocol = PROTOCOL_NT1;
1502  
1503         if (!cli_negprot(cli)) {
1504                 DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
1505 Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1506                 goto done;
1507         }
1508  
1509         if (cli->protocol != PROTOCOL_NT1) {
1510                 DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
1511                         remote_machine));
1512                 goto done;
1513         }
1514  
1515         /*
1516          * Do an anonymous session setup.
1517          */
1518  
1519         if (!cli_session_setup(cli, "", "", 0, "", 0, "")) {
1520                 DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
1521 Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1522                 goto done;
1523         }
1524  
1525         if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
1526                 DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
1527                         remote_machine));
1528                 goto done;
1529         }
1530
1531         if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
1532                 DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
1533 Error was : %s.\n", remote_machine, cli_errstr(cli) ));
1534                 goto done;
1535         }
1536
1537         /* Fetch domain sid */
1538  
1539         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1540                 DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
1541                 goto done;
1542         }
1543  
1544         result = cli_lsa_open_policy(cli, cli->mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
1545         if (!NT_STATUS_IS_OK(result)) {
1546                 DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
1547                         nt_errstr(result) ));
1548                 goto done;
1549         }
1550  
1551         result = cli_lsa_query_info_policy(cli, cli->mem_ctx, &lsa_pol, 5, domain, psid);
1552         if (!NT_STATUS_IS_OK(result)) {
1553                 DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
1554                         nt_errstr(result) ));
1555                 goto done;
1556         }
1557  
1558         ret = True;
1559
1560   done:
1561
1562         cli_shutdown(cli);
1563         return ret;
1564 }
1565
1566 #endif
1567
1568 NTSTATUS rpccli_lsa_open_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1569                                      POLICY_HND *pol, DOM_SID *dom_sid, uint32 access_mask,
1570                                      POLICY_HND *trustdom_pol)
1571 {
1572         prs_struct qbuf, rbuf;
1573         LSA_Q_OPEN_TRUSTED_DOMAIN q;
1574         LSA_R_OPEN_TRUSTED_DOMAIN r;
1575         NTSTATUS result;
1576
1577         ZERO_STRUCT(q);
1578         ZERO_STRUCT(r);
1579
1580         /* Initialise input parameters */
1581
1582         init_lsa_q_open_trusted_domain(&q, pol, dom_sid, access_mask);
1583
1584         /* Marshall data and send request */
1585
1586         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOM,
1587                 q, r,
1588                 qbuf, rbuf,
1589                 lsa_io_q_open_trusted_domain,
1590                 lsa_io_r_open_trusted_domain,
1591                 NT_STATUS_UNSUCCESSFUL);
1592
1593         /* Return output parameters */
1594         
1595         result = r.status;
1596
1597         if (NT_STATUS_IS_OK(result)) {
1598                 *trustdom_pol = r.handle;
1599         }
1600
1601         return result;
1602 }
1603
1604 NTSTATUS rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1605                                            POLICY_HND *pol, 
1606                                            uint16 info_class,  
1607                                            LSA_TRUSTED_DOMAIN_INFO **info)
1608 {
1609         prs_struct qbuf, rbuf;
1610         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO q;
1611         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1612         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1613
1614         ZERO_STRUCT(q);
1615         ZERO_STRUCT(r);
1616
1617         /* Marshall data and send request */
1618
1619         init_q_query_trusted_domain_info(&q, pol, info_class); 
1620
1621         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFO,
1622                 q, r,
1623                 qbuf, rbuf,
1624                 lsa_io_q_query_trusted_domain_info,
1625                 lsa_io_r_query_trusted_domain_info,
1626                 NT_STATUS_UNSUCCESSFUL);
1627
1628         result = r.status;
1629
1630         if (!NT_STATUS_IS_OK(result)) {
1631                 goto done;
1632         }
1633
1634         *info = r.info;
1635                 
1636 done:
1637         return result;
1638 }
1639
1640 NTSTATUS rpccli_lsa_open_trusted_domain_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1641                                                 POLICY_HND *pol, const char *name, uint32 access_mask,
1642                                                 POLICY_HND *trustdom_pol)
1643 {
1644         prs_struct qbuf, rbuf;
1645         LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME q;
1646         LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME r;
1647         NTSTATUS result;
1648
1649         ZERO_STRUCT(q);
1650         ZERO_STRUCT(r);
1651
1652         /* Initialise input parameters */
1653
1654         init_lsa_q_open_trusted_domain_by_name(&q, pol, name, access_mask);
1655
1656         /* Marshall data and send request */
1657
1658         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOMBYNAME,
1659                 q, r,
1660                 qbuf, rbuf,
1661                 lsa_io_q_open_trusted_domain_by_name,
1662                 lsa_io_r_open_trusted_domain_by_name,
1663                 NT_STATUS_UNSUCCESSFUL);
1664
1665         /* Return output parameters */
1666         
1667         result = r.status;
1668
1669         if (NT_STATUS_IS_OK(result)) {
1670                 *trustdom_pol = r.handle;
1671         }
1672
1673         return result;
1674 }
1675
1676
1677 NTSTATUS rpccli_lsa_query_trusted_domain_info_by_sid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1678                                                   POLICY_HND *pol, 
1679                                                   uint16 info_class, DOM_SID *dom_sid, 
1680                                                   LSA_TRUSTED_DOMAIN_INFO **info)
1681 {
1682         prs_struct qbuf, rbuf;
1683         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID q;
1684         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1685         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1686
1687         ZERO_STRUCT(q);
1688         ZERO_STRUCT(r);
1689
1690         /* Marshall data and send request */
1691
1692         init_q_query_trusted_domain_info_by_sid(&q, pol, info_class, dom_sid); 
1693
1694         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID,
1695                 q, r,
1696                 qbuf, rbuf,
1697                 lsa_io_q_query_trusted_domain_info_by_sid,
1698                 lsa_io_r_query_trusted_domain_info,
1699                 NT_STATUS_UNSUCCESSFUL);
1700
1701         result = r.status;
1702
1703         if (!NT_STATUS_IS_OK(result)) {
1704                 goto done;
1705         }
1706
1707         *info = r.info;
1708
1709 done:
1710
1711         return result;
1712 }
1713
1714 NTSTATUS rpccli_lsa_query_trusted_domain_info_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1715                                                    POLICY_HND *pol, 
1716                                                    uint16 info_class, const char *domain_name, 
1717                                                    LSA_TRUSTED_DOMAIN_INFO **info)
1718 {
1719         prs_struct qbuf, rbuf;
1720         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME q;
1721         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1722         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1723
1724         ZERO_STRUCT(q);
1725         ZERO_STRUCT(r);
1726
1727         /* Marshall data and send request */
1728
1729         init_q_query_trusted_domain_info_by_name(&q, pol, info_class, domain_name); 
1730
1731         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME,
1732                 q, r,
1733                 qbuf, rbuf,
1734                 lsa_io_q_query_trusted_domain_info_by_name,
1735                 lsa_io_r_query_trusted_domain_info,
1736                 NT_STATUS_UNSUCCESSFUL);
1737
1738         result = r.status;
1739
1740         if (!NT_STATUS_IS_OK(result)) {
1741                 goto done;
1742         }
1743
1744         *info = r.info;
1745
1746 done:
1747         
1748         return result;
1749 }
1750
1751 NTSTATUS cli_lsa_query_domain_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1752                                           POLICY_HND *pol, 
1753                                           uint16 info_class, LSA_DOM_INFO_UNION **info)
1754 {
1755         prs_struct qbuf, rbuf;
1756         LSA_Q_QUERY_DOM_INFO_POLICY q;
1757         LSA_R_QUERY_DOM_INFO_POLICY r;
1758         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1759
1760         ZERO_STRUCT(q);
1761         ZERO_STRUCT(r);
1762
1763         /* Marshall data and send request */
1764
1765         init_q_query_dom_info(&q, pol, info_class); 
1766
1767         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYDOMINFOPOL, 
1768                 q, r,
1769                 qbuf, rbuf,
1770                 lsa_io_q_query_dom_info,
1771                 lsa_io_r_query_dom_info,
1772                 NT_STATUS_UNSUCCESSFUL);
1773
1774         result = r.status;
1775
1776         if (!NT_STATUS_IS_OK(result)) {
1777                 goto done;
1778         }
1779
1780         *info = r.info;
1781
1782 done:
1783         return result;
1784 }
1785