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. */
21 #include "utils/net.h"
23 /********************************************************************
24 ********************************************************************/
26 static NTSTATUS
sid_to_name(struct rpc_pipe_client
*pipe_hnd
,
32 enum lsa_SidType
*sid_types
;
34 char **domains
, **names
;
36 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, True
,
37 SEC_RIGHTS_MAXIMUM_ALLOWED
, &pol
);
39 if ( !NT_STATUS_IS_OK(result
) )
42 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &pol
, 1, sid
, &domains
, &names
, &sid_types
);
44 if ( NT_STATUS_IS_OK(result
) ) {
46 fstr_sprintf( name
, "%s\\%s", domains
[0], names
[0] );
48 fstrcpy( name
, names
[0] );
51 rpccli_lsa_close(pipe_hnd
, mem_ctx
, &pol
);
55 /********************************************************************
56 ********************************************************************/
58 static NTSTATUS
name_to_sid(struct rpc_pipe_client
*pipe_hnd
,
60 DOM_SID
*sid
, const char *name
)
63 enum lsa_SidType
*sid_types
;
67 /* maybe its a raw SID */
68 if ( strncmp(name
, "S-", 2) == 0 && string_to_sid(sid
, name
) ) {
72 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, True
,
73 SEC_RIGHTS_MAXIMUM_ALLOWED
, &pol
);
75 if ( !NT_STATUS_IS_OK(result
) )
78 result
= rpccli_lsa_lookup_names(pipe_hnd
, mem_ctx
, &pol
, 1, &name
,
79 NULL
, &sids
, &sid_types
);
81 if ( NT_STATUS_IS_OK(result
) )
82 sid_copy( sid
, &sids
[0] );
84 rpccli_lsa_close(pipe_hnd
, mem_ctx
, &pol
);
88 /********************************************************************
89 ********************************************************************/
91 static NTSTATUS
enum_privileges(struct rpc_pipe_client
*pipe_hnd
,
96 uint32 enum_context
= 0;
97 uint32 pref_max_length
=0x1000;
104 uint16 lang_id_sys
=0;
108 result
= rpccli_lsa_enum_privilege(pipe_hnd
, ctx
, pol
, &enum_context
,
109 pref_max_length
, &count
, &privs_name
, &privs_high
, &privs_low
);
111 if ( !NT_STATUS_IS_OK(result
) )
116 for (i
= 0; i
< count
; i
++) {
117 d_printf("%30s ", privs_name
[i
] ? privs_name
[i
] : "*unknown*" );
119 /* try to get the description */
121 if ( !NT_STATUS_IS_OK(rpccli_lsa_get_dispname(pipe_hnd
, ctx
, pol
,
122 privs_name
[i
], lang_id
, lang_id_sys
, description
, &lang_id_desc
)) )
124 d_printf("??????\n");
128 d_printf("%s\n", description
);
134 /********************************************************************
135 ********************************************************************/
137 static NTSTATUS
check_privilege_for_user(struct rpc_pipe_client
*pipe_hnd
,
148 result
= rpccli_lsa_enum_account_rights(pipe_hnd
, ctx
, pol
, sid
, &count
, &rights
);
150 if (!NT_STATUS_IS_OK(result
)) {
155 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
158 for (i
= 0; i
< count
; i
++) {
159 if (StrCaseCmp(rights
[i
], right
) == 0) {
164 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
167 /********************************************************************
168 ********************************************************************/
170 static NTSTATUS
enum_privileges_for_user(struct rpc_pipe_client
*pipe_hnd
,
180 result
= rpccli_lsa_enum_account_rights(pipe_hnd
, ctx
, pol
, sid
, &count
, &rights
);
182 if (!NT_STATUS_IS_OK(result
))
186 d_printf("No privileges assigned\n");
188 for (i
= 0; i
< count
; i
++) {
189 printf("%s\n", rights
[i
]);
195 /********************************************************************
196 ********************************************************************/
198 static NTSTATUS
enum_accounts_for_privilege(struct rpc_pipe_client
*pipe_hnd
,
201 const char *privilege
)
204 uint32 enum_context
=0;
205 uint32 pref_max_length
=0x1000;
211 result
= rpccli_lsa_enum_sids(pipe_hnd
, ctx
, pol
, &enum_context
,
212 pref_max_length
, &count
, &sids
);
214 if (!NT_STATUS_IS_OK(result
))
217 d_printf("%s:\n", privilege
);
219 for ( i
=0; i
<count
; i
++ ) {
222 result
= check_privilege_for_user( pipe_hnd
, ctx
, pol
, &sids
[i
], privilege
);
224 if ( ! NT_STATUS_IS_OK(result
)) {
225 if ( ! NT_STATUS_EQUAL(result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
231 /* try to convert the SID to a name. Fall back to
232 printing the raw SID if necessary */
233 result
= sid_to_name( pipe_hnd
, ctx
, &sids
[i
], name
);
234 if ( !NT_STATUS_IS_OK (result
) )
235 fstrcpy( name
, sid_string_static(&sids
[i
]) );
237 d_printf(" %s\n", name
);
243 /********************************************************************
244 ********************************************************************/
246 static NTSTATUS
enum_privileges_for_accounts(struct rpc_pipe_client
*pipe_hnd
,
251 uint32 enum_context
=0;
252 uint32 pref_max_length
=0x1000;
258 result
= rpccli_lsa_enum_sids(pipe_hnd
, ctx
, pol
, &enum_context
,
259 pref_max_length
, &count
, &sids
);
261 if (!NT_STATUS_IS_OK(result
))
264 for ( i
=0; i
<count
; i
++ ) {
266 /* try to convert the SID to a name. Fall back to
267 printing the raw SID if necessary */
269 result
= sid_to_name(pipe_hnd
, ctx
, &sids
[i
], name
);
270 if ( !NT_STATUS_IS_OK (result
) )
271 fstrcpy( name
, sid_string_static(&sids
[i
]) );
273 d_printf("%s\n", name
);
275 result
= enum_privileges_for_user(pipe_hnd
, ctx
, pol
, &sids
[i
] );
277 if ( !NT_STATUS_IS_OK(result
) )
286 /********************************************************************
287 ********************************************************************/
289 static NTSTATUS
rpc_rights_list_internal(const DOM_SID
*domain_sid
,
290 const char *domain_name
,
291 struct cli_state
*cli
,
292 struct rpc_pipe_client
*pipe_hnd
,
303 uint16 lang_id_sys
= 0;
307 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, True
,
308 SEC_RIGHTS_MAXIMUM_ALLOWED
, &pol
);
310 if ( !NT_STATUS_IS_OK(result
) )
313 /* backwards compatibility; just list available privileges if no arguement */
316 result
= enum_privileges(pipe_hnd
, mem_ctx
, &pol
);
320 if (strequal(argv
[0], "privileges")) {
323 if (argv
[1] == NULL
) {
324 result
= enum_privileges(pipe_hnd
, mem_ctx
, &pol
);
328 while ( argv
[i
] != NULL
) {
329 fstrcpy( privname
, argv
[i
] );
332 /* verify that this is a valid privilege for error reporting */
334 result
= rpccli_lsa_get_dispname(pipe_hnd
, mem_ctx
, &pol
, privname
, lang_id
,
335 lang_id_sys
, description
, &lang_id_desc
);
337 if ( !NT_STATUS_IS_OK(result
) ) {
338 if ( NT_STATUS_EQUAL( result
, NT_STATUS_NO_SUCH_PRIVILEGE
) )
339 d_fprintf(stderr
, "No such privilege exists: %s.\n", privname
);
341 d_fprintf(stderr
, "Error resolving privilege display name [%s].\n", nt_errstr(result
));
345 result
= enum_accounts_for_privilege(pipe_hnd
, mem_ctx
, &pol
, privname
);
346 if (!NT_STATUS_IS_OK(result
)) {
347 d_fprintf(stderr
, "Error enumerating accounts for privilege %s [%s].\n",
348 privname
, nt_errstr(result
));
355 /* special case to enumerate all privileged SIDs with associated rights */
357 if (strequal( argv
[0], "accounts")) {
360 if (argv
[1] == NULL
) {
361 result
= enum_privileges_for_accounts(pipe_hnd
, mem_ctx
, &pol
);
365 while (argv
[i
] != NULL
) {
366 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[i
]);
367 if (!NT_STATUS_IS_OK(result
)) {
370 result
= enum_privileges_for_user(pipe_hnd
, mem_ctx
, &pol
, &sid
);
371 if (!NT_STATUS_IS_OK(result
)) {
379 /* backward comaptibility: if no keyword provided, treat the key
380 as an account name */
382 d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n");
383 result
= NT_STATUS_OK
;
387 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
388 if (!NT_STATUS_IS_OK(result
)) {
391 result
= enum_privileges_for_user(pipe_hnd
, mem_ctx
, &pol
, &sid
);
394 rpccli_lsa_close(pipe_hnd
, mem_ctx
, &pol
);
399 /********************************************************************
400 ********************************************************************/
402 static NTSTATUS
rpc_rights_grant_internal(const DOM_SID
*domain_sid
,
403 const char *domain_name
,
404 struct cli_state
*cli
,
405 struct rpc_pipe_client
*pipe_hnd
,
411 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
416 d_printf("Usage: net rpc rights grant <name|SID> <rights...>\n");
420 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
421 if (!NT_STATUS_IS_OK(result
))
424 result
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, True
,
425 SEC_RIGHTS_MAXIMUM_ALLOWED
,
428 if (!NT_STATUS_IS_OK(result
))
431 result
= rpccli_lsa_add_account_rights(pipe_hnd
, mem_ctx
, &dom_pol
, sid
,
434 if (!NT_STATUS_IS_OK(result
))
437 d_printf("Successfully granted rights.\n");
440 if ( !NT_STATUS_IS_OK(result
) ) {
441 d_fprintf(stderr
, "Failed to grant privileges for %s (%s)\n",
442 argv
[0], nt_errstr(result
));
445 rpccli_lsa_close(pipe_hnd
, mem_ctx
, &dom_pol
);
450 /********************************************************************
451 ********************************************************************/
453 static NTSTATUS
rpc_rights_revoke_internal(const DOM_SID
*domain_sid
,
454 const char *domain_name
,
455 struct cli_state
*cli
,
456 struct rpc_pipe_client
*pipe_hnd
,
462 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
467 d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n");
471 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
472 if (!NT_STATUS_IS_OK(result
))
475 result
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, True
,
476 SEC_RIGHTS_MAXIMUM_ALLOWED
,
479 if (!NT_STATUS_IS_OK(result
))
482 result
= rpccli_lsa_remove_account_rights(pipe_hnd
, mem_ctx
, &dom_pol
, sid
,
483 False
, argc
-1, argv
+1);
485 if (!NT_STATUS_IS_OK(result
))
488 d_printf("Successfully revoked rights.\n");
491 if ( !NT_STATUS_IS_OK(result
) ) {
492 d_fprintf(stderr
, "Failed to revoke privileges for %s (%s)\n",
493 argv
[0], nt_errstr(result
));
496 rpccli_lsa_close(pipe_hnd
, mem_ctx
, &dom_pol
);
502 /********************************************************************
503 ********************************************************************/
505 static int rpc_rights_list( int argc
, const char **argv
)
507 return run_rpc_command( NULL
, PI_LSARPC
, 0,
508 rpc_rights_list_internal
, argc
, argv
);
511 /********************************************************************
512 ********************************************************************/
514 static int rpc_rights_grant( int argc
, const char **argv
)
516 return run_rpc_command( NULL
, PI_LSARPC
, 0,
517 rpc_rights_grant_internal
, argc
, argv
);
520 /********************************************************************
521 ********************************************************************/
523 static int rpc_rights_revoke( int argc
, const char **argv
)
525 return run_rpc_command( NULL
, PI_LSARPC
, 0,
526 rpc_rights_revoke_internal
, argc
, argv
);
529 /********************************************************************
530 ********************************************************************/
532 static int net_help_rights( int argc
, const char **argv
)
534 d_printf("net rpc rights list [{accounts|privileges} [name|SID]] View available or assigned privileges\n");
535 d_printf("net rpc rights grant <name|SID> <right> Assign privilege[s]\n");
536 d_printf("net rpc rights revoke <name|SID> <right> Revoke privilege[s]\n");
538 d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
539 d_printf("For example\n");
540 d_printf("\n net rpc rights grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivilege\n");
541 d_printf("\nwould grant the printer admin and disk manager rights to the user 'VALE\\biddle'\n\n");
547 /********************************************************************
548 ********************************************************************/
550 int net_rpc_rights(int argc
, const char **argv
)
552 struct functable func
[] = {
553 {"list", rpc_rights_list
},
554 {"grant", rpc_rights_grant
},
555 {"revoke", rpc_rights_revoke
},
560 return net_run_function( argc
, argv
, func
, net_help_rights
);
562 return net_help_rights( argc
, argv
);
565 static NTSTATUS
rpc_sh_rights_list(TALLOC_CTX
*mem_ctx
, struct rpc_sh_ctx
*ctx
,
566 struct rpc_pipe_client
*pipe_hnd
,
567 int argc
, const char **argv
)
569 return rpc_rights_list_internal(ctx
->domain_sid
, ctx
->domain_name
,
570 ctx
->cli
, pipe_hnd
, mem_ctx
,
574 static NTSTATUS
rpc_sh_rights_grant(TALLOC_CTX
*mem_ctx
,
575 struct rpc_sh_ctx
*ctx
,
576 struct rpc_pipe_client
*pipe_hnd
,
577 int argc
, const char **argv
)
579 return rpc_rights_grant_internal(ctx
->domain_sid
, ctx
->domain_name
,
580 ctx
->cli
, pipe_hnd
, mem_ctx
,
584 static NTSTATUS
rpc_sh_rights_revoke(TALLOC_CTX
*mem_ctx
,
585 struct rpc_sh_ctx
*ctx
,
586 struct rpc_pipe_client
*pipe_hnd
,
587 int argc
, const char **argv
)
589 return rpc_rights_revoke_internal(ctx
->domain_sid
, ctx
->domain_name
,
590 ctx
->cli
, pipe_hnd
, mem_ctx
,
594 struct rpc_sh_cmd
*net_rpc_rights_cmds(TALLOC_CTX
*mem_ctx
,
595 struct rpc_sh_ctx
*ctx
)
597 static struct rpc_sh_cmd cmds
[] = {
599 { "list", NULL
, PI_LSARPC
, rpc_sh_rights_list
,
600 "View available or assigned privileges" },
602 { "grant", NULL
, PI_LSARPC
, rpc_sh_rights_grant
,
603 "Assign privilege[s]" },
605 { "revoke", NULL
, PI_LSARPC
, rpc_sh_rights_revoke
,
606 "Revoke privilege[s]" },
608 { NULL
, NULL
, 0, NULL
, NULL
}