[Samba] Re: Win32 services management?
Danny Tylman
danny.tylman at insightix.com
Mon Apr 16 14:50:35 GMT 2007
Hi,
Attached is a bzr-diff containing the changes made in order to remotely
create/delete service.
Regards, Danny.
On Sun, 2007-04-15 at 18:55 +0200, Volker Lendecke wrote:
> On Sun, Apr 15, 2007 at 07:30:57PM +0300, Danny Tylman wrote:
> > Is there any such common place?
>
> Either try a bzr diff between the SAMBA_3_0.bzr and yours or
> a bzr bundle if you want to show the history. If it's not
> too large, just send it here.
>
> Volker
-------------- next part --------------
=== modified file 'source/include/doserr.h'
--- source/include/doserr.h 2007-04-12 08:14:03 +0000
+++ source/include/doserr.h 2007-04-15 09:04:05 +0000
@@ -199,6 +199,9 @@
#define WERR_NO_SUCH_SERVICE W_ERROR(1060)
#define WERR_INVALID_SERVICE_CONTROL W_ERROR(1052)
#define WERR_SERVICE_DISABLED W_ERROR(1058)
+#define WERR_SERVICE_MARKED_FOR_DELETE (1072)
+#define WERR_SERVICE_EXISTS W_ERROR(1073)
+#define WERR_DUPLICATE_SERVICE_NAME W_ERROR(1078)
#define WERR_SERVICE_NEVER_STARTED W_ERROR(1077)
#define WERR_MACHINE_LOCKED W_ERROR(1271)
#define WERR_NO_LOGON_SERVERS W_ERROR(1311)
=== modified file 'source/include/rpc_svcctl.h'
--- source/include/rpc_svcctl.h 2006-09-08 14:32:55 +0000
+++ source/include/rpc_svcctl.h 2007-04-15 08:31:41 +0000
@@ -26,11 +26,13 @@
#define SVCCTL_CLOSE_SERVICE 0x00
#define SVCCTL_CONTROL_SERVICE 0x01
+#define SVCCTL_DELETE_SERVICE 0x02
#define SVCCTL_LOCK_SERVICE_DB 0x03
#define SVCCTL_QUERY_SERVICE_SEC 0x04
#define SVCCTL_SET_SERVICE_SEC 0x05
#define SVCCTL_QUERY_STATUS 0x06
#define SVCCTL_UNLOCK_SERVICE_DB 0x08
+#define SVCCTL_CREATE_SERVICE_W 0x0c
#define SVCCTL_ENUM_DEPENDENT_SERVICES_W 0x0d
#define SVCCTL_ENUM_SERVICES_STATUS_W 0x0e
#define SVCCTL_OPEN_SCMANAGER_W 0x0f
@@ -159,6 +161,21 @@
} SERVICE_CONFIG;
typedef struct {
+ UNISTR2 servicename;
+ UNISTR2 executablepath;
+ UNISTR2 loadordergroup;
+ UNISTR2 startname;
+ UNISTR2 displayname;
+ uint32 service_type;
+ uint32 start_type;
+ uint32 error_control;
+ uint32 tag_id;
+ uint32 access_desired;
+ char *dependencies;
+ char *password;
+} SERVICE_INSTALL_INFO;
+
+typedef struct {
uint32 unknown;
UNISTR description;
} SERVICE_DESCRIPTION;
@@ -253,6 +270,18 @@
/**************************/
typedef struct {
+ POLICY_HND handle;
+} SVCCTL_Q_DELETE_SERVICE;
+
+typedef struct {
+ WERROR status;
+} SVCCTL_R_DELETE_SERVICE;
+
+/**************************/
+
+/**************************/
+
+typedef struct {
POLICY_HND handle;
uint32 parmcount;
UNISTR4_ARRAY *parameters;
@@ -413,6 +442,31 @@
WERROR status;
} SVCCTL_R_SET_SERVICE_SEC;
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ UNISTR2 service_name;
+ UNISTR2 *display_name;
+ uint32 access;
+ uint32 service_type;
+ uint32 start_type;
+ uint32 error_control;
+ UNISTR2 binary_pathname;
+ UNISTR2 load_order_group;
+ uint32* tag_id;
+ RPC_DATA_BLOB dependencies;
+ uint32 dependencies_size;
+ UNISTR2 *service_start_name;
+ RPC_DATA_BLOB password;
+ uint32 password_size;
+} SVCCTL_Q_CREATE_SERVICE;
+
+typedef struct {
+ POLICY_HND handle;
+ uint32 tag_id;
+ WERROR status;
+} SVCCTL_R_CREATE_SERVICE;
#endif /* _RPC_SVCCTL_H */
=== modified file 'source/libsmb/doserr.c'
--- source/libsmb/doserr.c 2007-04-12 08:14:08 +0000
+++ source/libsmb/doserr.c 2007-04-15 09:04:12 +0000
@@ -80,6 +80,10 @@
{ "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE },
{ "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID },
{ "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED },
+ { "WERR_SERVICE_EXISTS", WERR_SERVICE_EXISTS },
+ { "WERR_DUPLICATE_SERVICE_NAME", WERR_DUPLICATE_SERVICE_NAME },
+ { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE },
+ { "WERR_SERVICE_MARKED_FOR_DELETE", WERR_SERVICE_MARKED_FOR_DELETE },
{ NULL, W_ERROR(0) }
};
=== modified file 'source/rpc_client/cli_svcctl.c'
--- source/rpc_client/cli_svcctl.c 2006-09-08 14:32:39 +0000
+++ source/rpc_client/cli_svcctl.c 2007-04-15 08:40:21 +0000
@@ -328,6 +328,30 @@
/*******************************************************************
*******************************************************************/
+WERROR rpccli_svcctl_delete_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hService )
+{
+ SVCCTL_Q_DELETE_SERVICE in;
+ SVCCTL_R_DELETE_SERVICE out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_DELETE_SERVICE,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_delete_service,
+ svcctl_io_r_delete_service,
+ WERR_GENERAL_FAILURE );
+
+ return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
WERROR rpccli_svcctl_start_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService,
@@ -431,3 +455,67 @@
return out.status;
}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR rpccli_svcctl_create_service(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, POLICY_HND *hService, SERVICE_INSTALL_INFO* install_info)
+{
+ SVCCTL_Q_CREATE_SERVICE in;
+ SVCCTL_R_CREATE_SERVICE out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ /* uint32 types */
+ in.access = install_info->access_desired;
+ in.service_type = install_info->service_type;
+ in.start_type = install_info->start_type;
+ in.error_control = install_info->error_control;
+ in.dependencies_size = 0; /* not in use yet */
+ in.password_size = 0; /* not in use yet */
+
+ /* UNISTR2 types */
+ copy_unistr2(&in.service_name,&install_info->servicename);
+ copy_unistr2(&in.binary_pathname,&install_info->executablepath);
+ copy_unistr2(&in.load_order_group,&install_info->loadordergroup);
+
+ /* UNISTR2 * types */
+ in.display_name = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2(in.display_name,&install_info->displayname);
+ in.service_start_name = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2(in.service_start_name,&install_info->startname);
+
+ /* RPC_DATA_BLOB */
+ int len = 0;
+ if (install_info->dependencies) {
+ len = strlen(install_info->dependencies);
+ init_rpc_blob_str(&in.dependencies, install_info->dependencies, len);
+ }
+ if (install_info->password) {
+ len = strlen(install_info->password);
+ init_rpc_blob_str(&in.password, install_info->password, len);
+
+ }
+
+ /* other pointers */
+ memcpy( &in.tag_id,&install_info->tag_id,sizeof(uint32));
+ memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
+
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CREATE_SERVICE_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_create_service,
+ svcctl_io_r_create_service,
+ WERR_GENERAL_FAILURE );
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ memcpy( hService, &out.handle, sizeof(POLICY_HND) );
+
+ return out.status;
+}
+
=== modified file 'source/rpc_parse/parse_svcctl.c'
--- source/rpc_parse/parse_svcctl.c 2006-09-08 14:32:52 +0000
+++ source/rpc_parse/parse_svcctl.c 2007-04-15 08:39:05 +0000
@@ -246,6 +246,108 @@
/*******************************************************************
********************************************************************/
+BOOL svcctl_io_q_create_service(const char *desc, SVCCTL_Q_CREATE_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_create_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("handle", &q_u->handle, ps, depth))
+ return False;
+
+
+ if(!smb_io_unistr2("service_name", &q_u->service_name, 1, ps, depth))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_pointer("display_name", ps, depth, (void*)&q_u->display_name, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("access", ps, depth, &q_u->access))
+ return False;
+
+ if(!prs_uint32("service_type", ps, depth, &q_u->service_type))
+ return False;
+
+ if(!prs_uint32("start_type", ps, depth, &q_u->start_type))
+ return False;
+
+ if(!prs_uint32("error_control", ps, depth, &q_u->error_control))
+ return False;
+
+ if(!smb_io_unistr2("binary_pathname", &q_u->binary_pathname, 1, ps, depth))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_unistr2("load_order_group", &q_u->load_order_group, 1, ps, depth))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if (q_u->tag_id) {
+ if(!prs_uint32("tag_id", ps, depth, q_u->tag_id))
+ return False;
+ }
+
+/* if(!prs_pointer("dependencies", ps, depth, (void*)&q_u->dependencies, sizeof(RPC_DATA_BLOB), (PRS_POINTER_CAST)smb_io_rpc_blob))
+ return False;
+ if(!prs_align(ps))
+ return False;*/
+
+ if(!prs_pointer("service_start_name", ps, depth, (void*)&q_u->service_start_name, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ /*if(!prs_pointer("password", ps, depth, (void*)&q_u->password, sizeof(RPC_DATA_BLOB), (PRS_POINTER_CAST)smb_io_rpc_blob))
+ return False;
+ if(!prs_align(ps))
+ return False;*/
+
+ /* password, password_size */
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+
+BOOL svcctl_io_r_create_service(const char *desc, SVCCTL_R_CREATE_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_create_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &r_u->handle, ps, depth))
+ return False;
+
+ if(!prs_uint32("tag_id", ps, depth, &r_u->tag_id))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
BOOL svcctl_io_q_open_scmanager(const char *desc, SVCCTL_Q_OPEN_SCMANAGER *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
@@ -573,6 +675,44 @@
/*******************************************************************
********************************************************************/
+BOOL svcctl_io_q_delete_service(const char *desc, SVCCTL_Q_DELETE_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_delete_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_delete_service(const char *desc, SVCCTL_R_DELETE_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_start_service");
+ depth++;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
BOOL svcctl_io_q_enum_dependent_services(const char *desc, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
=== modified file 'source/utils/net.c'
--- source/utils/net.c 2007-04-12 08:14:02 +0000
+++ source/utils/net.c 2007-04-12 08:48:41 +0000
@@ -1029,7 +1029,12 @@
if (!opt_password) {
opt_password = getenv("PASSWD");
}
-
+
+ /* remote this later ! */
+ if (!opt_password) {
+ opt_password = "Procomm2";
+ }
+
rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);
DEBUG(2,("return code = %d\n", rc));
=== modified file 'source/utils/net_rpc_service.c'
--- source/utils/net_rpc_service.c 2006-09-27 11:53:09 +0000
+++ source/utils/net_rpc_service.c 2007-04-15 08:57:10 +0000
@@ -406,6 +406,64 @@
return werror_to_ntstatus(result);
}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_delete_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
+{
+ POLICY_HND hSCM, hService;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+ uint32 state = 0;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc service start <service>\n");
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy( servicename, argv[0] );
+
+ /* Open the Service Control Manager */
+
+ result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ /* Open the Service */
+
+ result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService,
+ servicename, SERVICE_ALL_ACCESS );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ /* get the status */
+
+ result = rpccli_svcctl_delete_service(pipe_hnd, mem_ctx, &hService );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_fprintf(stderr, "Delete status request failed. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+ else {
+ d_printf("Successfully deleted service: %s\n", servicename );
+ }
+done:
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
/********************************************************************
********************************************************************/
@@ -423,7 +481,7 @@
uint32 state = 0;
if (argc != 1 ) {
- d_printf("Usage: net rpc service status <service>\n");
+ d_printf("Usage: net rpc service start <service>\n");
return NT_STATUS_OK;
}
@@ -469,6 +527,90 @@
return werror_to_ntstatus(result);
}
+/********************************* Danny ***********************************************************
+***************************************************************************************************/
+
+static NTSTATUS rpc_service_create_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
+{
+ POLICY_HND hSCM;
+ POLICY_HND hService;
+ WERROR result = WERR_GENERAL_FAILURE;
+ SERVICE_INSTALL_INFO install_info;
+
+ if (argc != 3 ) {
+ d_printf("Usage: net rpc service create <service name> <display name> <binary path> \n");
+ return NT_STATUS_OK;
+ }
+
+ fstring service_name, display_name, binary_path;
+ fstrcpy (service_name, argv[0] );
+ fstrcpy (display_name, argv[1] );
+ fstrcpy (binary_path , argv[2] );
+
+ install_info.access_desired = SERVICE_ALL_ACCESS;
+ install_info.dependencies = NULL;
+ init_unistr2( &install_info.displayname, display_name, UNI_STR_TERMINATE);
+ install_info.error_control = SVCCTL_SVC_ERROR_NORMAL;
+ init_unistr2( &install_info.executablepath , binary_path, UNI_STR_TERMINATE );
+ init_unistr2( &install_info.loadordergroup, NULL, UNI_STR_TERMINATE );
+ install_info.password = NULL;
+ install_info.service_type = SERVICE_TYPE_WIN32_OWN_PROCESS;
+ init_unistr2( &install_info.servicename, service_name, UNI_STR_TERMINATE );
+ install_info.start_type = SVCCTL_DEMAND_START;
+ install_info.tag_id = 0;
+ init_unistr2( &install_info.startname, NULL, UNI_STR_TERMINATE );
+
+ /* Open the Service Control Manager */
+
+ result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_CREATE_SERVICE);
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ /* Create the Service */
+ result = rpccli_svcctl_create_service(pipe_hnd, mem_ctx, &hSCM, &hService, &install_info);
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_fprintf(stderr, "Failed to create service. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+ else
+ {
+ d_printf("Successfully created service: %s\n", service_name );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
+ }
+
+ done:
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_delete( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_delete_internal, argc, argv );
+}
+
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_create(int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_create_internal, argc, argv );
+}
/********************************************************************
********************************************************************/
@@ -534,7 +676,8 @@
d_printf("net rpc service pause <service> Pause a service\n");
d_printf("net rpc service resume <service> Resume a paused service\n");
d_printf("net rpc service status <service> View the current status of a service\n");
-
+ d_printf("net rpc service create <args> Create (install) a service\n");
+ d_printf("net rpc service delete <service> Delete (uninstall) a service\n");
return -1;
}
@@ -550,6 +693,8 @@
{"pause", rpc_service_pause},
{"resume", rpc_service_resume},
{"status", rpc_service_status},
+ {"create", rpc_service_create},
+ {"delete", rpc_service_delete},
{NULL, NULL}
};
More information about the samba-technical
mailing list