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