Merging tridge's privillage client changes from HEAD.
[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 /* useful function to allow entering a name instead of a SID and
27  * looking it up automatically */
28 static NTSTATUS name_to_sid(struct cli_state *cli,
29                                 TALLOC_CTX *mem_ctx,
30                                 DOM_SID *sid, const char *name)
31 {
32         POLICY_HND pol;
33         uint32 *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 = cli_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 = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
50         if (!NT_STATUS_IS_OK(result))
51                 goto done;
52
53         cli_lsa_close(cli, mem_ctx, &pol);
54
55         *sid = sids[0];
56
57 done:
58         return result;
59 }
60
61 /* Look up domain related information on a remote host */
62
63 static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, 
64                                           TALLOC_CTX *mem_ctx, int argc, 
65                                           char **argv) 
66 {
67         POLICY_HND pol;
68         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
69         DOM_SID dom_sid;
70         GUID dom_guid;
71         fstring sid_str, domain_name="", dns_name="", forest_name="";
72         uint32 info_class = 3;
73
74         if (argc > 2) {
75                 printf("Usage: %s [info_class]\n", argv[0]);
76                 return NT_STATUS_OK;
77         }
78
79         if (argc == 2)
80                 info_class = atoi(argv[1]);
81         
82         /* Lookup info policy */
83         switch (info_class) {
84         case 12:
85                 result = cli_lsa_open_policy2(cli, mem_ctx, True, 
86                                              SEC_RIGHTS_MAXIMUM_ALLOWED,
87                                              &pol);
88
89                 if (!NT_STATUS_IS_OK(result))
90                         goto done;
91                 result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol,
92                                                     info_class, domain_name,
93                                                     dns_name, forest_name,
94                                                     &dom_guid, &dom_sid);
95                 break;
96         default:
97                 result = cli_lsa_open_policy(cli, mem_ctx, True, 
98                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
99                                      &pol);
100
101                 if (!NT_STATUS_IS_OK(result))
102                         goto done;
103                 result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, 
104                                                    info_class, domain_name, 
105                                                    &dom_sid);
106         }
107
108         if (!NT_STATUS_IS_OK(result))
109                 goto done;
110
111         sid_to_string(sid_str, &dom_sid);
112
113         if (domain_name[0])
114                 printf("domain %s has sid %s\n", domain_name, sid_str);
115         else
116                 printf("could not query info for level %d\n", info_class);
117
118         if (dns_name[0])
119                 printf("domain dns name is %s\n", dns_name);
120         if (forest_name[0])
121                 printf("forest name is %s\n", forest_name);
122
123         if (info_class == 12) {
124                 printf("domain GUID is ");
125                 print_guid(&dom_guid);
126         }
127  done:
128         return result;
129 }
130
131 /* Resolve a list of names to a list of sids */
132
133 static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli, 
134                                      TALLOC_CTX *mem_ctx, int argc, 
135                                      char **argv)
136 {
137         POLICY_HND pol;
138         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
139         DOM_SID *sids;
140         uint32 *types;
141         int i;
142
143         if (argc == 1) {
144                 printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]);
145                 return NT_STATUS_OK;
146         }
147
148         result = cli_lsa_open_policy(cli, mem_ctx, True, 
149                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
150                                      &pol);
151
152         if (!NT_STATUS_IS_OK(result))
153                 goto done;
154
155         result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, 
156                                       (const char**)(argv + 1), &sids, &types);
157
158         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
159             NT_STATUS_V(STATUS_SOME_UNMAPPED))
160                 goto done;
161
162         result = NT_STATUS_OK;
163
164         /* Print results */
165
166         for (i = 0; i < (argc - 1); i++) {
167                 fstring sid_str;
168                 sid_to_string(sid_str, &sids[i]);
169                 printf("%s %s (%s: %d)\n", argv[i + 1], sid_str,
170                        sid_type_lookup(types[i]), types[i]);
171         }
172
173  done:
174         return result;
175 }
176
177 /* Resolve a list of SIDs to a list of names */
178
179 static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
180                                     int argc, char **argv)
181 {
182         POLICY_HND pol;
183         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
184         DOM_SID *sids;
185         char **domains;
186         char **names;
187         uint32 *types;
188         int i;
189
190         if (argc == 1) {
191                 printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
192                 return NT_STATUS_OK;
193         }
194
195         result = cli_lsa_open_policy(cli, mem_ctx, True, 
196                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
197                                      &pol);
198
199         if (!NT_STATUS_IS_OK(result))
200                 goto done;
201
202         /* Convert arguments to sids */
203
204         sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (argc - 1));
205
206         if (!sids) {
207                 printf("could not allocate memory for %d sids\n", argc - 1);
208                 goto done;
209         }
210
211         for (i = 0; i < argc - 1; i++)
212                 string_to_sid(&sids[i], argv[i + 1]);
213
214         /* Lookup the SIDs */
215
216         result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, 
217                                      &domains, &names, &types);
218
219         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
220             NT_STATUS_V(STATUS_SOME_UNMAPPED))
221                 goto done;
222
223         result = NT_STATUS_OK;
224
225         /* Print results */
226
227         for (i = 0; i < (argc - 1); i++) {
228                 fstring sid_str;
229
230                 sid_to_string(sid_str, &sids[i]);
231                 printf("%s %s\\%s (%d)\n", sid_str, 
232                        domains[i] ? domains[i] : "*unknown*", 
233                        names[i] ? names[i] : "*unknown*", types[i]);
234         }
235
236  done:
237         return result;
238 }
239
240 /* Enumerate list of trusted domains */
241
242 static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, 
243                                        TALLOC_CTX *mem_ctx, int argc, 
244                                        char **argv)
245 {
246         POLICY_HND pol;
247         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
248         DOM_SID *domain_sids;
249         char **domain_names;
250
251         /* defaults, but may be changed using params */
252         uint32 enum_ctx = 0;
253         uint32 num_domains = 0;
254         int i;
255
256         if (argc > 2) {
257                 printf("Usage: %s [enum context (0)]\n", argv[0]);
258                 return NT_STATUS_OK;
259         }
260
261         if (argc == 2 && argv[1]) {
262                 enum_ctx = atoi(argv[2]);
263         }       
264
265         result = cli_lsa_open_policy(cli, mem_ctx, True, 
266                                      POLICY_VIEW_LOCAL_INFORMATION,
267                                      &pol);
268
269         if (!NT_STATUS_IS_OK(result))
270                 goto done;
271
272         /* Lookup list of trusted domains */
273
274         result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
275                                         &num_domains,
276                                         &domain_names, &domain_sids);
277         if (!NT_STATUS_IS_OK(result) &&
278             !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
279             !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
280             goto done;
281
282         /* Print results: list of names and sids returned in this response. */   
283         for (i = 0; i < num_domains; i++) {
284                 fstring sid_str;
285
286                 sid_to_string(sid_str, &domain_sids[i]);
287                 printf("%s %s\n", domain_names[i] ? domain_names[i] : 
288                        "*unknown*", sid_str);
289         }
290
291  done:
292         return result;
293 }
294
295 /* Enumerates privileges */
296
297 static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli, 
298                                           TALLOC_CTX *mem_ctx, int argc, 
299                                           char **argv) 
300 {
301         POLICY_HND pol;
302         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
303
304         uint32 enum_context=0;
305         uint32 pref_max_length=0x1000;
306         uint32 count=0;
307         char   **privs_name;
308         uint32 *privs_high;
309         uint32 *privs_low;
310         int i;
311
312         if (argc > 3) {
313                 printf("Usage: %s [enum context] [max length]\n", argv[0]);
314                 return NT_STATUS_OK;
315         }
316
317         if (argc>=2)
318                 enum_context=atoi(argv[1]);
319
320         if (argc==3)
321                 pref_max_length=atoi(argv[2]);
322
323         result = cli_lsa_open_policy(cli, mem_ctx, True, 
324                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
325                                      &pol);
326
327         if (!NT_STATUS_IS_OK(result))
328                 goto done;
329
330         result = cli_lsa_enum_privilege(cli, mem_ctx, &pol, &enum_context, pref_max_length,
331                                         &count, &privs_name, &privs_high, &privs_low);
332
333         if (!NT_STATUS_IS_OK(result))
334                 goto done;
335
336         /* Print results */
337         printf("found %d privileges\n\n", count);
338
339         for (i = 0; i < count; i++) {
340                 printf("%s \t\t%d:%d (0x%x:0x%x)\n", privs_name[i] ? privs_name[i] : "*unknown*",
341                        privs_high[i], privs_low[i], privs_high[i], privs_low[i]);
342         }
343
344  done:
345         return result;
346 }
347
348 /* Get privilege name */
349
350 static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli, 
351                                      TALLOC_CTX *mem_ctx, int argc, 
352                                      char **argv) 
353 {
354         POLICY_HND pol;
355         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
356
357         uint16 lang_id=0;
358         uint16 lang_id_sys=0;
359         uint16 lang_id_desc;
360         fstring description;
361
362         if (argc != 2) {
363                 printf("Usage: %s privilege name\n", argv[0]);
364                 return NT_STATUS_OK;
365         }
366
367         result = cli_lsa_open_policy(cli, mem_ctx, True, 
368                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
369                                      &pol);
370
371         if (!NT_STATUS_IS_OK(result))
372                 goto done;
373
374         result = cli_lsa_get_dispname(cli, mem_ctx, &pol, argv[1], lang_id, lang_id_sys, description, &lang_id_desc);
375
376         if (!NT_STATUS_IS_OK(result))
377                 goto done;
378
379         /* Print results */
380         printf("%s -> %s (language: 0x%x)\n", argv[1], description, lang_id_desc);
381
382  done:
383         return result;
384 }
385
386 /* Enumerate the LSA SIDS */
387
388 static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli, 
389                                      TALLOC_CTX *mem_ctx, int argc, 
390                                      char **argv) 
391 {
392         POLICY_HND pol;
393         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
394
395         uint32 enum_context=0;
396         uint32 pref_max_length=0x1000;
397         DOM_SID *sids;
398         uint32 count=0;
399         int i;
400
401         if (argc > 3) {
402                 printf("Usage: %s [enum context] [max length]\n", argv[0]);
403                 return NT_STATUS_OK;
404         }
405
406         if (argc>=2)
407                 enum_context=atoi(argv[1]);
408
409         if (argc==3)
410                 pref_max_length=atoi(argv[2]);
411
412         result = cli_lsa_open_policy(cli, mem_ctx, True, 
413                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
414                                      &pol);
415
416         if (!NT_STATUS_IS_OK(result))
417                 goto done;
418
419         result = cli_lsa_enum_sids(cli, mem_ctx, &pol, &enum_context, pref_max_length,
420                                         &count, &sids);
421
422         if (!NT_STATUS_IS_OK(result))
423                 goto done;
424
425         /* Print results */
426         printf("found %d SIDs\n\n", count);
427
428         for (i = 0; i < count; i++) {
429                 fstring sid_str;
430
431                 sid_to_string(sid_str, &sids[i]);
432                 printf("%s\n", sid_str);
433         }
434
435  done:
436         return result;
437 }
438
439 /* Enumerate the privileges of an SID */
440
441 static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli, 
442                                            TALLOC_CTX *mem_ctx, int argc, 
443                                            char **argv) 
444 {
445         POLICY_HND dom_pol;
446         POLICY_HND user_pol;
447         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
448         uint32 access_desired = 0x000f000f;
449         
450         DOM_SID sid;
451         uint32 count=0;
452         LUID_ATTR *set;
453         int i;
454
455         if (argc != 2 ) {
456                 printf("Usage: %s SID\n", argv[0]);
457                 return NT_STATUS_OK;
458         }
459
460         string_to_sid(&sid, argv[1]);
461
462         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
463                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
464                                      &dom_pol);
465
466         if (!NT_STATUS_IS_OK(result))
467                 goto done;
468
469         result = cli_lsa_open_account(cli, mem_ctx, &dom_pol, &sid, access_desired, &user_pol);
470
471         if (!NT_STATUS_IS_OK(result))
472                 goto done;
473
474         result = cli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set);
475
476         if (!NT_STATUS_IS_OK(result))
477                 goto done;
478
479         /* Print results */
480         printf("found %d privileges for SID %s\n\n", count, argv[1]);
481         printf("high\tlow\tattribute\n");
482
483         for (i = 0; i < count; i++) {
484                 printf("%u\t%u\t%u\n", set[i].luid.high, set[i].luid.low, set[i].attr);
485         }
486
487  done:
488         return result;
489 }
490
491
492 /* Enumerate the privileges of an SID via LsaEnumerateAccountRights */
493
494 static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli, 
495                                          TALLOC_CTX *mem_ctx, int argc, 
496                                          char **argv) 
497 {
498         POLICY_HND dom_pol;
499         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
500
501         DOM_SID sid;
502         uint32 count;
503         char **rights;
504
505         int i;
506
507         if (argc != 2 ) {
508                 printf("Usage: %s SID\n", argv[0]);
509                 return NT_STATUS_OK;
510         }
511
512         string_to_sid(&sid, argv[1]);
513
514         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
515                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
516                                      &dom_pol);
517
518         if (!NT_STATUS_IS_OK(result))
519                 goto done;
520
521         result = cli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, sid, &count, &rights);
522
523         if (!NT_STATUS_IS_OK(result))
524                 goto done;
525
526         printf("found %d privileges for SID %s\n", count, argv[1]);
527
528         for (i = 0; i < count; i++) {
529                 printf("\t%s\n", rights[i]);
530         }
531
532  done:
533         return result;
534 }
535
536
537 /* add some privileges to a SID via LsaAddAccountRights */
538
539 static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli, 
540                                         TALLOC_CTX *mem_ctx, int argc, 
541                                         const char **argv) 
542 {
543         POLICY_HND dom_pol;
544         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
545
546         DOM_SID sid;
547
548         if (argc < 3 ) {
549                 printf("Usage: %s SID [rights...]\n", argv[0]);
550                 return NT_STATUS_OK;
551         }
552
553         result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
554         if (!NT_STATUS_IS_OK(result))
555                 goto done;      
556
557         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
558                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
559                                      &dom_pol);
560
561         if (!NT_STATUS_IS_OK(result))
562                 goto done;
563
564         result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid, 
565                                             argc-2, argv+2);
566
567         if (!NT_STATUS_IS_OK(result))
568                 goto done;
569
570  done:
571         return result;
572 }
573
574
575 /* Get a privilege value given its name */
576
577 static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli, 
578                                            TALLOC_CTX *mem_ctx, int argc, 
579                                            char **argv) 
580 {
581         POLICY_HND pol;
582         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
583         LUID luid;
584
585         if (argc != 2 ) {
586                 printf("Usage: %s name\n", argv[0]);
587                 return NT_STATUS_OK;
588         }
589
590         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
591                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
592                                      &pol);
593
594         if (!NT_STATUS_IS_OK(result))
595                 goto done;
596
597         result = cli_lsa_lookupprivvalue(cli, mem_ctx, &pol, argv[1], &luid);
598
599         if (!NT_STATUS_IS_OK(result))
600                 goto done;
601
602         /* Print results */
603
604         printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low);
605
606  done:
607         return result;
608 }
609
610 /* Query LSA security object */
611
612 static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli, 
613                                      TALLOC_CTX *mem_ctx, int argc, 
614                                      char **argv) 
615 {
616         POLICY_HND pol;
617         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
618         SEC_DESC_BUF *sdb;
619         uint32 sec_info = 0x00000004; /* ??? */
620
621         if (argc != 1 ) {
622                 printf("Usage: %s\n", argv[0]);
623                 return NT_STATUS_OK;
624         }
625
626         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
627                                       SEC_RIGHTS_MAXIMUM_ALLOWED,
628                                       &pol);
629
630         if (!NT_STATUS_IS_OK(result))
631                 goto done;
632
633         result = cli_lsa_query_secobj(cli, mem_ctx, &pol, sec_info, &sdb);
634
635         if (!NT_STATUS_IS_OK(result))
636                 goto done;
637
638         /* Print results */
639
640         display_sec_desc(sdb->sec);
641
642  done:
643         return result;
644 }
645
646
647 /* List of commands exported by this module */
648
649 struct cmd_set lsarpc_commands[] = {
650
651         { "LSARPC" },
652
653         { "lsaquery",            cmd_lsa_query_info_policy,  PI_LSARPC, "Query info policy",                    "" },
654         { "lookupsids",          cmd_lsa_lookup_sids,        PI_LSARPC, "Convert SIDs to names",                "" },
655         { "lookupnames",         cmd_lsa_lookup_names,       PI_LSARPC, "Convert names to SIDs",                "" },
656         { "enumtrust",           cmd_lsa_enum_trust_dom,     PI_LSARPC, "Enumerate trusted domains",            "Usage: [preferred max number] [enum context (0)]" },
657         { "enumprivs",           cmd_lsa_enum_privilege,     PI_LSARPC, "Enumerate privileges",                 "" },
658         { "getdispname",         cmd_lsa_get_dispname,       PI_LSARPC, "Get the privilege name",               "" },
659         { "lsaenumsid",          cmd_lsa_enum_sids,          PI_LSARPC, "Enumerate the LSA SIDS",               "" },
660         { "lsaenumprivsaccount", cmd_lsa_enum_privsaccounts, PI_LSARPC, "Enumerate the privileges of an SID",   "" },
661         { "lsaenumacctrights",   cmd_lsa_enum_acct_rights,   PI_LSARPC, "Enumerate the rights of an SID",   "" },
662         { "lsaaddacctrights",   cmd_lsa_add_acct_rights,   PI_LSARPC, "Add rights to an account",   "" },
663         { "lsalookupprivvalue",  cmd_lsa_lookupprivvalue,    PI_LSARPC, "Get a privilege value given its name", "" },
664         { "lsaquerysecobj",      cmd_lsa_query_secobj,       PI_LSARPC, "Query LSA security object", "" },
665
666         { NULL }
667 };