1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r22135: Check in most of Michael Adam's net conf utility. A good share of this patch

is moving functions around to fix some linker dependencies for the registry.

Michael, I've renamed your auth_utils2.c to token_utils.c.

Thanks!

Volker
This commit is contained in:
Volker Lendecke 2007-04-09 10:38:55 +00:00 committed by Gerald (Jerry) Carter
parent 85df3fca68
commit 9de16f25c1
9 changed files with 1976 additions and 783 deletions

View File

@ -341,7 +341,8 @@ REGOBJS_OBJ = registry/reg_objects.o
REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \
registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o \
registry/reg_smbconf.o registry/reg_api.o
registry/reg_smbconf.o registry/reg_api.o \
registry/reg_frontend_hilvl.o
RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o
@ -462,8 +463,8 @@ AUTH_UNIX_OBJ = auth/auth_unix.o
AUTH_WINBIND_OBJ = auth/auth_winbind.o
AUTH_SCRIPT_OBJ = auth/auth_script.o
AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/auth_compat.o \
auth/auth_ntlmssp.o \
AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/token_util.o \
auth/auth_compat.o auth/auth_ntlmssp.o \
$(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ)
MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o
@ -639,8 +640,22 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_domain.o utils/net_help.o \
utils/net_rpc_service.o utils/net_rpc_registry.o utils/net_usershare.o \
utils/netlookup.o utils/net_sam.o utils/net_rpc_shell.o \
utils/net_util.o utils/net_rpc_sh_acct.o utils/net_rpc_audit.o \
$(PASSWD_UTIL_OBJ) utils/net_dns.o utils/net_ads_gpo.o
$(PASSWD_UTIL_OBJ) utils/net_dns.o utils/net_ads_gpo.o \
utils/net_conf.o
NET_REG_OBJ = registry/reg_api.o \
registry/reg_frontend_hilvl.o \
registry/reg_smbconf.o \
registry/reg_db.o \
registry/reg_util.o \
\
registry/reg_cachehook.o \
registry/reg_eventlog.o \
registry/reg_perfcount.o \
registry/reg_dynamic.o \
\
auth/token_util.o
NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LIBADDNS_OBJ0) \
@ -648,7 +663,8 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(REGFIO_OBJ) $(READLINE_OBJ) \
$(LDB_OBJ) $(LIBGPO_OBJ) $(INIPARSER_OBJ) $(DISPLAY_SEC_OBJ)
$(LDB_OBJ) $(LIBGPO_OBJ) $(INIPARSER_OBJ) $(DISPLAY_SEC_OBJ) \
$(NET_REG_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)

View File

