s4-smbtorture: add test for svcctl_QueryServiceConfig2W.
[ira/wip.git] / source4 / torture / rpc / svcctl.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for srvsvc rpc operations
4
5    Copyright (C) Jelmer Vernooij 2004
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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "librpc/gen_ndr/ndr_svcctl_c.h"
24 #include "torture/rpc/rpc.h"
25
26 static bool test_OpenSCManager(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
27 {
28         struct svcctl_OpenSCManagerW r;
29
30         r.in.MachineName = NULL;
31         r.in.DatabaseName = NULL;
32         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
33         r.out.handle = h;
34
35         torture_assert_ntstatus_ok(tctx,
36                                    dcerpc_svcctl_OpenSCManagerW(p, tctx, &r),
37                                    "OpenSCManager failed!");
38
39         return true;
40 }
41
42 static bool test_CloseServiceHandle(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
43 {
44         struct svcctl_CloseServiceHandle r;
45
46         r.in.handle = h;
47         r.out.handle = h;
48         torture_assert_ntstatus_ok(tctx,
49                                    dcerpc_svcctl_CloseServiceHandle(p, tctx, &r),
50                                    "CloseServiceHandle failed");
51
52         return true;
53 }
54
55 static bool test_OpenService(struct dcerpc_pipe *p, struct torture_context *tctx,
56                              struct policy_handle *h, const char *name, struct policy_handle *s)
57 {
58         struct svcctl_OpenServiceW r;
59
60         r.in.scmanager_handle = h;
61         r.in.ServiceName = name;
62         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
63         r.out.handle = s;
64
65         torture_assert_ntstatus_ok(tctx,
66                                    dcerpc_svcctl_OpenServiceW(p, tctx, &r),
67                                    "OpenServiceW failed!");
68         torture_assert_werr_ok(tctx, r.out.result, "OpenServiceW failed!");
69
70         return true;
71
72 }
73
74 static bool test_QueryServiceStatusEx(struct torture_context *tctx, struct dcerpc_pipe *p)
75 {
76         struct svcctl_QueryServiceStatusEx r;
77         struct policy_handle h, s;
78         NTSTATUS status;
79
80         uint32_t info_level = 0;
81         uint8_t *buffer;
82         uint32_t buf_size = 0;
83         uint32_t bytes_needed = 0;
84
85         if (!test_OpenSCManager(p, tctx, &h))
86                 return false;
87
88         if (!test_OpenService(p, tctx, &h, "Netlogon", &s))
89                 return false;
90
91         buffer = talloc(tctx, uint8_t);
92
93         r.in.handle = &s;
94         r.in.info_level = 0;
95         r.in.buf_size = buf_size;
96         r.out.buffer = buffer;
97         r.out.bytes_needed = &bytes_needed;
98
99         status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
100         torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
101
102         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
103                 r.in.buf_size = bytes_needed;
104                 buffer = talloc_array(tctx, uint8_t, bytes_needed);
105                 r.out.buffer = buffer;
106
107                 status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
108                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
109                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatusEx failed!");
110         }
111
112         if (!test_CloseServiceHandle(p, tctx, &s))
113                 return false;
114
115         if (!test_CloseServiceHandle(p, tctx, &h))
116                 return false;
117
118         return true;
119 }
120
121 static bool test_QueryServiceConfig2W(struct torture_context *tctx, struct dcerpc_pipe *p)
122 {
123         struct svcctl_QueryServiceConfig2W r;
124         struct policy_handle h, s;
125         NTSTATUS status;
126
127         uint32_t info_level = 0;
128         uint8_t *buffer;
129         uint32_t buf_size = 0;
130         uint32_t bytes_needed = 0;
131
132         if (!test_OpenSCManager(p, tctx, &h))
133                 return false;
134
135         if (!test_OpenService(p, tctx, &h, "Netlogon", &s))
136                 return false;
137
138         buffer = talloc(tctx, uint8_t);
139
140         r.in.handle = &s;
141         r.in.info_level = 1;
142         r.in.buf_size = buf_size;
143         r.out.buffer = buffer;
144         r.out.bytes_needed = &bytes_needed;
145
146         status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
147         torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
148
149         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
150                 r.in.buf_size = bytes_needed;
151                 buffer = talloc_array(tctx, uint8_t, bytes_needed);
152                 r.out.buffer = buffer;
153
154                 status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
155                 torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
156                 torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
157         }
158
159         if (!test_CloseServiceHandle(p, tctx, &s))
160                 return false;
161
162         if (!test_CloseServiceHandle(p, tctx, &h))
163                 return false;
164
165         return true;
166 }
167
168 static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_pipe *p)
169 {
170         struct svcctl_EnumServicesStatusW r;
171         struct policy_handle h;
172         int i;
173         NTSTATUS status;
174         uint32_t resume_handle = 0;
175         struct ENUM_SERVICE_STATUS *service = NULL;
176         uint32_t bytes_needed = 0;
177         uint32_t services_returned = 0;
178
179         if (!test_OpenSCManager(p, tctx, &h))
180                 return false;
181
182         r.in.handle = &h;
183         r.in.type = SERVICE_TYPE_WIN32;
184         r.in.state = SERVICE_STATE_ALL;
185         r.in.buf_size = 0;
186         r.in.resume_handle = &resume_handle;
187         r.out.service = NULL;
188         r.out.resume_handle = &resume_handle;
189         r.out.services_returned = &services_returned;
190         r.out.bytes_needed = &bytes_needed;
191
192         status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
193
194         torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
195
196         if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
197                 r.in.buf_size = bytes_needed;
198                 r.out.service = talloc_array(tctx, uint8_t, bytes_needed);
199
200                 status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
201
202                 torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
203                 torture_assert_werr_ok(tctx, r.out.result, "EnumServicesStatus failed");
204
205                 service = (struct ENUM_SERVICE_STATUS *)r.out.service;
206         }
207
208         for(i = 0; i < services_returned; i++) {
209                 printf("Type: %d, State: %d\n", service[i].status.type, service[i].status.state);
210         }
211
212         if (!test_CloseServiceHandle(p, tctx, &h))
213                 return false;
214
215         return true;
216 }
217
218 static bool test_SCManager(struct torture_context *tctx,
219                                                    struct dcerpc_pipe *p)
220 {
221         struct policy_handle h;
222
223         if (!test_OpenSCManager(p, tctx, &h))
224                 return false;
225
226         if (!test_CloseServiceHandle(p, tctx, &h))
227                 return false;
228
229         return true;
230 }
231
232 struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx)
233 {
234         struct torture_suite *suite = torture_suite_create(mem_ctx, "SVCCTL");
235         struct torture_rpc_tcase *tcase;
236
237         tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", &ndr_table_svcctl);
238
239         torture_rpc_tcase_add_test(tcase, "SCManager",
240                                    test_SCManager);
241         torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
242                                    test_EnumServicesStatus);
243         torture_rpc_tcase_add_test(tcase, "QueryServiceStatusEx",
244                                    test_QueryServiceStatusEx);
245         torture_rpc_tcase_add_test(tcase, "QueryServiceConfig2W",
246                                    test_QueryServiceConfig2W);
247
248         return suite;
249 }