source: branches/samba-3.0/source/libmsrpc/cac_svcctl.c@ 105

Last change on this file since 105 was 1, checked in by Paul Smedley, 19 years ago

Initial code import

File size: 14.3 KB
Line 
1
2/*
3 * Unix SMB/CIFS implementation.
4 * MS-RPC client library implementation (SVCCTL pipe)
5 * Copyright (C) Chris Nicholls 2005.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "libmsrpc.h"
23#include "libsmb_internal.h"
24
25#define WAIT_SLEEP_TIME 300000
26
27int cac_WaitForService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
28 POLICY_HND * svc_hnd, uint32 state, uint32 timeout,
29 SERVICE_STATUS * status );
30
31int cac_SvcOpenScm( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
32 struct SvcOpenScm *op )
33{
34 SMBCSRV *srv = NULL;
35 struct rpc_pipe_client *pipe_hnd = NULL;
36 WERROR err;
37
38 POLICY_HND *scm_out = NULL;
39
40 if ( !hnd )
41 return CAC_FAILURE;
42
43 if ( !hnd->_internal.ctx ) {
44 hnd->status = NT_STATUS_INVALID_HANDLE;
45 return CAC_FAILURE;
46 }
47
48 if ( !op || op->in.access == 0 || !mem_ctx ) {
49 hnd->status = NT_STATUS_INVALID_PARAMETER;
50 return CAC_FAILURE;
51 }
52
53 srv = cac_GetServer( hnd );
54 if ( !srv ) {
55 hnd->status = NT_STATUS_INVALID_CONNECTION;
56 return CAC_FAILURE;
57 }
58
59 /*initialize for samr pipe if we have to */
60 if ( !hnd->_internal.pipes[PI_SVCCTL] ) {
61 if ( !
62 ( pipe_hnd =
63 cli_rpc_pipe_open_noauth( srv->cli, PI_SVCCTL,
64 &( hnd->status ) ) ) ) {
65 hnd->status = NT_STATUS_UNSUCCESSFUL;
66 return CAC_FAILURE;
67 }
68
69 hnd->_internal.pipes[PI_SVCCTL] = True;
70 }
71
72 scm_out = talloc( mem_ctx, POLICY_HND );
73 if ( !scm_out ) {
74 hnd->status = NT_STATUS_NO_MEMORY;
75 return CAC_FAILURE;
76 }
77
78 err = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, scm_out,
79 op->in.access );
80 hnd->status = werror_to_ntstatus( err );
81
82 if ( !NT_STATUS_IS_OK( hnd->status ) )
83 return CAC_FAILURE;
84
85 op->out.scm_hnd = scm_out;
86
87 return CAC_SUCCESS;
88}
89
90int cac_SvcClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
91 POLICY_HND * scm_hnd )
92{
93 struct rpc_pipe_client *pipe_hnd = NULL;
94 WERROR err;
95
96 if ( !hnd )
97 return CAC_FAILURE;
98
99 if ( !hnd->_internal.ctx ) {
100 hnd->status = NT_STATUS_INVALID_HANDLE;
101 return CAC_FAILURE;
102 }
103
104 if ( !scm_hnd || !mem_ctx ) {
105 hnd->status = NT_STATUS_INVALID_PARAMETER;
106 return CAC_FAILURE;
107 }
108
109 pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
110 if ( !pipe_hnd ) {
111 hnd->status = NT_STATUS_INVALID_HANDLE;
112 return CAC_FAILURE;
113 }
114
115 err = rpccli_svcctl_close_service( pipe_hnd, mem_ctx, scm_hnd );
116 hnd->status = werror_to_ntstatus( err );
117
118 if ( !NT_STATUS_IS_OK( hnd->status ) )
119 return CAC_FAILURE;
120
121 return CAC_SUCCESS;
122}
123
124int cac_SvcEnumServices( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
125 struct SvcEnumServices *op )
126{
127 struct rpc_pipe_client *pipe_hnd = NULL;
128 WERROR err;
129
130 uint32 type_buf = 0;
131 uint32 state_buf = 0;
132
133 uint32 num_svc_out = 0;
134
135 ENUM_SERVICES_STATUS *svc_buf = NULL;
136
137 if ( !hnd )
138 return CAC_FAILURE;
139
140 if ( !hnd->_internal.ctx ) {
141 hnd->status = NT_STATUS_INVALID_HANDLE;
142 return CAC_FAILURE;
143 }
144
145 if ( !op || !op->in.scm_hnd || !mem_ctx ) {
146 hnd->status = NT_STATUS_INVALID_PARAMETER;
147 return CAC_FAILURE;
148 }
149
150 pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
151 if ( !pipe_hnd ) {
152 hnd->status = NT_STATUS_INVALID_HANDLE;
153 return CAC_FAILURE;
154 }
155
156 type_buf =
157 ( op->in.type !=
158 0 ) ? op->in.
159 type : ( SVCCTL_TYPE_DRIVER | SVCCTL_TYPE_WIN32 );
160 state_buf = ( op->in.state != 0 ) ? op->in.state : SVCCTL_STATE_ALL;
161
162 err = rpccli_svcctl_enumerate_services( pipe_hnd, mem_ctx,
163 op->in.scm_hnd, type_buf,
164 state_buf, &num_svc_out,
165 &svc_buf );
166 hnd->status = werror_to_ntstatus( err );
167
168 if ( !NT_STATUS_IS_OK( hnd->status ) )
169 return CAC_FAILURE;
170
171 op->out.services =
172 cac_MakeServiceArray( mem_ctx, svc_buf, num_svc_out );
173
174 if ( !op->out.services ) {
175 hnd->status = NT_STATUS_NO_MEMORY;
176 return CAC_FAILURE;
177 }
178
179 TALLOC_FREE( svc_buf );
180
181 op->out.num_services = num_svc_out;
182
183 return CAC_SUCCESS;
184}
185
186int cac_SvcOpenService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
187 struct SvcOpenService *op )
188{
189 struct rpc_pipe_client *pipe_hnd = NULL;
190 WERROR err;
191
192 POLICY_HND *svc_hnd_out = NULL;
193
194 if ( !hnd )
195 return CAC_FAILURE;
196
197 if ( !hnd->_internal.ctx ) {
198 hnd->status = NT_STATUS_INVALID_HANDLE;
199 return CAC_FAILURE;
200 }
201
202 if ( !op || !op->in.scm_hnd || !op->in.name || !mem_ctx ) {
203 hnd->status = NT_STATUS_INVALID_PARAMETER;
204 return CAC_FAILURE;
205 }
206
207 pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
208 if ( !pipe_hnd ) {
209 hnd->status = NT_STATUS_INVALID_HANDLE;
210 return CAC_FAILURE;
211 }
212
213 svc_hnd_out = talloc( mem_ctx, POLICY_HND );
214 if ( !svc_hnd_out ) {
215 hnd->status = NT_STATUS_NO_MEMORY;
216 return CAC_FAILURE;
217 }
218
219 err = rpccli_svcctl_open_service( pipe_hnd, mem_ctx, op->in.scm_hnd,
220 svc_hnd_out, op->in.name,
221 op->in.access );
222 hnd->status = werror_to_ntstatus( err );
223
224 if ( !NT_STATUS_IS_OK( hnd->status ) )
225 return CAC_FAILURE;
226
227 op->out.svc_hnd = svc_hnd_out;
228
229 return CAC_SUCCESS;
230}
231
232int cac_SvcControlService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
233 struct SvcControlService *op )
234{
235 struct rpc_pipe_client *pipe_hnd = NULL;
236 WERROR err;
237
238 SERVICE_STATUS status_out;
239
240 if ( !hnd )
241 return CAC_FAILURE;
242
243 if ( !hnd->_internal.ctx ) {
244 hnd->status = NT_STATUS_INVALID_HANDLE;
245 return CAC_FAILURE;
246 }
247
248 if ( !op || !op->in.svc_hnd || !mem_ctx ) {
249 hnd->status = NT_STATUS_INVALID_PARAMETER;
250 return CAC_FAILURE;
251 }
252
253 if ( op->in.control < SVCCTL_CONTROL_STOP
254 || op->in.control > SVCCTL_CONTROL_SHUTDOWN ) {
255 hnd->status = NT_STATUS_INVALID_PARAMETER;
256 return CAC_FAILURE;
257 }
258
259 pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
260 if ( !pipe_hnd ) {
261 hnd->status = NT_STATUS_INVALID_HANDLE;
262 return CAC_FAILURE;
263 }
264
265 err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx,
266 op->in.svc_hnd, op->in.control,
267 &status_out );
268 hnd->status = werror_to_ntstatus( err );
269
270 if ( !NT_STATUS_IS_OK( hnd->status ) )
271 return CAC_FAILURE;
272
273 return CAC_SUCCESS;
274}
275
276int cac_SvcGetStatus( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
277 struct SvcGetStatus *op )
278{
279 struct rpc_pipe_client *pipe_hnd = NULL;
280 WERROR err;
281
282 SERVICE_STATUS status_out;
283
284 if ( !hnd )
285 return CAC_FAILURE;
286
287 if ( !hnd->_internal.ctx ) {
288 hnd->status = NT_STATUS_INVALID_HANDLE;
289 return CAC_FAILURE;
290 }
291
292 if ( !op || !op->in.svc_hnd || !mem_ctx ) {
293 hnd->status = NT_STATUS_INVALID_PARAMETER;
294 return CAC_FAILURE;
295 }
296
297 pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
298 if ( !pipe_hnd ) {
299 hnd->status = NT_STATUS_INVALID_HANDLE;
300 return CAC_FAILURE;
301 }
302
303 err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, op->in.svc_hnd,
304 &status_out );
305 hnd->status = werror_to_ntstatus( err );
306
307 if ( !NT_STATUS_IS_OK( hnd->status ) )
308 return CAC_FAILURE;
309
310 op->out.status = status_out;