@ -27,12 +27,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
BOOL is_guest,
int num_groupsids,
const DOM_SID *groupsids);
/****************************************************************************
Create a UNIX user on demand.
****************************************************************************/
@ -481,38 +475,6 @@ void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
(long int)groups[i]));
}
/******************************************************************************
Create a token for the root user to be used internally by smbd.
This is similar to running under the context of the LOCAL_SYSTEM account
in Windows. This is a read-only token. Do not modify it or free() it.
Create a copy if your need to change it.
******************************************************************************/
NT_USER_TOKEN *get_root_nt_token( void )
{
static NT_USER_TOKEN *token = NULL;
DOM_SID u_sid, g_sid;
struct passwd *pw;
if ( token )
return token;
if ( !(pw = sys_getpwnam( "root" )) ) {
DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n"));
return NULL;
}
/* get the user and primary group SIDs; although the
BUILTIN\Administrators SId is really the one that matters here */
uid_to_sid(&u_sid, pw->pw_uid);
gid_to_sid(&g_sid, pw->pw_gid);
token = create_local_nt_token(NULL, &u_sid, False,
1, &global_sid_Builtin_Administrators);
return token;
}
static int server_info_dtor(auth_serversupplied_info *server_info)
{
TALLOC_FREE(server_info->sam_account);
@ -631,53 +593,6 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
return NT_STATUS_OK;
}
/*
* Add alias SIDs from memberships within the partially created token SID list
*/
static NTSTATUS add_aliases(const DOM_SID *domain_sid,
struct nt_user_token *token)
{
uint32 *aliases;
size_t i, num_aliases;
NTSTATUS status;
TALLOC_CTX *tmp_ctx;
if (!(tmp_ctx = talloc_init("add_aliases"))) {
return NT_STATUS_NO_MEMORY;
}
aliases = NULL;
num_aliases = 0;
status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
token->user_sids,
token->num_sids,
&aliases, &num_aliases);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
nt_errstr(status)));
TALLOC_FREE(tmp_ctx);
return status;
}
for (i=0; i<num_aliases; i++) {
DOM_SID alias_sid;
sid_compose(&alias_sid, domain_sid, aliases[i]);
if (!add_sid_to_array_unique(token, &alias_sid,
&token->user_sids,
&token->num_sids)) {
DEBUG(0, ("add_sid_to_array failed\n"));
TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
}
TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
{
char *command;
@ -714,270 +629,6 @@ static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
return NT_STATUS_OK;
}
/*******************************************************************
*******************************************************************/
static NTSTATUS add_builtin_administrators( struct nt_user_token *token )
{
DOM_SID domadm;
/* nothing to do if we aren't in a domain */
if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
return NT_STATUS_OK;
}
/* Find the Domain Admins SID */
if ( IS_DC ) {
sid_copy( &domadm, get_global_sam_sid() );
} else {
if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) )
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
/* Add Administrators if the user beloongs to Domain Admins */
if ( nt_token_check_sid( &domadm, token ) ) {
if (!add_sid_to_array(token, &global_sid_Builtin_Administrators,
&token->user_sids, &token->num_sids)) {
return NT_STATUS_NO_MEMORY;
}
}
return NT_STATUS_OK;
}
/*******************************************************************
*******************************************************************/
static NTSTATUS create_builtin_users( void )
{
NTSTATUS status;
DOM_SID dom_users;
status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_users: Failed to create Users\n"));
return status;
}
/* add domain users */
if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
&& secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
{
sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_users: Failed to add Domain Users to"
" Users\n"));
return status;
}
}
return NT_STATUS_OK;
}
/*******************************************************************
*******************************************************************/
static NTSTATUS create_builtin_administrators( void )
{
NTSTATUS status;
DOM_SID dom_admins, root_sid;
fstring root_name;
enum lsa_SidType type;
TALLOC_CTX *ctx;
BOOL ret;
status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
return status;
}
/* add domain admins */
if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
&& secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
{
sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
" Administrators\n"));
return status;
}
}
/* add root */
if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
return NT_STATUS_NO_MEMORY;
}
fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
TALLOC_FREE( ctx );
if ( ret ) {
status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to add root"
" Administrators\n"));
return status;
}
}
return NT_STATUS_OK;
}
/*******************************************************************
Create a NT token for the user, expanding local aliases
*******************************************************************/
static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
BOOL is_guest,
int num_groupsids,
const DOM_SID *groupsids)
{
struct nt_user_token *result = NULL;
int i;
NTSTATUS status;
gid_t gid;
DEBUG(10, ("Create local NT token for %s\n", sid_string_static(user_sid)));
if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
/* Add the user and primary group sid */
if (!add_sid_to_array(result, user_sid,
&result->user_sids, &result->num_sids)) {
return NULL;
}
/* For guest, num_groupsids may be zero. */
if (num_groupsids) {
if (!add_sid_to_array(result, &groupsids[0],
&result->user_sids, &result->num_sids)) {
return NULL;
}
}
/* Add in BUILTIN sids */
if (!add_sid_to_array(result, &global_sid_World,
&result->user_sids, &result->num_sids)) {
return NULL;
}
if (!add_sid_to_array(result, &global_sid_Network,
&result->user_sids, &result->num_sids)) {
return NULL;
}
if (is_guest) {
if (!add_sid_to_array(result, &global_sid_Builtin_Guests,
&result->user_sids, &result->num_sids)) {
return NULL;
}
} else {
if (!add_sid_to_array(result, &global_sid_Authenticated_Users,
&result->user_sids, &result->num_sids)) {
return NULL;
}
}
/* Now the SIDs we got from authentication. These are the ones from
* the info3 struct or from the pdb_enum_group_memberships, depending
* on who authenticated the user.
* Note that we start the for loop at "1" here, we already added the
* first group sid as primary above. */
for (i=1; i<num_groupsids; i++) {
if (!add_sid_to_array_unique(result, &groupsids[i],
&result->user_sids, &result->num_sids)) {
return NULL;
}
}
/* Deal with the BUILTIN\Administrators group. If the SID can
be resolved then assume that the add_aliasmem( S-1-5-32 )
handled it. */
if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
/* We can only create a mapping if winbind is running
and the nested group functionality has been enabled */
if ( lp_winbind_nested_groups() && winbind_ping() ) {
become_root();
status = create_builtin_administrators( );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
/* don't fail, just log the message */
}
unbecome_root();
}
else {
status = add_builtin_administrators( result );
if ( !NT_STATUS_IS_OK(status) ) {
/* just log a complaint but do not fail */
DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
" membership (%s)\n", nt_errstr(status)));
}
}
}
/* Deal with the BUILTIN\Users group. If the SID can
be resolved then assume that the add_aliasmem( S-1-5-32 )
handled it. */
if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
/* We can only create a mapping if winbind is running
and the nested group functionality has been enabled */
if ( lp_winbind_nested_groups() && winbind_ping() ) {
become_root();
status = create_builtin_users( );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Users group!\n"));
/* don't fail, just log the message */
}
unbecome_root();
}
}
/* Deal with local groups */
if (lp_winbind_nested_groups()) {
/* Now add the aliases. First the one from our local SAM */
status = add_aliases(get_global_sam_sid(), result);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(result);
return NULL;
}
/* Finally the builtin ones */
status = add_aliases(&global_sid_Builtin, result);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(result);
return NULL;
}
}
get_privileges_for_sids(&result->privileges, result->user_sids,
result->num_sids);
return result;
}
/*
* Create the token to use from server_info->sam_account and
* server_info->sids (the info3/sam groups). Find the unix gids.
@ -2039,89 +1690,6 @@ BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_me
return True;
}
/****************************************************************************
Duplicate a SID token.
****************************************************************************/
NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken)
{
NT_USER_TOKEN *token;
if (!ptoken)
return NULL;
token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
if (token == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
ZERO_STRUCTP(token);
if (ptoken->user_sids && ptoken->num_sids) {
token->user_sids = (DOM_SID *)talloc_memdup(
token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
if (token->user_sids == NULL) {
DEBUG(0, ("talloc_memdup failed\n"));
TALLOC_FREE(token);
return NULL;
}
token->num_sids = ptoken->num_sids;
}
/* copy the privileges; don't consider failure to be critical here */
if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. "
"Continuing with 0 privileges assigned.\n"));
}
return token;
}
/****************************************************************************
Check for a SID in an NT_USER_TOKEN
****************************************************************************/
BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
{
int i;
if ( !sid || !token )
return False;
for ( i=0; i<token->num_sids; i++ ) {
if ( sid_equal( sid, &token->user_sids[i] ) )
return True;
}
return False;
}
BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
{
DOM_SID domain_sid;
/* if we are a domain member, the get the domain SID, else for
a DC or standalone server, use our own SID */
if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
if ( !secrets_fetch_domain_sid( lp_workgroup(),
&domain_sid ) ) {
DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
"SID for domain [%s]\n", lp_workgroup()));
return False;
}
}
else
sid_copy( &domain_sid, get_global_sam_sid() );
sid_append_rid( &domain_sid, rid );
return nt_token_check_sid( &domain_sid, token );\
}
/**
* Verify whether or not given domain is trusted.
*

458
source/auth/token_util.c Normal file
View File

@ -0,0 +1,458 @@
/*
* Unix SMB/CIFS implementation.
* Authentication utility functions
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Andrew Bartlett 2001
* Copyright (C) Jeremy Allison 2000-2001
* Copyright (C) Rafal Szczesniak 2002
* Copyright (C) Volker Lendecke 2006
* Copyright (C) Michael Adam 2007
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* functions moved from auth/auth_util.c to minimize linker deps */
#include "includes.h"
/****************************************************************************
Duplicate a SID token.
****************************************************************************/
NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken)
{
NT_USER_TOKEN *token;
if (!ptoken)
return NULL;
token = TALLOC_P(mem_ctx, NT_USER_TOKEN);
if (token == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
ZERO_STRUCTP(token);
if (ptoken->user_sids && ptoken->num_sids) {
token->user_sids = (DOM_SID *)talloc_memdup(
token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
if (token->user_sids == NULL) {
DEBUG(0, ("talloc_memdup failed\n"));
TALLOC_FREE(token);
return NULL;
}
token->num_sids = ptoken->num_sids;
}
/* copy the privileges; don't consider failure to be critical here */
if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. "
"Continuing with 0 privileges assigned.\n"));
}
return token;
}
/****************************************************************************
Check for a SID in an NT_USER_TOKEN
****************************************************************************/
BOOL nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
{
int i;
if ( !sid || !token )
return False;
for ( i=0; i<token->num_sids; i++ ) {
if ( sid_equal( sid, &token->user_sids[i] ) )
return True;
}
return False;
}
BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
{
DOM_SID domain_sid;
/* if we are a domain member, the get the domain SID, else for
a DC or standalone server, use our own SID */
if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
if ( !secrets_fetch_domain_sid( lp_workgroup(),
&domain_sid ) ) {
DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
"SID for domain [%s]\n", lp_workgroup()));
return False;
}
}
else
sid_copy( &domain_sid, get_global_sam_sid() );
sid_append_rid( &domain_sid, rid );
return nt_token_check_sid( &domain_sid, token );\
}
/******************************************************************************
Create a token for the root user to be used internally by smbd.
This is similar to running under the context of the LOCAL_SYSTEM account
in Windows. This is a read-only token. Do not modify it or free() it.
Create a copy if your need to change it.
******************************************************************************/
NT_USER_TOKEN *get_root_nt_token( void )
{
static NT_USER_TOKEN *token = NULL;
DOM_SID u_sid, g_sid;
struct passwd *pw;
if ( token )
return token;
if ( !(pw = sys_getpwnam( "root" )) ) {
DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n"));
return NULL;
}
/* get the user and primary group SIDs; although the
BUILTIN\Administrators SId is really the one that matters here */
uid_to_sid(&u_sid, pw->pw_uid);
gid_to_sid(&g_sid, pw->pw_gid);
token = create_local_nt_token(NULL, &u_sid, False,
1, &global_sid_Builtin_Administrators);
return token;
}
/*
* Add alias SIDs from memberships within the partially created token SID list
*/
static NTSTATUS add_aliases(const DOM_SID *domain_sid,
struct nt_user_token *token)
{
uint32 *aliases;
size_t i, num_aliases;
NTSTATUS status;
TALLOC_CTX *tmp_ctx;
if (!(tmp_ctx = talloc_init("add_aliases"))) {
return NT_STATUS_NO_MEMORY;
}
aliases = NULL;
num_aliases = 0;
status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
token->user_sids,
token->num_sids,
&aliases, &num_aliases);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
nt_errstr(status)));
TALLOC_FREE(tmp_ctx);
return status;
}
for (i=0; i<num_aliases; i++) {
DOM_SID alias_sid;
sid_compose(&alias_sid, domain_sid, aliases[i]);
if (!add_sid_to_array_unique(token, &alias_sid,
&token->user_sids,
&token->num_sids)) {
DEBUG(0, ("add_sid_to_array failed\n"));
TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
}
TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
/*******************************************************************
*******************************************************************/
static NTSTATUS add_builtin_administrators( struct nt_user_token *token )
{
DOM_SID domadm;
/* nothing to do if we aren't in a domain */
if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
return NT_STATUS_OK;
}
/* Find the Domain Admins SID */
if ( IS_DC ) {
sid_copy( &domadm, get_global_sam_sid() );
} else {
if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) )
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
/* Add Administrators if the user beloongs to Domain Admins */
if ( nt_token_check_sid( &domadm, token ) ) {
if (!add_sid_to_array(token, &global_sid_Builtin_Administrators,
&token->user_sids, &token->num_sids)) {
return NT_STATUS_NO_MEMORY;
}
}
return NT_STATUS_OK;
}
/*******************************************************************
*******************************************************************/
static NTSTATUS create_builtin_users( void )
{
NTSTATUS status;
DOM_SID dom_users;
status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_USERS );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_users: Failed to create Users\n"));
return status;
}
/* add domain users */
if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
&& secrets_fetch_domain_sid(lp_workgroup(), &dom_users))
{
sid_append_rid(&dom_users, DOMAIN_GROUP_RID_USERS );
status = pdb_add_aliasmem( &global_sid_Builtin_Users, &dom_users);
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to add Domain Users to"
" Users\n"));
return status;
}
}
return NT_STATUS_OK;
}
/*******************************************************************
*******************************************************************/
static NTSTATUS create_builtin_administrators( void )
{
NTSTATUS status;
DOM_SID dom_admins, root_sid;
fstring root_name;
enum lsa_SidType type;
TALLOC_CTX *ctx;
BOOL ret;
status = pdb_create_builtin_alias( BUILTIN_ALIAS_RID_ADMINS );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to create Administrators\n"));
return status;
}
/* add domain admins */
if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
&& secrets_fetch_domain_sid(lp_workgroup(), &dom_admins))
{
sid_append_rid(&dom_admins, DOMAIN_GROUP_RID_ADMINS);
status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &dom_admins );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to add Domain Admins"
" Administrators\n"));
return status;
}
}
/* add root */
if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
return NT_STATUS_NO_MEMORY;
}
fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
TALLOC_FREE( ctx );
if ( ret ) {
status = pdb_add_aliasmem( &global_sid_Builtin_Administrators, &root_sid );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(0,("create_builtin_administrators: Failed to add root"
" Administrators\n"));
return status;
}
}
return NT_STATUS_OK;
}
/*******************************************************************
Create a NT token for the user, expanding local aliases
*******************************************************************/
struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
BOOL is_guest,
int num_groupsids,
const DOM_SID *groupsids)
{
struct nt_user_token *result = NULL;
int i;
NTSTATUS status;
gid_t gid;
DEBUG(10, ("Create local NT token for %s\n", sid_string_static(user_sid)));
if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
/* Add the user and primary group sid */
if (!add_sid_to_array(result, user_sid,
&result->user_sids, &result->num_sids)) {
return NULL;
}
/* For guest, num_groupsids may be zero. */
if (num_groupsids) {
if (!add_sid_to_array(result, &groupsids[0],
&result->user_sids, &result->num_sids)) {
return NULL;
}
}
/* Add in BUILTIN sids */
if (!add_sid_to_array(result, &global_sid_World,
&result->user_sids, &result->num_sids)) {
return NULL;
}
if (!add_sid_to_array(result, &global_sid_Network,
&result->user_sids, &result->num_sids)) {
return NULL;
}
if (is_guest) {
if (!add_sid_to_array(result, &global_sid_Builtin_Guests,
&result->user_sids, &result->num_sids)) {
return NULL;
}
} else {
if (!add_sid_to_array(result, &global_sid_Authenticated_Users,
&result->user_sids, &result->num_sids)) {
return NULL;
}
}
/* Now the SIDs we got from authentication. These are the ones from
* the info3 struct or from the pdb_enum_group_memberships, depending
* on who authenticated the user.
* Note that we start the for loop at "1" here, we already added the
* first group sid as primary above. */
for (i=1; i<num_groupsids; i++) {
if (!add_sid_to_array_unique(result, &groupsids[i],
&result->user_sids, &result->num_sids)) {
return NULL;
}
}
/* Deal with the BUILTIN\Administrators group. If the SID can
be resolved then assume that the add_aliasmem( S-1-5-32 )
handled it. */
if ( !sid_to_gid( &global_sid_Builtin_Administrators, &gid ) ) {
/* We can only create a mapping if winbind is running
and the nested group functionality has been enabled */
if ( lp_winbind_nested_groups() && winbind_ping() ) {
become_root();
status = create_builtin_administrators( );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Administrators group!\n"));
/* don't fail, just log the message */
}
unbecome_root();
}
else {
status = add_builtin_administrators( result );
if ( !NT_STATUS_IS_OK(status) ) {
/* just log a complaint but do not fail */
DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
" membership (%s)\n", nt_errstr(status)));
}
}
}
/* Deal with the BUILTIN\Users group. If the SID can
be resolved then assume that the add_aliasmem( S-1-5-32 )
handled it. */
if ( !sid_to_gid( &global_sid_Builtin_Users, &gid ) ) {
/* We can only create a mapping if winbind is running
and the nested group functionality has been enabled */
if ( lp_winbind_nested_groups() && winbind_ping() ) {
become_root();
status = create_builtin_users( );
if ( !NT_STATUS_IS_OK(status) ) {
DEBUG(2,("create_local_nt_token: Failed to create BUILTIN\\Users group!\n"));
/* don't fail, just log the message */
}
unbecome_root();
}
}
/* Deal with local groups */
if (lp_winbind_nested_groups()) {
/* Now add the aliases. First the one from our local SAM */
status = add_aliases(get_global_sam_sid(), result);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(result);
return NULL;
}
/* Finally the builtin ones */
status = add_aliases(&global_sid_Builtin, result);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(result);
return NULL;
}
}
get_privileges_for_sids(&result->privileges, result->user_sids,
result->num_sids);
return result;
}
/* END */

