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 "rpc_client/rpc_client.h"
23 #include "../librpc/gen_ndr/ndr_lsa_c.h"
24 #include "rpc_client/cli_lsarpc.h"
25 #include "rpc_client/init_lsa.h"
26 #include "../libcli/security/security.h"
27 #include "lib/util/string_wrappers.h"
29 /********************************************************************
30 ********************************************************************/
32 static NTSTATUS
sid_to_name(struct rpc_pipe_client
*pipe_hnd
,
37 struct policy_handle pol
;
38 enum lsa_SidType
*sid_types
= NULL
;
39 NTSTATUS status
, result
;
40 char **domains
= NULL
, **names
= NULL
;
41 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
43 status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
44 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
46 if ( !NT_STATUS_IS_OK(status
) )
49 status
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, &pol
, 1, sid
, &domains
, &names
, &sid_types
);
51 if ( NT_STATUS_IS_OK(status
) ) {
53 fstr_sprintf( name
, "%s\\%s", domains
[0], names
[0] );
55 fstrcpy( name
, names
[0] );
58 dcerpc_lsa_Close(b
, mem_ctx
, &pol
, &result
);
62 /********************************************************************
63 ********************************************************************/
65 static NTSTATUS
name_to_sid(struct rpc_pipe_client
*pipe_hnd
,
67 struct dom_sid
*sid
, const char *name
)
69 struct policy_handle pol
;
70 enum lsa_SidType
*sid_types
;
71 NTSTATUS status
, result
;
73 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
75 /* maybe its a raw SID */
76 if (dom_sid_parse(name
, sid
)) {
80 status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
81 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
83 if ( !NT_STATUS_IS_OK(status
) )
86 status
= rpccli_lsa_lookup_names(pipe_hnd
, mem_ctx
, &pol
, 1, &name
,
87 NULL
, 1, &sids
, &sid_types
);
89 if ( NT_STATUS_IS_OK(status
) )
90 sid_copy( sid
, &sids
[0] );
92 dcerpc_lsa_Close(b
, mem_ctx
, &pol
, &result
);
96 /********************************************************************
97 ********************************************************************/
99 static NTSTATUS
enum_privileges(struct rpc_pipe_client
*pipe_hnd
,
101 struct policy_handle
*pol
)
103 NTSTATUS status
, result
;
104 uint32_t enum_context
= 0;
105 uint32_t pref_max_length
=0x1000;
108 uint16_t lang_id_sys
=0;
109 uint16_t lang_id_desc
;
110 struct lsa_StringLarge
*description
= NULL
;
111 struct lsa_PrivArray priv_array
;
112 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
114 status
= dcerpc_lsa_EnumPrivs(b
, ctx
,
121 if ( !NT_STATUS_IS_OK(status
) )
123 if (!NT_STATUS_IS_OK(result
)) {
129 for (i
= 0; i
< priv_array
.count
; i
++) {
131 struct lsa_String lsa_name
;
134 priv_array
.privs
[i
].name
.string
? priv_array
.privs
[i
].name
.string
: "*unknown*" );
136 /* try to get the description */
138 init_lsa_String(&lsa_name
, priv_array
.privs
[i
].name
.string
);
140 status
= dcerpc_lsa_LookupPrivDisplayName(b
, ctx
,
148 if (!NT_STATUS_IS_OK(status
)) {
149 d_printf("??????\n");
152 if (!NT_STATUS_IS_OK(result
)) {
153 d_printf("??????\n");
157 d_printf("%s\n", description
? description
->string
: "??????");
163 /********************************************************************
164 ********************************************************************/
166 static NTSTATUS
check_privilege_for_user(struct rpc_pipe_client
*pipe_hnd
,
168 struct policy_handle
*pol
,
172 NTSTATUS status
, result
;
173 struct lsa_RightSet rights
;
175 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
177 status
= dcerpc_lsa_EnumAccountRights(b
, ctx
,
182 if (!NT_STATUS_IS_OK(status
)) {
185 if (!NT_STATUS_IS_OK(result
)) {
189 if (rights
.count
== 0) {
190 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
193 for (i
= 0; i
< rights
.count
; i
++) {
194 if (strcasecmp_m(rights
.names
[i
].string
, right
) == 0) {
199 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
202 /********************************************************************
203 ********************************************************************/
205 static NTSTATUS
enum_privileges_for_user(struct rpc_pipe_client
*pipe_hnd
,
207 struct policy_handle
*pol
,
208 struct dom_sid
*sid
)
210 NTSTATUS status
, result
;
211 struct lsa_RightSet rights
;
213 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
215 status
= dcerpc_lsa_EnumAccountRights(b
, ctx
,
220 if (!NT_STATUS_IS_OK(status
))
222 if (!NT_STATUS_IS_OK(result
))
225 if (rights
.count
== 0) {
226 d_printf(_("No privileges assigned\n"));
229 for (i
= 0; i
< rights
.count
; i
++) {
230 printf("%s\n", rights
.names
[i
].string
);
236 /********************************************************************
237 ********************************************************************/
239 static NTSTATUS
enum_accounts_for_privilege(struct rpc_pipe_client
*pipe_hnd
,
241 struct policy_handle
*pol
,
242 const char *privilege
)
244 NTSTATUS status
, result
;
245 uint32_t enum_context
=0;
246 uint32_t pref_max_length
=0x1000;
247 struct lsa_SidArray sid_array
;
250 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
252 status
= dcerpc_lsa_EnumAccounts(b
, ctx
,
258 if (!NT_STATUS_IS_OK(status
))
260 if (!NT_STATUS_IS_OK(result
))
263 d_printf("%s:\n", privilege
);
265 for ( i
=0; i
<sid_array
.num_sids
; i
++ ) {
267 status
= check_privilege_for_user(pipe_hnd
, ctx
, pol
,
268 sid_array
.sids
[i
].sid
,
271 if ( ! NT_STATUS_IS_OK(status
)) {
272 if ( ! NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
278 /* try to convert the SID to a name. Fall back to
279 printing the raw SID if necessary */
280 status
= sid_to_name( pipe_hnd
, ctx
, sid_array
.sids
[i
].sid
, name
);
281 if ( !NT_STATUS_IS_OK (status
) )
282 sid_to_fstring(name
, sid_array
.sids
[i
].sid
);
284 d_printf(" %s\n", name
);
290 /********************************************************************
291 ********************************************************************/
293 static NTSTATUS
enum_privileges_for_accounts(struct rpc_pipe_client
*pipe_hnd
,
295 struct policy_handle
*pol
)
297 NTSTATUS status
, result
;
298 uint32_t enum_context
=0;
299 uint32_t pref_max_length
=0x1000;
300 struct lsa_SidArray sid_array
;
303 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
305 status
= dcerpc_lsa_EnumAccounts(b
, ctx
,
311 if (!NT_STATUS_IS_OK(status
))
313 if (!NT_STATUS_IS_OK(result
))
316 for ( i
=0; i
<sid_array
.num_sids
; i
++ ) {
318 /* try to convert the SID to a name. Fall back to
319 printing the raw SID if necessary */
321 status
= sid_to_name(pipe_hnd
, ctx
, sid_array
.sids
[i
].sid
, name
);
322 if ( !NT_STATUS_IS_OK (status
) )
323 sid_to_fstring(name
, sid_array
.sids
[i
].sid
);
325 d_printf("%s\n", name
);
327 status
= enum_privileges_for_user(pipe_hnd
, ctx
, pol
,
328 sid_array
.sids
[i
].sid
);
329 if ( !NT_STATUS_IS_OK(status
) )
338 /********************************************************************
339 ********************************************************************/
341 static NTSTATUS
rpc_rights_list_internal(struct net_context
*c
,
342 const struct dom_sid
*domain_sid
,
343 const char *domain_name
,
344 struct cli_state
*cli
,
345 struct rpc_pipe_client
*pipe_hnd
,
350 struct policy_handle pol
;
351 NTSTATUS status
, result
;
354 struct lsa_String lsa_name
;
355 struct lsa_StringLarge
*description
= NULL
;
356 uint16_t lang_id
= 0;
357 uint16_t lang_id_sys
= 0;
358 uint16_t lang_id_desc
;
359 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
361 status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, true,
362 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
364 if ( !NT_STATUS_IS_OK(status
) )
367 /* backwards compatibility; just list available privileges if no arguement */
370 status
= enum_privileges(pipe_hnd
, mem_ctx
, &pol
);
374 if (strequal(argv
[0], "privileges")) {
377 if (argv
[1] == NULL
) {
378 status
= enum_privileges(pipe_hnd
, mem_ctx
, &pol
);
382 while ( argv
[i
] != NULL
) {
383 fstrcpy(privname
, argv
[i
]);
384 init_lsa_String(&lsa_name
, argv
[i
]);
387 /* verify that this is a valid privilege for error reporting */
388 status
= dcerpc_lsa_LookupPrivDisplayName(b
, mem_ctx
,
396 if (!NT_STATUS_IS_OK(status
)) {
400 if ( !NT_STATUS_IS_OK(result
) ) {
401 if ( NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_PRIVILEGE
))
402 d_fprintf(stderr
, _("No such privilege "
403 "exists: %s.\n"), privname
);
405 d_fprintf(stderr
, _("Error resolving "
406 "privilege display name "
412 status
= enum_accounts_for_privilege(pipe_hnd
, mem_ctx
, &pol
, privname
);
413 if (!NT_STATUS_IS_OK(status
)) {
414 d_fprintf(stderr
, _("Error enumerating "
415 "accounts for privilege %s [%s].\n"),
416 privname
, nt_errstr(status
));
423 /* special case to enumerate all privileged SIDs with associated rights */
425 if (strequal( argv
[0], "accounts")) {
428 if (argv
[1] == NULL
) {
429 status
= enum_privileges_for_accounts(pipe_hnd
, mem_ctx
, &pol
);
433 while (argv
[i
] != NULL
) {
434 status
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[i
]);
435 if (!NT_STATUS_IS_OK(status
)) {
438 status
= enum_privileges_for_user(pipe_hnd
, mem_ctx
, &pol
, &sid
);
439 if (!NT_STATUS_IS_OK(status
)) {
447 /* backward comaptibility: if no keyword provided, treat the key
448 as an account name */
450 d_printf("%s net rpc rights list [[accounts|privileges] "
451 "[name|SID]]\n", _("Usage:"));
452 status
= NT_STATUS_OK
;
456 status
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
457 if (!NT_STATUS_IS_OK(status
)) {
460 status
= enum_privileges_for_user(pipe_hnd
, mem_ctx
, &pol
, &sid
);
463 dcerpc_lsa_Close(b
, mem_ctx
, &pol
, &result
);
468 /********************************************************************
469 ********************************************************************/
471 static NTSTATUS
rpc_rights_grant_internal(struct net_context
*c
,
472 const struct dom_sid
*domain_sid
,
473 const char *domain_name
,
474 struct cli_state
*cli
,
475 struct rpc_pipe_client
*pipe_hnd
,
480 struct policy_handle dom_pol
;
481 NTSTATUS status
, result
;
482 struct lsa_RightSet rights
;
484 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
491 _(" net rpc rights grant <name|SID> <rights...>\n"));
495 status
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
496 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
))
497 status
= NT_STATUS_NO_SUCH_USER
;
499 if (!NT_STATUS_IS_OK(status
))
502 status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true,
503 SEC_FLAG_MAXIMUM_ALLOWED
,
506 if (!NT_STATUS_IS_OK(status
))
509 rights
.count
= argc
-1;
510 rights
.names
= talloc_array(mem_ctx
, struct lsa_StringLarge
,
513 return NT_STATUS_NO_MEMORY
;
516 for (i
=0; i
<argc
-1; i
++) {
517 init_lsa_StringLarge(&rights
.names
[i
], argv
[i
+1]);
520 status
= dcerpc_lsa_AddAccountRights(b
, mem_ctx
,
525 if (!NT_STATUS_IS_OK(status
))
527 if (!NT_STATUS_IS_OK(result
)) {
532 d_printf(_("Successfully granted rights.\n"));
535 if ( !NT_STATUS_IS_OK(status
) ) {
536 d_fprintf(stderr
, _("Failed to grant privileges for %s (%s)\n"),
537 argv
[0], nt_errstr(status
));
540 dcerpc_lsa_Close(b
, mem_ctx
, &dom_pol
, &result
);
545 /********************************************************************
546 ********************************************************************/
548 static NTSTATUS
rpc_rights_revoke_internal(struct net_context
*c
,
549 const struct dom_sid
*domain_sid
,
550 const char *domain_name
,
551 struct cli_state
*cli
,
552 struct rpc_pipe_client
*pipe_hnd
,
557 struct policy_handle dom_pol
;
558 NTSTATUS status
, result
;
559 struct lsa_RightSet rights
;
562 struct dcerpc_binding_handle
*b
= pipe_hnd
->binding_handle
;
567 _(" net rpc rights revoke <name|SID> <rights...>\n"));
571 status
= name_to_sid(pipe_hnd
, mem_ctx
, &sid
, argv
[0]);
572 if (!NT_STATUS_IS_OK(status
))
575 status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, true,
576 SEC_FLAG_MAXIMUM_ALLOWED
,
579 if (!NT_STATUS_IS_OK(status
))
582 rights
.count
= argc
-1;
583 rights
.names
= talloc_array(mem_ctx
, struct lsa_StringLarge
,
586 return NT_STATUS_NO_MEMORY
;
589 for (i
=0; i
<argc
-1; i
++) {
590 init_lsa_StringLarge(&rights
.names
[i
], argv
[i
+1]);
593 status
= dcerpc_lsa_RemoveAccountRights(b
, mem_ctx
,
599 if (!NT_STATUS_IS_OK(status
))
601 if (!NT_STATUS_IS_OK(result
)) {
606 d_printf(_("Successfully revoked rights.\n"));
609 if ( !NT_STATUS_IS_OK(status
) ) {
610 d_fprintf(stderr
,_("Failed to revoke privileges for %s (%s)\n"),
611 argv
[0], nt_errstr(status
));
614 dcerpc_lsa_Close(b
, mem_ctx
, &dom_pol
, &result
);
620 /********************************************************************
621 ********************************************************************/
623 static int rpc_rights_list(struct net_context
*c
, int argc
, const char **argv
)
625 if (c
->display_usage
) {
628 _("net rpc rights list [{accounts|privileges} "
630 " View available/assigned privileges\n"));
634 return run_rpc_command(c
, NULL
, &ndr_table_lsarpc
, 0,
635 rpc_rights_list_internal
, argc
, argv
);
638 /********************************************************************
639 ********************************************************************/
641 static int rpc_rights_grant(struct net_context
*c
, int argc
, const char **argv
)
643 if (c
->display_usage
) {
646 _("net rpc rights grant <name|SID> <right>\n"
647 " Assign privilege[s]\n"));
648 d_printf(_("For example:\n"
649 " net rpc rights grant 'VALE\\biddle' "
650 "SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"
651 " would grant the printer admin and disk manager "
652 "rights to the user 'VALE\\biddle'\n"));
656 return run_rpc_command(c
, NULL
, &ndr_table_lsarpc
, 0,
657 rpc_rights_grant_internal
, argc
, argv
);
660 /********************************************************************
661 ********************************************************************/
663 static int rpc_rights_revoke(struct net_context
*c
, int argc
, const char **argv
)
665 if (c
->display_usage
) {
668 _("net rpc rights revoke <name|SID> <right>\n"
669 " Revoke privilege[s]\n"));
670 d_printf(_("For example:\n"
671 " net rpc rights revoke 'VALE\\biddle' "
672 "SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"
673 " would revoke the printer admin and disk manager"
674 " rights from the user 'VALE\\biddle'\n"));
678 return run_rpc_command(c
, NULL
, &ndr_table_lsarpc
, 0,
679 rpc_rights_revoke_internal
, argc
, argv
);
682 /********************************************************************
683 ********************************************************************/
685 int net_rpc_rights(struct net_context
*c
, int argc
, const char **argv
)
687 struct functable func
[] = {
692 N_("View available/assigned privileges"),
693 N_("net rpc rights list\n"
694 " View available/assigned privileges")
700 N_("Assign privilege[s]"),
701 N_("net rpc rights grant\n"
702 " Assign privilege[s]")
708 N_("Revoke privilege[s]"),
709 N_("net rpc rights revoke\n"
710 " Revoke privilege[s]")
712 {NULL
, NULL
, 0, NULL
, NULL
}
715 return net_run_function(c
, argc
, argv
, "net rpc rights", func
);
718 static NTSTATUS
rpc_sh_rights_list(struct net_context
*c
,
719 TALLOC_CTX
*mem_ctx
, struct rpc_sh_ctx
*ctx
,
720 struct rpc_pipe_client
*pipe_hnd
,
721 int argc
, const char **argv
)
723 return rpc_rights_list_internal(c
, ctx
->domain_sid
, ctx
->domain_name
,
724 ctx
->cli
, pipe_hnd
, mem_ctx
,
728 static NTSTATUS
rpc_sh_rights_grant(struct net_context
*c
,
730 struct rpc_sh_ctx
*ctx
,
731 struct rpc_pipe_client
*pipe_hnd
,
732 int argc
, const char **argv
)
734 return rpc_rights_grant_internal(c
, ctx
->domain_sid
, ctx
->domain_name
,
735 ctx
->cli
, pipe_hnd
, mem_ctx
,
739 static NTSTATUS
rpc_sh_rights_revoke(struct net_context
*c
,
741 struct rpc_sh_ctx
*ctx
,
742 struct rpc_pipe_client
*pipe_hnd
,
743 int argc
, const char **argv
)
745 return rpc_rights_revoke_internal(c
, ctx
->domain_sid
, ctx
->domain_name
,
746 ctx
->cli
, pipe_hnd
, mem_ctx
,
750 struct rpc_sh_cmd
*net_rpc_rights_cmds(struct net_context
*c
, TALLOC_CTX
*mem_ctx
,
751 struct rpc_sh_ctx
*ctx
)
753 static struct rpc_sh_cmd cmds
[] = {
755 { "list", NULL
, &ndr_table_lsarpc
, rpc_sh_rights_list
,
756 N_("View available or assigned privileges") },
758 { "grant", NULL
, &ndr_table_lsarpc
, rpc_sh_rights_grant
,
759 N_("Assign privilege[s]") },
761 { "revoke", NULL
, &ndr_table_lsarpc
, rpc_sh_rights_revoke
,
762 N_("Revoke privilege[s]") },
764 { NULL
, NULL
, 0, NULL
, NULL
}