mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r6038: adding more flesh to 'net rpc service'
open and close the service control manager. Also experimenting with ideas for cli_xxx() interface.
This commit is contained in:
parent
167f7d3caa
commit
4da89ef17b
@ -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 */
|
||||
|
@ -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 {
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -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))
|
||||
if(!prs_pointer("database", ps, depth, (void**)&q_u->database, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
|
||||
return False;
|
||||
if(!smb_io_unistr2("database", &q_u->database, q_u->ptr_db, ps, depth))
|
||||
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;
|
||||
|
@ -20,55 +20,93 @@
|
||||
#include "includes.h"
|
||||
#include "utils/net.h"
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
static WERROR open_scmanager( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hSCM )
|
||||
{
|
||||
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 */
|
||||
|
||||
in.database = NULL;
|
||||
|
||||
/* set the server name */
|
||||
|
||||
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 );
|
||||
|
||||
in.access = SC_MANAGER_ALL_ACCESS;
|
||||
|
||||
result = cli_svcctl_open_scm( cli, mem_ctx, &in, &out );
|
||||
|
||||
if ( !W_ERROR_IS_OK( result ) )
|
||||
return result;
|
||||
|
||||
memcpy( hSCM, &out.handle, sizeof(POLICY_HND) );
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
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 )
|
||||
struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv )
|
||||
{
|
||||
#if 0
|
||||
POLICY_HND dom_pol;
|
||||
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
DOM_SID sid;
|
||||
|
||||
if (argc < 2 ) {
|
||||
d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n");
|
||||
POLICY_HND hSCM;
|
||||
WERROR result = WERR_GENERAL_FAILURE;
|
||||
|
||||
if (argc != 0 ) {
|
||||
d_printf("Usage: net rpc service list\n");
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
|
||||
if (!NT_STATUS_IS_OK(result))
|
||||
return result;
|
||||
|
||||
result = cli_lsa_open_policy2(cli, mem_ctx, True,
|
||||
SEC_RIGHTS_MAXIMUM_ALLOWED,
|
||||
&dom_pol);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result))
|
||||
return result;
|
||||
|
||||
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");
|
||||
|
||||
done:
|
||||
if ( !NT_STATUS_IS_OK(result) ) {
|
||||
d_printf("Failed to revoke privileges for %s (%s)",
|
||||
argv[0], nt_errstr(result));
|
||||
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);
|
||||
}
|
||||
|
||||
cli_lsa_close(cli, mem_ctx, &dom_pol);
|
||||
|
||||
return result;
|
||||
#else
|
||||
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 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user