View File

@ -496,3 +496,63 @@ WERROR reg_deletevalue(struct registry_key *key, const char *name)
return WERR_OK;
}
/*
* Utility function to open a complete registry path including the hive
* prefix. This should become the replacement function for
* regkey_open_internal.
*/
WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
uint32 desired_access, const struct nt_user_token *token,
struct registry_key **pkey)
{
struct registry_key *hive, *key;
char *path, *p;
WERROR err;
if (!(path = SMB_STRDUP(orig_path))) {
return WERR_NOMEM;
}
p = strchr(path, '\\');
if ((p == NULL) || (p[1] == '\0')) {
/*
* No key behind the hive, just return the hive
*/
err = reg_openhive(mem_ctx, path, desired_access, token,
&hive);
if (!W_ERROR_IS_OK(err)) {
SAFE_FREE(path);
return err;
}
SAFE_FREE(path);
*pkey = hive;
return WERR_OK;
}
*p = '\0';
err = reg_openhive(mem_ctx, path, SEC_RIGHTS_ENUM_SUBKEYS, token,
&hive);
if (!W_ERROR_IS_OK(err)) {
SAFE_FREE(path);
return err;
}
err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
TALLOC_FREE(hive);
SAFE_FREE(path);
if (!W_ERROR_IS_OK(err)) {
return err;
}
*pkey = key;
return WERR_OK;
}
/* END */

