2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) Gerald (Jerry) Carter 2004
5 Copyright (C) Guenther Deschner 2008
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "utils/net.h"
22 #include "../librpc/gen_ndr/cli_lsa.h"
24 /********************************************************************
25 ********************************************************************/
27 static NTSTATUS
sid_to_name(struct rpc_pipe_client
*pipe_hnd
,
32 struct policy_handle pol
;
33 enum lsa_SidType
*sid_types
= NULL
;
35 char **domains
= NULL
, **names
= NULL
;
37 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
38 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
40 if ( !NT_STATUS_IS_OK(result
) )
43 result
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &pol
, 1, sid
, &domains
, &names
, &sid_types
);
45 if ( NT_STATUS_IS_OK(result
) ) {
47 fstr_sprintf( name
, "%s\\%s", domains
[0], names
[0] );
49 fstrcpy( name
, names
[0] );
52 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &pol
);
56 /********************************************************************
57 ********************************************************************/
59 static NTSTATUS
name_to_sid(struct rpc_pipe_client
*pipe_hnd
,
61 DOM_SID
*sid
, const char *name
)
63 struct policy_handle pol
;
64 enum lsa_SidType
*sid_types
;
68 /* maybe its a raw SID */
69 if ( strncmp(name
, "S-", 2) == 0 && string_to_sid(sid
, name
) ) {
73 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
74 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
76 if ( !NT_STATUS_IS_OK(result
) )
79 result
= rpccli_lsa_lookup_names(pipe_hnd
, mem_ctx
, &pol
, 1, &name
,
80 NULL
, 1, &sids
, &sid_types
);
82 if ( NT_STATUS_IS_OK(result
) )
83 sid_copy( sid
, &sids
[0] );
85 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &pol
);
89 /********************************************************************
90 ********************************************************************/
92 static NTSTATUS
enum_privileges(struct rpc_pipe_client
*pipe_hnd
,
94 struct policy_handle
*pol
)
97 uint32 enum_context
= 0;
98 uint32 pref_max_length
=0x1000;
101 uint16 lang_id_sys
=0;
103 struct lsa_StringLarge
*description
= NULL
;
104 struct lsa_PrivArray priv_array
;
106 result
= rpccli_lsa_EnumPrivs(pipe_hnd
, ctx
,
112 if ( !NT_STATUS_IS_OK(result
) )
117 for (i
= 0; i
< priv_array
.count
; i
++) {
119 struct lsa_String lsa_name
;
122 priv_array
.privs
[i
].name
.string
? priv_array
.privs
[i
].name
.string
: "*unknown*" );
124 /* try to get the description */
126 init_lsa_String(&lsa_name
, priv_array
.privs
[i
].name
.string
);
128 result
= rpccli_lsa_LookupPrivDisplayName(pipe_hnd
, ctx
,
136 if (!NT_STATUS_IS_OK(result
)) {
137 d_printf("??????\n");
141 d_printf("%s\n", description
->string
);
147 /********************************************************************
148 ********************************************************************/
150 static NTSTATUS
check_privilege_for_user(struct rpc_pipe_client
*pipe_hnd
,
152 struct policy_handle
*pol
,
157 struct lsa_RightSet rights
;
160 result
= rpccli_lsa_EnumAccountRights(pipe_hnd
, ctx
,
165 if (!NT_STATUS_IS_OK(result
)) {
169 if (rights
.count
== 0) {
170 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
173 for (i
= 0; i
< rights
.count
; i
++) {
174 if (StrCaseCmp(rights
.names
[i
].string
, right
) == 0) {
179 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
182 /********************************************************************
183 ********************************************************************/
185 static NTSTATUS
enum_privileges_for_user(struct rpc_pipe_client
*pipe_hnd
,
187 struct policy_handle
*pol
,
191 struct lsa_RightSet rights
;
194 result
= rpccli_lsa_EnumAccountRights(pipe_hnd
, ctx
,
199 if (!NT_STATUS_IS_OK(result
))
202 if (rights
.count
== 0) {
203 d_printf(_("No privileges assigned\n"));
206 for (i
= 0; i
< rights
.count
; i
++) {
207 printf("%s\n", rights
.names
[i
].string
);
213 /********************************************************************
214 ********************************************************************/
216 static NTSTATUS
enum_accounts_for_privilege(struct rpc_pipe_client
*pipe_hnd
,
218 struct policy_handle
*pol
,
219 const char *privilege
)
222 uint32 enum_context
=0;
223 uint32 pref_max_length
=0x1000;
224 struct lsa_SidArray sid_array
;
228 result
= rpccli_lsa_EnumAccounts(pipe_hnd
, ctx
,
234 if (!NT_STATUS_IS_OK(result
))
237 d_printf("%s:\n", privilege
);
239 for ( i
=0; i
<sid_array
.num_sids
; i
++ ) {
241 result
= check_privilege_for_user(pipe_hnd
, ctx
, pol
,
242 sid_array
.sids
[i
].sid
,
245 if ( ! NT_STATUS_IS_OK(result
)) {
246 if ( ! NT_STATUS_EQUAL(result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
252 /* try to convert the SID to a name. Fall back to
253 printing the raw SID if necessary */
254 result
= sid_to_name( pipe_hnd
, ctx
, sid_array
.sids
[i
].sid
, name
);
255 if ( !NT_STATUS_IS_OK (result
) )
256 sid_to_fstring(name
, sid_array
.sids
[i
].sid
);
258 d_printf(" %s\n", name
);
264 /********************************************************************
265 ********************************************************************/
267 static NTSTATUS
enum_privileges_for_accounts(struct rpc_pipe_client
*pipe_hnd
,
269 struct policy_handle
*pol
)
272 uint32 enum_context
=0;
273 uint32 pref_max_length
=0x1000;
274 struct lsa_SidArray sid_array
;
278 result
= rpccli_lsa_EnumAccounts(pipe_hnd
, ctx
,
284 if (!NT_STATUS_IS_OK(result
))
287 for ( i
=0; i
<sid_array
.num_sids
; i
++ ) {
289 /* try to convert the SID to a name. Fall back to
290 printing the raw SID if necessary */
292 result
= sid_to_name(pipe_hnd
, ctx
, sid_array
.sids
[i
].sid
, name
);
293 if ( !NT_STATUS_IS_OK (result
) )
294 sid_to_fstring(name
, sid_array
.sids
[i
].sid
);
296 d_printf("%s\n", name
);
298 result
= enum_privileges_for_user(pipe_hnd
, ctx
, pol
,
299 sid_array
.sids
[i
].sid
);
300 if ( !NT_STATUS_IS_OK(result
) )
309 /********************************************************************
310 ********************************************************************/
312 static NTSTATUS
rpc_rights_list_internal(struct net_context
*c
,
313 const DOM_SID
*domain_sid
,
314 const char *domain_name
,
315 struct cli_state
*cli
,
316 struct rpc_pipe_client
*pipe_hnd
,
321 struct policy_handle pol
;
325 struct lsa_String lsa_name
;
326 struct lsa_StringLarge
*description
= NULL
;
328 uint16 lang_id_sys
= 0;
331 result
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
332 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
334 if ( !NT_STATUS_IS_OK(result
) )
337 /* backwards compatibility; just list available privileges if no arguement */
340 result
= enum_privileges(pipe_hnd
, mem_ctx
, &pol
);
344 if (strequal(argv
[0], "privileges")) {
347 if (argv
[1] == NULL
) {
348 result
= enum_privileges(pipe_hnd
, mem_ctx
, &pol
);
352 while ( argv
[i
] != NULL
) {
353 fstrcpy(privname
, argv
[i
]);
354 init_lsa_String(&lsa_name
, argv
[i
]);
357 /* verify that this is a valid privilege for error reporting */
358 result
= rpccli_lsa_LookupPrivDisplayName(pipe_hnd
, mem_ctx
,
366 if ( !NT_STATUS_IS_OK(result
) ) {
367 if ( NT_STATUS_EQUAL( result
, NT_STATUS_NO_SUCH_PRIVILEGE
) )
368 d_fprintf(stderr
, _("No such privilege "
369 "exists: %s.\n"), privname
);
371 d_fprintf(stderr
, _("Error resolving "
372 "privilege display name "
378 result
= enum_accounts_for_privilege(pipe_hnd
, mem_ctx
, &pol
, privname
);
379 if (!NT_STATUS_IS_OK(result
)) {
380 d_fprintf(stderr
, _("Error enumerating "
381 "accounts for privilege %s [%s].\n"),
382 privname
, nt_errstr(result
));
389 /* special case to enumerate all privileged SIDs with associated rights */
391 if (strequal( argv
[0], "accounts")) {
394 if (argv
[1] == NULL
) {
395 result
= enum_privileges_for_accounts(pipe_hnd
, mem_ctx
, &pol
);
399 while (argv
[i
] != NULL
) {
400 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[i
]);
401 if (!NT_STATUS_IS_OK(result
)) {
404 result
= enum_privileges_for_user(pipe_hnd
, mem_ctx
, &pol
, &sid
);
405 if (!NT_STATUS_IS_OK(result
)) {
413 /* backward comaptibility: if no keyword provided, treat the key
414 as an account name */
416 d_printf("%s net rpc rights list [[accounts|privileges] "
417 "[name|SID]]\n", _("Usage:"));
418 result
= NT_STATUS_OK
;
422 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
423 if (!NT_STATUS_IS_OK(result
)) {
426 result
= enum_privileges_for_user(pipe_hnd
, mem_ctx
, &pol
, &sid
);
429 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &pol
);
434 /********************************************************************
435 ********************************************************************/
437 static NTSTATUS
rpc_rights_grant_internal(struct net_context
*c
,
438 const DOM_SID
*domain_sid
,
439 const char *domain_name
,
440 struct cli_state
*cli
,
441 struct rpc_pipe_client
*pipe_hnd
,
446 struct policy_handle dom_pol
;
447 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
448 struct lsa_RightSet rights
;
456 _(" net rpc rights grant <name|SID> <rights...>\n"));
460 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
461 if (NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
))
462 result
= NT_STATUS_NO_SUCH_USER
;
464 if (!NT_STATUS_IS_OK(result
))
467 result
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true,
468 SEC_FLAG_MAXIMUM_ALLOWED
,
471 if (!NT_STATUS_IS_OK(result
))
474 rights
.count
= argc
-1;
475 rights
.names
= TALLOC_ARRAY(mem_ctx
, struct lsa_StringLarge
,
478 return NT_STATUS_NO_MEMORY
;
481 for (i
=0; i
<argc
-1; i
++) {
482 init_lsa_StringLarge(&rights
.names
[i
], argv
[i
+1]);
485 result
= rpccli_lsa_AddAccountRights(pipe_hnd
, mem_ctx
,
490 if (!NT_STATUS_IS_OK(result
))
493 d_printf(_("Successfully granted rights.\n"));
496 if ( !NT_STATUS_IS_OK(result
) ) {
497 d_fprintf(stderr
, _("Failed to grant privileges for %s (%s)\n"),
498 argv
[0], nt_errstr(result
));
501 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &dom_pol
);
506 /********************************************************************
507 ********************************************************************/
509 static NTSTATUS
rpc_rights_revoke_internal(struct net_context
*c
,
510 const DOM_SID
*domain_sid
,
511 const char *domain_name
,
512 struct cli_state
*cli
,
513 struct rpc_pipe_client
*pipe_hnd
,
518 struct policy_handle dom_pol
;
519 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
520 struct lsa_RightSet rights
;
527 _(" net rpc rights revoke <name|SID> <rights...>\n"));
531 result
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
532 if (!NT_STATUS_IS_OK(result
))
535 result
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true,
536 SEC_FLAG_MAXIMUM_ALLOWED
,
539 if (!NT_STATUS_IS_OK(result
))
542 rights
.count
= argc
-1;
543 rights
.names
= TALLOC_ARRAY(mem_ctx
, struct lsa_StringLarge
,
546 return NT_STATUS_NO_MEMORY
;
549 for (i
=0; i
<argc
-1; i
++) {
550 init_lsa_StringLarge(&rights
.names
[i
], argv
[i
+1]);
553 result
= rpccli_lsa_RemoveAccountRights(pipe_hnd
, mem_ctx
,
559 if (!NT_STATUS_IS_OK(result
))
562 d_printf(_("Successfully revoked rights.\n"));
565 if ( !NT_STATUS_IS_OK(result
) ) {
566 d_fprintf(stderr
,_("Failed to revoke privileges for %s (%s)\n"),
567 argv
[0], nt_errstr(result
));
570 rpccli_lsa_Close(pipe_hnd
, mem_ctx
, &dom_pol
);
576 /********************************************************************
577 ********************************************************************/
579 static int rpc_rights_list(struct net_context
*c
, int argc
, const char **argv
)
581 if (c
->display_usage
) {
584 _("net rpc rights list [{accounts|privileges} "
586 " View available/assigned privileges\n"));
590 return run_rpc_command(c
, NULL
, &ndr_table_lsarpc
.syntax_id
, 0,
591 rpc_rights_list_internal
, argc
, argv
);
594 /********************************************************************
595 ********************************************************************/
597 static int rpc_rights_grant(struct net_context
*c
, int argc
, const char **argv
)
599 if (c
->display_usage
) {
602 _("net rpc rights grant <name|SID> <right>\n"
603 " Assign privilege[s]\n"));
604 d_printf(_("For example:\n"
605 " net rpc rights grant 'VALE\\biddle' "
606 "SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"
607 " would grant the printer admin and disk manager "
608 "rights to the user 'VALE\\biddle'\n"));
612 return run_rpc_command(c
, NULL
, &ndr_table_lsarpc
.syntax_id
, 0,
613 rpc_rights_grant_internal
, argc
, argv
);
616 /********************************************************************
617 ********************************************************************/
619 static int rpc_rights_revoke(struct net_context
*c
, int argc
, const char **argv
)
621 if (c
->display_usage
) {
624 _("net rpc rights revoke <name|SID> <right>\n"
625 " Revoke privilege[s]\n"));
626 d_printf(_("For example:\n"
627 " net rpc rights revoke 'VALE\\biddle' "
628 "SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"
629 " would revoke the printer admin and disk manager"
630 " rights from the user 'VALE\\biddle'\n"));
634 return run_rpc_command(c
, NULL
, &ndr_table_lsarpc
.syntax_id
, 0,
635 rpc_rights_revoke_internal
, argc
, argv
);
638 /********************************************************************
639 ********************************************************************/
641 int net_rpc_rights(struct net_context
*c
, int argc
, const char **argv
)
643 struct functable func
[] = {
648 N_("View available/assigned privileges"),
649 N_("net rpc rights list\n"
650 " View available/assigned privileges")
656 N_("Assign privilege[s]"),
657 N_("net rpc rights grant\n"
658 " Assign privilege[s]")
664 N_("Revoke privilege[s]"),
665 N_("net rpc rights revoke\n"
666 " Revoke privilege[s]")
668 {NULL
, NULL
, 0, NULL
, NULL
}
671 return net_run_function(c
, argc
, argv
, "net rpc rights", func
);
674 static NTSTATUS
rpc_sh_rights_list(struct net_context
*c
,
675 TALLOC_CTX
*mem_ctx
, struct rpc_sh_ctx
*ctx
,
676 struct rpc_pipe_client
*pipe_hnd
,
677 int argc
, const char **argv
)
679 return rpc_rights_list_internal(c
, ctx
->domain_sid
, ctx
->domain_name
,
680 ctx
->cli
, pipe_hnd
, mem_ctx
,
684 static NTSTATUS
rpc_sh_rights_grant(struct net_context
*c
,
686 struct rpc_sh_ctx
*ctx
,
687 struct rpc_pipe_client
*pipe_hnd
,
688 int argc
, const char **argv
)
690 return rpc_rights_grant_internal(c
, ctx
->domain_sid
, ctx
->domain_name
,
691 ctx
->cli
, pipe_hnd
, mem_ctx
,
695 static NTSTATUS
rpc_sh_rights_revoke(struct net_context
*c
,
697 struct rpc_sh_ctx
*ctx
,
698 struct rpc_pipe_client
*pipe_hnd
,
699 int argc
, const char **argv
)
701 return rpc_rights_revoke_internal(c
, ctx
->domain_sid
, ctx
->domain_name
,
702 ctx
->cli
, pipe_hnd
, mem_ctx
,
706 struct rpc_sh_cmd
*net_rpc_rights_cmds(struct net_context
*c
, TALLOC_CTX
*mem_ctx
,
707 struct rpc_sh_ctx
*ctx
)
709 static struct rpc_sh_cmd cmds
[] = {
711 { "list", NULL
, &ndr_table_lsarpc
.syntax_id
, rpc_sh_rights_list
,
712 N_("View available or assigned privileges") },
714 { "grant", NULL
, &ndr_table_lsarpc
.syntax_id
, rpc_sh_rights_grant
,
715 N_("Assign privilege[s]") },
717 { "revoke", NULL
, &ndr_table_lsarpc
.syntax_id
, rpc_sh_rights_revoke
,
718 N_("Revoke privilege[s]") },
720 { NULL
, NULL
, 0, NULL
, NULL
}