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 cli_state
*cli
,
28 DOM_SID
*sid
, fstring name
)
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
) )
41 result
= cli_lsa_lookup_sids(cli
, mem_ctx
, &pol
, 1, sid
, &domains
, &names
, &sid_types
);
43 if ( NT_STATUS_IS_OK(result
) ) {
45 fstr_sprintf( name
, "%s\\%s", domains
[0], names
[0] );
47 fstrcpy( name
, names
[0] );
50 cli_lsa_close(cli
, mem_ctx
, &pol
);
54 /********************************************************************
55 ********************************************************************/
57 static NTSTATUS
name_to_sid(struct cli_state
*cli
,
59 DOM_SID
*sid
, const char *name
)
66 /* maybe its a raw SID */
67 if ( strncmp(name
, "S-", 2) == 0 && string_to_sid(sid
, name
) )
72 result
= cli_lsa_open_policy(cli
, mem_ctx
, True
,
73 SEC_RIGHTS_MAXIMUM_ALLOWED
, &pol
);
75 if ( !NT_STATUS_IS_OK(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
);
87 /********************************************************************
88 ********************************************************************/
90 static NTSTATUS
enum_privileges( TALLOC_CTX
*ctx
, struct cli_state
*cli
,
94 uint32 enum_context
= 0;
95 uint32 pref_max_length
=0x1000;
102 uint16 lang_id_sys
=0;
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
) )
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");
126 d_printf("%s\n", description
);
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
)
144 result
= cli_lsa_enum_account_rights(cli
, ctx
, pol
, sid
, &count
, &rights
);
146 if (!NT_STATUS_IS_OK(result
)) {
151 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
154 for (i
= 0; i
< count
; i
++) {
155 if (StrCaseCmp(rights
[i
], right
) == 0) {
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
)
174 result
= cli_lsa_enum_account_rights(cli
, ctx
, pol
, sid
, &count
, &rights
);
176 if (!NT_STATUS_IS_OK(result
))
180 d_printf("No privileges assigned\n");
182 for (i
= 0; i
< count
; i
++) {
183 printf("%s\n", rights
[i
]);
189 /********************************************************************
190 ********************************************************************/
192 static NTSTATUS
enum_accounts_for_privilege(TALLOC_CTX
*ctx
, struct cli_state
*cli
,
193 POLICY_HND
*pol
, const char *privilege
)
196 uint32 enum_context
=0;
197 uint32 pref_max_length
=0x1000;
203 result
= cli_lsa_enum_sids(cli
, ctx
, pol
, &enum_context
,
204 pref_max_length
, &count
, &sids
);
206 if (!NT_STATUS_IS_OK(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
)) {
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
);
235 /********************************************************************
236 ********************************************************************/
238 static NTSTATUS
enum_privileges_for_accounts( TALLOC_CTX
*ctx
, struct cli_state
*cli
,
242 uint32 enum_context
=0;
243 uint32 pref_max_length
=0x1000;
249 result
= cli_lsa_enum_sids(cli
, ctx
, pol
, &enum_context
,
250 pref_max_length
, &count
, &sids
);
252 if (!NT_STATUS_IS_OK(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
) )
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
)
290 uint16 lang_id_sys
= 0;
294 result
= cli_lsa_open_policy(cli
, mem_ctx
, True
,
295 SEC_RIGHTS_MAXIMUM_ALLOWED
, &pol
);
297 if ( !NT_STATUS_IS_OK(result
) )
300 /* backwards compatibility; just list available privileges if no arguement */
303 result
= enum_privileges( mem_ctx
, cli
, &pol
);
307 if (strequal(argv
[0], "privileges")) {
310 if (argv
[1] == NULL
) {
311 result
= enum_privileges( mem_ctx
, cli
, &pol
);
315 while ( argv
[i
] != NULL
)
317 fstrcpy( privname
, argv
[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
);
329 d_printf("Error resolving privilege display name [%s].\n", nt_errstr(result
));
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
));
343 /* special case to enumerate all privileged SIDs with associated rights */
345 if (strequal( argv
[0], "accounts")) {
348 if (argv
[1] == NULL
) {
349 result
= enum_privileges_for_accounts(mem_ctx
, cli
, &pol
);
353 while (argv
[i
] != NULL
) {
354 result
= name_to_sid(cli
, mem_ctx
, &sid
, argv
[i
]);
355 if (!NT_STATUS_IS_OK(result
)) {
358 result
= enum_privileges_for_user(mem_ctx
, cli
, &pol
, &sid
);
359 if (!NT_STATUS_IS_OK(result
)) {
367 /* backward comaptibility: if no keyword provided, treat the key
368 as an account name */
370 d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n");
371 result
= NT_STATUS_OK
;
375 result
= name_to_sid(cli
, mem_ctx
, &sid
, argv
[0]);
376 if (!NT_STATUS_IS_OK(result
)) {
379 result
= enum_privileges_for_user( mem_ctx
, cli
, &pol
, &sid
);
382 cli_lsa_close(cli
, mem_ctx
, &pol
);
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
)
395 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
400 d_printf("Usage: net rpc rights grant <name|SID> <rights...>\n");
404 result
= name_to_sid(cli
, mem_ctx
, &sid
, argv
[0]);
405 if (!NT_STATUS_IS_OK(result
))
408 result
= cli_lsa_open_policy2(cli
, mem_ctx
, True
,
409 SEC_RIGHTS_MAXIMUM_ALLOWED
,
412 if (!NT_STATUS_IS_OK(result
))
415 result
= cli_lsa_add_account_rights(cli
, mem_ctx
, &dom_pol
, sid
,
418 if (!NT_STATUS_IS_OK(result
))
421 d_printf("Successfully granted rights.\n");
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
);
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
)
442 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
447 d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n");
451 result
= name_to_sid(cli
, mem_ctx
, &sid
, argv
[0]);
452 if (!NT_STATUS_IS_OK(result
))
455 result
= cli_lsa_open_policy2(cli
, mem_ctx
, True
,
456 SEC_RIGHTS_MAXIMUM_ALLOWED
,
459 if (!NT_STATUS_IS_OK(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
))
468 d_printf("Successfully revoked rights.\n");
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
);
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");
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
},
540 return net_run_function( argc
, argv
, func
, net_help_rights
);
542 return net_help_rights( argc
, argv
);