r6304: missed some files in the previous commit
[Samba.git] / source / rpc_server / srv_svcctl_nt.c
bloba76e68a312c91f2971f201a8b6db1cf36daf87a0
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Gerald (Jerry) Carter 2005
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_RPC_SRV
27 * sertup the \PIPE\svcctl db API
30 #define SCVCTL_DATABASE_VERSION_V1 1
32 /********************************************************************
33 ********************************************************************/
35 #if 0 /* unused static function and static variable*/
37 static TDB_CONTEXT *svcctl_tdb; /* used for share security descriptors */
39 static BOOL init_svcctl_db( void )
41 static pid_t local_pid;
42 const char *vstring = "INFO/version";
44 /* see if we've already opened the tdb */
46 if (svcctl_tdb && local_pid == sys_getpid())
47 return True;
49 /* so open it */
50 if ( !(svcctl_tdb = tdb_open_log(lock_path("svcctl.tdb"), 0, TDB_DEFAULT,
51 O_RDWR|O_CREAT, 0600)))
53 DEBUG(0,("Failed to open svcctl database %s (%s)\n",
54 lock_path("svcctl.tdb"), strerror(errno) ));
55 return False;
58 local_pid = sys_getpid();
60 /***** BEGIN Check the tdb version ******/
62 tdb_lock_bystring(svcctl_tdb, vstring, 0);
64 if ( tdb_fetch_int32(svcctl_tdb, vstring) != SCVCTL_DATABASE_VERSION_V1 )
65 tdb_store_int32(svcctl_tdb, vstring, SCVCTL_DATABASE_VERSION_V1);
67 tdb_unlock_bystring(svcctl_tdb, vstring);
69 /***** END Check the tdb version ******/
71 return True;
74 #endif
76 /********************************************************************
77 TODO
78 (a) get and set security descriptors on services
79 (b) read and write QUERY_SERVICE_CONFIG structures
80 (c) create default secdesc objects for services and SCM
81 (d) check access control masks with se_access_check()
82 (e) implement SERVICE * for associating with open handles
83 ********************************************************************/
85 /********************************************************************
86 ********************************************************************/
88 WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u)
90 /* just fake it for now */
92 if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
93 return WERR_ACCESS_DENIED;
95 return WERR_OK;
98 /********************************************************************
99 ********************************************************************/
101 WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u)
103 fstring service;
105 rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
107 /* can only be called on service name (not displayname) */
109 if ( !(strequal( service, "NETLOGON") || strequal(service, "Spooler")) )
110 return WERR_NO_SUCH_SERVICE;
112 if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
113 return WERR_ACCESS_DENIED;
115 return WERR_OK;
118 /********************************************************************
119 ********************************************************************/
121 WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u)
123 if ( !close_policy_hnd( p, &q_u->handle ) )
124 return WERR_BADFID;
126 return WERR_OK;
129 /********************************************************************
130 ********************************************************************/
132 WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u)
134 fstring service;
135 fstring displayname;
137 rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
139 DEBUG(10,("_svcctl_get_display_name: service name [%s]\n", service));
141 if ( !strequal( service, "NETLOGON" ) )
142 return WERR_ACCESS_DENIED;
144 fstrcpy( displayname, "Net Logon");
145 init_svcctl_r_get_display_name( r_u, displayname );
147 return WERR_OK;
150 /********************************************************************
151 ********************************************************************/
153 WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u)
156 r_u->svc_status.type = 0x0110;
157 r_u->svc_status.state = 0x0004;
158 r_u->svc_status.controls_accepted = 0x0005;
160 return WERR_OK;
163 /********************************************************************
164 ********************************************************************/
166 WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, SVCCTL_R_ENUM_SERVICES_STATUS *r_u)
168 ENUM_SERVICES_STATUS *services = NULL;
169 uint32 num_services = 0;
170 int i = 0;
171 size_t buffer_size;
172 WERROR result = WERR_OK;
174 /* num_services = str_list_count( lp_enable_svcctl() ); */
175 num_services = 2;
177 if ( !(services = TALLOC_ARRAY( p->mem_ctx, ENUM_SERVICES_STATUS, num_services )) )
178 return WERR_NOMEM;
180 DEBUG(8,("_svcctl_enum_services_status: Enumerating %d services\n", num_services));
182 init_unistr( &services[i].servicename, "Spooler" );
183 init_unistr( &services[i].displayname, "Spooler" );
185 services[i].status.type = 0x110;
186 services[i].status.controls_accepted = 0x0;
187 services[i].status.win32_exit_code = 0x0;
188 services[i].status.service_exit_code = 0x0;
189 services[i].status.check_point = 0x0;
190 services[i].status.wait_hint = 0x0;
191 if ( !lp_disable_spoolss() )
192 services[i].status.state = SVCCTL_RUNNING;
193 else
194 services[i].status.state = SVCCTL_STOPPED;
196 i++;
198 init_unistr( &services[i].servicename, "Netlogon" );
199 init_unistr( &services[i].displayname, "Net Logon" );
201 services[i].status.type = 0x20;
202 services[i].status.controls_accepted = 0x0;
203 services[i].status.win32_exit_code = 0x0;
204 services[i].status.service_exit_code = 0x0;
205 services[i].status.check_point = 0x0;
206 services[i].status.wait_hint = 0x0;
207 if ( lp_servicenumber("NETLOGON") != -1 )
208 services[i].status.state = SVCCTL_RUNNING;
209 else
210 services[i].status.state = SVCCTL_STOPPED;
212 buffer_size = 0;
213 for (i=0; i<num_services; i++ )
214 buffer_size += svcctl_sizeof_enum_services_status( &services[i] );
216 buffer_size += buffer_size % 4;
218 if ( buffer_size > q_u->buffer_size ) {
219 num_services = 0;
220 result = WERR_MORE_DATA;
223 /* we have to set the outgoing buffer size to the same as the
224 incoming buffer size (even in the case of failure */
226 rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
228 if ( W_ERROR_IS_OK(result) ) {
229 for ( i=0; i<num_services; i++ )
230 svcctl_io_enum_services_status( "", &services[i], &r_u->buffer, 0 );
233 r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
234 r_u->returned = num_services;
236 if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) )
237 return WERR_NOMEM;
239 *r_u->resume = 0x0;
241 return result;
244 /********************************************************************
245 ********************************************************************/
247 WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u)
249 return WERR_ACCESS_DENIED;
252 /********************************************************************
253 ********************************************************************/
255 WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u)
257 return WERR_ACCESS_DENIED;
260 /********************************************************************
261 ********************************************************************/
263 WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u )
266 /* we have to set the outgoing buffer size to the same as the
267 incoming buffer size (even in the case of failure */
269 rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
271 r_u->needed = q_u->buffer_size;
273 /* no dependent services...basically a stub function */
274 r_u->returned = 0;
276 return WERR_OK;
279 /********************************************************************
280 ********************************************************************/
282 WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u )
285 /* we have to set the outgoing buffer size to the same as the
286 incoming buffer size (even in the case of failure */
288 r_u->needed = q_u->buffer_size;
290 /* no dependent services...basically a stub function */
292 return WERR_ACCESS_DENIED;