r10656: BIG merge from trunk. Features not copied over
[ira/wip.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 2 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, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 /** @defgroup lsa LSA - Local Security Architecture
27  *  @ingroup rpc_client
28  *
29  * @{
30  **/
31
32 /**
33  * @file cli_lsarpc.c
34  *
35  * RPC client routines for the LSA RPC pipe.  LSA means "local
36  * security authority", which is half of a password database.
37  **/
38
39 /** Open a LSA policy handle
40  *
41  * @param cli Handle on an initialised SMB connection */
42
43 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
44                                 TALLOC_CTX *mem_ctx,
45                                 BOOL sec_qos, uint32 des_access,
46                                 POLICY_HND *pol)
47 {
48         prs_struct qbuf, rbuf;
49         LSA_Q_OPEN_POL q;
50         LSA_R_OPEN_POL r;
51         LSA_SEC_QOS qos;
52         NTSTATUS result;
53
54         ZERO_STRUCT(q);
55         ZERO_STRUCT(r);
56
57         /* Initialise input parameters */
58
59         if (sec_qos) {
60                 init_lsa_sec_qos(&qos, 2, 1, 0);
61                 init_q_open_pol(&q, '\\', 0, des_access, &qos);
62         } else {
63                 init_q_open_pol(&q, '\\', 0, des_access, NULL);
64         }
65
66         /* Marshall data and send request */
67
68         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY,
69                         q, r,
70                         qbuf, rbuf,
71                         lsa_io_q_open_pol,
72                         lsa_io_r_open_pol,
73                         NT_STATUS_UNSUCCESSFUL );
74
75         /* Return output parameters */
76
77         if (NT_STATUS_IS_OK(result = r.status)) {
78                 *pol = r.pol;
79 #ifdef __INSURE__
80                 pol->marker = MALLOC(1);
81 #endif
82         }
83
84         return result;
85 }
86
87 /** Open a LSA policy handle
88   *
89   * @param cli Handle on an initialised SMB connection 
90   */
91
92 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
93                                  TALLOC_CTX *mem_ctx, BOOL sec_qos,
94                                  uint32 des_access, POLICY_HND *pol)
95 {
96         prs_struct qbuf, rbuf;
97         LSA_Q_OPEN_POL2 q;
98         LSA_R_OPEN_POL2 r;
99         LSA_SEC_QOS qos;
100         NTSTATUS result;
101         char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
102
103         ZERO_STRUCT(q);
104         ZERO_STRUCT(r);
105
106         if (sec_qos) {
107                 init_lsa_sec_qos(&qos, 2, 1, 0);
108                 init_q_open_pol2(&q, srv_name_slash, 0, des_access, &qos);
109         } else {
110                 init_q_open_pol2(&q, srv_name_slash, 0, des_access, NULL);
111         }
112
113         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY2,
114                         q, r,
115                         qbuf, rbuf,
116                         lsa_io_q_open_pol2,
117                         lsa_io_r_open_pol2,
118                         NT_STATUS_UNSUCCESSFUL );
119
120         /* Return output parameters */
121
122         if (NT_STATUS_IS_OK(result = r.status)) {
123                 *pol = r.pol;
124 #ifdef __INSURE__
125                 pol->marker = (char *)malloc(1);
126 #endif
127         }
128
129         return result;
130 }
131
132 /** Close a LSA policy handle */
133
134 NTSTATUS rpccli_lsa_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
135                           POLICY_HND *pol)
136 {
137         prs_struct qbuf, rbuf;
138         LSA_Q_CLOSE q;
139         LSA_R_CLOSE r;
140         NTSTATUS result;
141
142         ZERO_STRUCT(q);
143         ZERO_STRUCT(r);
144
145         init_lsa_q_close(&q, pol);
146
147         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CLOSE,
148                         q, r,
149                         qbuf, rbuf,
150                         lsa_io_q_close,
151                         lsa_io_r_close,
152                         NT_STATUS_UNSUCCESSFUL );
153
154         /* Return output parameters */
155
156         if (NT_STATUS_IS_OK(result = r.status)) {
157 #ifdef __INSURE__
158                 SAFE_FREE(pol->marker);
159 #endif
160                 *pol = r.pol;
161         }
162
163         return result;
164 }
165
166 /** Lookup a list of sids */
167
168 NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
169                                 TALLOC_CTX *mem_ctx,
170                                 POLICY_HND *pol, int num_sids,
171                                 const DOM_SID *sids, 
172                                 char ***domains, char ***names, uint32 **types)
173 {
174         prs_struct qbuf, rbuf;
175         LSA_Q_LOOKUP_SIDS q;
176         LSA_R_LOOKUP_SIDS r;
177         DOM_R_REF ref;
178         LSA_TRANS_NAME_ENUM t_names;
179         NTSTATUS result = NT_STATUS_OK;
180         int i;
181
182         ZERO_STRUCT(q);
183         ZERO_STRUCT(r);
184
185         init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);
186
187         ZERO_STRUCT(ref);
188         ZERO_STRUCT(t_names);
189
190         r.dom_ref = &ref;
191         r.names = &t_names;
192
193         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPSIDS,
194                         q, r,
195                         qbuf, rbuf,
196                         lsa_io_q_lookup_sids,
197                         lsa_io_r_lookup_sids,
198                         NT_STATUS_UNSUCCESSFUL );
199
200         if (!NT_STATUS_IS_OK(r.status) &&
201             NT_STATUS_V(r.status) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
202           
203                 /* An actual error occured */
204                 result = r.status;
205
206                 goto done;
207         }
208
209         /* Return output parameters */
210
211         if (r.mapped_count == 0) {
212                 result = NT_STATUS_NONE_MAPPED;
213                 goto done;
214         }
215
216         if (!((*domains) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
217                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
218                 result = NT_STATUS_UNSUCCESSFUL;
219                 goto done;
220         }
221
222         if (!((*names) = TALLOC_ARRAY(mem_ctx, char *, num_sids))) {
223                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
224                 result = NT_STATUS_UNSUCCESSFUL;
225                 goto done;
226         }
227
228         if (!((*types) = TALLOC_ARRAY(mem_ctx, uint32, num_sids))) {
229                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
230                 result = NT_STATUS_UNSUCCESSFUL;
231                 goto done;
232         }
233                 
234         for (i = 0; i < num_sids; i++) {
235                 fstring name, dom_name;
236                 uint32 dom_idx = t_names.name[i].domain_idx;
237
238                 /* Translate optimised name through domain index array */
239
240                 if (dom_idx != 0xffffffff) {
241
242                         rpcstr_pull_unistr2_fstring(
243                                 dom_name, &ref.ref_dom[dom_idx].uni_dom_name);
244                         rpcstr_pull_unistr2_fstring(
245                                 name, &t_names.uni_name[i]);
246
247                         (*names)[i] = talloc_strdup(mem_ctx, name);
248                         (*domains)[i] = talloc_strdup(mem_ctx, dom_name);
249                         (*types)[i] = t_names.name[i].sid_name_use;
250                         
251                         if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) {
252                                 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
253                                 result = NT_STATUS_UNSUCCESSFUL;
254                                 goto done;
255                         }
256
257                 } else {
258                         (*names)[i] = NULL;
259                         (*domains)[i] = NULL;
260                         (*types)[i] = SID_NAME_UNKNOWN;
261                 }
262         }
263
264  done:
265
266         return result;
267 }
268
269 /** Lookup a list of names */
270
271 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
272                                  TALLOC_CTX *mem_ctx,
273                                  POLICY_HND *pol, int num_names, 
274                                  const char **names, DOM_SID **sids, 
275                                  uint32 **types)
276 {
277         prs_struct qbuf, rbuf;
278         LSA_Q_LOOKUP_NAMES q;
279         LSA_R_LOOKUP_NAMES r;
280         DOM_R_REF ref;
281         NTSTATUS result;
282         int i;
283         
284         ZERO_STRUCT(q);
285         ZERO_STRUCT(r);
286
287         ZERO_STRUCT(ref);
288         r.dom_ref = &ref;
289
290         init_q_lookup_names(mem_ctx, &q, pol, num_names, names);
291
292         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPNAMES,
293                         q, r,
294                         qbuf, rbuf,
295                         lsa_io_q_lookup_names,
296                         lsa_io_r_lookup_names,
297                         NT_STATUS_UNSUCCESSFUL);
298
299         result = r.status;
300
301         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
302             NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
303
304                 /* An actual error occured */
305
306                 goto done;
307         }
308
309         /* Return output parameters */
310
311         if (r.mapped_count == 0) {
312                 result = NT_STATUS_NONE_MAPPED;
313                 goto done;
314         }
315
316         if (!((*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_names)))) {
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_names)))) {
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_names; i++) {
329                 DOM_RID2 *t_rids = r.dom_rid;
330                 uint32 dom_idx = t_rids[i].rid_idx;
331                 uint32 dom_rid = t_rids[i].rid;
332                 DOM_SID *sid = &(*sids)[i];
333
334                 /* Translate optimised sid through domain index array */
335
336                 if (dom_idx != 0xffffffff) {
337
338                         sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
339
340                         if (dom_rid != 0xffffffff) {
341                                 sid_append_rid(sid, dom_rid);
342                         }
343
344                         (*types)[i] = t_rids[i].type;
345                 } else {
346                         ZERO_STRUCTP(sid);
347                         (*types)[i] = SID_NAME_UNKNOWN;
348                 }
349         }
350
351  done:
352
353         return result;
354 }
355
356 /** Query info policy
357  *
358  *  @param domain_sid - returned remote server's domain sid */
359
360 NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
361                                       TALLOC_CTX *mem_ctx,
362                                       POLICY_HND *pol, uint16 info_class, 
363                                       char **domain_name, DOM_SID **domain_sid)
364 {
365         prs_struct qbuf, rbuf;
366         LSA_Q_QUERY_INFO q;
367         LSA_R_QUERY_INFO r;
368         NTSTATUS result;
369
370         ZERO_STRUCT(q);
371         ZERO_STRUCT(r);
372
373         init_q_query(&q, pol, info_class);
374
375         CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
376                 q, r,
377                 qbuf, rbuf,
378                 lsa_io_q_query,
379                 lsa_io_r_query,
380                 NT_STATUS_UNSUCCESSFUL);
381
382         if (!NT_STATUS_IS_OK(result = r.status)) {
383                 goto done;
384         }
385
386         /* Return output parameters */
387
388         switch (info_class) {
389
390         case 3:
391                 if (domain_name && (r.dom.id3.buffer_dom_name != 0)) {
392                         *domain_name = unistr2_tdup(mem_ctx, 
393                                                    &r.dom.id3.
394                                                    uni_domain_name);
395                 }
396
397                 if (domain_sid && (r.dom.id3.buffer_dom_sid != 0)) {
398                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
399                         if (*domain_sid) {
400                                 sid_copy(*domain_sid, &r.dom.id3.dom_sid.sid);
401                         }
402                 }
403
404                 break;
405
406         case 5:
407                 
408                 if (domain_name && (r.dom.id5.buffer_dom_name != 0)) {
409                         *domain_name = unistr2_tdup(mem_ctx, 
410                                                    &r.dom.id5.
411                                                    uni_domain_name);
412                 }
413                         
414                 if (domain_sid && (r.dom.id5.buffer_dom_sid != 0)) {
415                         *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
416                         if (*domain_sid) {
417                                 sid_copy(*domain_sid, &r.dom.id5.dom_sid.sid);
418                         }
419                 }
420                 break;
421                         
422         default:
423                 DEBUG(3, ("unknown info class %d\n", info_class));
424                 break;                
425         }
426         
427  done:
428
429         return result;
430 }
431
432 /** Query info policy2
433  *
434  *  @param domain_name - returned remote server's domain name
435  *  @param dns_name - returned remote server's dns domain name
436  *  @param forest_name - returned remote server's forest name
437  *  @param domain_guid - returned remote server's domain guid
438  *  @param domain_sid - returned remote server's domain sid */
439
440 NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
441                                        TALLOC_CTX *mem_ctx,
442                                        POLICY_HND *pol, uint16 info_class, 
443                                        char **domain_name, char **dns_name,
444                                        char **forest_name,
445                                        struct uuid **domain_guid,
446                                        DOM_SID **domain_sid)
447 {
448         prs_struct qbuf, rbuf;
449         LSA_Q_QUERY_INFO2 q;
450         LSA_R_QUERY_INFO2 r;
451         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
452
453         if (info_class != 12)
454                 goto done;
455
456         ZERO_STRUCT(q);
457         ZERO_STRUCT(r);
458
459         init_q_query2(&q, pol, info_class);
460
461         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
462                 q, r,
463                 qbuf, rbuf,
464                 lsa_io_q_query_info2,
465                 lsa_io_r_query_info2,
466                 NT_STATUS_UNSUCCESSFUL);
467
468         if (!NT_STATUS_IS_OK(result = r.status)) {
469                 goto done;
470         }
471
472         /* Return output parameters */
473
474         ZERO_STRUCTP(domain_guid);
475
476         if (domain_name && r.info.dns_dom_info.hdr_nb_dom_name.buffer) {
477                 *domain_name = unistr2_tdup(mem_ctx, 
478                                             &r.info.dns_dom_info
479                                             .uni_nb_dom_name);
480         }
481         if (dns_name && r.info.dns_dom_info.hdr_dns_dom_name.buffer) {
482                 *dns_name = unistr2_tdup(mem_ctx, 
483                                          &r.info.dns_dom_info
484                                          .uni_dns_dom_name);
485         }
486         if (forest_name && r.info.dns_dom_info.hdr_forest_name.buffer) {
487                 *forest_name = unistr2_tdup(mem_ctx, 
488                                             &r.info.dns_dom_info
489                                             .uni_forest_name);
490         }
491         
492         if (domain_guid) {
493                 *domain_guid = TALLOC_P(mem_ctx, struct uuid);
494                 memcpy(*domain_guid, 
495                        &r.info.dns_dom_info.dom_guid, 
496                        sizeof(struct uuid));
497         }
498
499         if (domain_sid && r.info.dns_dom_info.ptr_dom_sid != 0) {
500                 *domain_sid = TALLOC_P(mem_ctx, DOM_SID);
501                 if (*domain_sid) {
502                         sid_copy(*domain_sid, 
503                                  &r.info.dns_dom_info.dom_sid.sid);
504                 }
505         }
506         
507  done:
508
509         return result;
510 }
511
512 /**
513  * Enumerate list of trusted domains
514  *
515  * @param cli client state (cli_state) structure of the connection
516  * @param mem_ctx memory context
517  * @param pol opened lsa policy handle
518  * @param enum_ctx enumeration context ie. index of first returned domain entry
519  * @param pref_num_domains preferred max number of entries returned in one response
520  * @param num_domains total number of trusted domains returned by response
521  * @param domain_names returned trusted domain names
522  * @param domain_sids returned trusted domain sids
523  *
524  * @return nt status code of response
525  **/
526
527 NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
528                                    TALLOC_CTX *mem_ctx,
529                                    POLICY_HND *pol, uint32 *enum_ctx, 
530                                    uint32 *num_domains,
531                                    char ***domain_names, DOM_SID **domain_sids)
532 {
533         prs_struct qbuf, rbuf;
534         LSA_Q_ENUM_TRUST_DOM in;
535         LSA_R_ENUM_TRUST_DOM out;
536         int i;
537         fstring tmp;
538
539         ZERO_STRUCT(in);
540         ZERO_STRUCT(out);
541
542         /* 64k is enough for about 2000 trusted domains */
543         
544         init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
545
546         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM, 
547                     in, out, 
548                     qbuf, rbuf,
549                     lsa_io_q_enum_trust_dom,
550                     lsa_io_r_enum_trust_dom, 
551                     NT_STATUS_UNSUCCESSFUL );
552
553
554         /* check for an actual error */
555
556         if ( !NT_STATUS_IS_OK(out.status) 
557                 && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES) 
558                 && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
559         {
560                 return out.status;
561         }
562                 
563         /* Return output parameters */
564
565         *num_domains  = out.count;
566         *enum_ctx     = out.enum_context;
567         
568         if ( out.count ) {
569
570                 /* Allocate memory for trusted domain names and sids */
571
572                 if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
573                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
574                         return NT_STATUS_NO_MEMORY;
575                 }
576
577                 if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
578                         DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
579                         return NT_STATUS_NO_MEMORY;
580                 }
581
582                 /* Copy across names and sids */
583
584                 for (i = 0; i < out.count; i++) {
585
586                         rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer, 
587                                 sizeof(tmp), out.domlist->domains[i].name.length, 0);
588                         (*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
589
590                         sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
591                 }
592         }
593
594         return out.status;
595 }
596
597 /** Enumerate privileges*/
598
599 NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
600                                 POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
601                                 uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
602 {
603         prs_struct qbuf, rbuf;
604         LSA_Q_ENUM_PRIVS q;
605         LSA_R_ENUM_PRIVS r;
606         NTSTATUS result;
607         int i;
608
609         ZERO_STRUCT(q);
610         ZERO_STRUCT(r);
611
612         init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
613
614         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,
615                 q, r,
616                 qbuf, rbuf,
617                 lsa_io_q_enum_privs,
618                 lsa_io_r_enum_privs,
619                 NT_STATUS_UNSUCCESSFUL);
620
621         if (!NT_STATUS_IS_OK(result = r.status)) {
622                 goto done;
623         }
624
625         /* Return output parameters */
626
627         *enum_context = r.enum_context;
628         *count = r.count;
629
630         if (!((*privs_name = TALLOC_ARRAY(mem_ctx, char *, r.count)))) {
631                 DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
632                 result = NT_STATUS_UNSUCCESSFUL;
633                 goto done;
634         }
635
636         if (!((*privs_high = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
637                 DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
638                 result = NT_STATUS_UNSUCCESSFUL;
639                 goto done;
640         }
641
642         if (!((*privs_low = TALLOC_ARRAY(mem_ctx, uint32, r.count)))) {
643                 DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
644                 result = NT_STATUS_UNSUCCESSFUL;
645                 goto done;
646         }
647
648         for (i = 0; i < r.count; i++) {
649                 fstring name;
650
651                 rpcstr_pull_unistr2_fstring( name, &r.privs[i].name);
652
653                 (*privs_name)[i] = talloc_strdup(mem_ctx, name);
654
655                 (*privs_high)[i] = r.privs[i].luid_high;
656                 (*privs_low)[i] = r.privs[i].luid_low;
657         }
658
659  done:
660
661         return result;
662 }
663
664 /** Get privilege name */
665
666 NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
667                               POLICY_HND *pol, const char *name, 
668                               uint16 lang_id, uint16 lang_id_sys,
669                               fstring description, uint16 *lang_id_desc)
670 {
671         prs_struct qbuf, rbuf;
672         LSA_Q_PRIV_GET_DISPNAME q;
673         LSA_R_PRIV_GET_DISPNAME r;
674         NTSTATUS result;
675
676         ZERO_STRUCT(q);
677         ZERO_STRUCT(r);
678
679         init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
680
681         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_PRIV_GET_DISPNAME,
682                 q, r,
683                 qbuf, rbuf,
684                 lsa_io_q_priv_get_dispname,
685                 lsa_io_r_priv_get_dispname,
686                 NT_STATUS_UNSUCCESSFUL);
687
688         if (!NT_STATUS_IS_OK(result = r.status)) {
689                 goto done;
690         }
691
692         /* Return output parameters */
693         
694         rpcstr_pull_unistr2_fstring(description , &r.desc);
695         *lang_id_desc = r.lang_id;
696
697  done:
698
699         return result;
700 }
701
702 /** Enumerate list of SIDs  */
703
704 NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
705                                 POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, 
706                                 uint32 *num_sids, DOM_SID **sids)
707 {
708         prs_struct qbuf, rbuf;
709         LSA_Q_ENUM_ACCOUNTS q;
710         LSA_R_ENUM_ACCOUNTS r;
711         NTSTATUS result;
712         int i;
713
714         ZERO_STRUCT(q);
715         ZERO_STRUCT(r);
716
717         init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
718
719         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS,
720                 q, r,
721                 qbuf, rbuf,
722                 lsa_io_q_enum_accounts,
723                 lsa_io_r_enum_accounts,
724                 NT_STATUS_UNSUCCESSFUL);
725
726         result = r.status;
727
728         if (!NT_STATUS_IS_OK(result = r.status)) {
729                 goto done;
730         }
731
732         if (r.sids.num_entries==0)
733                 goto done;
734
735         /* Return output parameters */
736
737         *sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.sids.num_entries);
738         if (!*sids) {
739                 DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
740                 result = NT_STATUS_UNSUCCESSFUL;
741                 goto done;
742         }
743
744         /* Copy across names and sids */
745
746         for (i = 0; i < r.sids.num_entries; i++) {
747                 sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
748         }
749
750         *num_sids= r.sids.num_entries;
751         *enum_ctx = r.enum_context;
752
753  done:
754
755         return result;
756 }
757
758 /** Create a LSA user handle
759  *
760  * @param cli Handle on an initialised SMB connection
761  *
762  * FIXME: The code is actually identical to open account
763  * TODO: Check and code what the function should exactly do
764  *
765  * */
766
767 NTSTATUS rpccli_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
768                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access, 
769                              POLICY_HND *user_pol)
770 {
771         prs_struct qbuf, rbuf;
772         LSA_Q_CREATEACCOUNT q;
773         LSA_R_CREATEACCOUNT r;
774         NTSTATUS result;
775
776         ZERO_STRUCT(q);
777         ZERO_STRUCT(r);
778
779         /* Initialise input parameters */
780
781         init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
782
783         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CREATEACCOUNT,
784                 q, r,
785                 qbuf, rbuf,
786                 lsa_io_q_create_account,
787                 lsa_io_r_create_account,
788                 NT_STATUS_UNSUCCESSFUL);
789
790         /* Return output parameters */
791
792         if (NT_STATUS_IS_OK(result = r.status)) {
793                 *user_pol = r.pol;
794         }
795
796         return result;
797 }
798
799 /** Open a LSA user handle
800  *
801  * @param cli Handle on an initialised SMB connection */
802
803 NTSTATUS rpccli_lsa_open_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
804                              POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, 
805                              POLICY_HND *user_pol)
806 {
807         prs_struct qbuf, rbuf;
808         LSA_Q_OPENACCOUNT q;
809         LSA_R_OPENACCOUNT r;
810         NTSTATUS result;
811
812         ZERO_STRUCT(q);
813         ZERO_STRUCT(r);
814
815         /* Initialise input parameters */
816
817         init_lsa_q_open_account(&q, dom_pol, sid, des_access);
818
819         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENACCOUNT,
820                 q, r,
821                 qbuf, rbuf,
822                 lsa_io_q_open_account,
823                 lsa_io_r_open_account,
824                 NT_STATUS_UNSUCCESSFUL);
825
826         /* Return output parameters */
827
828         if (NT_STATUS_IS_OK(result = r.status)) {
829                 *user_pol = r.pol;
830         }
831
832         return result;
833 }
834
835 /** Enumerate user privileges
836  *
837  * @param cli Handle on an initialised SMB connection */
838
839 NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
840                              POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
841 {
842         prs_struct qbuf, rbuf;
843         LSA_Q_ENUMPRIVSACCOUNT q;
844         LSA_R_ENUMPRIVSACCOUNT r;
845         NTSTATUS result;
846         int i;
847
848         ZERO_STRUCT(q);
849         ZERO_STRUCT(r);
850
851         /* Initialise input parameters */
852
853         init_lsa_q_enum_privsaccount(&q, pol);
854
855         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT,
856                 q, r,
857                 qbuf, rbuf,
858                 lsa_io_q_enum_privsaccount,
859                 lsa_io_r_enum_privsaccount,
860                 NT_STATUS_UNSUCCESSFUL);
861
862         /* Return output parameters */
863
864         if (!NT_STATUS_IS_OK(result = r.status)) {
865                 goto done;
866         }
867
868         if (r.count == 0)
869                 goto done;
870
871         if (!((*set = TALLOC_ARRAY(mem_ctx, LUID_ATTR, r.count)))) {
872                 DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
873                 result = NT_STATUS_UNSUCCESSFUL;
874                 goto done;
875         }
876
877         for (i=0; i<r.count; i++) {
878                 (*set)[i].luid.low = r.set.set[i].luid.low;
879                 (*set)[i].luid.high = r.set.set[i].luid.high;
880                 (*set)[i].attr = r.set.set[i].attr;
881         }
882
883         *count=r.count;
884  done:
885
886         return result;
887 }
888
889 /** Get a privilege value given its name */
890
891 NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
892                                  POLICY_HND *pol, const char *name, LUID *luid)
893 {
894         prs_struct qbuf, rbuf;
895         LSA_Q_LOOKUP_PRIV_VALUE q;
896         LSA_R_LOOKUP_PRIV_VALUE r;
897         NTSTATUS result;
898
899         ZERO_STRUCT(q);
900         ZERO_STRUCT(r);
901
902         /* Marshall data and send request */
903
904         init_lsa_q_lookup_priv_value(&q, pol, name);
905
906         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE,
907                 q, r,
908                 qbuf, rbuf,
909                 lsa_io_q_lookup_priv_value,
910                 lsa_io_r_lookup_priv_value,
911                 NT_STATUS_UNSUCCESSFUL);
912
913         if (!NT_STATUS_IS_OK(result = r.status)) {
914                 goto done;
915         }
916
917         /* Return output parameters */
918
919         (*luid).low=r.luid.low;
920         (*luid).high=r.luid.high;
921
922  done:
923
924         return result;
925 }
926
927 /** Query LSA security object */
928
929 NTSTATUS rpccli_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
930                               POLICY_HND *pol, uint32 sec_info, 
931                               SEC_DESC_BUF **psdb)
932 {
933         prs_struct qbuf, rbuf;
934         LSA_Q_QUERY_SEC_OBJ q;
935         LSA_R_QUERY_SEC_OBJ r;
936         NTSTATUS result;
937
938         ZERO_STRUCT(q);
939         ZERO_STRUCT(r);
940
941         /* Marshall data and send request */
942
943         init_q_query_sec_obj(&q, pol, sec_info);
944
945         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYSECOBJ,
946                 q, r,
947                 qbuf, rbuf,
948                 lsa_io_q_query_sec_obj,
949                 lsa_io_r_query_sec_obj,
950                 NT_STATUS_UNSUCCESSFUL);
951
952         if (!NT_STATUS_IS_OK(result = r.status)) {
953                 goto done;
954         }
955
956         /* Return output parameters */
957
958         if (psdb)
959                 *psdb = r.buf;
960
961  done:
962
963         return result;
964 }
965
966
967 /* Enumerate account rights This is similar to enum_privileges but
968    takes a SID directly, avoiding the open_account call.
969 */
970
971 NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
972                                      POLICY_HND *pol, DOM_SID *sid,
973                                      uint32 *count, char ***priv_names)
974 {
975         prs_struct qbuf, rbuf;
976         LSA_Q_ENUM_ACCT_RIGHTS q;
977         LSA_R_ENUM_ACCT_RIGHTS r;
978         NTSTATUS result;
979         int i;
980         fstring *privileges;
981         char **names;
982
983         ZERO_STRUCT(q);
984         ZERO_STRUCT(r);
985
986         /* Marshall data and send request */
987         init_q_enum_acct_rights(&q, pol, 2, sid);
988
989         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS,
990                 q, r,
991                 qbuf, rbuf,
992                 lsa_io_q_enum_acct_rights,
993                 lsa_io_r_enum_acct_rights,
994                 NT_STATUS_UNSUCCESSFUL);
995
996         if (!NT_STATUS_IS_OK(result = r.status)) {
997                 goto done;
998         }
999
1000         *count = r.count;
1001         if (! *count) {
1002                 goto done;
1003         }
1004
1005         
1006         privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
1007         names      = TALLOC_ARRAY( mem_ctx, char *, *count );
1008
1009         for ( i=0; i<*count; i++ ) {
1010                 UNISTR4 *uni_string = &r.rights->strings[i];
1011
1012                 if ( !uni_string->string )
1013                         continue;
1014
1015                 rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
1016                         
1017                 /* now copy to the return array */
1018                 names[i] = talloc_strdup( mem_ctx, privileges[i] );
1019         }
1020         
1021         *priv_names = names;
1022
1023 done:
1024
1025         return result;
1026 }
1027
1028
1029
1030 /* add account rights to an account. */
1031
1032 NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1033                                     POLICY_HND *pol, DOM_SID sid,
1034                                         uint32 count, const char **privs_name)
1035 {
1036         prs_struct qbuf, rbuf;
1037         LSA_Q_ADD_ACCT_RIGHTS q;
1038         LSA_R_ADD_ACCT_RIGHTS r;
1039         NTSTATUS result;
1040
1041         ZERO_STRUCT(q);
1042         ZERO_STRUCT(r);
1043
1044         /* Marshall data and send request */
1045         init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
1046
1047         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS,
1048                 q, r,
1049                 qbuf, rbuf,
1050                 lsa_io_q_add_acct_rights,
1051                 lsa_io_r_add_acct_rights,
1052                 NT_STATUS_UNSUCCESSFUL);
1053
1054         if (!NT_STATUS_IS_OK(result = r.status)) {
1055                 goto done;
1056         }
1057 done:
1058
1059         return result;
1060 }
1061
1062
1063 /* remove account rights for an account. */
1064
1065 NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1066                                        POLICY_HND *pol, DOM_SID sid, BOOL removeall,
1067                                        uint32 count, const char **privs_name)
1068 {
1069         prs_struct qbuf, rbuf;
1070         LSA_Q_REMOVE_ACCT_RIGHTS q;
1071         LSA_R_REMOVE_ACCT_RIGHTS r;
1072         NTSTATUS result;
1073
1074         ZERO_STRUCT(q);
1075         ZERO_STRUCT(r);
1076
1077         /* Marshall data and send request */
1078         init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
1079
1080         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS,
1081                 q, r,
1082                 qbuf, rbuf,
1083                 lsa_io_q_remove_acct_rights,
1084                 lsa_io_r_remove_acct_rights,
1085                 NT_STATUS_UNSUCCESSFUL);
1086
1087         if (!NT_STATUS_IS_OK(result = r.status)) {
1088                 goto done;
1089         }
1090 done:
1091
1092         return result;
1093 }
1094
1095
1096 #if 0
1097
1098 /** An example of how to use the routines in this file.  Fetch a DOMAIN
1099     sid. Does complete cli setup / teardown anonymously. */
1100
1101 BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
1102 {
1103         extern pstring global_myname;
1104         struct cli_state cli;
1105         NTSTATUS result;
1106         POLICY_HND lsa_pol;
1107         BOOL ret = False;
1108  
1109         ZERO_STRUCT(cli);
1110         if(cli_initialise(&cli) == False) {
1111                 DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
1112                 return False;
1113         }
1114  
1115         if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
1116                 DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
1117                 goto done;
1118         }
1119  
1120         if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
1121                 DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
1122 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1123                 goto done;
1124         }
1125
1126         if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
1127                 DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n", 
1128                         remote_machine));
1129                 goto done;
1130         }
1131  
1132         cli.protocol = PROTOCOL_NT1;
1133  
1134         if (!cli_negprot(&cli)) {
1135                 DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
1136 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1137                 goto done;
1138         }
1139  
1140         if (cli.protocol != PROTOCOL_NT1) {
1141                 DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
1142                         remote_machine));
1143                 goto done;
1144         }
1145  
1146         /*
1147          * Do an anonymous session setup.
1148          */
1149  
1150         if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
1151                 DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
1152 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1153                 goto done;
1154         }
1155  
1156         if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
1157                 DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
1158                         remote_machine));
1159                 goto done;
1160         }
1161
1162         if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
1163                 DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
1164 Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
1165                 goto done;
1166         }
1167
1168         /* Fetch domain sid */
1169  
1170         if (!cli_nt_session_open(&cli, PI_LSARPC)) {
1171                 DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
1172                 goto done;
1173         }
1174  
1175         result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
1176         if (!NT_STATUS_IS_OK(result)) {
1177                 DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
1178                         nt_errstr(result) ));
1179                 goto done;
1180         }
1181  
1182         result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid);
1183         if (!NT_STATUS_IS_OK(result)) {
1184                 DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
1185                         nt_errstr(result) ));
1186                 goto done;
1187         }
1188  
1189         ret = True;
1190
1191   done:
1192
1193         cli_shutdown(&cli);
1194         return ret;
1195 }
1196
1197 #endif
1198
1199 NTSTATUS rpccli_lsa_open_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1200                                      POLICY_HND *pol, DOM_SID *dom_sid, uint32 access_mask,
1201                                      POLICY_HND *trustdom_pol)
1202 {
1203         prs_struct qbuf, rbuf;
1204         LSA_Q_OPEN_TRUSTED_DOMAIN q;
1205         LSA_R_OPEN_TRUSTED_DOMAIN r;
1206         NTSTATUS result;
1207
1208         ZERO_STRUCT(q);
1209         ZERO_STRUCT(r);
1210
1211         /* Initialise input parameters */
1212
1213         init_lsa_q_open_trusted_domain(&q, pol, dom_sid, access_mask);
1214
1215         /* Marshall data and send request */
1216
1217         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOM,
1218                 q, r,
1219                 qbuf, rbuf,
1220                 lsa_io_q_open_trusted_domain,
1221                 lsa_io_r_open_trusted_domain,
1222                 NT_STATUS_UNSUCCESSFUL);
1223
1224         /* Return output parameters */
1225         
1226         if (NT_STATUS_IS_OK(result = r.status)) {
1227                 *trustdom_pol = r.handle;
1228         }
1229
1230         return result;
1231 }
1232
1233 NTSTATUS rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1234                                            POLICY_HND *pol, 
1235                                            uint16 info_class, DOM_SID *dom_sid, 
1236                                            LSA_TRUSTED_DOMAIN_INFO **info)
1237 {
1238         prs_struct qbuf, rbuf;
1239         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO q;
1240         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1241         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1242
1243         ZERO_STRUCT(q);
1244         ZERO_STRUCT(r);
1245
1246         /* Marshall data and send request */
1247
1248         init_q_query_trusted_domain_info(&q, pol, info_class); 
1249
1250         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFO,
1251                 q, r,
1252                 qbuf, rbuf,
1253                 lsa_io_q_query_trusted_domain_info,
1254                 lsa_io_r_query_trusted_domain_info,
1255                 NT_STATUS_UNSUCCESSFUL);
1256
1257         if (!NT_STATUS_IS_OK(result = r.status)) {
1258                 goto done;
1259         }
1260
1261         *info = r.info;
1262                 
1263 done:
1264         return result;
1265 }
1266
1267
1268 NTSTATUS rpccli_lsa_query_trusted_domain_info_by_sid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1269                                                   POLICY_HND *pol, 
1270                                                   uint16 info_class, DOM_SID *dom_sid, 
1271                                                   LSA_TRUSTED_DOMAIN_INFO **info)
1272 {
1273         prs_struct qbuf, rbuf;
1274         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID q;
1275         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1276         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1277
1278         ZERO_STRUCT(q);
1279         ZERO_STRUCT(r);
1280
1281         /* Marshall data and send request */
1282
1283         init_q_query_trusted_domain_info_by_sid(&q, pol, info_class, dom_sid); 
1284
1285         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID,
1286                 q, r,
1287                 qbuf, rbuf,
1288                 lsa_io_q_query_trusted_domain_info_by_sid,
1289                 lsa_io_r_query_trusted_domain_info,
1290                 NT_STATUS_UNSUCCESSFUL);
1291
1292         if (!NT_STATUS_IS_OK(result = r.status)) {
1293                 goto done;
1294         }
1295
1296         *info = r.info;
1297
1298 done:
1299
1300         return result;
1301 }
1302
1303 NTSTATUS rpccli_lsa_query_trusted_domain_info_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1304                                                    POLICY_HND *pol, 
1305                                                    uint16 info_class, const char *domain_name, 
1306                                                    LSA_TRUSTED_DOMAIN_INFO **info)
1307 {
1308         prs_struct qbuf, rbuf;
1309         LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME q;
1310         LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
1311         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1312
1313         ZERO_STRUCT(q);
1314         ZERO_STRUCT(r);
1315
1316         /* Marshall data and send request */
1317
1318         init_q_query_trusted_domain_info_by_name(&q, pol, info_class, domain_name); 
1319
1320         CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME,
1321                 q, r,
1322                 qbuf, rbuf,
1323                 lsa_io_q_query_trusted_domain_info_by_name,
1324                 lsa_io_r_query_trusted_domain_info,
1325                 NT_STATUS_UNSUCCESSFUL);
1326
1327         if (!NT_STATUS_IS_OK(result = r.status)) {
1328                 goto done;
1329         }
1330
1331         *info = r.info;
1332
1333 done:
1334         
1335         return result;
1336 }