s3: smbd: Fix schedule_smb2_aio_read() to allow the last read in a compound to go...
[Samba.git] / source4 / torture / gpo / apply.c
blob560408f7a85e7b2eeb9dc89a88a6c8b429d3dc4d
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) David Mulder 2017
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 3 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, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "param/param.h"
22 #include "param/loadparm.h"
23 #include "torture/smbtorture.h"
24 #include "lib/util/mkdir_p.h"
25 #include "dsdb/samdb/samdb.h"
26 #include "auth/session.h"
27 #include "lib/ldb/include/ldb.h"
28 #include "torture/gpo/proto.h"
29 #include <unistd.h>
30 #include "lib/util/samba_util.h"
31 #include "util/tevent_ntstatus.h"
33 #undef strncasecmp
35 struct torture_suite *gpo_apply_suite(TALLOC_CTX *ctx)
37 struct torture_suite *suite = torture_suite_create(ctx, "apply");
39 torture_suite_add_simple_test(suite, "gpo_param_from_gpo",
40 torture_gpo_system_access_policies);
42 suite->description = talloc_strdup(suite, "Group Policy apply tests");
44 return suite;
47 static int exec_wait(struct torture_context *tctx, const char **gpo_update_cmd)
49 NTSTATUS status;
50 int ret = 0;
51 struct tevent_req *req;
53 req = samba_runcmd_send(tctx,
54 tctx->ev,
55 timeval_current_ofs(100, 0),
56 2, 0,
57 gpo_update_cmd,
58 "gpo_reload_cmd", NULL);
59 if (req == NULL) {
60 return -1;
63 if (!tevent_req_poll_ntstatus(req, tctx->ev, &status)) {
64 return -1;
66 if (samba_runcmd_recv(req, &ret) != 0) {
67 return -1;
69 return ret;
72 static int unix2nttime(const char *sval)
74 return (strtoll(sval, NULL, 10) * -1 / 60 / 60 / 24 / 10000000);
77 #define GPODIR "addom.samba.example.com/Policies/"\
78 "{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Microsoft/"\
79 "Windows NT/SecEdit"
80 #define GPOFILE "GptTmpl.inf"
81 #define GPTTMPL "[System Access]\n\
82 MinimumPasswordAge = %d\n\
83 MaximumPasswordAge = %d\n\
84 MinimumPasswordLength = %d\n\
85 PasswordComplexity = %d\n\
87 #define GPTINI "addom.samba.example.com/Policies/"\
88 "{31B2F340-016D-11D2-945F-00C04FB984F9}/GPT.INI"
90 bool torture_gpo_system_access_policies(struct torture_context *tctx)
92 TALLOC_CTX *ctx = talloc_new(tctx);
93 int ret, vers = 0, i;
94 const char *sysvol_path = NULL, *gpo_dir = NULL;
95 const char *gpo_file = NULL, *gpt_file = NULL;
96 struct ldb_context *samdb = NULL;
97 struct ldb_result *result;
98 const char *attrs[] = {
99 "minPwdAge",
100 "maxPwdAge",
101 "minPwdLength",
102 "pwdProperties",
103 NULL
105 FILE *fp = NULL;
106 const char **gpo_update_cmd;
107 const char **gpo_unapply_cmd;
108 const char **gpo_update_force_cmd;
109 int minpwdcases[] = { 0, 1, 998 };
110 int maxpwdcases[] = { 0, 1, 999 };
111 int pwdlencases[] = { 0, 1, 14 };
112 int pwdpropcases[] = { 0, 1, 1 };
113 struct ldb_message *old_message = NULL;
114 const char **itr;
115 int gpo_update_len = 0;
117 sysvol_path = lpcfg_path(lpcfg_service(tctx->lp_ctx, "sysvol"),
118 lpcfg_default_service(tctx->lp_ctx), tctx);
119 torture_assert(tctx, sysvol_path, "Failed to fetch the sysvol path");
121 /* Ensure the sysvol path exists */
122 gpo_dir = talloc_asprintf(ctx, "%s/%s", sysvol_path, GPODIR);
123 mkdir_p(gpo_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
124 gpo_file = talloc_asprintf(ctx, "%s/%s", gpo_dir, GPOFILE);
126 /* Get the gpo update command */
127 gpo_update_cmd = lpcfg_gpo_update_command(tctx->lp_ctx);
128 torture_assert(tctx, gpo_update_cmd && gpo_update_cmd[0],
129 "Failed to fetch the gpo update command");
131 /* Open and read the samba db and store the initial password settings */
132 samdb = samdb_connect(ctx,
133 tctx->ev,
134 tctx->lp_ctx,
135 system_session(tctx->lp_ctx),
136 NULL,
138 torture_assert(tctx, samdb, "Failed to connect to the samdb");
140 ret = ldb_search(samdb, ctx, &result, ldb_get_default_basedn(samdb),
141 LDB_SCOPE_BASE, attrs, NULL);
142 torture_assert(tctx, ret == LDB_SUCCESS && result->count == 1,
143 "Searching the samdb failed");
145 old_message = result->msgs[0];
147 for (i = 0; i < 3; i++) {
148 /* Write out the sysvol */
149 if ( (fp = fopen(gpo_file, "w")) ) {
150 fputs(talloc_asprintf(ctx, GPTTMPL, minpwdcases[i],
151 maxpwdcases[i], pwdlencases[i],
152 pwdpropcases[i]), fp);
153 fclose(fp);
156 /* Update the version in the GPT.INI */
157 gpt_file = talloc_asprintf(ctx, "%s/%s", sysvol_path, GPTINI);
158 if ( (fp = fopen(gpt_file, "r")) ) {
159 char line[256];
160 while (fgets(line, 256, fp)) {
161 if (strncasecmp(line, "Version=", 8) == 0) {
162 vers = atoi(line+8);
163 break;
166 fclose(fp);
168 if ( (fp = fopen(gpt_file, "w")) ) {
169 char *data = talloc_asprintf(ctx,
170 "[General]\nVersion=%d\n",
171 ++vers);
172 fputs(data, fp);
173 fclose(fp);
176 /* Run the gpo update command */
177 ret = exec_wait(tctx, gpo_update_cmd);
179 torture_assert(tctx, ret == 0,
180 "Failed to execute the gpo update command");
181 ret = ldb_search(samdb, ctx, &result,
182 ldb_get_default_basedn(samdb),
183 LDB_SCOPE_BASE, attrs, NULL);
184 torture_assert(tctx, ret == LDB_SUCCESS && result->count == 1,
185 "Searching the samdb failed");
187 /* minPwdAge */
188 torture_assert_int_equal(tctx, unix2nttime(
189 ldb_msg_find_attr_as_string(
190 result->msgs[0],
191 attrs[0],
192 "")), minpwdcases[i],
193 "The minPwdAge was not applied");
195 /* maxPwdAge */
196 torture_assert_int_equal(tctx, unix2nttime(
197 ldb_msg_find_attr_as_string(
198 result->msgs[0],
199 attrs[1],
200 "")), maxpwdcases[i],
201 "The maxPwdAge was not applied");
203 /* minPwdLength */
204 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
205 result->msgs[0],
206 attrs[2],
207 -1),
208 pwdlencases[i],
209 "The minPwdLength was not applied");
211 /* pwdProperties */
212 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
213 result->msgs[0],
214 attrs[3],
215 -1),
216 pwdpropcases[i],
217 "The pwdProperties were not applied");
220 /* Reset settings, then verify a reapply doesn't force them back */
221 for (i = 0; i < old_message->num_elements; i++) {
222 old_message->elements[i].flags = LDB_FLAG_MOD_REPLACE;
224 ret = ldb_modify(samdb, old_message);
225 torture_assert(tctx, ret == 0, "Failed to reset password settings.");
227 ret = exec_wait(tctx, gpo_update_cmd);
228 torture_assert(tctx, ret == 0,
229 "Failed to execute the gpo update command");
231 /* Validate that the apply did nothing (without --force param) */
232 ret = ldb_search(samdb, ctx, &result, ldb_get_default_basedn(samdb),
233 LDB_SCOPE_BASE, attrs, NULL);
234 torture_assert(tctx, ret == LDB_SUCCESS && result->count == 1,
235 "Searching the samdb failed");
236 /* minPwdAge */
237 torture_assert_int_equal(tctx, unix2nttime(ldb_msg_find_attr_as_string(
238 result->msgs[0],
239 attrs[0],
240 "")),
241 unix2nttime(ldb_msg_find_attr_as_string(old_message,
242 attrs[0],
245 "The minPwdAge was re-applied");
246 /* maxPwdAge */
247 torture_assert_int_equal(tctx, unix2nttime(ldb_msg_find_attr_as_string(
248 result->msgs[0],
249 attrs[1],
250 "")),
251 unix2nttime(ldb_msg_find_attr_as_string(old_message,
252 attrs[1],
255 "The maxPwdAge was re-applied");
256 /* minPwdLength */
257 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
258 result->msgs[0],
259 attrs[2],
260 -1),
261 ldb_msg_find_attr_as_int(
262 old_message,
263 attrs[2],
264 -2),
265 "The minPwdLength was re-applied");
266 /* pwdProperties */
267 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
268 result->msgs[0],
269 attrs[3],
270 -1),
271 ldb_msg_find_attr_as_int(
272 old_message,
273 attrs[3],
274 -2),
275 "The pwdProperties were re-applied");
277 for (itr = gpo_update_cmd; *itr != NULL; itr++) {
278 gpo_update_len++;
281 /* Run gpupdate --force and verify settings are re-applied */
282 gpo_update_force_cmd = talloc_array(ctx, const char*, gpo_update_len+2);
283 for (i = 0; i < gpo_update_len; i++) {
284 gpo_update_force_cmd[i] = talloc_strdup(gpo_update_force_cmd,
285 gpo_update_cmd[i]);
287 gpo_update_force_cmd[i] = talloc_asprintf(gpo_update_force_cmd,
288 "--force");
289 gpo_update_force_cmd[i+1] = NULL;
290 ret = exec_wait(tctx, gpo_update_force_cmd);
291 torture_assert(tctx, ret == 0,
292 "Failed to execute the gpupdate --force command");
294 ret = ldb_search(samdb, ctx, &result,
295 ldb_get_default_basedn(samdb),
296 LDB_SCOPE_BASE, attrs, NULL);
297 torture_assert(tctx, ret == LDB_SUCCESS && result->count == 1,
298 "Searching the samdb failed");
300 /* minPwdAge */
301 torture_assert_int_equal(tctx, unix2nttime(
302 ldb_msg_find_attr_as_string(
303 result->msgs[0],
304 attrs[0],
305 "")), minpwdcases[2],
306 "The minPwdAge was not applied");
308 /* maxPwdAge */
309 torture_assert_int_equal(tctx, unix2nttime(
310 ldb_msg_find_attr_as_string(
311 result->msgs[0],
312 attrs[1],
313 "")), maxpwdcases[2],
314 "The maxPwdAge was not applied");
316 /* minPwdLength */
317 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
318 result->msgs[0],
319 attrs[2],
320 -1),
321 pwdlencases[2],
322 "The minPwdLength was not applied");
324 /* pwdProperties */
325 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
326 result->msgs[0],
327 attrs[3],
328 -1),
329 pwdpropcases[2],
330 "The pwdProperties were not applied");
332 /* Unapply the settings and verify they are removed */
333 gpo_unapply_cmd = talloc_array(ctx, const char*, gpo_update_len+2);
334 for (i = 0; i < gpo_update_len; i++) {
335 gpo_unapply_cmd[i] = talloc_strdup(gpo_unapply_cmd,
336 gpo_update_cmd[i]);
338 gpo_unapply_cmd[i] = talloc_asprintf(gpo_unapply_cmd, "--unapply");
339 gpo_unapply_cmd[i+1] = NULL;
340 ret = exec_wait(tctx, gpo_unapply_cmd);
341 torture_assert(tctx, ret == 0,
342 "Failed to execute the gpo unapply command");
343 ret = ldb_search(samdb, ctx, &result, ldb_get_default_basedn(samdb),
344 LDB_SCOPE_BASE, attrs, NULL);
345 torture_assert(tctx, ret == LDB_SUCCESS && result->count == 1,
346 "Searching the samdb failed");
347 /* minPwdAge */
348 torture_assert_int_equal(tctx, unix2nttime(ldb_msg_find_attr_as_string(
349 result->msgs[0],
350 attrs[0],
351 "")),
352 unix2nttime(ldb_msg_find_attr_as_string(old_message,
353 attrs[0],
356 "The minPwdAge was not unapplied");
357 /* maxPwdAge */
358 torture_assert_int_equal(tctx, unix2nttime(ldb_msg_find_attr_as_string(
359 result->msgs[0],
360 attrs[1],
361 "")),
362 unix2nttime(ldb_msg_find_attr_as_string(old_message,
363 attrs[1],
366 "The maxPwdAge was not unapplied");
367 /* minPwdLength */
368 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
369 result->msgs[0],
370 attrs[2],
371 -1),
372 ldb_msg_find_attr_as_int(
373 old_message,
374 attrs[2],
375 -2),
376 "The minPwdLength was not unapplied");
377 /* pwdProperties */
378 torture_assert_int_equal(tctx, ldb_msg_find_attr_as_int(
379 result->msgs[0],
380 attrs[3],
381 -1),
382 ldb_msg_find_attr_as_int(
383 old_message,
384 attrs[3],
385 -2),
386 "The pwdProperties were not unapplied");
388 talloc_free(ctx);
389 return true;