/* Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility Copyright (C) Gerald (Jerry) Carter 2004 Copyright (C) Guenther Deschner 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "includes.h" #include "utils/net.h" /******************************************************************** ********************************************************************/ static NTSTATUS sid_to_name(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, DOM_SID *sid, fstring name) { POLICY_HND pol; enum lsa_SidType *sid_types = NULL; NTSTATUS result; char **domains = NULL, **names = NULL; result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); if ( !NT_STATUS_IS_OK(result) ) return result; result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types); if ( NT_STATUS_IS_OK(result) ) { if ( *domains[0] ) fstr_sprintf( name, "%s\\%s", domains[0], names[0] ); else fstrcpy( name, names[0] ); } rpccli_lsa_Close(pipe_hnd, mem_ctx, &pol); return result; } /******************************************************************** ********************************************************************/ static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, DOM_SID *sid, const char *name) { POLICY_HND pol; enum lsa_SidType *sid_types; NTSTATUS result; DOM_SID *sids; /* maybe its a raw SID */ if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) ) { return NT_STATUS_OK; } result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); if ( !NT_STATUS_IS_OK(result) ) return result; result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &pol, 1, &name, NULL, 1, &sids, &sid_types); if ( NT_STATUS_IS_OK(result) ) sid_copy( sid, &sids[0] ); rpccli_lsa_Close(pipe_hnd, mem_ctx, &pol); return result; } /******************************************************************** ********************************************************************/ static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, POLICY_HND *pol ) { NTSTATUS result; uint32 enum_context = 0; uint32 pref_max_length=0x1000; int i; uint16 lang_id=0; uint16 lang_id_sys=0; uint16 lang_id_desc; struct lsa_StringLarge *description = NULL; struct lsa_PrivArray priv_array; result = rpccli_lsa_EnumPrivs(pipe_hnd, ctx, pol, &enum_context, &priv_array, pref_max_length); if ( !NT_STATUS_IS_OK(result) ) return result; /* Print results */ for (i = 0; i < priv_array.count; i++) { struct lsa_String lsa_name; d_printf("%30s ", priv_array.privs[i].name.string ? priv_array.privs[i].name.string : "*unknown*" ); /* try to get the description */ init_lsa_String(&lsa_name, priv_array.privs[i].name.string); result = rpccli_lsa_LookupPrivDisplayName(pipe_hnd, ctx, pol, &lsa_name, lang_id, lang_id_sys, &description, &lang_id_desc); if (!NT_STATUS_IS_OK(result)) { d_printf("??????\n"); continue; } d_printf("%s\n", description->string); } return NT_STATUS_OK; } /******************************************************************** ********************************************************************/ static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, POLICY_HND *pol, DOM_SID *sid, const char *right) { NTSTATUS result; struct lsa_RightSet rights; int i; result = rpccli_lsa_EnumAccountRights(pipe_hnd, ctx, pol, sid, &rights); if (!NT_STATUS_IS_OK(result)) { return result; } if (rights.count == 0) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } for (i = 0; i < rights.count; i++) { if (StrCaseCmp(rights.names[i].string, right) == 0) { return NT_STATUS_OK; } } return NT_STATUS_OBJECT_NAME_NOT_FOUND; } /******************************************************************** ********************************************************************/ static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, POLICY_HND *pol, DOM_SID *sid ) { NTSTATUS result; struct lsa_RightSet rights; int i; result = rpccli_lsa_EnumAccountRights(pipe_hnd, ctx, pol, sid, &rights); if (!NT_STATUS_IS_OK(result)) return result; if (rights.count == 0) { d_printf("No privileges assigned\n"); } for (i = 0; i < rights.count; i++) { printf("%s\n", rights.names[i].string); } return NT_STATUS_OK; } /******************************************************************** ********************************************************************/ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, POLICY_HND *pol, const char *privilege) { NTSTATUS result; uint32 enum_context=0; uint32 pref_max_length=0x1000; struct lsa_SidArray sid_array; int i; fstring name; result = rpccli_lsa_EnumAccounts(pipe_hnd, ctx, pol, &enum_context, &sid_array, pref_max_length); if (!NT_STATUS_IS_OK(result)) return result; d_printf("%s:\n", privilege); for ( i=0; i 1) { d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n"); result = NT_STATUS_OK; goto done; } result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]); if (!NT_STATUS_IS_OK(result)) { goto done; } result = enum_privileges_for_user(pipe_hnd, mem_ctx, &pol, &sid ); done: rpccli_lsa_Close(pipe_hnd, mem_ctx, &pol); return result; } /******************************************************************** ********************************************************************/ static NTSTATUS rpc_rights_grant_internal(struct net_context *c, const DOM_SID *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv ) { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_RightSet rights; int i; DOM_SID sid; if (argc < 2 ) { d_printf("Usage: net rpc rights grant \n"); return NT_STATUS_OK; } result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]); if (!NT_STATUS_IS_OK(result)) return result; result = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &dom_pol); if (!NT_STATUS_IS_OK(result)) return result; rights.count = argc-1; rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, rights.count); if (!rights.names) { return NT_STATUS_NO_MEMORY; } for (i=0; i \n"); return NT_STATUS_OK; } result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]); if (!NT_STATUS_IS_OK(result)) return result; result = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &dom_pol); if (!NT_STATUS_IS_OK(result)) return result; rights.count = argc-1; rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, rights.count); if (!rights.names) { return NT_STATUS_NO_MEMORY; } for (i=0; idisplay_usage) { d_printf("Usage:\n" "net rpc rights list [{accounts|privileges} " "[name|SID]]\n" " View available/assigned privileges\n"); return 0; } return run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0, rpc_rights_list_internal, argc, argv ); } /******************************************************************** ********************************************************************/ static int rpc_rights_grant(struct net_context *c, int argc, const char **argv ) { if (c->display_usage) { d_printf("Usage:\n" "net rpc rights grant \n" " Assign privilege[s]\n"); d_printf("For example:\n"); d_printf(" net rpc rights grant 'VALE\\biddle' " "SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"); d_printf(" would grant the printer admin and disk manager " "rights to the user 'VALE\\biddle'\n"); return 0; } return run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0, rpc_rights_grant_internal, argc, argv ); } /******************************************************************** ********************************************************************/ static int rpc_rights_revoke(struct net_context *c, int argc, const char **argv) { if (c->display_usage) { d_printf("Usage:\n" "net rpc rights revoke \n" " Revoke privilege[s]\n"); d_printf("For example:\n"); d_printf(" net rpc rights revoke 'VALE\\biddle' " "SePrintOperatorPrivilege SeDiskOperatorPrivilege\n"); d_printf(" would revoke the printer admin and disk manager " "rights from the user 'VALE\\biddle'\n"); return 0; } return run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0, rpc_rights_revoke_internal, argc, argv ); } /******************************************************************** ********************************************************************/ int net_rpc_rights(struct net_context *c, int argc, const char **argv) { struct functable func[] = { { "list", rpc_rights_list, NET_TRANSPORT_RPC, "View available/assigned privileges", "net rpc rights list\n" " View available/assigned privileges" }, { "grant", rpc_rights_grant, NET_TRANSPORT_RPC, "Assign privilege[s]", "net rpc rights grant\n" " Assign privilege[s]" }, { "revoke", rpc_rights_revoke, NET_TRANSPORT_RPC, "Revoke privilege[s]", "net rpc rights revoke\n" " Revoke privilege[s]" }, {NULL, NULL, 0, NULL, NULL} }; return net_run_function(c, argc, argv, "net rpc rights", func); } static NTSTATUS rpc_sh_rights_list(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, int argc, const char **argv) { return rpc_rights_list_internal(c, ctx->domain_sid, ctx->domain_name, ctx->cli, pipe_hnd, mem_ctx, argc, argv); } static NTSTATUS rpc_sh_rights_grant(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, int argc, const char **argv) { return rpc_rights_grant_internal(c, ctx->domain_sid, ctx->domain_name, ctx->cli, pipe_hnd, mem_ctx, argc, argv); } static NTSTATUS rpc_sh_rights_revoke(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, int argc, const char **argv) { return rpc_rights_revoke_internal(c, ctx->domain_sid, ctx->domain_name, ctx->cli, pipe_hnd, mem_ctx, argc, argv); } struct rpc_sh_cmd *net_rpc_rights_cmds(struct net_context *c, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx) { static struct rpc_sh_cmd cmds[] = { { "list", NULL, &ndr_table_lsarpc.syntax_id, rpc_sh_rights_list, "View available or assigned privileges" }, { "grant", NULL, &ndr_table_lsarpc.syntax_id, rpc_sh_rights_grant, "Assign privilege[s]" }, { "revoke", NULL, &ndr_table_lsarpc.syntax_id, rpc_sh_rights_revoke, "Revoke privilege[s]" }, { NULL, NULL, 0, NULL, NULL } }; return cmds; }