1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-22 16:59:09 +03:00
Files
samba-mirror/source/rpc_server/srv_svcctl_nt.c
Derrell Lipman 994694f7f2 r6149: Fixes bugs #2498 and 2484.
1. using smbc_getxattr() et al, one may now request all access control
   entities in the ACL without getting all other NT attributes.
2. added the ability to exclude specified attributes from the result set
   provided by smbc_getxattr() et al, when requesting all attributes,
   all NT attributes, or all DOS attributes.
3. eliminated all compiler warnings, including when --enable-developer
   compiler flags are in use.  removed -Wcast-qual flag from list, as that
   is specifically to force warnings in the case of casting away qualifiers.

Note: In the process of eliminating compiler warnings, a few nasties were
      discovered.  In the file libads/sasl.c, PRIVATE kerberos interfaces
      are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED
      kerberos interfaces are being used.  Someone who knows kerberos
      should look at these and determine if there is an alternate method
      of accomplishing the task.
2007-10-10 10:56:24 -05:00

296 lines
9.0 KiB
C

/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
/*
* sertup the \PIPE\svcctl db API
*/
#define SCVCTL_DATABASE_VERSION_V1 1
/********************************************************************
********************************************************************/
#if 0 /* unused static function and static variable*/
static TDB_CONTEXT *svcctl_tdb; /* used for share security descriptors */
static BOOL init_svcctl_db( void )
{
static pid_t local_pid;
const char *vstring = "INFO/version";
/* see if we've already opened the tdb */
if (svcctl_tdb && local_pid == sys_getpid())
return True;
/* so open it */
if ( !(svcctl_tdb = tdb_open_log(lock_path("svcctl.tdb"), 0, TDB_DEFAULT,
O_RDWR|O_CREAT, 0600)))
{
DEBUG(0,("Failed to open svcctl database %s (%s)\n",
lock_path("svcctl.tdb"), strerror(errno) ));
return False;
}
local_pid = sys_getpid();
/***** BEGIN Check the tdb version ******/
tdb_lock_bystring(svcctl_tdb, vstring, 0);
if ( tdb_fetch_int32(svcctl_tdb, vstring) != SCVCTL_DATABASE_VERSION_V1 )
tdb_store_int32(svcctl_tdb, vstring, SCVCTL_DATABASE_VERSION_V1);
tdb_unlock_bystring(svcctl_tdb, vstring);
/***** END Check the tdb version ******/
return True;
}
#endif
/********************************************************************
TODO
(a) get and set security descriptors on services
(b) read and write QUERY_SERVICE_CONFIG structures
(c) create default secdesc objects for services and SCM
(d) check access control masks with se_access_check()
(e) implement SERVICE * for associating with open handles
********************************************************************/
/********************************************************************
********************************************************************/
WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u)
{
/* just fake it for now */
if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
return WERR_ACCESS_DENIED;
return WERR_OK;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u)
{
fstring service;
rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
/* can only be called on service name (not displayname) */
if ( !(strequal( service, "NETLOGON") || strequal(service, "Spooler")) )
return WERR_NO_SUCH_SERVICE;
if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
return WERR_ACCESS_DENIED;
return WERR_OK;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u)
{
if ( !close_policy_hnd( p, &q_u->handle ) )
return WERR_BADFID;
return WERR_OK;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u)
{
fstring service;
fstring displayname;
rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
DEBUG(10,("_svcctl_get_display_name: service name [%s]\n", service));
if ( !strequal( service, "NETLOGON" ) )
return WERR_ACCESS_DENIED;
fstrcpy( displayname, "Net Logon");
init_svcctl_r_get_display_name( r_u, displayname );
return WERR_OK;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u)
{
r_u->svc_status.type = 0x0110;
r_u->svc_status.state = 0x0004;
r_u->svc_status.controls_accepted = 0x0005;
return WERR_OK;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, SVCCTL_R_ENUM_SERVICES_STATUS *r_u)
{
ENUM_SERVICES_STATUS *services = NULL;
uint32 num_services = 0;
int i = 0;
size_t buffer_size;
WERROR result = WERR_OK;
/* num_services = str_list_count( lp_enable_svcctl() ); */
num_services = 2;
if ( !(services = TALLOC_ARRAY( p->mem_ctx, ENUM_SERVICES_STATUS, num_services )) )
return WERR_NOMEM;
DEBUG(8,("_svcctl_enum_services_status: Enumerating %d services\n", num_services));
init_unistr( &services[i].servicename, "Spooler" );
init_unistr( &services[i].displayname, "Spooler" );
services[i].status.type = 0x110;
services[i].status.controls_accepted = 0x0;
services[i].status.win32_exit_code = 0x0;
services[i].status.service_exit_code = 0x0;
services[i].status.check_point = 0x0;
services[i].status.wait_hint = 0x0;
if ( !lp_disable_spoolss() )
services[i].status.state = SVCCTL_RUNNING;
else
services[i].status.state = SVCCTL_STOPPED;
i++;
init_unistr( &services[i].servicename, "Netlogon" );
init_unistr( &services[i].displayname, "Net Logon" );
services[i].status.type = 0x20;
services[i].status.controls_accepted = 0x0;
services[i].status.win32_exit_code = 0x0;
services[i].status.service_exit_code = 0x0;
services[i].status.check_point = 0x0;
services[i].status.wait_hint = 0x0;
if ( lp_servicenumber("NETLOGON") != -1 )
services[i].status.state = SVCCTL_RUNNING;
else
services[i].status.state = SVCCTL_STOPPED;
buffer_size = 0;
for (i=0; i<num_services; i++ )
buffer_size += svcctl_sizeof_enum_services_status( &services[i] );
buffer_size += buffer_size % 4;
if ( buffer_size > q_u->buffer_size ) {
num_services = 0;
result = WERR_MORE_DATA;
}
/* we have to set the outgoing buffer size to the same as the
incoming buffer size (even in the case of failure */
rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
if ( W_ERROR_IS_OK(result) ) {
for ( i=0; i<num_services; i++ )
svcctl_io_enum_services_status( "", &services[i], &r_u->buffer, 0 );
}
r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
r_u->returned = num_services;
if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) )
return WERR_NOMEM;
*r_u->resume = 0x0;
return result;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u)
{
return WERR_ACCESS_DENIED;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u)
{
return WERR_ACCESS_DENIED;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u )
{
/* we have to set the outgoing buffer size to the same as the
incoming buffer size (even in the case of failure */
rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
r_u->needed = q_u->buffer_size;
/* no dependent services...basically a stub function */
r_u->returned = 0;
return WERR_OK;
}
/********************************************************************
********************************************************************/
WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u )
{
/* we have to set the outgoing buffer size to the same as the
incoming buffer size (even in the case of failure */
r_u->needed = q_u->buffer_size;
/* no dependent services...basically a stub function */
return WERR_ACCESS_DENIED;
}