Updates to the 'name -> sid' code:
[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 /* Look up domain related information on a remote host */
27
28 static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, 
29                                           TALLOC_CTX *mem_ctx, int argc, 
30                                           char **argv) 
31 {
32         POLICY_HND pol;
33         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
34         DOM_SID dom_sid;
35         fstring sid_str, domain_name;
36         uint32 info_class = 3;
37
38         if (argc > 2) {
39                 printf("Usage: %s [info_class]\n", argv[0]);
40                 return NT_STATUS_OK;
41         }
42
43         if (argc == 2)
44                 info_class = atoi(argv[1]);
45         
46         result = cli_lsa_open_policy(cli, mem_ctx, True, 
47                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
48                                      &pol);
49
50         if (!NT_STATUS_IS_OK(result))
51                 goto done;
52
53         /* Lookup info policy */
54
55         result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, 
56                                            domain_name, &dom_sid);
57
58         if (!NT_STATUS_IS_OK(result))
59                 goto done;
60
61         sid_to_string(sid_str, &dom_sid);
62
63         if (domain_name[0])
64                 printf("domain %s has sid %s\n", domain_name, sid_str);
65         else
66                 printf("could not query info for level %d\n", info_class);
67
68  done:
69         return result;
70 }
71
72 /* Resolve a list of names to a list of sids */
73
74 static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli, 
75                                      TALLOC_CTX *mem_ctx, int argc, 
76                                      char **argv)
77 {
78         POLICY_HND pol;
79         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
80         DOM_SID *sids;
81         uint32 *types;
82         int i;
83
84         if (argc == 1) {
85                 printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]);
86                 return NT_STATUS_OK;
87         }
88
89         result = cli_lsa_open_policy(cli, mem_ctx, True, 
90                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
91                                      &pol);
92
93         if (!NT_STATUS_IS_OK(result))
94                 goto done;
95
96         result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, 
97                                       (const char**)(argv + 1), &sids, &types);
98
99         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
100             NT_STATUS_V(STATUS_SOME_UNMAPPED))
101                 goto done;
102
103         result = NT_STATUS_OK;
104
105         /* Print results */
106
107         for (i = 0; i < (argc - 1); i++) {
108                 fstring sid_str;
109                 sid_to_string(sid_str, &sids[i]);
110                 printf("%s %s (%s: %d)\n", argv[i + 1], sid_str,
111                        sid_type_lookup(types[i]), types[i]);
112         }
113
114  done:
115         return result;
116 }
117
118 /* Resolve a list of SIDs to a list of names */
119
120 static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
121                                     int argc, char **argv)
122 {
123         POLICY_HND pol;
124         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
125         DOM_SID *sids;
126         char **domains;
127         char **names;
128         uint32 *types;
129         int i;
130
131         if (argc == 1) {
132                 printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
133                 return NT_STATUS_OK;
134         }
135
136         result = cli_lsa_open_policy(cli, mem_ctx, True, 
137                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
138                                      &pol);
139
140         if (!NT_STATUS_IS_OK(result))
141                 goto done;
142
143         /* Convert arguments to sids */
144
145         sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (argc - 1));
146
147         if (!sids) {
148                 printf("could not allocate memory for %d sids\n", argc - 1);
149                 goto done;
150         }
151
152         for (i = 0; i < argc - 1; i++)
153                 string_to_sid(&sids[i], argv[i + 1]);
154
155         /* Lookup the SIDs */
156
157         result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, 
158                                      &domains, &names, &types);
159
160         if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
161             NT_STATUS_V(STATUS_SOME_UNMAPPED))
162                 goto done;
163
164         result = NT_STATUS_OK;
165
166         /* Print results */
167
168         for (i = 0; i < (argc - 1); i++) {
169                 fstring sid_str;
170
171                 sid_to_string(sid_str, &sids[i]);
172                 printf("%s %s\\%s (%d)\n", sid_str, 
173                        domains[i] ? domains[i] : "*unknown*", 
174                        names[i] ? names[i] : "*unknown*", types[i]);
175         }
176
177  done:
178         return result;
179 }
180
181 /* Enumerate list of trusted domains */
182
183 static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, 
184                                        TALLOC_CTX *mem_ctx, int argc, 
185                                        char **argv)
186 {
187         POLICY_HND pol;
188         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
189         DOM_SID *domain_sids;
190         char **domain_names;
191
192         /* defaults, but may be changed using params */
193         uint32 enum_ctx = 0;
194         uint32 preferred_maxnum = 5;
195         uint32 num_domains = 0;
196         int i;
197
198         if (argc > 3) {
199                 printf("Usage: %s [preferred max number (%d)] [enum context (0)]\n",
200                         argv[0], preferred_maxnum);
201                 return NT_STATUS_OK;
202         }
203
204         /* enumeration context */
205         if (argc >= 2 && argv[1]) {
206                 preferred_maxnum = atoi(argv[1]);
207         }       
208
209         /* preferred maximum number */
210         if (argc == 3 && argv[2]) {
211                 enum_ctx = atoi(argv[2]);
212         }       
213
214         result = cli_lsa_open_policy(cli, mem_ctx, True, 
215                                      POLICY_VIEW_LOCAL_INFORMATION,
216                                      &pol);
217
218         if (!NT_STATUS_IS_OK(result))
219                 goto done;
220
221         /* Lookup list of trusted domains */
222
223         result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
224                                                 &preferred_maxnum, &num_domains,
225                                                 &domain_names, &domain_sids);
226         if (!NT_STATUS_IS_OK(result) &&
227             !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
228             !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
229             goto done;
230
231         /* Print results: list of names and sids returned in this response. */   
232         for (i = 0; i < num_domains; i++) {
233                 fstring sid_str;
234
235                 sid_to_string(sid_str, &domain_sids[i]);
236                 printf("%s %s\n", domain_names[i] ? domain_names[i] : 
237                        "*unknown*", sid_str);
238         }
239
240  done:
241         return result;
242 }
243
244 /* Enumerates privileges */
245
246 static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli, 
247                                           TALLOC_CTX *mem_ctx, int argc, 
248                                           char **argv) 
249 {
250         POLICY_HND pol;
251         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
252
253         uint32 enum_context=0;
254         uint32 pref_max_length=0x1000;
255         uint32 count=0;
256         char   **privs_name;
257         uint32 *privs_high;
258         uint32 *privs_low;
259         int i;
260
261         if (argc > 3) {
262                 printf("Usage: %s [enum context] [max length]\n", argv[0]);
263                 return NT_STATUS_OK;
264         }
265
266         if (argc>=2)
267                 enum_context=atoi(argv[1]);
268
269         if (argc==3)
270                 pref_max_length=atoi(argv[2]);
271
272         result = cli_lsa_open_policy(cli, mem_ctx, True, 
273                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
274                                      &pol);
275
276         if (!NT_STATUS_IS_OK(result))
277                 goto done;
278
279         result = cli_lsa_enum_privilege(cli, mem_ctx, &pol, &enum_context, pref_max_length,
280                                         &count, &privs_name, &privs_high, &privs_low);
281
282         if (!NT_STATUS_IS_OK(result))
283                 goto done;
284
285         /* Print results */
286         printf("found %d privileges\n\n", count);
287
288         for (i = 0; i < count; i++) {
289                 printf("%s \t\t%d:%d (0x%x:0x%x)\n", privs_name[i] ? privs_name[i] : "*unknown*",
290                        privs_high[i], privs_low[i], privs_high[i], privs_low[i]);
291         }
292
293  done:
294         return result;
295 }
296
297 /* Get privilege name */
298
299 static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli, 
300                                      TALLOC_CTX *mem_ctx, int argc, 
301                                      char **argv) 
302 {
303         POLICY_HND pol;
304         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
305
306         uint16 lang_id=0;
307         uint16 lang_id_sys=0;
308         uint16 lang_id_desc;
309         fstring description;
310
311         if (argc != 2) {
312                 printf("Usage: %s privilege name\n", argv[0]);
313                 return NT_STATUS_OK;
314         }
315
316         result = cli_lsa_open_policy(cli, mem_ctx, True, 
317                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
318                                      &pol);
319
320         if (!NT_STATUS_IS_OK(result))
321                 goto done;
322
323         result = cli_lsa_get_dispname(cli, mem_ctx, &pol, argv[1], lang_id, lang_id_sys, description, &lang_id_desc);
324
325         if (!NT_STATUS_IS_OK(result))
326                 goto done;
327
328         /* Print results */
329         printf("%s -> %s (language: 0x%x)\n", argv[1], description, lang_id_desc);
330
331  done:
332         return result;
333 }
334
335 /* Enumerate the LSA SIDS */
336
337 static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli, 
338                                      TALLOC_CTX *mem_ctx, int argc, 
339                                      char **argv) 
340 {
341         POLICY_HND pol;
342         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
343
344         uint32 enum_context=0;
345         uint32 pref_max_length=0x1000;
346         DOM_SID *sids;
347         uint32 count=0;
348         int i;
349
350         if (argc > 3) {
351                 printf("Usage: %s [enum context] [max length]\n", argv[0]);
352                 return NT_STATUS_OK;
353         }
354
355         if (argc>=2)
356                 enum_context=atoi(argv[1]);
357
358         if (argc==3)
359                 pref_max_length=atoi(argv[2]);
360
361         result = cli_lsa_open_policy(cli, mem_ctx, True, 
362                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
363                                      &pol);
364
365         if (!NT_STATUS_IS_OK(result))
366                 goto done;
367
368         result = cli_lsa_enum_sids(cli, mem_ctx, &pol, &enum_context, pref_max_length,
369                                         &count, &sids);
370
371         if (!NT_STATUS_IS_OK(result))
372                 goto done;
373
374         /* Print results */
375         printf("found %d SIDs\n\n", count);
376
377         for (i = 0; i < count; i++) {
378                 fstring sid_str;
379
380                 sid_to_string(sid_str, &sids[i]);
381                 printf("%s\n", sid_str);
382         }
383
384  done:
385         return result;
386 }
387
388 /* Enumerate the privileges of an SID */
389
390 static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli, 
391                                            TALLOC_CTX *mem_ctx, int argc, 
392                                            char **argv) 
393 {
394         POLICY_HND dom_pol;
395         POLICY_HND user_pol;
396         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
397         uint32 access_desired = 0x000f000f;
398         
399         DOM_SID sid;
400         uint32 count=0;
401         LUID_ATTR *set;
402         int i;
403
404         if (argc != 2 ) {
405                 printf("Usage: %s SID\n", argv[0]);
406                 return NT_STATUS_OK;
407         }
408
409         string_to_sid(&sid, argv[1]);
410
411         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
412                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
413                                      &dom_pol);
414
415         if (!NT_STATUS_IS_OK(result))
416                 goto done;
417
418         result = cli_lsa_open_account(cli, mem_ctx, &dom_pol, &sid, access_desired, &user_pol);
419
420         if (!NT_STATUS_IS_OK(result))
421                 goto done;
422
423         result = cli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set);
424
425         if (!NT_STATUS_IS_OK(result))
426                 goto done;
427
428         /* Print results */
429         printf("found %d privileges for SID %s\n\n", count, argv[1]);
430         printf("high\tlow\tattribute\n");
431
432         for (i = 0; i < count; i++) {
433                 printf("%u\t%u\t%u\n", set[i].luid.high, set[i].luid.low, set[i].attr);
434         }
435
436  done:
437         return result;
438 }
439
440 /* Get a privilege value given its name */
441
442 static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli, 
443                                            TALLOC_CTX *mem_ctx, int argc, 
444                                            char **argv) 
445 {
446         POLICY_HND pol;
447         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
448         LUID luid;
449
450         if (argc != 2 ) {
451                 printf("Usage: %s name\n", argv[0]);
452                 return NT_STATUS_OK;
453         }
454
455         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
456                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
457                                      &pol);
458
459         if (!NT_STATUS_IS_OK(result))
460                 goto done;
461
462         result = cli_lsa_lookupprivvalue(cli, mem_ctx, &pol, argv[1], &luid);
463
464         if (!NT_STATUS_IS_OK(result))
465                 goto done;
466
467         /* Print results */
468
469         printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low);
470
471  done:
472         return result;
473 }
474
475 /* Query LSA security object */
476
477 static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli, 
478                                      TALLOC_CTX *mem_ctx, int argc, 
479                                      char **argv) 
480 {
481         POLICY_HND pol;
482         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
483         SEC_DESC_BUF *sdb;
484         uint32 sec_info = 0x00000004; /* ??? */
485
486         if (argc != 1 ) {
487                 printf("Usage: %s\n", argv[0]);
488                 return NT_STATUS_OK;
489         }
490
491         result = cli_lsa_open_policy2(cli, mem_ctx, True, 
492                                       SEC_RIGHTS_MAXIMUM_ALLOWED,
493                                       &pol);
494
495         if (!NT_STATUS_IS_OK(result))
496                 goto done;
497
498         result = cli_lsa_query_secobj(cli, mem_ctx, &pol, sec_info, &sdb);
499
500         if (!NT_STATUS_IS_OK(result))
501                 goto done;
502
503         /* Print results */
504
505         display_sec_desc(sdb->sec);
506
507  done:
508         return result;
509 }
510
511 /* List of commands exported by this module */
512
513 struct cmd_set lsarpc_commands[] = {
514
515         { "LSARPC" },
516
517         { "lsaquery",            cmd_lsa_query_info_policy,  PIPE_LSARPC, "Query info policy",                    "" },
518         { "lookupsids",          cmd_lsa_lookup_sids,        PIPE_LSARPC, "Convert SIDs to names",                "" },
519         { "lookupnames",         cmd_lsa_lookup_names,       PIPE_LSARPC, "Convert names to SIDs",                "" },
520         { "enumtrust",           cmd_lsa_enum_trust_dom,     PIPE_LSARPC, "Enumerate trusted domains",            "Usage: [preferred max number] [enum context (0)]" },
521         { "enumprivs",           cmd_lsa_enum_privilege,     PIPE_LSARPC, "Enumerate privileges",                 "" },
522         { "getdispname",         cmd_lsa_get_dispname,       PIPE_LSARPC, "Get the privilege name",               "" },
523         { "lsaenumsid",          cmd_lsa_enum_sids,          PIPE_LSARPC, "Enumerate the LSA SIDS",               "" },
524         { "lsaenumprivsaccount", cmd_lsa_enum_privsaccounts, PIPE_LSARPC, "Enumerate the privileges of an SID",   "" },
525         { "lsalookupprivvalue",  cmd_lsa_lookupprivvalue,    PIPE_LSARPC, "Get a privilege value given its name", "" },
526         { "lsaquerysecobj",      cmd_lsa_query_secobj,       PIPE_LSARPC, "Query LSA security object", "" },
527
528         { NULL }
529 };