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