mirror of
https://github.com/samba-team/samba.git
synced 2025-02-24 13:57:43 +03:00
s3-services: Migrated svcctl registry functions to winreg.
This is a bigger commit. It moves the relevant function to svc_winreg_glue. We need to use them in the same commit else we have problems with prototypes in proto.h. Signed-off-by: Günther Deschner <gd@samba.org>
This commit is contained in:
parent
1adbbeef32
commit
96565db5f6
@ -688,7 +688,8 @@ RPC_WKSSVC_OBJ = librpc/gen_ndr/srv_wkssvc.o \
|
|||||||
|
|
||||||
RPC_SVCCTL_OBJ = rpc_server/srv_svcctl_nt.o \
|
RPC_SVCCTL_OBJ = rpc_server/srv_svcctl_nt.o \
|
||||||
librpc/gen_ndr/srv_svcctl.o \
|
librpc/gen_ndr/srv_svcctl.o \
|
||||||
services/svc_spoolss.o services/svc_rcinit.o services/services_db.o \
|
services/svc_winreg_glue.o \
|
||||||
|
services/svc_spoolss.o services/svc_rcinit.o \
|
||||||
services/svc_netlogon.o services/svc_winreg.o \
|
services/svc_netlogon.o services/svc_winreg.o \
|
||||||
services/svc_wins.o
|
services/svc_wins.o
|
||||||
|
|
||||||
|
@ -4412,18 +4412,6 @@ bool init_service_op_table( void );
|
|||||||
/* The following definitions come from rpcclient/rpcclient.c */
|
/* The following definitions come from rpcclient/rpcclient.c */
|
||||||
|
|
||||||
|
|
||||||
/* The following definitions come from services/services_db.c */
|
|
||||||
|
|
||||||
void svcctl_init_keys( void );
|
|
||||||
struct security_descriptor *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, struct security_token *token );
|
|
||||||
bool svcctl_set_secdesc(const char *name, struct security_descriptor *sec_desc,
|
|
||||||
struct security_token *token);
|
|
||||||
const char *svcctl_get_string_value(TALLOC_CTX *ctx, const char *key_name,
|
|
||||||
const char *value_name,
|
|
||||||
struct security_token *token);
|
|
||||||
const char *svcctl_lookup_dispname(TALLOC_CTX *ctx, const char *name, struct security_token *token );
|
|
||||||
const char *svcctl_lookup_description(TALLOC_CTX *ctx, const char *name, struct security_token *token );
|
|
||||||
|
|
||||||
/* The following definitions come from services/svc_netlogon.c */
|
/* The following definitions come from services/svc_netlogon.c */
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "../librpc/gen_ndr/srv_ntsvcs.h"
|
#include "../librpc/gen_ndr/srv_ntsvcs.h"
|
||||||
|
#include "services/svc_winreg_glue.h"
|
||||||
|
|
||||||
#undef DBGC_CLASS
|
#undef DBGC_CLASS
|
||||||
#define DBGC_CLASS DBGC_RPC_SRV
|
#define DBGC_CLASS DBGC_RPC_SRV
|
||||||
@ -142,7 +143,10 @@ WERROR _PNP_GetDeviceRegProp(struct pipes_struct *p,
|
|||||||
|
|
||||||
mem_ctx = talloc_stackframe();
|
mem_ctx = talloc_stackframe();
|
||||||
|
|
||||||
result = svcctl_lookup_dispname(mem_ctx, ptr, p->server_info->ptok);
|
result = svcctl_lookup_dispname(mem_ctx,
|
||||||
|
p->msg_ctx,
|
||||||
|
p->server_info,
|
||||||
|
ptr);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
return WERR_GENERAL_FAILURE;
|
return WERR_GENERAL_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,10 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "../librpc/gen_ndr/srv_svcctl.h"
|
#include "../librpc/gen_ndr/srv_svcctl.h"
|
||||||
#include "services/services.h"
|
|
||||||
#include "../libcli/security/security.h"
|
#include "../libcli/security/security.h"
|
||||||
#include "../librpc/gen_ndr/ndr_security.h"
|
#include "../librpc/gen_ndr/ndr_security.h"
|
||||||
|
#include "services/services.h"
|
||||||
|
#include "services/svc_winreg_glue.h"
|
||||||
|
|
||||||
#undef DBGC_CLASS
|
#undef DBGC_CLASS
|
||||||
#define DBGC_CLASS DBGC_RPC_SRV
|
#define DBGC_CLASS DBGC_RPC_SRV
|
||||||
@ -301,11 +302,19 @@ WERROR _svcctl_OpenServiceW(struct pipes_struct *p,
|
|||||||
if ( !find_service_info_by_hnd( p, r->in.scmanager_handle) )
|
if ( !find_service_info_by_hnd( p, r->in.scmanager_handle) )
|
||||||
return WERR_BADFID;
|
return WERR_BADFID;
|
||||||
|
|
||||||
/* perform access checks. Use the root token in order to ensure that we
|
/*
|
||||||
retrieve the security descriptor */
|
* Perform access checks. Use the system server_info in order to ensure
|
||||||
|
* that we retrieve the security descriptor
|
||||||
if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) )
|
*/
|
||||||
|
sec_desc = svcctl_get_secdesc(p->mem_ctx,
|
||||||
|
p->msg_ctx,
|
||||||
|
get_server_info_system(),
|
||||||
|
service);
|
||||||
|
if (sec_desc == NULL) {
|
||||||
|
DEBUG(0, ("_svcctl_OpenServiceW: Failed to get a valid security "
|
||||||
|
"descriptor"));
|
||||||
return WERR_NOMEM;
|
return WERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
se_map_generic( &r->in.access_mask, &svc_generic_map );
|
se_map_generic( &r->in.access_mask, &svc_generic_map );
|
||||||
status = svcctl_access_check( sec_desc, p->server_info->ptok,
|
status = svcctl_access_check( sec_desc, p->server_info->ptok,
|
||||||
@ -349,8 +358,10 @@ WERROR _svcctl_GetServiceDisplayNameW(struct pipes_struct *p,
|
|||||||
|
|
||||||
service = r->in.service_name;
|
service = r->in.service_name;
|
||||||
|
|
||||||
display_name = svcctl_lookup_dispname(p->mem_ctx, service,
|
display_name = svcctl_lookup_dispname(p->mem_ctx,
|
||||||
p->server_info->ptok);
|
p->msg_ctx,
|
||||||
|
p->server_info,
|
||||||
|
service);
|
||||||
if (!display_name) {
|
if (!display_name) {
|
||||||
display_name = "";
|
display_name = "";
|
||||||
}
|
}
|
||||||
@ -386,7 +397,10 @@ WERROR _svcctl_QueryServiceStatus(struct pipes_struct *p,
|
|||||||
/********************************************************************
|
/********************************************************************
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static int enumerate_status( TALLOC_CTX *ctx, struct ENUM_SERVICE_STATUSW **status, struct security_token *token )
|
static int enumerate_status(TALLOC_CTX *ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
struct auth_serversupplied_info *server_info,
|
||||||
|
struct ENUM_SERVICE_STATUSW **status)
|
||||||
{
|
{
|
||||||
int num_services = 0;
|
int num_services = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -405,7 +419,10 @@ static int enumerate_status( TALLOC_CTX *ctx, struct ENUM_SERVICE_STATUSW **stat
|
|||||||
for ( i=0; i<num_services; i++ ) {
|
for ( i=0; i<num_services; i++ ) {
|
||||||
st[i].service_name = talloc_strdup(st, svcctl_ops[i].name );
|
st[i].service_name = talloc_strdup(st, svcctl_ops[i].name );
|
||||||
|
|
||||||
display_name = svcctl_lookup_dispname(ctx, svcctl_ops[i].name, token );
|
display_name = svcctl_lookup_dispname(ctx,
|
||||||
|
msg_ctx,
|
||||||
|
server_info,
|
||||||
|
svcctl_ops[i].name);
|
||||||
st[i].display_name = talloc_strdup(st, display_name ? display_name : "");
|
st[i].display_name = talloc_strdup(st, display_name ? display_name : "");
|
||||||
|
|
||||||
svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
|
svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
|
||||||
@ -429,7 +446,6 @@ WERROR _svcctl_EnumServicesStatusW(struct pipes_struct *p,
|
|||||||
size_t buffer_size = 0;
|
size_t buffer_size = 0;
|
||||||
WERROR result = WERR_OK;
|
WERROR result = WERR_OK;
|
||||||
SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
|
SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
|
||||||
struct security_token *token = p->server_info->ptok;
|
|
||||||
DATA_BLOB blob = data_blob_null;
|
DATA_BLOB blob = data_blob_null;
|
||||||
|
|
||||||
/* perform access checks */
|
/* perform access checks */
|
||||||
@ -441,7 +457,10 @@ WERROR _svcctl_EnumServicesStatusW(struct pipes_struct *p,
|
|||||||
return WERR_ACCESS_DENIED;
|
return WERR_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_services = enumerate_status( p->mem_ctx, &services, token );
|
num_services = enumerate_status(p->mem_ctx,
|
||||||
|
p->msg_ctx,
|
||||||
|
p->server_info,
|
||||||
|
&services);
|
||||||
if (num_services == -1 ) {
|
if (num_services == -1 ) {
|
||||||
return WERR_NOMEM;
|
return WERR_NOMEM;
|
||||||
}
|
}
|
||||||
@ -639,23 +658,36 @@ WERROR _svcctl_QueryServiceStatusEx(struct pipes_struct *p,
|
|||||||
/********************************************************************
|
/********************************************************************
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name,
|
static WERROR fill_svc_config(TALLOC_CTX *ctx,
|
||||||
struct QUERY_SERVICE_CONFIG *config,
|
struct messaging_context *msg_ctx,
|
||||||
struct security_token *token )
|
struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name,
|
||||||
|
struct QUERY_SERVICE_CONFIG *config)
|
||||||
{
|
{
|
||||||
TALLOC_CTX *mem_ctx = talloc_stackframe();
|
TALLOC_CTX *mem_ctx = talloc_stackframe();
|
||||||
const char *result = NULL;
|
const char *result = NULL;
|
||||||
|
|
||||||
/* now fill in the individual values */
|
/* now fill in the individual values */
|
||||||
|
|
||||||
config->displayname = svcctl_lookup_dispname(mem_ctx, name, token);
|
config->displayname = svcctl_lookup_dispname(mem_ctx,
|
||||||
|
msg_ctx,
|
||||||
|
server_info,
|
||||||
|
name);
|
||||||
|
|
||||||
result = svcctl_get_string_value(mem_ctx, name, "ObjectName", token);
|
result = svcctl_get_string_value(mem_ctx,
|
||||||
|
msg_ctx,
|
||||||
|
server_info,
|
||||||
|
name,
|
||||||
|
"ObjectName");
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
config->startname = result;
|
config->startname = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = svcctl_get_string_value(mem_ctx, name, "ImagePath", token);
|
result = svcctl_get_string_value(mem_ctx,
|
||||||
|
msg_ctx,
|
||||||
|
server_info,
|
||||||
|
name,
|
||||||
|
"ImagePath");
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
config->executablepath = result;
|
config->executablepath = result;
|
||||||
}
|
}
|
||||||
@ -708,8 +740,11 @@ WERROR _svcctl_QueryServiceConfigW(struct pipes_struct *p,
|
|||||||
|
|
||||||
*r->out.needed = r->in.offered;
|
*r->out.needed = r->in.offered;
|
||||||
|
|
||||||
wresult = fill_svc_config( p->mem_ctx, info->name, r->out.query,
|
wresult = fill_svc_config(p->mem_ctx,
|
||||||
p->server_info->ptok);
|
p->msg_ctx,
|
||||||
|
p->server_info,
|
||||||
|
info->name,
|
||||||
|
r->out.query);
|
||||||
if ( !W_ERROR_IS_OK(wresult) )
|
if ( !W_ERROR_IS_OK(wresult) )
|
||||||
return wresult;
|
return wresult;
|
||||||
|
|
||||||
@ -754,8 +789,10 @@ WERROR _svcctl_QueryServiceConfig2W(struct pipes_struct *p,
|
|||||||
enum ndr_err_code ndr_err;
|
enum ndr_err_code ndr_err;
|
||||||
DATA_BLOB blob;
|
DATA_BLOB blob;
|
||||||
|
|
||||||
description = svcctl_lookup_description(
|
description = svcctl_lookup_description(p->mem_ctx,
|
||||||
p->mem_ctx, info->name, p->server_info->ptok);
|
p->msg_ctx,
|
||||||
|
p->server_info,
|
||||||
|
info->name);
|
||||||
|
|
||||||
desc_buf.description = description;
|
desc_buf.description = description;
|
||||||
|
|
||||||
@ -874,10 +911,14 @@ WERROR _svcctl_QueryServiceObjectSecurity(struct pipes_struct *p,
|
|||||||
if ( (r->in.security_flags & SECINFO_DACL) != SECINFO_DACL )
|
if ( (r->in.security_flags & SECINFO_DACL) != SECINFO_DACL )
|
||||||
return WERR_INVALID_PARAM;
|
return WERR_INVALID_PARAM;
|
||||||
|
|
||||||
/* lookup the security descriptor and marshall it up for a reply */
|
/* Lookup the security descriptor and marshall it up for a reply */
|
||||||
|
sec_desc = svcctl_get_secdesc(p->mem_ctx,
|
||||||
if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) )
|
p->msg_ctx,
|
||||||
return WERR_NOMEM;
|
get_server_info_system(),
|
||||||
|
info->name);
|
||||||
|
if (sec_desc == NULL) {
|
||||||
|
return WERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
*r->out.needed = ndr_size_security_descriptor(sec_desc, 0);
|
*r->out.needed = ndr_size_security_descriptor(sec_desc, 0);
|
||||||
|
|
||||||
@ -949,7 +990,7 @@ WERROR _svcctl_SetServiceObjectSecurity(struct pipes_struct *p,
|
|||||||
|
|
||||||
/* store the new SD */
|
/* store the new SD */
|
||||||
|
|
||||||
if (!svcctl_set_secdesc(info->name, sec_desc, p->server_info->ptok))
|
if (!svcctl_set_secdesc(p->msg_ctx, p->server_info, info->name, sec_desc))
|
||||||
return WERR_ACCESS_DENIED;
|
return WERR_ACCESS_DENIED;
|
||||||
|
|
||||||
return WERR_OK;
|
return WERR_OK;
|
||||||
|
364
source3/services/svc_winreg_glue.c
Normal file
364
source3/services/svc_winreg_glue.c
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
/*
|
||||||
|
* Unix SMB/CIFS implementation.
|
||||||
|
*
|
||||||
|
* SVC winreg glue
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Marcin Krzysztof Porwit
|
||||||
|
* Copyright (c) 2005 Gerald (Jerry) Carter
|
||||||
|
* Copyright (c) 2011 Andreas Schneider <asn@samba.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "services/services.h"
|
||||||
|
#include "services/svc_winreg_glue.h"
|
||||||
|
#include "rpc_client/cli_winreg_int.h"
|
||||||
|
#include "rpc_client/cli_winreg.h"
|
||||||
|
#include "../librpc/gen_ndr/ndr_winreg_c.h"
|
||||||
|
#include "../libcli/security/security.h"
|
||||||
|
|
||||||
|
#define TOP_LEVEL_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
|
||||||
|
|
||||||
|
struct security_descriptor* svcctl_gen_service_sd(TALLOC_CTX *mem_ctx)
|
||||||
|
{
|
||||||
|
struct security_descriptor *sd = NULL;
|
||||||
|
struct security_acl *theacl = NULL;
|
||||||
|
struct security_ace ace[4];
|
||||||
|
size_t sd_size;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
/* Basic access for everyone */
|
||||||
|
init_sec_ace(&ace[i++], &global_sid_World,
|
||||||
|
SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_READ_ACCESS, 0);
|
||||||
|
|
||||||
|
init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users,
|
||||||
|
SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_EXECUTE_ACCESS, 0);
|
||||||
|
|
||||||
|
init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators,
|
||||||
|
SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_ALL_ACCESS, 0);
|
||||||
|
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
|
||||||
|
SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_ALL_ACCESS, 0);
|
||||||
|
|
||||||
|
/* Create the security descriptor */
|
||||||
|
theacl = make_sec_acl(mem_ctx,
|
||||||
|
NT4_ACL_REVISION,
|
||||||
|
i,
|
||||||
|
ace);
|
||||||
|
if (theacl == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd = make_sec_desc(mem_ctx,
|
||||||
|
SECURITY_DESCRIPTOR_REVISION_1,
|
||||||
|
SEC_DESC_SELF_RELATIVE,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
theacl,
|
||||||
|
&sd_size);
|
||||||
|
if (sd == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct security_descriptor *svcctl_get_secdesc(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
struct dcerpc_binding_handle *h = NULL;
|
||||||
|
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||||
|
struct policy_handle hive_hnd, key_hnd;
|
||||||
|
struct security_descriptor *sd = NULL;
|
||||||
|
char *key = NULL;
|
||||||
|
NTSTATUS status;
|
||||||
|
WERROR result = WERR_OK;
|
||||||
|
|
||||||
|
key = talloc_asprintf(mem_ctx,
|
||||||
|
"%s\\%s\\Security",
|
||||||
|
TOP_LEVEL_SERVICES_KEY, name);
|
||||||
|
if (key == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dcerpc_winreg_int_hklm_openkey(mem_ctx,
|
||||||
|
server_info,
|
||||||
|
msg_ctx,
|
||||||
|
&h,
|
||||||
|
key,
|
||||||
|
false,
|
||||||
|
access_mask,
|
||||||
|
&hive_hnd,
|
||||||
|
&key_hnd,
|
||||||
|
&result);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
|
||||||
|
key, nt_errstr(status)));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
|
||||||
|
key, win_errstr(result)));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dcerpc_winreg_query_sd(mem_ctx,
|
||||||
|
h,
|
||||||
|
&key_hnd,
|
||||||
|
"Security",
|
||||||
|
&sd,
|
||||||
|
&result);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(0, ("svcctl_get_secdesc: error getting value 'Security': "
|
||||||
|
"%s\n", nt_errstr(status)));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
|
||||||
|
goto fallback_to_default_sd;
|
||||||
|
} else if (!W_ERROR_IS_OK(result)) {
|
||||||
|
DEBUG(0, ("svcctl_get_secdesc: error getting value 'Security': "
|
||||||
|
"%s\n", win_errstr(result)));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
fallback_to_default_sd:
|
||||||
|
DEBUG(6, ("svcctl_get_secdesc: constructing default secdesc for "
|
||||||
|
"service [%s]\n", name));
|
||||||
|
sd = svcctl_gen_service_sd(mem_ctx);
|
||||||
|
|
||||||
|
done:
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name,
|
||||||
|
struct security_descriptor *sd)
|
||||||
|
{
|
||||||
|
struct dcerpc_binding_handle *h = NULL;
|
||||||
|
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||||
|
struct policy_handle hive_hnd, key_hnd;
|
||||||
|
char *key = NULL;
|
||||||
|
bool ok = false;
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
NTSTATUS status;
|
||||||
|
WERROR result = WERR_OK;
|
||||||
|
|
||||||
|
tmp_ctx = talloc_stackframe();
|
||||||
|
if (tmp_ctx == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = talloc_asprintf(tmp_ctx, "%s\\%s", TOP_LEVEL_SERVICES_KEY, name);
|
||||||
|
if (key == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
|
||||||
|
server_info,
|
||||||
|
msg_ctx,
|
||||||
|
&h,
|
||||||
|
key,
|
||||||
|
false,
|
||||||
|
access_mask,
|
||||||
|
&hive_hnd,
|
||||||
|
&key_hnd,
|
||||||
|
&result);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
|
||||||
|
key, nt_errstr(status)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
DEBUG(0, ("svcctl_set_secdesc: Could not open %s - %s\n",
|
||||||
|
key, win_errstr(result)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_valid_policy_hnd(&key_hnd)) {
|
||||||
|
dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
enum winreg_CreateAction action = REG_ACTION_NONE;
|
||||||
|
struct winreg_String wkey;
|
||||||
|
struct winreg_String wkeyclass;
|
||||||
|
|
||||||
|
wkey.name = talloc_asprintf(tmp_ctx, "%s\\Security", key);
|
||||||
|
if (wkey.name == NULL) {
|
||||||
|
result = WERR_NOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZERO_STRUCT(wkeyclass);
|
||||||
|
wkeyclass.name = "";
|
||||||
|
|
||||||
|
status = dcerpc_winreg_CreateKey(h,
|
||||||
|
tmp_ctx,
|
||||||
|
&hive_hnd,
|
||||||
|
wkey,
|
||||||
|
wkeyclass,
|
||||||
|
0,
|
||||||
|
access_mask,
|
||||||
|
NULL,
|
||||||
|
&key_hnd,
|
||||||
|
&action,
|
||||||
|
&result);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(0, ("svcctl_set_secdesc: Could not create key %s: %s\n",
|
||||||
|
wkey.name, nt_errstr(status)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
DEBUG(0, ("svcctl_set_secdesc: Could not create key %s: %s\n",
|
||||||
|
wkey.name, win_errstr(result)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dcerpc_winreg_set_sd(tmp_ctx,
|
||||||
|
h,
|
||||||
|
&key_hnd,
|
||||||
|
"Security",
|
||||||
|
sd,
|
||||||
|
&result);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = true;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (is_valid_policy_hnd(&key_hnd)) {
|
||||||
|
dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
talloc_free(tmp_ctx);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *svcctl_get_string_value(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *key_name,
|
||||||
|
const char *value_name)
|
||||||
|
{
|
||||||
|
struct dcerpc_binding_handle *h = NULL;
|
||||||
|
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||||
|
struct policy_handle hive_hnd, key_hnd;
|
||||||
|
const char *data = NULL;
|
||||||
|
char *path = NULL;
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
NTSTATUS status;
|
||||||
|
WERROR result = WERR_OK;
|
||||||
|
|
||||||
|
tmp_ctx = talloc_stackframe();
|
||||||
|
if (tmp_ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path = talloc_asprintf(tmp_ctx, "%s\\%s",
|
||||||
|
TOP_LEVEL_SERVICES_KEY, key_name);
|
||||||
|
if (path == NULL) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
|
||||||
|
server_info,
|
||||||
|
msg_ctx,
|
||||||
|
&h,
|
||||||
|
path,
|
||||||
|
false,
|
||||||
|
access_mask,
|
||||||
|
&hive_hnd,
|
||||||
|
&key_hnd,
|
||||||
|
&result);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(0, ("svcctl_get_string_value: Could not open %s - %s\n",
|
||||||
|
path, nt_errstr(status)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!W_ERROR_IS_OK(result)) {
|
||||||
|
DEBUG(0, ("svcctl_get_string_value: Could not open %s - %s\n",
|
||||||
|
path, win_errstr(result)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = dcerpc_winreg_query_sz(mem_ctx,
|
||||||
|
h,
|
||||||
|
&key_hnd,
|
||||||
|
value_name,
|
||||||
|
&data,
|
||||||
|
&result);
|
||||||
|
|
||||||
|
done:
|
||||||
|
talloc_free(tmp_ctx);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
const char *svcctl_lookup_dispname(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
const char *display_name = NULL;
|
||||||
|
|
||||||
|
display_name = svcctl_get_string_value(mem_ctx,
|
||||||
|
msg_ctx,
|
||||||
|
server_info,
|
||||||
|
name,
|
||||||
|
"DisplayName");
|
||||||
|
|
||||||
|
if (display_name == NULL) {
|
||||||
|
display_name = talloc_strdup(mem_ctx, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return display_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
********************************************************************/
|
||||||
|
|
||||||
|
const char *svcctl_lookup_description(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
const char *description = NULL;
|
||||||
|
|
||||||
|
description = svcctl_get_string_value(mem_ctx,
|
||||||
|
msg_ctx,
|
||||||
|
server_info,
|
||||||
|
name,
|
||||||
|
"Description");
|
||||||
|
|
||||||
|
if (description == NULL) {
|
||||||
|
description = talloc_strdup(mem_ctx, "Unix Service");
|
||||||
|
}
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
|
57
source3/services/svc_winreg_glue.h
Normal file
57
source3/services/svc_winreg_glue.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Unix SMB/CIFS implementation.
|
||||||
|
*
|
||||||
|
* SVC winreg glue
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Marcin Krzysztof Porwit
|
||||||
|
* Copyright (c) 2005 Gerald (Jerry) Carter
|
||||||
|
* Copyright (c) 2011 Andreas Schneider <asn@samba.org>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SVC_WINREG_GLUE_H
|
||||||
|
#define SVC_WINREG_GLUE_H
|
||||||
|
|
||||||
|
struct security_descriptor* svcctl_gen_service_sd(TALLOC_CTX *mem_ctx);
|
||||||
|
|
||||||
|
struct security_descriptor *svcctl_get_secdesc(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name,
|
||||||
|
struct security_descriptor *sd);
|
||||||
|
|
||||||
|
const char *svcctl_get_string_value(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *key_name,
|
||||||
|
const char *value_name);
|
||||||
|
|
||||||
|
const char *svcctl_lookup_dispname(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
const char *svcctl_lookup_description(TALLOC_CTX *mem_ctx,
|
||||||
|
struct messaging_context *msg_ctx,
|
||||||
|
const struct auth_serversupplied_info *server_info,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
#endif /* SVC_WINREG_GLUE_H */
|
||||||
|
|
||||||
|
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
|
Loading…
x
Reference in New Issue
Block a user