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