From 259d44dbb2c2239339f6888fd5da12632abcbb28 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Mar 2005 16:11:23 +0000 Subject: r6038: adding more flesh to 'net rpc service' open and close the service control manager. Also experimenting with ideas for cli_xxx() interface. (This used to be commit 4da89ef17b8c4644b97b923cebfe8e446b508b4d) --- source3/include/rpc_secdes.h | 47 +++++++++++++++++ source3/include/rpc_svcctl.h | 8 ++- source3/libsmb/doserr.c | 1 + source3/rpc_client/cli_svcctl.c | 109 ++++++++++++++++++++++++++++++++++++++- source3/rpc_parse/parse_svcctl.c | 11 ++-- source3/utils/net_rpc_service.c | 106 +++++++++++++++++++++++++------------ 6 files changed, 233 insertions(+), 49 deletions(-) diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index 3e4c47dce9a..ea987f9e4e0 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -472,4 +472,51 @@ typedef struct standard_mapping { (STANDARD_RIGHTS_EXECUTE_ACCESS | \ SA_RIGHT_ALIAS_LOOKUP_INFO ) /* 0x00020008 */ +/* + * Acces bits for the svcctl objects + */ + +/* Service Control Manager Bits */ + +#define SC_RIGHT_MGR_CONNECT 0x0001 +#define SC_RIGHT_MGR_CREATE_SERVICE 0x0002 +#define SC_RIGHT_MGR_ENUMERATE_SERVICE 0x0004 +#define SC_RIGHT_MGR_LOCK 0x0008 +#define SC_RIGHT_MGR_QUERY_LOCK_STATUS 0x0010 +#define SC_RIGHT_MGR_MODIFY_BOOT_CONFIG 0x0020 + +#define SC_MANAGER_ALL_ACCESS \ + ( STANDARD_RIGHTS_REQUIRED_ACCESS | \ + SC_RIGHT_MGR_CONNECT | \ + SC_RIGHT_MGR_CREATE_SERVICE | \ + SC_RIGHT_MGR_ENUMERATE_SERVICE | \ + SC_RIGHT_MGR_LOCK | \ + SC_RIGHT_MGR_QUERY_LOCK_STATUS | \ + SC_RIGHT_MGR_MODIFY_BOOT_CONFIG ) + +/* Service Object Bits */ + +#define SC_RIGHT_SVC_QUERY_CONFIG 0x0001 +#define SC_RIGHT_SVC_CHANGE_CONFIG 0x0002 +#define SC_RIGHT_SVC_QUERY_STATUS 0x0004 +#define SC_RIGHT_SVC_ENUMERATE_DEPENDENTS 0x0008 +#define SC_RIGHT_SVC_START 0x0010 +#define SC_RIGHT_SVC_STOP 0x0020 +#define SC_RIGHT_SVC_PAUSE_CONTINUE 0x0040 +#define SC_RIGHT_SVC_INTERROGATE 0x0080 +#define SC_RIGHT_SVC_USER_DEFINED_CONTROL 0x0100 + +#define SERVICE_ALL_ACCESS \ + ( STANDARD_RIGHTS_REQUIRED_ACCESS | \ + SC_RIGHT_SVC_QUERY_CONFIG | \ + SC_RIGHT_SVC_CHANGE_CONFIG | \ + SC_RIGHT_SVC_QUERY_STATUS | \ + SC_RIGHT_SVC_ENUMERATE_DEPENDENTS | \ + SC_RIGHT_SVC_START | \ + SC_RIGHT_SVC_STOP | \ + SC_RIGHT_SVC_PAUSE_CONTINUE | \ + SC_RIGHT_SVC_INTERROGATE | \ + SC_RIGHT_SVC_USER_DEFINED_CONTROL ) + + #endif /* _RPC_SECDES_H */ diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index 8006ea00910..55b7828d35c 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -119,11 +119,9 @@ typedef struct { /**************************/ typedef struct { - uint32 ptr_srv; - UNISTR2 servername; - uint32 ptr_db; - UNISTR2 database; - uint32 access_mask; + UNISTR2 *servername; + UNISTR2 *database; + uint32 access; } SVCCTL_Q_OPEN_SCMANAGER; typedef struct { diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 96c052c7c56..daac5c46644 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -31,6 +31,7 @@ typedef const struct werror_code_struct dos_errs[] = { { "WERR_OK", WERR_OK }, + { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_BADFILE", WERR_BADFILE }, { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED }, { "WERR_BADFID", WERR_BADFID }, diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c index afef5f4fbb6..7bf7392cd6f 100644 --- a/source3/rpc_client/cli_svcctl.c +++ b/source3/rpc_client/cli_svcctl.c @@ -21,13 +21,118 @@ #include "includes.h" +/******************************************************************* +*******************************************************************/ + +WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx, + SVCCTL_Q_OPEN_SCMANAGER *in, SVCCTL_R_OPEN_SCMANAGER *out ) +{ + prs_struct qbuf, rbuf; + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + out->status = WERR_GENERAL_FAILURE; + + /* Marshall data and send request */ + + if ( svcctl_io_q_open_scmanager("", in, &qbuf, 0) ) { + if ( rpc_api_pipe_req(cli, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W, &qbuf, &rbuf) ) { + /* Unmarshall response */ + if (!svcctl_io_r_open_scmanager("", out, &rbuf, 0)) { + out->status = WERR_GENERAL_FAILURE; + } + } + } + + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return out->status; +} /******************************************************************* *******************************************************************/ -NTSTATUS cli_svcctl_enumerate_services(struct cli_state *cli, TALLOC_CTX *mem_ctx ) +WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, + SVCCTL_Q_CLOSE_SERVICE *in, SVCCTL_R_CLOSE_SERVICE *out ) { - return NT_STATUS_OK; + prs_struct qbuf, rbuf; + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + out->status = WERR_GENERAL_FAILURE; + + /* Marshall data and send request */ + + if ( svcctl_io_q_close_service("", in, &qbuf, 0) ) { + if ( rpc_api_pipe_req(cli, PI_SVCCTL, SVCCTL_CLOSE_SERVICE, &qbuf, &rbuf) ) { + /* Unmarshall response */ + if (!svcctl_io_r_close_service("", out, &rbuf, 0)) { + out->status = WERR_GENERAL_FAILURE; + } + } + } + + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return out->status; +} + +/******************************************************************* +*******************************************************************/ + +WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hSCM, uint32 type, uint32 state, + uint32 *resume, uint32 buffer_size, RPC_BUFFER *buffer, + uint32 returned ) +{ + prs_struct qbuf, rbuf; + SVCCTL_Q_ENUM_SERVICES_STATUS q; + SVCCTL_R_ENUM_SERVICES_STATUS r; + WERROR result = WERR_GENERAL_FAILURE; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + + /* Marshall data and send request */ + + if (!svcctl_io_q_enum_services_status("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!svcctl_io_r_enum_services_status("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if (W_ERROR_IS_OK(result = r.status)) { + *buffer = r.buffer; + } + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; } /******************************************************************* diff --git a/source3/rpc_parse/parse_svcctl.c b/source3/rpc_parse/parse_svcctl.c index 15f71b0ca0f..f13f01a05ab 100644 --- a/source3/rpc_parse/parse_svcctl.c +++ b/source3/rpc_parse/parse_svcctl.c @@ -192,22 +192,17 @@ BOOL svcctl_io_q_open_scmanager(const char *desc, SVCCTL_Q_OPEN_SCMANAGER *q_u, if(!prs_align(ps)) return False; - if(!prs_uint32("srv_ptr", ps, depth, &q_u->ptr_srv)) - return False; - if(!smb_io_unistr2("servername", &q_u->servername, q_u->ptr_srv, ps, depth)) + if(!prs_pointer("servername", ps, depth, (void**)&q_u->servername, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) return False; if(!prs_align(ps)) return False; - if(!prs_uint32("db_ptr", ps, depth, &q_u->ptr_db)) - return False; - if(!smb_io_unistr2("database", &q_u->database, q_u->ptr_db, ps, depth)) + if(!prs_pointer("database", ps, depth, (void**)&q_u->database, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) return False; - if(!prs_align(ps)) return False; - if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask)) + if(!prs_uint32("access", ps, depth, &q_u->access)) return False; return True; diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c index d9791610dde..79e7eaa900a 100644 --- a/source3/utils/net_rpc_service.c +++ b/source3/utils/net_rpc_service.c @@ -20,55 +20,93 @@ #include "includes.h" #include "utils/net.h" + /******************************************************************** ********************************************************************/ -static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char *domain_name, - struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, const char **argv ) +static WERROR open_scmanager( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hSCM ) { -#if 0 - POLICY_HND dom_pol; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + SVCCTL_Q_OPEN_SCMANAGER in; + SVCCTL_R_OPEN_SCMANAGER out; + WERROR result; + fstring server; + + ZERO_STRUCT(in); + ZERO_STRUCT(out); + + /* leave the database name NULL to get the default service db */ - DOM_SID sid; + in.database = NULL; - if (argc < 2 ) { - d_printf("Usage: net rpc rights revoke \n"); - return NT_STATUS_OK; - } + /* set the server name */ - result = name_to_sid(cli, mem_ctx, &sid, argv[0]); - if (!NT_STATUS_IS_OK(result)) - return result; + if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) ) + return WERR_NOMEM; + fstr_sprintf( server, "\\\\%s", cli->desthost ); + init_unistr2( in.servername, server, UNI_STR_TERMINATE ); - result = cli_lsa_open_policy2(cli, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &dom_pol); + in.access = SC_MANAGER_ALL_ACCESS; + + result = cli_svcctl_open_scm( cli, mem_ctx, &in, &out ); + + if ( !W_ERROR_IS_OK( result ) ) + return result; - if (!NT_STATUS_IS_OK(result)) - return result; + memcpy( hSCM, &out.handle, sizeof(POLICY_HND) ); + + return WERR_OK; +} - result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid, - False, argc-1, argv+1); - if (!NT_STATUS_IS_OK(result)) - goto done; +/******************************************************************** +********************************************************************/ - d_printf("Successfully revoked rights.\n"); +static WERROR close_service_handle( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService ) +{ + SVCCTL_Q_CLOSE_SERVICE in; + SVCCTL_R_CLOSE_SERVICE out; + WERROR result; + + ZERO_STRUCT(in); + ZERO_STRUCT(out); + + memcpy( &in.handle, hService, sizeof(POLICY_HND) ); + + result = cli_svcctl_close_service( cli, mem_ctx, &in, &out ); + + if ( !W_ERROR_IS_OK( result ) ) + return result; + + return WERR_OK; +} -done: - if ( !NT_STATUS_IS_OK(result) ) { - d_printf("Failed to revoke privileges for %s (%s)", - argv[0], nt_errstr(result)); - } + + +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char *domain_name, + struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv ) +{ + POLICY_HND hSCM; + WERROR result = WERR_GENERAL_FAILURE; - cli_lsa_close(cli, mem_ctx, &dom_pol); + if (argc != 0 ) { + d_printf("Usage: net rpc service list\n"); + return NT_STATUS_OK; + } - return result; -#else + if ( !W_ERROR_IS_OK(result = open_scmanager( cli, mem_ctx, &hSCM )) ) { + d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + return werror_to_ntstatus(result); + } + + d_printf("Successfully opened Service Control Manager.\n"); + + close_service_handle( cli, mem_ctx, &hSCM ); + return NT_STATUS_OK; -#endif } @@ -77,7 +115,7 @@ done: static int rpc_service_list( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_LSARPC, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_list_internal, argc, argv ); } -- cgit