[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[sfrench/samba-autobuild/.git] / source3 / rpcclient / cmd_lsarpc.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Tim Potter              2000
6    Copyright (C) Rafal Szczesniak        2002
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "rpcclient.h"
24
25
26 /* useful function to allow entering a name instead of a SID and
27  * looking it up automatically */
28 static NTSTATUS name_to_sid(struct rpc_pipe_client *cli, 
29                             TALLOC_CTX *mem_ctx,
30                             DOM_SID *sid, const char *name)
31 {
32         POLICY_HND pol;
33         enum lsa_SidType *sid_types;
34         NTSTATUS result;
35         DOM_SID *sids;
36
37         /* maybe its a raw SID */
38         if (strncmp(name, "S-", 2) == 0 &&
39             string_to_sid(sid, name)) {
40                 return NT_STATUS_OK;
41         }
42
43         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
44                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
45                                      &pol);
46         if (!NT_STATUS_IS_OK(result))
47                 goto done;
48
49         result = rpccli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, NULL, 1, &sids, &sid_types);
50         if (!NT_STATUS_IS_OK(result))
51                 goto done;
52
53         rpccli_lsa_Close(cli, mem_ctx, &pol);
54
55         *sid = sids[0];
56
57 done:
58         return result;
59 }
60
61 static void display_query_info_1(DOM_QUERY_1 d)
62 {
63         d_printf("percent_full:\t%d\n", d.percent_full);
64         d_printf("log_size:\t%d\n", d.log_size);
65         d_printf("retention_time:\t%lld\n", (long long)d.retention_time);
66         d_printf("shutdown_in_progress:\t%d\n", d.shutdown_in_progress);
67         d_printf("time_to_shutdown:\t%lld\n", (long long)d.time_to_shutdown);
68         d_printf("next_audit_record:\t%d\n", d.next_audit_record);
69         d_printf("unknown:\t%d\n", d.unknown);
70 }
71
72 static void display_query_info_2(DOM_QUERY_2 d, TALLOC_CTX *mem_ctx)
73 {
74         int i;
75         d_printf("Auditing enabled:\t%d\n", d.auditing_enabled);
76         d_printf("Auditing categories:\t%d\n", d.count1);
77         d_printf("Auditsettings:\n");
78         for (i=0; i<d.count1; i++) {
79                 const char *val = audit_policy_str(mem_ctx, d.auditsettings[i]);
80                 const char *policy = audit_description_str(i);
81                 d_printf("%s:\t%s\n", policy, val);
82         }
83 }
84
85 static void display_query_info_3(DOM_QUERY_3 d)
86 {
87         fstring name;
88
89         unistr2_to_ascii(name, &d.uni_domain_name, sizeof(name));
90
91         d_printf("Domain Name: %s\n", name);
92         d_printf("Domain Sid: %s\n", sid_string_static(&d.dom_sid.sid));
93 }
94
95 static void display_query_info_5(DOM_QUERY_5 d)
96 {
97         fstring name;
98
99         unistr2_to_ascii(name, &d.uni_domain_name, sizeof(name));
100
101         d_printf("Domain Name: %s\n", name);
102         d_printf("Domain Sid: %s\n", sid_string_static(&d.dom_sid.sid));
103 }
104
105 static void display_query_info_10(DOM_QUERY_10 d)
106 {
107         d_printf("Shutdown on full: %d\n", d.shutdown_on_full);
108 }
109
110 static void display_query_info_11(DOM_QUERY_11 d)
111 {
112         d_printf("Shutdown on full: %d\n", d.shutdown_on_full);
113         d_printf("Log is full: %d\n", d.log_is_full);
114         d_printf("Unknown: %d\n", d.unknown);
115 }
116
117 static void display_query_info_12(DOM_QUERY_12 d)
118 {
119         fstring dom_name, dns_dom_name, forest_name;
120
121         unistr2_to_ascii(dom_name, &d.uni_nb_dom_name, sizeof(dom_name));
122         unistr2_to_ascii(dns_dom_name, &d.uni_dns_dom_name, sizeof(dns_dom_name));
123         unistr2_to_ascii(forest_name, &d.uni_forest_name, sizeof(forest_name));
124
125         d_printf("Domain NetBios Name: %s\n", dom_name);
126         d_printf("Domain DNS Name: %s\n", dns_dom_name);
127         d_printf("Domain Forest Name: %s\n", forest_name);
128         d_printf("Domain Sid: %s\n", sid_string_static(&d.dom_sid.sid));
129         d_printf("Domain GUID: %s\n", smb_uuid_string_static(d.dom_guid));
130
131 }
132
133
134
135 static void display_lsa_query_info(LSA_INFO_CTR *dom, TALLOC_CTX *mem_ctx)
136 {
137         switch (dom->info_class) {
138                 case 1:
139                         display_query_info_1(dom->info.id1);
140                         break;
141                 case 2:
142                         display_query_info_2(dom->info.id2, mem_ctx);
143                         break;
144                 case 3:
145                         display_query_info_3(dom->info.id3);
146                         break;
147                 case 5:
148                         display_query_info_5(dom->info.id5);
149                         break;
150                 case 10:
151                         display_query_info_10(dom->info.id10);
152                         break;
153                 case 11:
154                         display_query_info_11(dom->info.id11);
155                         break;
156                 case 12:
157                         display_query_info_12(dom->info.id12);
158                         break;
159                 default:
160                         printf("can't display info level: %d\n", dom->info_class);
161                         break;
162         }
163 }
164
165 static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli, 
166                                           TALLOC_CTX *mem_ctx, int argc, 
167                                           const char **argv) 
168 {
169         POLICY_HND pol;
170         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
171         LSA_INFO_CTR dom;
172
173         uint32 info_class = 3;
174
175         if (argc > 2) {
176                 printf("Usage: %s [info_class]\n", argv[0]);
177                 return NT_STATUS_OK;
178         }
179
180         if (argc == 2)
181                 info_class = atoi(argv[1]);
182
183         switch (info_class) {
184         case 12:
185                 result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
186                                                  SEC_RIGHTS_MAXIMUM_ALLOWED,
187                                                  &pol);
188
189                 if (!NT_STATUS_IS_OK(result))
190                         goto done;
191                         
192                 result = rpccli_lsa_query_info_policy2_new(cli, mem_ctx, &pol,
193                                                            info_class, &dom);
194                 break;
195         default:
196                 result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
197                                                 SEC_RIGHTS_MAXIMUM_ALLOWED,
198                                                 &pol);
199
200                 if (!NT_STATUS_IS_OK(result))
201                         goto done;
202                 
203                 result = rpccli_lsa_query_info_policy_new(cli, mem_ctx, &pol, 
204                                                           info_class, &dom);
205         }
206
207
208         display_lsa_query_info(&dom, mem_ctx);
209
210         rpccli_lsa_Close(cli, mem_ctx, &pol);
211
212  done:
213         return result;
214 }
215
216 /* Resolve a list of names to a list of sids */
217
218 static NTSTATUS cmd_lsa_lookup_names(struct rpc_pipe_client *cli, 
219                                      TALLOC_CTX *mem_ctx, int argc, 
220                                      const char **argv)
221 {
222         POLICY_HND pol;
223         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
224         DOM_SID *sids;
225         enum lsa_SidType *types;
226         int i;
227
228         if (argc == 1) {
229                 printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]);
230                 return NT_STATUS_OK;
231         }
232
233         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
234                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
235                                      &pol);
236
237         if (!NT_STATUS_IS_OK(result))
238                 goto done;
239
240         result = rpccli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, 
241                                       (const char**)(argv + 1), NULL, 1, &sids, &types);
242
243         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
244             NT_STATUS_V(STATUS_SOME_UNMAPPED))
245                 goto done;
246
247         result = NT_STATUS_OK;
248
249         /* Print results */
250
251         for (i = 0; i < (argc - 1); i++) {
252                 fstring sid_str;
253                 sid_to_string(sid_str, &sids[i]);
254                 printf("%s %s (%s: %d)\n", argv[i + 1], sid_str,
255                        sid_type_lookup(types[i]), types[i]);
256         }
257
258         rpccli_lsa_Close(cli, mem_ctx, &pol);
259
260  done:
261         return result;
262 }
263
264 /* Resolve a list of names to a list of sids */
265
266 static NTSTATUS cmd_lsa_lookup_names_level(struct rpc_pipe_client *cli, 
267                                            TALLOC_CTX *mem_ctx, int argc, 
268                                            const char **argv)
269 {
270         POLICY_HND pol;
271         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
272         DOM_SID *sids;
273         enum lsa_SidType *types;
274         int i, level;
275
276         if (argc < 3) {
277                 printf("Usage: %s [level] [name1 [name2 [...]]]\n", argv[0]);
278                 return NT_STATUS_OK;
279         }
280
281         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
282                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
283                                      &pol);
284
285         if (!NT_STATUS_IS_OK(result))
286                 goto done;
287
288         level = atoi(argv[1]);
289
290         result = rpccli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 2, 
291                                       (const char**)(argv + 2), NULL, level, &sids, &types);
292
293         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
294             NT_STATUS_V(STATUS_SOME_UNMAPPED))
295                 goto done;
296
297         result = NT_STATUS_OK;
298
299         /* Print results */
300
301         for (i = 0; i < (argc - 2); i++) {
302                 fstring sid_str;
303                 sid_to_string(sid_str, &sids[i]);
304                 printf("%s %s (%s: %d)\n", argv[i + 2], sid_str,
305                        sid_type_lookup(types[i]), types[i]);
306         }
307
308         rpccli_lsa_Close(cli, mem_ctx, &pol);
309
310  done:
311         return result;
312 }
313
314
315 /* Resolve a list of SIDs to a list of names */
316
317 static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
318                                     int argc, const char **argv)
319 {
320         POLICY_HND pol;
321         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
322         DOM_SID *sids;
323         char **domains;
324         char **names;
325         enum lsa_SidType *types;
326         int i;
327
328         if (argc == 1) {
329                 printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
330                 return NT_STATUS_OK;
331         }
332
333         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
334                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
335                                      &pol);
336
337         if (!NT_STATUS_IS_OK(result))
338                 goto done;
339
340         /* Convert arguments to sids */
341
342         sids = TALLOC_ARRAY(mem_ctx, DOM_SID, argc - 1);
343
344         if (!sids) {
345                 printf("could not allocate memory for %d sids\n", argc - 1);
346                 goto done;
347         }
348
349         for (i = 0; i < argc - 1; i++) 
350                 if (!string_to_sid(&sids[i], argv[i + 1])) {
351                         result = NT_STATUS_INVALID_SID;
352                         goto done;
353                 }
354
355         /* Lookup the SIDs */
356
357         result = rpccli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, 
358                                      &domains, &names, &types);
359
360         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
361             NT_STATUS_V(STATUS_SOME_UNMAPPED))
362                 goto done;
363
364         result = NT_STATUS_OK;
365
366         /* Print results */
367
368         for (i = 0; i < (argc - 1); i++) {
369                 fstring sid_str;
370
371                 sid_to_string(sid_str, &sids[i]);
372                 printf("%s %s\\%s (%d)\n", sid_str, 
373                        domains[i] ? domains[i] : "*unknown*", 
374                        names[i] ? names[i] : "*unknown*", types[i]);
375         }
376
377         rpccli_lsa_Close(cli, mem_ctx, &pol);
378
379  done:
380         return result;
381 }
382
383 /* Enumerate list of trusted domains */
384
385 static NTSTATUS cmd_lsa_enum_trust_dom(struct rpc_pipe_client *cli, 
386                                        TALLOC_CTX *mem_ctx, int argc, 
387                                        const char **argv)
388 {
389         POLICY_HND pol;
390         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
391         DOM_SID *domain_sids;
392         char **domain_names;
393
394         /* defaults, but may be changed using params */
395         uint32 enum_ctx = 0;
396         uint32 num_domains = 0;
397         int i;
398
399         if (argc > 2) {
400                 printf("Usage: %s [enum context (0)]\n", argv[0]);
401                 return NT_STATUS_OK;
402         }
403
404         if (argc == 2 && argv[1]) {
405                 enum_ctx = atoi(argv[2]);
406         }       
407
408         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
409                                      POLICY_VIEW_LOCAL_INFORMATION,
410                                      &pol);
411
412         if (!NT_STATUS_IS_OK(result))
413                 goto done;
414
415         result = STATUS_MORE_ENTRIES;
416
417         while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
418
419                 /* Lookup list of trusted domains */
420
421                 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
422                                                 &num_domains,
423                                                 &domain_names, &domain_sids);
424                 if (!NT_STATUS_IS_OK(result) &&
425                     !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
426                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
427                         goto done;
428
429                 /* Print results: list of names and sids returned in this
430                  * response. */  
431                 for (i = 0; i < num_domains; i++) {
432                         fstring sid_str;
433
434                         sid_to_string(sid_str, &domain_sids[i]);
435                         printf("%s %s\n", domain_names[i] ? domain_names[i] : 
436                                "*unknown*", sid_str);
437                 }
438         }
439
440         rpccli_lsa_Close(cli, mem_ctx, &pol);
441  done:
442         return result;
443 }
444
445 /* Enumerates privileges */
446
447 static NTSTATUS cmd_lsa_enum_privilege(struct rpc_pipe_client *cli, 
448                                        TALLOC_CTX *mem_ctx, int argc, 
449                                        const char **argv) 
450 {
451         POLICY_HND pol;
452         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
453
454         uint32 enum_context=0;
455         uint32 pref_max_length=0x1000;
456         uint32 count=0;
457         char   **privs_name;
458         uint32 *privs_high;
459         uint32 *privs_low;
460         int i;
461
462         if (argc > 3) {
463                 printf("Usage: %s [enum context] [max length]\n", argv[0]);
464                 return NT_STATUS_OK;
465         }
466
467         if (argc>=2)
468                 enum_context=atoi(argv[1]);
469
470         if (argc==3)
471                 pref_max_length=atoi(argv[2]);
472
473         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
474                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
475                                      &pol);
476
477         if (!NT_STATUS_IS_OK(result))
478                 goto done;
479
480         result = rpccli_lsa_enum_privilege(cli, mem_ctx, &pol, &enum_context, pref_max_length,
481                                         &count, &privs_name, &privs_high, &privs_low);
482
483         if (!NT_STATUS_IS_OK(result))
484                 goto done;
485
486         /* Print results */
487         printf("found %d privileges\n\n", count);
488
489         for (i = 0; i < count; i++) {
490                 printf("%s \t\t%d:%d (0x%x:0x%x)\n", privs_name[i] ? privs_name[i] : "*unknown*",
491                        privs_high[i], privs_low[i], privs_high[i], privs_low[i]);
492         }
493
494         rpccli_lsa_Close(cli, mem_ctx, &pol);
495  done:
496         return result;
497 }
498
499 /* Get privilege name */
500
501 static NTSTATUS cmd_lsa_get_dispname(struct rpc_pipe_client *cli, 
502                                      TALLOC_CTX *mem_ctx, int argc, 
503                                      const char **argv) 
504 {
505         POLICY_HND pol;
506         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
507
508         uint16 lang_id=0;
509         uint16 lang_id_sys=0;
510         uint16 lang_id_desc;
511         fstring description;
512
513         if (argc != 2) {
514                 printf("Usage: %s privilege name\n", argv[0]);
515                 return NT_STATUS_OK;
516         }
517
518         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
519                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
520                                      &pol);
521
522         if (!NT_STATUS_IS_OK(result))
523                 goto done;
524
525         result = rpccli_lsa_get_dispname(cli, mem_ctx, &pol, argv[1], lang_id, lang_id_sys, description, &lang_id_desc);
526
527         if (!NT_STATUS_IS_OK(result))
528                 goto done;
529
530         /* Print results */
531         printf("%s -> %s (language: 0x%x)\n", argv[1], description, lang_id_desc);
532
533         rpccli_lsa_Close(cli, mem_ctx, &pol);
534  done:
535         return result;
536 }
537
538 /* Enumerate the LSA SIDS */
539
540 static NTSTATUS cmd_lsa_enum_sids(struct rpc_pipe_client *cli, 
541                                   TALLOC_CTX *mem_ctx, int argc, 
542                                   const char **argv) 
543 {
544         POLICY_HND pol;
545         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
546
547         uint32 enum_context=0;
548         uint32 pref_max_length=0x1000;
549         DOM_SID *sids;
550         uint32 count=0;
551         int i;
552
553         if (argc > 3) {
554                 printf("Usage: %s [enum context] [max length]\n", argv[0]);
555                 return NT_STATUS_OK;
556         }
557
558         if (argc>=2)
559                 enum_context=atoi(argv[1]);
560
561         if (argc==3)
562                 pref_max_length=atoi(argv[2]);
563
564         result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
565                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
566                                      &pol);
567
568         if (!NT_STATUS_IS_OK(result))
569                 goto done;
570
571         result = rpccli_lsa_enum_sids(cli, mem_ctx, &pol, &enum_context, pref_max_length,
572                                         &count, &sids);
573
574         if (!NT_STATUS_IS_OK(result))
575                 goto done;
576
577         /* Print results */
578         printf("found %d SIDs\n\n", count);
579
580         for (i = 0; i < count; i++) {
581                 fstring sid_str;
582
583                 sid_to_string(sid_str, &sids[i]);
584                 printf("%s\n", sid_str);
585         }
586
587         rpccli_lsa_Close(cli, mem_ctx, &pol);
588  done:
589         return result;
590 }
591
592 /* Create a new account */
593
594 static NTSTATUS cmd_lsa_create_account(struct rpc_pipe_client *cli, 
595                                            TALLOC_CTX *mem_ctx, int argc, 
596                                            const char **argv) 
597 {
598         POLICY_HND dom_pol;
599         POLICY_HND user_pol;
600         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
601         uint32 des_access = 0x000f000f;
602         
603         DOM_SID sid;
604
605         if (argc != 2 ) {
606                 printf("Usage: %s SID\n", argv[0]);
607                 return NT_STATUS_OK;
608         }
609
610         result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
611         if (!NT_STATUS_IS_OK(result))
612                 goto done;      
613
614         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
615                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
616                                      &dom_pol);
617
618         if (!NT_STATUS_IS_OK(result))
619                 goto done;
620
621         result = rpccli_lsa_create_account(cli, mem_ctx, &dom_pol, &sid, des_access, &user_pol);
622
623         if (!NT_STATUS_IS_OK(result))
624                 goto done;
625
626         printf("Account for SID %s successfully created\n\n", argv[1]);
627         result = NT_STATUS_OK;
628
629         rpccli_lsa_Close(cli, mem_ctx, &dom_pol);
630  done:
631         return result;
632 }
633
634
635 /* Enumerate the privileges of an SID */
636
637 static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli, 
638                                            TALLOC_CTX *mem_ctx, int argc, 
639                                            const char **argv) 
640 {
641         POLICY_HND dom_pol;
642         POLICY_HND user_pol;
643         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
644         uint32 access_desired = 0x000f000f;
645         
646         DOM_SID sid;
647         uint32 count=0;
648         LUID_ATTR *set;
649         int i;
650
651         if (argc != 2 ) {
652                 printf("Usage: %s SID\n", argv[0]);
653                 return NT_STATUS_OK;
654         }
655
656         result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
657         if (!NT_STATUS_IS_OK(result))
658                 goto done;      
659
660         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
661                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
662                                      &dom_pol);
663
664         if (!NT_STATUS_IS_OK(result))
665                 goto done;
666
667         result = rpccli_lsa_open_account(cli, mem_ctx, &dom_pol, &sid, access_desired, &user_pol);
668
669         if (!NT_STATUS_IS_OK(result))
670                 goto done;
671
672         result = rpccli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set);
673
674         if (!NT_STATUS_IS_OK(result))
675                 goto done;
676
677         /* Print results */
678         printf("found %d privileges for SID %s\n\n", count, argv[1]);
679         printf("high\tlow\tattribute\n");
680
681         for (i = 0; i < count; i++) {
682                 printf("%u\t%u\t%u\n", set[i].luid.high, set[i].luid.low, set[i].attr);
683         }
684
685         rpccli_lsa_Close(cli, mem_ctx, &dom_pol);
686  done:
687         return result;
688 }
689
690
691 /* Enumerate the privileges of an SID via LsaEnumerateAccountRights */
692
693 static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli, 
694                                          TALLOC_CTX *mem_ctx, int argc, 
695                                          const char **argv) 
696 {
697         POLICY_HND dom_pol;
698         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
699
700         DOM_SID sid;
701         uint32 count;
702         char **rights;
703
704         int i;
705
706         if (argc != 2 ) {
707                 printf("Usage: %s SID\n", argv[0]);
708                 return NT_STATUS_OK;
709         }
710
711         result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
712         if (!NT_STATUS_IS_OK(result))
713                 goto done;      
714
715         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
716                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
717                                      &dom_pol);
718
719         if (!NT_STATUS_IS_OK(result))
720                 goto done;
721
722         result = rpccli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, &sid, &count, &rights);
723
724         if (!NT_STATUS_IS_OK(result))
725                 goto done;
726
727         printf("found %d privileges for SID %s\n", count, sid_string_static(&sid));
728
729         for (i = 0; i < count; i++) {
730                 printf("\t%s\n", rights[i]);
731         }
732
733         rpccli_lsa_Close(cli, mem_ctx, &dom_pol);
734  done:
735         return result;
736 }
737
738
739 /* add some privileges to a SID via LsaAddAccountRights */
740
741 static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli, 
742                                         TALLOC_CTX *mem_ctx, int argc, 
743                                         const char **argv) 
744 {
745         POLICY_HND dom_pol;
746         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
747
748         DOM_SID sid;
749
750         if (argc < 3 ) {
751                 printf("Usage: %s SID [rights...]\n", argv[0]);
752                 return NT_STATUS_OK;
753         }
754
755         result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
756         if (!NT_STATUS_IS_OK(result))
757                 goto done;      
758
759         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
760                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
761                                      &dom_pol);
762
763         if (!NT_STATUS_IS_OK(result))
764                 goto done;
765
766         result = rpccli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid, 
767                                             argc-2, argv+2);
768
769         if (!NT_STATUS_IS_OK(result))
770                 goto done;
771
772         rpccli_lsa_Close(cli, mem_ctx, &dom_pol);
773  done:
774         return result;
775 }
776
777
778 /* remove some privileges to a SID via LsaRemoveAccountRights */
779
780 static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli, 
781                                         TALLOC_CTX *mem_ctx, int argc, 
782                                         const char **argv) 
783 {
784         POLICY_HND dom_pol;
785         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
786
787         DOM_SID sid;
788
789         if (argc < 3 ) {
790                 printf("Usage: %s SID [rights...]\n", argv[0]);
791                 return NT_STATUS_OK;
792         }
793
794         result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
795         if (!NT_STATUS_IS_OK(result))
796                 goto done;      
797
798         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
799                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
800                                      &dom_pol);
801
802         if (!NT_STATUS_IS_OK(result))
803                 goto done;
804
805         result = rpccli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid, 
806                                                False, argc-2, argv+2);
807
808         if (!NT_STATUS_IS_OK(result))
809                 goto done;
810
811         rpccli_lsa_Close(cli, mem_ctx, &dom_pol);
812
813  done:
814         return result;
815 }
816
817
818 /* Get a privilege value given its name */
819
820 static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli, 
821                                         TALLOC_CTX *mem_ctx, int argc, 
822                                         const char **argv) 
823 {
824         POLICY_HND pol;
825         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
826         LUID luid;
827
828         if (argc != 2 ) {
829                 printf("Usage: %s name\n", argv[0]);
830                 return NT_STATUS_OK;
831         }
832
833         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
834                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
835                                      &pol);
836
837         if (!NT_STATUS_IS_OK(result))
838                 goto done;
839
840         result = rpccli_lsa_lookup_priv_value(cli, mem_ctx, &pol, argv[1], &luid);
841
842         if (!NT_STATUS_IS_OK(result))
843                 goto done;
844
845         /* Print results */
846
847         printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low);
848
849         rpccli_lsa_Close(cli, mem_ctx, &pol);
850  done:
851         return result;
852 }
853
854 /* Query LSA security object */
855
856 static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli, 
857                                      TALLOC_CTX *mem_ctx, int argc, 
858                                      const char **argv) 
859 {
860         POLICY_HND pol;
861         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
862         SEC_DESC_BUF *sdb;
863         uint32 sec_info = DACL_SECURITY_INFORMATION;
864
865         if (argc < 1 || argc > 2) {
866                 printf("Usage: %s [sec_info]\n", argv[0]);
867                 return NT_STATUS_OK;
868         }
869
870         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
871                                       SEC_RIGHTS_MAXIMUM_ALLOWED,
872                                       &pol);
873
874         if (argc == 2) 
875                 sscanf(argv[1], "%x", &sec_info);
876
877         if (!NT_STATUS_IS_OK(result))
878                 goto done;
879
880         result = rpccli_lsa_query_secobj(cli, mem_ctx, &pol, sec_info, &sdb);
881
882         if (!NT_STATUS_IS_OK(result))
883                 goto done;
884
885         /* Print results */
886
887         display_sec_desc(sdb->sd);
888
889         rpccli_lsa_Close(cli, mem_ctx, &pol);
890  done:
891         return result;
892 }
893
894 static void display_trust_dom_info_1(TRUSTED_DOMAIN_INFO_NAME *n)
895 {
896         printf("NetBIOS Name:\t%s\n", unistr2_static(&n->netbios_name.unistring));
897 }
898
899 static void display_trust_dom_info_3(TRUSTED_DOMAIN_INFO_POSIX_OFFSET *p)
900 {
901         printf("Posix Offset:\t%08x (%d)\n", p->posix_offset, p->posix_offset);
902 }
903
904 static void display_trust_dom_info_4(TRUSTED_DOMAIN_INFO_PASSWORD *p, const char *password)
905 {
906         char *pwd, *pwd_old;
907         
908         DATA_BLOB data     = data_blob(NULL, p->password.length);
909         DATA_BLOB data_old = data_blob(NULL, p->old_password.length);
910
911         memcpy(data.data, p->password.data, p->password.length);
912         memcpy(data_old.data, p->old_password.data, p->old_password.length);
913         
914         pwd     = decrypt_trustdom_secret(password, &data);
915         pwd_old = decrypt_trustdom_secret(password, &data_old);
916         
917         d_printf("Password:\t%s\n", pwd);
918         d_printf("Old Password:\t%s\n", pwd_old);
919
920         SAFE_FREE(pwd);
921         SAFE_FREE(pwd_old);
922         
923         data_blob_free(&data);
924         data_blob_free(&data_old);
925 }
926
927 static void display_trust_dom_info_6(TRUSTED_DOMAIN_INFO_EX *i)
928 {
929         printf("Domain Name:\t\t%s\n", unistr2_static(&i->domain_name.unistring));
930         printf("NetBIOS Name:\t\t%s\n", unistr2_static(&i->netbios_name.unistring));
931         printf("SID:\t\t\t%s\n", sid_string_static(&i->sid.sid));
932         printf("Trust Direction:\t0x%08x\n", i->trust_direction);
933         printf("Trust Type:\t\t0x%08x\n", i->trust_type);
934         printf("Trust Attributes:\t0x%08x\n", i->trust_attributes);
935 }
936
937
938 static void display_trust_dom_info(LSA_TRUSTED_DOMAIN_INFO *info, uint32 info_class, const char *pass)
939 {
940         switch (info_class) {
941         case 1:
942                 display_trust_dom_info_1(&info->name);
943                 break;
944         case 3:
945                 display_trust_dom_info_3(&info->posix_offset);
946                 break;
947         case 4:
948                 display_trust_dom_info_4(&info->password, pass);
949                 break;
950         case 6:
951                 display_trust_dom_info_6(&info->info_ex);
952                 break;
953         default:
954                 printf("unsupported info-class: %d\n", info_class);
955                 break;
956         }
957 }
958
959 static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli,
960                                                 TALLOC_CTX *mem_ctx, int argc, 
961                                                 const char **argv) 
962 {
963         POLICY_HND pol;
964         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
965         DOM_SID dom_sid;
966         uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
967         LSA_TRUSTED_DOMAIN_INFO *info;
968
969         uint32 info_class = 1; 
970
971         if (argc > 3 || argc < 2) {
972                 printf("Usage: %s [sid] [info_class]\n", argv[0]);
973                 return NT_STATUS_OK;
974         }
975
976         if (!string_to_sid(&dom_sid, argv[1]))
977                 return NT_STATUS_NO_MEMORY;
978
979         if (argc == 3)
980                 info_class = atoi(argv[2]);
981
982         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
983
984         if (!NT_STATUS_IS_OK(result))
985                 goto done;
986
987         result = rpccli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, &pol,
988                                                           info_class, &dom_sid, &info);
989
990         if (!NT_STATUS_IS_OK(result))
991                 goto done;
992
993         display_trust_dom_info(info, info_class, cli->pwd.password);
994
995  done:
996         if (&pol)
997                 rpccli_lsa_Close(cli, mem_ctx, &pol);
998
999         return result;
1000 }
1001
1002 static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli,
1003                                                  TALLOC_CTX *mem_ctx, int argc,
1004                                                  const char **argv) 
1005 {
1006         POLICY_HND pol;
1007         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1008         uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1009         LSA_TRUSTED_DOMAIN_INFO *info;
1010         uint32 info_class = 1; 
1011
1012         if (argc > 3 || argc < 2) {
1013                 printf("Usage: %s [name] [info_class]\n", argv[0]);
1014                 return NT_STATUS_OK;
1015         }
1016
1017         if (argc == 3)
1018                 info_class = atoi(argv[2]);
1019
1020         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
1021
1022         if (!NT_STATUS_IS_OK(result))
1023                 goto done;
1024
1025         result = rpccli_lsa_query_trusted_domain_info_by_name(cli, mem_ctx, &pol, 
1026                                                            info_class, argv[1], &info);
1027
1028         if (!NT_STATUS_IS_OK(result))
1029                 goto done;
1030
1031         display_trust_dom_info(info, info_class, cli->pwd.password);
1032
1033  done:
1034         if (&pol)
1035                 rpccli_lsa_Close(cli, mem_ctx, &pol);
1036
1037         return result;
1038 }
1039
1040 static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli,
1041                                            TALLOC_CTX *mem_ctx, int argc,
1042                                            const char **argv) 
1043 {
1044         POLICY_HND pol, trustdom_pol;
1045         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1046         uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1047         LSA_TRUSTED_DOMAIN_INFO *info;
1048         DOM_SID dom_sid;
1049         uint32 info_class = 1; 
1050
1051         if (argc > 3 || argc < 2) {
1052                 printf("Usage: %s [sid] [info_class]\n", argv[0]);
1053                 return NT_STATUS_OK;
1054         }
1055
1056         if (!string_to_sid(&dom_sid, argv[1]))
1057                 return NT_STATUS_NO_MEMORY;
1058
1059
1060         if (argc == 3)
1061                 info_class = atoi(argv[2]);
1062
1063         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
1064
1065         if (!NT_STATUS_IS_OK(result))
1066                 goto done;
1067         
1068         result = rpccli_lsa_open_trusted_domain(cli, mem_ctx, &pol,
1069                                              &dom_sid, access_mask, &trustdom_pol);
1070
1071         if (!NT_STATUS_IS_OK(result))
1072                 goto done;
1073
1074         result = rpccli_lsa_query_trusted_domain_info(cli, mem_ctx, &trustdom_pol, 
1075                                                    info_class, &info);
1076
1077         if (!NT_STATUS_IS_OK(result))
1078                 goto done;
1079
1080         display_trust_dom_info(info, info_class, cli->pwd.password);
1081
1082  done:
1083         if (&pol)
1084                 rpccli_lsa_Close(cli, mem_ctx, &pol);
1085
1086         return result;
1087 }
1088
1089
1090
1091 /* List of commands exported by this module */
1092
1093 struct cmd_set lsarpc_commands[] = {
1094
1095         { "LSARPC" },
1096
1097         { "lsaquery",            RPC_RTYPE_NTSTATUS, cmd_lsa_query_info_policy,  NULL, PI_LSARPC, NULL, "Query info policy",                    "" },
1098         { "lookupsids",          RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_sids,        NULL, PI_LSARPC, NULL, "Convert SIDs to names",                "" },
1099         { "lookupnames",         RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_names,       NULL, PI_LSARPC, NULL, "Convert names to SIDs",                "" },
1100         { "lookupnames_level",   RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_names_level, NULL, PI_LSARPC, NULL, "Convert names to SIDs",                "" },
1101         { "enumtrust",           RPC_RTYPE_NTSTATUS, cmd_lsa_enum_trust_dom,     NULL, PI_LSARPC, NULL, "Enumerate trusted domains",            "Usage: [preferred max number] [enum context (0)]" },
1102         { "enumprivs",           RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privilege,     NULL, PI_LSARPC, NULL, "Enumerate privileges",                 "" },
1103         { "getdispname",         RPC_RTYPE_NTSTATUS, cmd_lsa_get_dispname,       NULL, PI_LSARPC, NULL, "Get the privilege name",               "" },
1104         { "lsaenumsid",          RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids,          NULL, PI_LSARPC, NULL, "Enumerate the LSA SIDS",               "" },
1105         { "lsacreateaccount",    RPC_RTYPE_NTSTATUS, cmd_lsa_create_account,     NULL, PI_LSARPC, NULL, "Create a new lsa account",   "" },
1106         { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, NULL, "Enumerate the privileges of an SID",   "" },
1107         { "lsaenumacctrights",   RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights,   NULL, PI_LSARPC, NULL, "Enumerate the rights of an SID",   "" },
1108 #if 0
1109         { "lsaaddpriv",          RPC_RTYPE_NTSTATUS, cmd_lsa_add_priv,           NULL, PI_LSARPC, "Assign a privilege to a SID", "" },
1110         { "lsadelpriv",          RPC_RTYPE_NTSTATUS, cmd_lsa_del_priv,           NULL, PI_LSARPC, "Revoke a privilege from a SID", "" },
1111 #endif
1112         { "lsaaddacctrights",    RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights,    NULL, PI_LSARPC, NULL, "Add rights to an account",   "" },
1113         { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, NULL, "Remove rights from an account",   "" },
1114         { "lsalookupprivvalue",  RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_priv_value,  NULL, PI_LSARPC, NULL, "Get a privilege value given its name", "" },
1115         { "lsaquerysecobj",      RPC_RTYPE_NTSTATUS, cmd_lsa_query_secobj,       NULL, PI_LSARPC, NULL, "Query LSA security object", "" },
1116         { "lsaquerytrustdominfo",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfo, NULL, PI_LSARPC, NULL, "Query LSA trusted domains info (given a SID)", "" },
1117         { "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, PI_LSARPC, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
1118         { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, PI_LSARPC, NULL, "Query LSA trusted domains info (given a SID)", "" },
1119
1120         { NULL }
1121 };
1122