summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2011-01-31 16:40:33 +0100
committerGünther Deschner <gd@samba.org>2011-02-07 12:32:01 +0100
commit96565db5f66f791968ed354fc8f39464ff0a7e5a (patch)
tree998a39f6de96ef7f320c0ff9fe57d5a8a1a0ad81
parent1adbbeef32b71450b6c878ea34b431d19ea39523 (diff)
downloadsamba-96565db5f66f791968ed354fc8f39464ff0a7e5a.tar.gz
samba-96565db5f66f791968ed354fc8f39464ff0a7e5a.tar.bz2
samba-96565db5f66f791968ed354fc8f39464ff0a7e5a.zip
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>
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/proto.h12
-rw-r--r--source3/rpc_server/srv_ntsvcs_nt.c6
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c93
-rw-r--r--source3/services/svc_winreg_glue.c364
-rw-r--r--source3/services/svc_winreg_glue.h57
6 files changed, 495 insertions, 40 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index ad7690771b..92687f0ba2 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -688,7 +688,8 @@ RPC_WKSSVC_OBJ = librpc/gen_ndr/srv_wkssvc.o \
RPC_SVCCTL_OBJ = rpc_server/srv_svcctl_nt.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_wins.o
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 94cd0a9867..4094df7769 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4412,18 +4412,6 @@ bool init_service_op_table( void );
/* 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 */
diff --git a/source3/rpc_server/srv_ntsvcs_nt.c b/source3/rpc_server/srv_ntsvcs_nt.c
index a948b86c21..4933cb31a5 100644
--- a/source3/rpc_server/srv_ntsvcs_nt.c
+++ b/source3/rpc_server/srv_ntsvcs_nt.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "../librpc/gen_ndr/srv_ntsvcs.h"
+#include "services/svc_winreg_glue.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -142,7 +143,10 @@ WERROR _PNP_GetDeviceRegProp(struct pipes_struct *p,
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) {
return WERR_GENERAL_FAILURE;
}
diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index 2a7ef81645..cc6cf84eb6 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -24,9 +24,10 @@
#include "includes.h"
#include "../librpc/gen_ndr/srv_svcctl.h"
-#include "services/services.h"
#include "../libcli/security/security.h"
#include "../librpc/gen_ndr/ndr_security.h"
+#include "services/services.h"
+#include "services/svc_winreg_glue.h"
#undef DBGC_CLASS
#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) )
return WERR_BADFID;
- /* perform access checks. Use the root token in order to ensure that we
- retrieve the security descriptor */
-
- if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) )
+ /*
+ * Perform access checks. Use the system server_info in order to ensure
+ * that we retrieve the security descriptor
+ */
+ 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;
+ }
se_map_generic( &r->in.access_mask, &svc_generic_map );
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;
- display_name = svcctl_lookup_dispname(p->mem_ctx, service,
- p->server_info->ptok);
+ display_name = svcctl_lookup_dispname(p->mem_ctx,
+ p->msg_ctx,
+ p->server_info,
+ service);
if (!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 i;
@@ -405,7 +419,10 @@ static int enumerate_status( TALLOC_CTX *ctx, struct ENUM_SERVICE_STATUSW **stat
for ( i=0; i<num_services; i++ ) {
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 : "");
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;
WERROR result = WERR_OK;
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;
/* perform access checks */
@@ -441,7 +457,10 @@ WERROR _svcctl_EnumServicesStatusW(struct pipes_struct *p,
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 ) {
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,
- struct QUERY_SERVICE_CONFIG *config,
- struct security_token *token )
+static WERROR fill_svc_config(TALLOC_CTX *ctx,
+ struct messaging_context *msg_ctx,
+ struct auth_serversupplied_info *server_info,
+ const char *name,
+ struct QUERY_SERVICE_CONFIG *config)
{
TALLOC_CTX *mem_ctx = talloc_stackframe();
const char *result = NULL;
/* 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) {
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) {
config->executablepath = result;
}
@@ -708,8 +740,11 @@ WERROR _svcctl_QueryServiceConfigW(struct pipes_struct *p,
*r->out.needed = r->in.offered;
- wresult = fill_svc_config( p->mem_ctx, info->name, r->out.query,
- p->server_info->ptok);
+ wresult = fill_svc_config(p->mem_ctx,
+ p->msg_ctx,
+ p->server_info,
+ info->name,
+ r->out.query);
if ( !W_ERROR_IS_OK(wresult) )
return wresult;
@@ -754,8 +789,10 @@ WERROR _svcctl_QueryServiceConfig2W(struct pipes_struct *p,
enum ndr_err_code ndr_err;
DATA_BLOB blob;
- description = svcctl_lookup_description(
- p->mem_ctx, info->name, p->server_info->ptok);
+ description = svcctl_lookup_description(p->mem_ctx,
+ p->msg_ctx,
+ p->server_info,
+ info->name);
desc_buf.description = description;
@@ -874,10 +911,14 @@ WERROR _svcctl_QueryServiceObjectSecurity(struct pipes_struct *p,
if ( (r->in.security_flags & SECINFO_DACL) != SECINFO_DACL )
return WERR_INVALID_PARAM;
- /* lookup the security descriptor and marshall it up for a reply */
-
- if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) )
- return WERR_NOMEM;
+ /* Lookup the security descriptor and marshall it up for a reply */
+ sec_desc = svcctl_get_secdesc(p->mem_ctx,
+ p->msg_ctx,
+ get_server_info_system(),
+ info->name);
+ if (sec_desc == NULL) {
+ return WERR_NOMEM;
+ }
*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 */
- 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_OK;
diff --git a/source3/services/svc_winreg_glue.c b/source3/services/svc_winreg_glue.c
new file mode 100644
index 0000000000..2ab9914bcc
--- /dev/null
+++ b/source3/services/svc_winreg_glue.c
@@ -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: */
diff --git a/source3/services/svc_winreg_glue.h b/source3/services/svc_winreg_glue.h
new file mode 100644
index 0000000000..f2f036e725
--- /dev/null
+++ b/source3/services/svc_winreg_glue.h
@@ -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: */