r8323: * convert RegSetValue() calls immediately beneath the printer
[Samba/gbeck.git] / source / utils / net_rpc_rights.c
blob3a986ed2516d13ee5a63bf533cbb84af1af9c9f9
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) Gerald (Jerry) Carter 2004
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #include "includes.h"
21 #include "utils/net.h"
23 /********************************************************************
24 ********************************************************************/
26 static NTSTATUS sid_to_name(struct cli_state *cli,
27 TALLOC_CTX *mem_ctx,
28 DOM_SID *sid, fstring name)
30 POLICY_HND pol;
31 uint32 *sid_types;
32 NTSTATUS result;
33 char **domains, **names;
35 result = cli_lsa_open_policy(cli, mem_ctx, True,
36 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
38 if ( !NT_STATUS_IS_OK(result) )
39 return result;
41 result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types);
43 if ( NT_STATUS_IS_OK(result) ) {
44 if ( *domains[0] )
45 fstr_sprintf( name, "%s\\%s", domains[0], names[0] );
46 else
47 fstrcpy( name, names[0] );
50 cli_lsa_close(cli, mem_ctx, &pol);
51 return result;
54 /********************************************************************
55 ********************************************************************/
57 static NTSTATUS name_to_sid(struct cli_state *cli,
58 TALLOC_CTX *mem_ctx,
59 DOM_SID *sid, const char *name)
61 POLICY_HND pol;
62 uint32 *sid_types;
63 NTSTATUS result;
64 DOM_SID *sids;
66 /* maybe its a raw SID */
67 if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) )
69 return NT_STATUS_OK;
72 result = cli_lsa_open_policy(cli, mem_ctx, True,
73 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
75 if ( !NT_STATUS_IS_OK(result) )
76 return result;
78 result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
80 if ( NT_STATUS_IS_OK(result) )
81 sid_copy( sid, &sids[0] );
83 cli_lsa_close(cli, mem_ctx, &pol);
84 return result;
87 /********************************************************************
88 ********************************************************************/
90 static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
91 POLICY_HND *pol )
93 NTSTATUS result;
94 uint32 enum_context = 0;
95 uint32 pref_max_length=0x1000;
96 uint32 count=0;
97 char **privs_name;
98 uint32 *privs_high;
99 uint32 *privs_low;
100 int i;
101 uint16 lang_id=0;
102 uint16 lang_id_sys=0;
103 uint16 lang_id_desc;
104 fstring description;
106 result = cli_lsa_enum_privilege(cli, ctx, pol, &enum_context,
107 pref_max_length, &count, &privs_name, &privs_high, &privs_low);
109 if ( !NT_STATUS_IS_OK(result) )
110 return result;
112 /* Print results */
114 for (i = 0; i < count; i++) {
115 d_printf("%30s ", privs_name[i] ? privs_name[i] : "*unknown*" );
117 /* try to get the description */
119 if ( !NT_STATUS_IS_OK(cli_lsa_get_dispname(cli, ctx, pol,
120 privs_name[i], lang_id, lang_id_sys, description, &lang_id_desc)) )
122 d_printf("??????\n");
123 continue;
126 d_printf("%s\n", description );
129 return NT_STATUS_OK;
133 /********************************************************************
134 ********************************************************************/
136 static NTSTATUS check_privilege_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
137 POLICY_HND *pol, DOM_SID *sid, const char *right)
139 NTSTATUS result;
140 uint32 count;
141 char **rights;
142 int i;
144 result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
146 if (!NT_STATUS_IS_OK(result)) {
147 return result;
150 if (count == 0) {
151 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
154 for (i = 0; i < count; i++) {
155 if (StrCaseCmp(rights[i], right) == 0) {
156 return NT_STATUS_OK;
160 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
163 /********************************************************************
164 ********************************************************************/
166 static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
167 POLICY_HND *pol, DOM_SID *sid )
169 NTSTATUS result;
170 uint32 count;
171 char **rights;
172 int i;
174 result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
176 if (!NT_STATUS_IS_OK(result))
177 return result;
179 if ( count == 0 )
180 d_printf("No privileges assigned\n");
182 for (i = 0; i < count; i++) {
183 printf("%s\n", rights[i]);
186 return NT_STATUS_OK;
189 /********************************************************************
190 ********************************************************************/
192 static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *cli,
193 POLICY_HND *pol, const char *privilege)
195 NTSTATUS result;
196 uint32 enum_context=0;
197 uint32 pref_max_length=0x1000;
198 DOM_SID *sids;
199 uint32 count=0;
200 int i;
201 fstring name;
203 result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context,
204 pref_max_length, &count, &sids);
206 if (!NT_STATUS_IS_OK(result))
207 return result;
209 d_printf("%s:\n", privilege);
211 for ( i=0; i<count; i++ ) {
214 result = check_privilege_for_user( ctx, cli, pol, &sids[i], privilege);
216 if ( ! NT_STATUS_IS_OK(result)) {
217 if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
218 return result;
220 continue;
223 /* try to convert the SID to a name. Fall back to
224 printing the raw SID if necessary */
225 result = sid_to_name( cli, ctx, &sids[i], name );
226 if ( !NT_STATUS_IS_OK (result) )
227 fstrcpy( name, sid_string_static(&sids[i]) );
229 d_printf(" %s\n", name);
232 return NT_STATUS_OK;
235 /********************************************************************
236 ********************************************************************/
238 static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state *cli,
239 POLICY_HND *pol )
241 NTSTATUS result;
242 uint32 enum_context=0;
243 uint32 pref_max_length=0x1000;
244 DOM_SID *sids;
245 uint32 count=0;
246 int i;
247 fstring name;
249 result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context,
250 pref_max_length, &count, &sids);
252 if (!NT_STATUS_IS_OK(result))
253 return result;
255 for ( i=0; i<count; i++ ) {
257 /* try to convert the SID to a name. Fall back to
258 printing the raw SID if necessary */
260 result = sid_to_name( cli, ctx, &sids[i], name );
261 if ( !NT_STATUS_IS_OK (result) )
262 fstrcpy( name, sid_string_static(&sids[i]) );
264 d_printf("%s\n", name);
266 result = enum_privileges_for_user( ctx, cli, pol, &sids[i] );
268 if ( !NT_STATUS_IS_OK(result) )
269 return result;
271 d_printf("\n");
274 return NT_STATUS_OK;
277 /********************************************************************
278 ********************************************************************/
280 static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char *domain_name,
281 struct cli_state *cli, TALLOC_CTX *mem_ctx,
282 int argc, const char **argv )
284 POLICY_HND pol;
285 NTSTATUS result;
286 DOM_SID sid;
287 fstring privname;
288 fstring description;
289 uint16 lang_id = 0;
290 uint16 lang_id_sys = 0;
291 uint16 lang_id_desc;
294 result = cli_lsa_open_policy(cli, mem_ctx, True,
295 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
297 if ( !NT_STATUS_IS_OK(result) )
298 return result;
300 /* backwards compatibility; just list available privileges if no arguement */
302 if (argc == 0) {
303 result = enum_privileges( mem_ctx, cli, &pol );
304 goto done;
307 if (strequal(argv[0], "privileges")) {
308 int i = 1;
310 if (argv[1] == NULL) {
311 result = enum_privileges( mem_ctx, cli, &pol );
312 goto done;
315 while ( argv[i] != NULL )
317 fstrcpy( privname, argv[i] );
318 i++;
320 /* verify that this is a valid privilege for error reporting */
322 result = cli_lsa_get_dispname(cli, mem_ctx, &pol, privname, lang_id,
323 lang_id_sys, description, &lang_id_desc);
325 if ( !NT_STATUS_IS_OK(result) ) {
326 if ( NT_STATUS_EQUAL( result, NT_STATUS_NO_SUCH_PRIVILEGE ) )
327 d_printf("No such privilege exists: %s.\n", privname);
328 else
329 d_printf("Error resolving privilege display name [%s].\n", nt_errstr(result));
330 continue;
333 result = enum_accounts_for_privilege(mem_ctx, cli, &pol, privname);
334 if (!NT_STATUS_IS_OK(result)) {
335 d_printf("Error enumerating accounts for privilege %s [%s].\n",
336 privname, nt_errstr(result));
337 continue;
340 goto done;
343 /* special case to enumerate all privileged SIDs with associated rights */
345 if (strequal( argv[0], "accounts")) {
346 int i = 1;
348 if (argv[1] == NULL) {
349 result = enum_privileges_for_accounts(mem_ctx, cli, &pol);
350 goto done;
353 while (argv[i] != NULL) {
354 result = name_to_sid(cli, mem_ctx, &sid, argv[i]);
355 if (!NT_STATUS_IS_OK(result)) {
356 goto done;
358 result = enum_privileges_for_user(mem_ctx, cli, &pol, &sid);
359 if (!NT_STATUS_IS_OK(result)) {
360 goto done;
362 i++;
364 goto done;
367 /* backward comaptibility: if no keyword provided, treat the key
368 as an account name */
369 if (argc > 1) {
370 d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n");
371 result = NT_STATUS_OK;
372 goto done;
375 result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
376 if (!NT_STATUS_IS_OK(result)) {
377 goto done;
379 result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
381 done:
382 cli_lsa_close(cli, mem_ctx, &pol);
384 return result;
387 /********************************************************************
388 ********************************************************************/
390 static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char *domain_name,
391 struct cli_state *cli, TALLOC_CTX *mem_ctx,
392 int argc, const char **argv )
394 POLICY_HND dom_pol;
395 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
397 DOM_SID sid;
399 if (argc < 2 ) {
400 d_printf("Usage: net rpc rights grant <name|SID> <rights...>\n");
401 return NT_STATUS_OK;
404 result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
405 if (!NT_STATUS_IS_OK(result))
406 return result;
408 result = cli_lsa_open_policy2(cli, mem_ctx, True,
409 SEC_RIGHTS_MAXIMUM_ALLOWED,
410 &dom_pol);
412 if (!NT_STATUS_IS_OK(result))
413 return result;
415 result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid,
416 argc-1, argv+1);
418 if (!NT_STATUS_IS_OK(result))
419 goto done;
421 d_printf("Successfully granted rights.\n");
423 done:
424 if ( !NT_STATUS_IS_OK(result) ) {
425 d_printf("Failed to grant privileges for %s (%s)\n",
426 argv[0], nt_errstr(result));
429 cli_lsa_close(cli, mem_ctx, &dom_pol);
431 return result;
434 /********************************************************************
435 ********************************************************************/
437 static NTSTATUS rpc_rights_revoke_internal( const DOM_SID *domain_sid, const char *domain_name,
438 struct cli_state *cli, TALLOC_CTX *mem_ctx,
439 int argc, const char **argv )
441 POLICY_HND dom_pol;
442 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
444 DOM_SID sid;
446 if (argc < 2 ) {
447 d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n");
448 return NT_STATUS_OK;
451 result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
452 if (!NT_STATUS_IS_OK(result))
453 return result;
455 result = cli_lsa_open_policy2(cli, mem_ctx, True,
456 SEC_RIGHTS_MAXIMUM_ALLOWED,
457 &dom_pol);
459 if (!NT_STATUS_IS_OK(result))
460 return result;
462 result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid,
463 False, argc-1, argv+1);
465 if (!NT_STATUS_IS_OK(result))
466 goto done;
468 d_printf("Successfully revoked rights.\n");
470 done:
471 if ( !NT_STATUS_IS_OK(result) ) {
472 d_printf("Failed to revoke privileges for %s (%s)",
473 argv[0], nt_errstr(result));
476 cli_lsa_close(cli, mem_ctx, &dom_pol);
478 return result;
482 /********************************************************************
483 ********************************************************************/
485 static int rpc_rights_list( int argc, const char **argv )
487 return run_rpc_command( NULL, PI_LSARPC, 0,
488 rpc_rights_list_internal, argc, argv );
491 /********************************************************************
492 ********************************************************************/
494 static int rpc_rights_grant( int argc, const char **argv )
496 return run_rpc_command( NULL, PI_LSARPC, 0,
497 rpc_rights_grant_internal, argc, argv );
500 /********************************************************************
501 ********************************************************************/
503 static int rpc_rights_revoke( int argc, const char **argv )
505 return run_rpc_command( NULL, PI_LSARPC, 0,
506 rpc_rights_revoke_internal, argc, argv );
509 /********************************************************************
510 ********************************************************************/
512 static int net_help_rights( int argc, const char **argv )
514 d_printf("net rpc rights list [{accounts|privileges} [name|SID]] View available or assigned privileges\n");
515 d_printf("net rpc rights grant <name|SID> <right> Assign privilege[s]\n");
516 d_printf("net rpc rights revoke <name|SID> <right> Revoke privilege[s]\n");
518 d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
519 d_printf("For example\n");
520 d_printf("\n net rpc rights grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivilege\n");
521 d_printf("\nwould grant the printer admin and disk manager rights to the user 'VALE\\biddle'\n\n");
524 return -1;
527 /********************************************************************
528 ********************************************************************/
530 int net_rpc_rights(int argc, const char **argv)
532 struct functable func[] = {
533 {"list", rpc_rights_list},
534 {"grant", rpc_rights_grant},
535 {"revoke", rpc_rights_revoke},
536 {NULL, NULL}
539 if ( argc )
540 return net_run_function( argc, argv, func, net_help_rights );
542 return net_help_rights( argc, argv );