summaryrefslogtreecommitdiffstats
path: root/source3/services
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /source3/services
parentInitial commit. (diff)
downloadsamba-4f5791ebd03eaec1c7da0865a383175b05102712.tar.xz
samba-4f5791ebd03eaec1c7da0865a383175b05102712.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source3/services')
-rw-r--r--source3/services/services.h54
-rw-r--r--source3/services/svc_netlogon.c75
-rw-r--r--source3/services/svc_rcinit.c150
-rw-r--r--source3/services/svc_spoolss.c87
-rw-r--r--source3/services/svc_winreg.c64
-rw-r--r--source3/services/svc_winreg_glue.c370
-rw-r--r--source3/services/svc_winreg_glue.h60
-rw-r--r--source3/services/svc_wins.c72
8 files changed, 932 insertions, 0 deletions
diff --git a/source3/services/services.h b/source3/services/services.h
new file mode 100644
index 0000000..f65eed1
--- /dev/null
+++ b/source3/services/services.h
@@ -0,0 +1,54 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997,
+ Copyright (C) Gerald (Jerry) Carter 2005
+
+ 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 _SERVICES_H /* _SERVICES_H */
+#define _SERVICES_H
+
+#include "../librpc/gen_ndr/svcctl.h"
+
+/* where we assume the location of the service control scripts */
+#define SVCCTL_SCRIPT_DIR "svcctl"
+
+/*
+ * dispatch table of functions to handle the =ServiceControl API
+ */
+
+typedef struct {
+ /* functions for enumerating subkeys and values */
+ WERROR (*stop_service)( const char *service, struct SERVICE_STATUS *status );
+ WERROR (*start_service) ( const char *service );
+ WERROR (*service_status)( const char *service, struct SERVICE_STATUS *status );
+} SERVICE_CONTROL_OPS;
+
+/* structure to store the service handle information */
+
+typedef struct _ServiceInfo {
+ uint8_t type;
+ char *name;
+ uint32_t access_granted;
+ SERVICE_CONTROL_OPS *ops;
+} SERVICE_INFO;
+
+#define SVC_HANDLE_IS_SCM 0x0000001
+#define SVC_HANDLE_IS_SERVICE 0x0000002
+#define SVC_HANDLE_IS_DBLOCK 0x0000003
+
+#endif /* _SERICES_H */
+
diff --git a/source3/services/svc_netlogon.c b/source3/services/svc_netlogon.c
new file mode 100644
index 0000000..582cb56
--- /dev/null
+++ b/source3/services/svc_netlogon.c
@@ -0,0 +1,75 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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"
+
+/* Implementation for internal netlogon service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR netlogon_status( const char *service, struct SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ service_status->type = SERVICE_TYPE_WIN32_SHARE_PROCESS;
+ service_status->controls_accepted = SVCCTL_ACCEPT_NONE;
+
+ if ( lp_servicenumber("NETLOGON") != -1 ) {
+ service_status->state = SVCCTL_RUNNING;
+ service_status->win32_exit_code = WERR_SERVICE_NEVER_STARTED;
+ }
+ else
+ service_status->state = SVCCTL_STOPPED;
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR netlogon_stop( const char *service, struct SERVICE_STATUS *service_status )
+{
+ netlogon_status( service, service_status );
+
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR netlogon_start( const char *service )
+{
+ if ( lp_servicenumber("NETLOGON") == -1 )
+ return WERR_SERVICE_DISABLED;
+
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate netlogon service */
+
+SERVICE_CONTROL_OPS netlogon_svc_ops = {
+ netlogon_stop,
+ netlogon_start,
+ netlogon_status
+};
diff --git a/source3/services/svc_rcinit.c b/source3/services/svc_rcinit.c
new file mode 100644
index 0000000..7a8ad65
--- /dev/null
+++ b/source3/services/svc_rcinit.c
@@ -0,0 +1,150 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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"
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR rcinit_stop( const char *service, struct SERVICE_STATUS *status )
+{
+ int ret = -1;
+
+ /*
+ * Disabled due to security concerns and unknown use in the
+ * field -- vl@samba.org
+ */
+#if 0
+ char *command = NULL;
+ int fd;
+
+ if (asprintf(&command, "%s/%s/%s stop",
+ get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* we've already performed the access check when the service was opened */
+
+ become_root();
+ ret = smbrun(command, &fd, NULL);
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ SAFE_FREE(command);
+
+ ZERO_STRUCTP( status );
+
+ status->type = SERVICE_TYPE_WIN32_SHARE_PROCESS;
+ status->state = (ret == 0 ) ? SVCCTL_STOPPED : SVCCTL_RUNNING;
+ status->controls_accepted = SVCCTL_ACCEPT_STOP |
+ SVCCTL_ACCEPT_SHUTDOWN;
+#endif
+ return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR rcinit_start( const char *service )
+{
+ int ret = -1;
+ /*
+ * Disabled due to security concerns and unknown use in the
+ * field -- vl@samba.org
+ */
+#if 0
+ char *command = NULL;
+ int fd;
+
+ if (asprintf(&command, "%s/%s/%s start",
+ get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* we've already performed the access check when the service was opened */
+
+ become_root();
+ ret = smbrun(command, &fd, NULL);
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ SAFE_FREE(command);
+#endif
+ return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR rcinit_status( const char *service, struct SERVICE_STATUS *status )
+{
+ /*
+ * Disabled due to security concerns and unknown use in the
+ * field -- vl@samba.org
+ */
+#if 0
+ char *command = NULL;
+ int ret, fd;
+
+ if (asprintf(&command, "%s/%s/%s status",
+ get_dyn_MODULESDIR(), SVCCTL_SCRIPT_DIR, service) < 0) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* we've already performed the access check when the service was opened */
+ /* assume as return code of 0 means that the service is ok. Anything else
+ is STOPPED */
+
+ become_root();
+ ret = smbrun(command, &fd, NULL);
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ SAFE_FREE(command);
+
+ ZERO_STRUCTP( status );
+
+ status->type = SERVICE_TYPE_WIN32_SHARE_PROCESS;
+ status->state = (ret == 0 ) ? SVCCTL_RUNNING : SVCCTL_STOPPED;
+ status->controls_accepted = SVCCTL_ACCEPT_STOP |
+ SVCCTL_ACCEPT_SHUTDOWN;
+
+ return WERR_OK;
+#else
+ return WERR_ACCESS_DENIED;
+#endif
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate rcinit service */
+
+SERVICE_CONTROL_OPS rcinit_svc_ops = {
+ rcinit_stop,
+ rcinit_start,
+ rcinit_status
+};
diff --git a/source3/services/svc_spoolss.c b/source3/services/svc_spoolss.c
new file mode 100644
index 0000000..e827013
--- /dev/null
+++ b/source3/services/svc_spoolss.c
@@ -0,0 +1,87 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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"
+
+/* Implementation for internal spoolss service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR spoolss_stop( const char *service, struct SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ lp_set_spoolss_state( SVCCTL_STOPPED );
+
+ service_status->type = SERVICE_TYPE_INTERACTIVE_PROCESS |
+ SERVICE_TYPE_WIN32_OWN_PROCESS;
+ service_status->state = SVCCTL_STOPPED;
+ service_status->controls_accepted = SVCCTL_ACCEPT_STOP;
+
+ DEBUG(6,("spoolss_stop: spooler stopped (not really)\n"));
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR spoolss_start( const char *service )
+{
+ /* see if the smb.conf will support this anyways */
+
+ if ( lp__disable_spoolss() )
+ return WERR_ACCESS_DENIED;
+
+ if (lp_get_spoolss_state() == SVCCTL_RUNNING) {
+ return WERR_SERVICE_ALREADY_RUNNING;
+ }
+
+ lp_set_spoolss_state( SVCCTL_RUNNING );
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR spoolss_status( const char *service, struct SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ service_status->type = SERVICE_TYPE_INTERACTIVE_PROCESS |
+ SERVICE_TYPE_WIN32_OWN_PROCESS;
+ service_status->state = lp_get_spoolss_state();
+ service_status->controls_accepted = SVCCTL_ACCEPT_STOP;
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate spoolss service */
+
+SERVICE_CONTROL_OPS spoolss_svc_ops = {
+ spoolss_stop,
+ spoolss_start,
+ spoolss_status
+};
diff --git a/source3/services/svc_winreg.c b/source3/services/svc_winreg.c
new file mode 100644
index 0000000..04c137f
--- /dev/null
+++ b/source3/services/svc_winreg.c
@@ -0,0 +1,64 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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"
+
+/* Implementation for internal winreg service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR winreg_stop( const char *service, struct SERVICE_STATUS *service_status )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR winreg_start( const char *service )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR winreg_status( const char *service, struct SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ service_status->type = SERVICE_TYPE_WIN32_SHARE_PROCESS;
+ service_status->controls_accepted = SVCCTL_ACCEPT_NONE;
+ service_status->state = SVCCTL_RUNNING;
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate winreg service */
+
+SERVICE_CONTROL_OPS winreg_svc_ops = {
+ winreg_stop,
+ winreg_start,
+ winreg_status
+};
diff --git a/source3/services/svc_winreg_glue.c b/source3/services/svc_winreg_glue.c
new file mode 100644
index 0000000..50b9897
--- /dev/null
+++ b/source3/services/svc_winreg_glue.c
@@ -0,0 +1,370 @@
+/*
+ * 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;
+}
+
+WERROR svcctl_get_secdesc(struct messaging_context *msg_ctx,
+ const struct auth_session_info *session_info,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ struct security_descriptor **psd)
+{
+ 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 WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ status = dcerpc_winreg_int_hklm_openkey(mem_ctx,
+ session_info,
+ msg_ctx,
+ &h,
+ key,
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
+ key, nt_errstr(status)));
+ return WERR_INTERNAL_ERROR;
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("svcctl_set_secdesc: Could not open %s - %s\n",
+ key, win_errstr(result)));
+ return result;
+ }
+
+ status = dcerpc_winreg_query_sd(mem_ctx,
+ h,
+ &key_hnd,
+ "Security",
+ &sd,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
+ "%s\n", nt_errstr(status)));
+ return WERR_INTERNAL_ERROR;
+ }
+ if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
+ goto fallback_to_default_sd;
+ } else if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("svcctl_get_secdesc: error getting value 'Security': "
+ "%s\n", win_errstr(result)));
+ return result;
+ }
+
+ 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);
+ if (sd == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+done:
+ *psd = sd;
+ return WERR_OK;
+}
+
+bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
+ const struct auth_session_info *session_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;
+ struct policy_handle key_hnd = { 0, };
+ 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,
+ session_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 = { 0, };
+ struct winreg_String wkeyclass;
+
+ wkey.name = talloc_asprintf(tmp_ctx, "%s\\Security", key);
+ if (wkey.name == NULL) {
+ result = WERR_NOT_ENOUGH_MEMORY;
+ 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(2, ("svcctl_set_secdesc: Could not create key %s: %s\n",
+ wkey.name, nt_errstr(status)));
+ goto done;
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("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_session_info *session_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,
+ session_info,
+ msg_ctx,
+ &h,
+ path,
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2, ("svcctl_get_string_value: Could not open %s - %s\n",
+ path, nt_errstr(status)));
+ goto done;
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("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_session_info *session_info,
+ const char *name)
+{
+ const char *display_name = NULL;
+
+ display_name = svcctl_get_string_value(mem_ctx,
+ msg_ctx,
+ session_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_session_info *session_info,
+ const char *name)
+{
+ const char *description = NULL;
+
+ description = svcctl_get_string_value(mem_ctx,
+ msg_ctx,
+ session_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 0000000..e013f8d
--- /dev/null
+++ b/source3/services/svc_winreg_glue.h
@@ -0,0 +1,60 @@
+/*
+ * 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 auth_session_info;
+
+struct security_descriptor* svcctl_gen_service_sd(TALLOC_CTX *mem_ctx);
+
+WERROR svcctl_get_secdesc(struct messaging_context *msg_ctx,
+ const struct auth_session_info *session_info,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ struct security_descriptor **result);
+
+bool svcctl_set_secdesc(struct messaging_context *msg_ctx,
+ const struct auth_session_info *session_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_session_info *session_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_session_info *session_info,
+ const char *name);
+
+const char *svcctl_lookup_description(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ const struct auth_session_info *session_info,
+ const char *name);
+
+#endif /* SVC_WINREG_GLUE_H */
+
+/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
diff --git a/source3/services/svc_wins.c b/source3/services/svc_wins.c
new file mode 100644
index 0000000..c8d72bc
--- /dev/null
+++ b/source3/services/svc_wins.c
@@ -0,0 +1,72 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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"
+
+/* Implementation for internal wins service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR wins_status( const char *service, struct SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ service_status->type = SERVICE_TYPE_WIN32_OWN_PROCESS;
+ service_status->controls_accepted = SVCCTL_ACCEPT_NONE;
+
+ if ( lp_we_are_a_wins_server() )
+ service_status->state = SVCCTL_RUNNING;
+ else {
+ service_status->state = SVCCTL_STOPPED;
+ service_status->win32_exit_code = WERR_SERVICE_NEVER_STARTED;
+ }
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR wins_stop( const char *service, struct SERVICE_STATUS *service_status )
+{
+ wins_status( service, service_status );
+
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR wins_start( const char *service )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate wins service */
+
+SERVICE_CONTROL_OPS wins_svc_ops = {
+ wins_stop,
+ wins_start,
+ wins_status
+};