View File

@ -45,45 +45,6 @@ REGISTRY_HOOK reg_hooks[] = {
{ NULL, NULL }
};
static struct generic_mapping reg_generic_map =
{ REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
/********************************************************************
********************************************************************/
static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
{
SEC_ACE ace[2];
SEC_ACCESS mask;
size_t i = 0;
SEC_DESC *sd;
SEC_ACL *acl;
size_t sd_size;
/* basic access for Everyone */
init_sec_access(&mask, REG_KEY_READ );
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
/* Full Access 'BUILTIN\Administrators' */
init_sec_access(&mask, REG_KEY_ALL );
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
/* create the security descriptor */
if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
return NULL;
if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
return NULL;
return sd;
}
/***********************************************************************
Open the registry database and initialize the REGISTRY_HOOK cache
***********************************************************************/
@ -123,231 +84,6 @@ BOOL init_registry( void )
return True;
}
/***********************************************************************
High level wrapper function for storing registry subkeys
***********************************************************************/
BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
{
if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys )
return key->hook->ops->store_subkeys( key->name, subkeys );
return False;
}
/***********************************************************************
High level wrapper function for storing registry values
***********************************************************************/
BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
if ( check_dynamic_reg_values( key ) )
return False;
if ( key->hook && key->hook->ops && key->hook->ops->store_values )
return key->hook->ops->store_values( key->name, val );
return False;
}
/***********************************************************************
High level wrapper function for enumerating registry subkeys
Initialize the TALLOC_CTX if necessary
***********************************************************************/
int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
{
int result = -1;
if ( key->hook && key->hook->ops && key->hook->ops->fetch_subkeys )
result = key->hook->ops->fetch_subkeys( key->name, subkey_ctr );
return result;
}
/***********************************************************************
High level wrapper function for enumerating registry values
***********************************************************************/
int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
int result = -1;
if ( key->hook && key->hook->ops && key->hook->ops->fetch_values )
result = key->hook->ops->fetch_values( key->name, val );
/* if the backend lookup returned no data, try the dynamic overlay */
if ( result == 0 ) {
result = fetch_dynamic_reg_values( key, val );
return ( result != -1 ) ? result : 0;
}
return result;
}
/***********************************************************************
High level access check for passing the required access mask to the
underlying registry backend
***********************************************************************/
BOOL regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
const struct nt_user_token *token )
{
SEC_DESC *sec_desc;
NTSTATUS status;
WERROR err;
TALLOC_CTX *mem_ctx;
/* use the default security check if the backend has not defined its
* own */
if (key->hook && key->hook->ops && key->hook->ops->reg_access_check) {
return key->hook->ops->reg_access_check( key->name, requested,
granted, token );
}
/*
* The secdesc routines can't yet cope with a NULL talloc ctx sanely.
*/
if (!(mem_ctx = talloc_init("regkey_access_check"))) {
return False;
}
err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
if (!W_ERROR_IS_OK(err)) {
TALLOC_FREE(mem_ctx);
return False;
}
se_map_generic( &requested, &reg_generic_map );
if (!se_access_check(sec_desc, token, requested, granted, &status)) {
TALLOC_FREE(mem_ctx);
return False;
}
TALLOC_FREE(mem_ctx);
return NT_STATUS_IS_OK(status);
}
/***********************************************************************
***********************************************************************/
static int regkey_destructor(REGISTRY_KEY *key)
{
return regdb_close();
}
WERROR regkey_open_onelevel( TALLOC_CTX *mem_ctx, struct registry_key *parent,
const char *name,
const struct nt_user_token *token,
uint32 access_desired,
struct registry_key **pregkey)
{
WERROR result = WERR_OK;
struct registry_key *regkey;
REGISTRY_KEY *key;
REGSUBKEY_CTR *subkeys = NULL;
DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
SMB_ASSERT(strchr(name, '\\') == NULL);
if (!(regkey = TALLOC_ZERO_P(mem_ctx, struct registry_key)) ||
!(regkey->token = dup_nt_token(regkey, token)) ||
!(regkey->key = TALLOC_ZERO_P(regkey, REGISTRY_KEY))) {
result = WERR_NOMEM;
goto done;
}
if ( !(W_ERROR_IS_OK(result = regdb_open())) ) {
goto done;
}
key = regkey->key;
talloc_set_destructor(key, regkey_destructor);
/* initialization */
key->type = REG_KEY_GENERIC;
if (name[0] == '\0') {
/*
* Open a copy of the parent key
*/
if (!parent) {
result = WERR_BADFILE;
goto done;
}
key->name = talloc_strdup(key, parent->key->name);
}
else {
/*
* Normal subkey open
*/
key->name = talloc_asprintf(key, "%s%s%s",
parent ? parent->key->name : "",
parent ? "\\": "",
name);
}
if (key->name == NULL) {
result = WERR_NOMEM;
goto done;
}
/* Tag this as a Performance Counter Key */
if( StrnCaseCmp(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
key->type = REG_KEY_HKPD;
/* Look up the table of registry I/O operations */
if ( !(key->hook = reghook_cache_find( key->name )) ) {
DEBUG(0,("reg_open_onelevel: Failed to assigned a "
"REGISTRY_HOOK to [%s]\n", key->name ));
result = WERR_BADFILE;
goto done;
}
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
result = WERR_NOMEM;
goto done;
}
if ( fetch_reg_keys( key, subkeys ) == -1 ) {
result = WERR_BADFILE;
goto done;
}
TALLOC_FREE( subkeys );
if ( !regkey_access_check( key, access_desired, &key->access_granted,
token ) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
*pregkey = regkey;
result = WERR_OK;
done:
if ( !W_ERROR_IS_OK(result) ) {
TALLOC_FREE(regkey);
}
return result;
}
WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
const char *path,
const struct nt_user_token *token,
@ -366,29 +102,6 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
return WERR_OK;
}
WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
struct security_descriptor **psecdesc)
{
struct security_descriptor *secdesc;
if (key->hook && key->hook->ops && key->hook->ops->get_secdesc) {
WERROR err;
err = key->hook->ops->get_secdesc(mem_ctx, key->name,
psecdesc);
if (W_ERROR_IS_OK(err)) {
return WERR_OK;
}
}
if (!(secdesc = construct_registry_sd(mem_ctx))) {
return WERR_NOMEM;
}
*psecdesc = secdesc;
return WERR_OK;
}
WERROR regkey_set_secdesc(REGISTRY_KEY *key,
struct security_descriptor *psecdesc)
{
@ -399,65 +112,6 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
return WERR_ACCESS_DENIED;
}
/*
* Utility function to open a complete registry path including the hive
* prefix. This should become the replacement function for
* regkey_open_internal.
*/
WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
uint32 desired_access, const struct nt_user_token *token,
struct registry_key **pkey)
{
struct registry_key *hive, *key;
char *path, *p;
WERROR err;
if (!(path = SMB_STRDUP(orig_path))) {
return WERR_NOMEM;
}
p = strchr(path, '\\');
if ((p == NULL) || (p[1] == '\0')) {
/*
* No key behind the hive, just return the hive
*/
err = reg_openhive(mem_ctx, path, desired_access, token,
&hive);
if (!W_ERROR_IS_OK(err)) {
SAFE_FREE(path);
return err;
}
SAFE_FREE(path);
*pkey = hive;
return WERR_OK;
}
*p = '\0';
err = reg_openhive(mem_ctx, path, SEC_RIGHTS_ENUM_SUBKEYS, token,
&hive);
if (!W_ERROR_IS_OK(err)) {
SAFE_FREE(path);
return err;
}
err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
TALLOC_FREE(hive);
SAFE_FREE(path);
if (!W_ERROR_IS_OK(err)) {
return err;
}
*pkey = key;
return WERR_OK;
}
/*
* Utility function to create a registry key without opening the hive
* before. Assumes the hive already exists.

View File

@ -0,0 +1,315 @@
/*
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Gerald Carter 2002-2005
* Copyright (C) Michael Adam 2006
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Implementation of registry frontend view functions.
* Functions moved from reg_frontend.c to minimize linker deps.
*/
#include "includes.h"
static struct generic_mapping reg_generic_map =
{ REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
/********************************************************************
********************************************************************/
static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
{
SEC_ACE ace[2];
SEC_ACCESS mask;
size_t i = 0;
SEC_DESC *sd;
SEC_ACL *acl;
size_t sd_size;
/* basic access for Everyone */
init_sec_access(&mask, REG_KEY_READ );
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
/* Full Access 'BUILTIN\Administrators' */
init_sec_access(&mask, REG_KEY_ALL );
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
/* create the security descriptor */
if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
return NULL;
if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
return NULL;
return sd;
}
/***********************************************************************
High level wrapper function for storing registry subkeys
***********************************************************************/
BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
{
if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys )
return key->hook->ops->store_subkeys( key->name, subkeys );
return False;
}
/***********************************************************************
High level wrapper function for storing registry values
***********************************************************************/
BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
if ( check_dynamic_reg_values( key ) )
return False;
if ( key->hook && key->hook->ops && key->hook->ops->store_values )
return key->hook->ops->store_values( key->name, val );
return False;
}
/***********************************************************************
High level wrapper function for enumerating registry subkeys
Initialize the TALLOC_CTX if necessary
***********************************************************************/
int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
{
int result = -1;
if ( key->hook && key->hook->ops && key->hook->ops->fetch_subkeys )
result = key->hook->ops->fetch_subkeys( key->name, subkey_ctr );
return result;
}
/***********************************************************************
High level wrapper function for enumerating registry values
***********************************************************************/
int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
int result = -1;
if ( key->hook && key->hook->ops && key->hook->ops->fetch_values )
result = key->hook->ops->fetch_values( key->name, val );
/* if the backend lookup returned no data, try the dynamic overlay */
if ( result == 0 ) {
result = fetch_dynamic_reg_values( key, val );
return ( result != -1 ) ? result : 0;
}
return result;
}
/***********************************************************************
High level access check for passing the required access mask to the
underlying registry backend
***********************************************************************/
BOOL regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
const struct nt_user_token *token )
{
SEC_DESC *sec_desc;
NTSTATUS status;
WERROR err;
TALLOC_CTX *mem_ctx;
/* use the default security check if the backend has not defined its
* own */
if (key->hook && key->hook->ops && key->hook->ops->reg_access_check) {
return key->hook->ops->reg_access_check( key->name, requested,
granted, token );
}
/*
* The secdesc routines can't yet cope with a NULL talloc ctx sanely.
*/
if (!(mem_ctx = talloc_init("regkey_access_check"))) {
return False;
}
err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
if (!W_ERROR_IS_OK(err)) {
TALLOC_FREE(mem_ctx);
return False;
}
se_map_generic( &requested, &reg_generic_map );
if (!se_access_check(sec_desc, token, requested, granted, &status)) {
TALLOC_FREE(mem_ctx);
return False;
}
TALLOC_FREE(mem_ctx);
return NT_STATUS_IS_OK(status);
}
/***********************************************************************
***********************************************************************/
static int regkey_destructor(REGISTRY_KEY *key)
{
return regdb_close();
}
WERROR regkey_open_onelevel( TALLOC_CTX *mem_ctx, struct registry_key *parent,
const char *name,
const struct nt_user_token *token,
uint32 access_desired,
struct registry_key **pregkey)
{
WERROR result = WERR_OK;
struct registry_key *regkey;
REGISTRY_KEY *key;
REGSUBKEY_CTR *subkeys = NULL;
DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
SMB_ASSERT(strchr(name, '\\') == NULL);
if (!(regkey = TALLOC_ZERO_P(mem_ctx, struct registry_key)) ||
!(regkey->token = dup_nt_token(regkey, token)) ||
!(regkey->key = TALLOC_ZERO_P(regkey, REGISTRY_KEY))) {
result = WERR_NOMEM;
goto done;
}
if ( !(W_ERROR_IS_OK(result = regdb_open())) ) {
goto done;
}
key = regkey->key;
talloc_set_destructor(key, regkey_destructor);
/* initialization */
key->type = REG_KEY_GENERIC;
if (name[0] == '\0') {
/*
* Open a copy of the parent key
*/
if (!parent) {
result = WERR_BADFILE;
goto done;
}
key->name = talloc_strdup(key, parent->key->name);
}
else {
/*
* Normal subkey open
*/
key->name = talloc_asprintf(key, "%s%s%s",
parent ? parent->key->name : "",
parent ? "\\": "",
name);
}
if (key->name == NULL) {
result = WERR_NOMEM;
goto done;
}
/* Tag this as a Performance Counter Key */
if( StrnCaseCmp(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
key->type = REG_KEY_HKPD;
/* Look up the table of registry I/O operations */
if ( !(key->hook = reghook_cache_find( key->name )) ) {
DEBUG(0,("reg_open_onelevel: Failed to assigned a "
"REGISTRY_HOOK to [%s]\n", key->name ));
result = WERR_BADFILE;
goto done;
}
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
result = WERR_NOMEM;
goto done;
}
if ( fetch_reg_keys( key, subkeys ) == -1 ) {
result = WERR_BADFILE;
goto done;
}
TALLOC_FREE( subkeys );
if ( !regkey_access_check( key, access_desired, &key->access_granted,
token ) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
*pregkey = regkey;
result = WERR_OK;
done:
if ( !W_ERROR_IS_OK(result) ) {
TALLOC_FREE(regkey);
}
return result;
}
WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
struct security_descriptor **psecdesc)
{
struct security_descriptor *secdesc;
if (key->hook && key->hook->ops && key->hook->ops->get_secdesc) {
WERROR err;
err = key->hook->ops->get_secdesc(mem_ctx, key->name,
psecdesc);
if (W_ERROR_IS_OK(err)) {
return WERR_OK;
}
}
if (!(secdesc = construct_registry_sd(mem_ctx))) {
return WERR_NOMEM;
}
*psecdesc = secdesc;
return WERR_OK;
}
/* END */

View File

@ -85,6 +85,7 @@ int opt_attrs = 0;
int opt_timestamps = 0;
const char *opt_exclude = NULL;
const char *opt_destination = NULL;
BOOL opt_testmode = False;
BOOL opt_have_ip = False;
struct in_addr opt_dest_ip;
@ -871,6 +872,7 @@ static struct functable net_func[] = {
{"STATUS", net_status},
{"USERSHARE", net_usershare},
{"USERSIDLIST", net_usersidlist},
{"CONF", net_conf},
#ifdef WITH_FAKE_KASERVER
{"AFS", net_afs},
#endif
@ -912,6 +914,7 @@ static struct functable net_func[] = {
{"machine-pass",'P', POPT_ARG_NONE, &opt_machine_pass},
{"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
{"verbose", 'v', POPT_ARG_NONE, &opt_verbose},
{"test", 'T', POPT_ARG_NONE, &opt_testmode},
/* Options for 'net groupmap set' */
{"local", 'L', POPT_ARG_NONE, &opt_localgroup},
{"domain", 'D', POPT_ARG_NONE, &opt_domaingroup},

View File

@ -114,6 +114,7 @@ extern int opt_attrs;
extern int opt_timestamps;
extern const char *opt_exclude;
extern const char *opt_destination;
extern BOOL opt_testmode;
extern BOOL opt_have_ip;
extern struct in_addr opt_dest_ip;

1118
source/utils/net_conf.c Normal file

File diff suppressed because it is too large Load Diff