Line data Source code
1 : /*
2 : Samba Unix/Linux SMB client library
3 : Distributed SMB/CIFS Server Management Utility
4 : Copyright (C) 2006 Volker Lendecke (vl@samba.org)
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 3 of the License, or
9 : (at your option) any later version.
10 :
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.
15 :
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/>.
18 : */
19 : #include "includes.h"
20 : #include "utils/net.h"
21 : #include "rpc_client/rpc_client.h"
22 : #include "../librpc/gen_ndr/ndr_samr_c.h"
23 : #include "../libcli/security/security.h"
24 :
25 : /*
26 : * Do something with the account policies. Read them all, run a function on
27 : * them and possibly write them back. "fn" has to return the container index
28 : * it has modified, it can return 0 for no change.
29 : */
30 :
31 0 : static NTSTATUS rpc_sh_acct_do(struct net_context *c,
32 : TALLOC_CTX *mem_ctx,
33 : struct rpc_sh_ctx *ctx,
34 : struct rpc_pipe_client *pipe_hnd,
35 : int argc, const char **argv,
36 : int (*fn)(struct net_context *c,
37 : TALLOC_CTX *mem_ctx,
38 : struct rpc_sh_ctx *ctx,
39 : struct samr_DomInfo1 *i1,
40 : struct samr_DomInfo3 *i3,
41 : struct samr_DomInfo12 *i12,
42 : int argc, const char **argv))
43 : {
44 0 : struct policy_handle connect_pol, domain_pol;
45 0 : NTSTATUS status, result;
46 0 : union samr_DomainInfo *info1 = NULL;
47 0 : union samr_DomainInfo *info3 = NULL;
48 0 : union samr_DomainInfo *info12 = NULL;
49 0 : int store;
50 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
51 :
52 0 : ZERO_STRUCT(connect_pol);
53 0 : ZERO_STRUCT(domain_pol);
54 :
55 : /* Get sam policy handle */
56 :
57 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
58 0 : pipe_hnd->desthost,
59 : MAXIMUM_ALLOWED_ACCESS,
60 : &connect_pol,
61 : &result);
62 0 : if (!NT_STATUS_IS_OK(status)) {
63 0 : goto done;
64 : }
65 0 : if (!NT_STATUS_IS_OK(result)) {
66 0 : status = result;
67 0 : goto done;
68 : }
69 :
70 : /* Get domain policy handle */
71 :
72 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
73 : &connect_pol,
74 : MAXIMUM_ALLOWED_ACCESS,
75 : ctx->domain_sid,
76 : &domain_pol,
77 : &result);
78 0 : if (!NT_STATUS_IS_OK(status)) {
79 0 : goto done;
80 : }
81 0 : if (!NT_STATUS_IS_OK(result)) {
82 0 : status = result;
83 0 : goto done;
84 : }
85 :
86 0 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
87 : &domain_pol,
88 : 1,
89 : &info1,
90 : &result);
91 0 : if (!NT_STATUS_IS_OK(status)) {
92 0 : goto done;
93 : }
94 0 : if (!NT_STATUS_IS_OK(result)) {
95 0 : status = result;
96 0 : d_fprintf(stderr, _("query_domain_info level 1 failed: %s\n"),
97 : nt_errstr(result));
98 0 : goto done;
99 : }
100 :
101 0 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
102 : &domain_pol,
103 : 3,
104 : &info3,
105 : &result);
106 0 : if (!NT_STATUS_IS_OK(status)) {
107 0 : goto done;
108 : }
109 0 : if (!NT_STATUS_IS_OK(result)) {
110 0 : status = result;
111 0 : d_fprintf(stderr, _("query_domain_info level 3 failed: %s\n"),
112 : nt_errstr(result));
113 0 : goto done;
114 : }
115 :
116 0 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
117 : &domain_pol,
118 : 12,
119 : &info12,
120 : &result);
121 0 : if (!NT_STATUS_IS_OK(status)) {
122 0 : goto done;
123 : }
124 0 : if (!NT_STATUS_IS_OK(result)) {
125 0 : status = result;
126 0 : d_fprintf(stderr, _("query_domain_info level 12 failed: %s\n"),
127 : nt_errstr(result));
128 0 : goto done;
129 : }
130 :
131 0 : store = fn(c, mem_ctx, ctx, &info1->info1, &info3->info3,
132 0 : &info12->info12, argc, argv);
133 :
134 0 : if (store <= 0) {
135 : /* Don't save anything */
136 0 : goto done;
137 : }
138 :
139 0 : switch (store) {
140 0 : case 1:
141 0 : status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
142 : &domain_pol,
143 : 1,
144 : info1,
145 : &result);
146 0 : break;
147 0 : case 3:
148 0 : status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
149 : &domain_pol,
150 : 3,
151 : info3,
152 : &result);
153 0 : break;
154 0 : case 12:
155 0 : status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
156 : &domain_pol,
157 : 12,
158 : info12,
159 : &result);
160 0 : break;
161 0 : default:
162 0 : d_fprintf(stderr, _("Got unexpected info level %d\n"), store);
163 0 : status = NT_STATUS_INTERNAL_ERROR;
164 0 : goto done;
165 : }
166 :
167 0 : if (!NT_STATUS_IS_OK(status)) {
168 0 : goto done;
169 : }
170 :
171 0 : status = result;
172 :
173 0 : done:
174 0 : if (is_valid_policy_hnd(&domain_pol)) {
175 0 : dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
176 : }
177 0 : if (is_valid_policy_hnd(&connect_pol)) {
178 0 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
179 : }
180 :
181 0 : return status;
182 : }
183 :
184 0 : static int account_show(struct net_context *c,
185 : TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
186 : struct samr_DomInfo1 *i1,
187 : struct samr_DomInfo3 *i3,
188 : struct samr_DomInfo12 *i12,
189 : int argc, const char **argv)
190 : {
191 0 : if (argc != 0) {
192 0 : d_fprintf(stderr, "%s %s\n", _("Usage:"), ctx->whoami);
193 0 : return -1;
194 : }
195 :
196 0 : d_printf(_("Minimum password length: %d\n"), i1->min_password_length);
197 0 : d_printf(_("Password history length: %d\n"),
198 0 : i1->password_history_length);
199 :
200 0 : d_printf(_("Minimum password age: "));
201 0 : if (!nt_time_is_zero((NTTIME *)&i1->min_password_age)) {
202 0 : time_t t = nt_time_to_unix_abs((NTTIME *)&i1->min_password_age);
203 0 : d_printf(_("%d seconds\n"), (int)t);
204 : } else {
205 0 : d_printf(_("not set\n"));
206 : }
207 :
208 0 : d_printf(_("Maximum password age: "));
209 0 : if (nt_time_is_set((NTTIME *)&i1->max_password_age)) {
210 0 : time_t t = nt_time_to_unix_abs((NTTIME *)&i1->max_password_age);
211 0 : d_printf(_("%d seconds\n"), (int)t);
212 : } else {
213 0 : d_printf(_("not set\n"));
214 : }
215 :
216 0 : d_printf(_("Bad logon attempts: %d\n"), i12->lockout_threshold);
217 :
218 0 : if (i12->lockout_threshold != 0) {
219 :
220 0 : d_printf(_("Account lockout duration: "));
221 0 : if (nt_time_is_set(&i12->lockout_duration)) {
222 0 : time_t t = nt_time_to_unix_abs(&i12->lockout_duration);
223 0 : d_printf(_("%d seconds\n"), (int)t);
224 : } else {
225 0 : d_printf(_("not set\n"));
226 : }
227 :
228 0 : d_printf(_("Bad password count reset after: "));
229 0 : if (nt_time_is_set(&i12->lockout_window)) {
230 0 : time_t t = nt_time_to_unix_abs(&i12->lockout_window);
231 0 : d_printf(_("%d seconds\n"), (int)t);
232 : } else {
233 0 : d_printf(_("not set\n"));
234 : }
235 : }
236 :
237 0 : d_printf(_("Disconnect users when logon hours expire: %s\n"),
238 0 : nt_time_is_zero(&i3->force_logoff_time) ? _("yes") : _("no"));
239 :
240 0 : d_printf(_("User must logon to change password: %s\n"),
241 0 : (i1->password_properties & 0x2) ? _("yes") : _("no"));
242 :
243 0 : return 0; /* Don't save */
244 : }
245 :
246 0 : static NTSTATUS rpc_sh_acct_pol_show(struct net_context *c,
247 : TALLOC_CTX *mem_ctx,
248 : struct rpc_sh_ctx *ctx,
249 : struct rpc_pipe_client *pipe_hnd,
250 : int argc, const char **argv) {
251 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
252 : account_show);
253 : }
254 :
255 0 : static int account_set_badpw(struct net_context *c,
256 : TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
257 : struct samr_DomInfo1 *i1,
258 : struct samr_DomInfo3 *i3,
259 : struct samr_DomInfo12 *i12,
260 : int argc, const char **argv)
261 : {
262 0 : if (argc != 1) {
263 0 : d_fprintf(stderr, "%s %s <count>\n", _("Usage:"), ctx->whoami);
264 0 : return -1;
265 : }
266 :
267 0 : i12->lockout_threshold = atoi(argv[0]);
268 0 : d_printf(_("Setting bad password count to %d\n"),
269 0 : i12->lockout_threshold);
270 :
271 0 : return 12;
272 : }
273 :
274 0 : static NTSTATUS rpc_sh_acct_set_badpw(struct net_context *c,
275 : TALLOC_CTX *mem_ctx,
276 : struct rpc_sh_ctx *ctx,
277 : struct rpc_pipe_client *pipe_hnd,
278 : int argc, const char **argv)
279 : {
280 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
281 : account_set_badpw);
282 : }
283 :
284 0 : static int account_set_lockduration(struct net_context *c,
285 : TALLOC_CTX *mem_ctx,
286 : struct rpc_sh_ctx *ctx,
287 : struct samr_DomInfo1 *i1,
288 : struct samr_DomInfo3 *i3,
289 : struct samr_DomInfo12 *i12,
290 : int argc, const char **argv)
291 : {
292 0 : if (argc != 1) {
293 0 : d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
294 0 : return -1;
295 : }
296 :
297 0 : unix_to_nt_time_abs(&i12->lockout_duration, atoi(argv[0]));
298 0 : d_printf(_("Setting lockout duration to %d seconds\n"),
299 0 : (int)nt_time_to_unix_abs(&i12->lockout_duration));
300 :
301 0 : return 12;
302 : }
303 :
304 0 : static NTSTATUS rpc_sh_acct_set_lockduration(struct net_context *c,
305 : TALLOC_CTX *mem_ctx,
306 : struct rpc_sh_ctx *ctx,
307 : struct rpc_pipe_client *pipe_hnd,
308 : int argc, const char **argv)
309 : {
310 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
311 : account_set_lockduration);
312 : }
313 :
314 0 : static int account_set_resetduration(struct net_context *c,
315 : TALLOC_CTX *mem_ctx,
316 : struct rpc_sh_ctx *ctx,
317 : struct samr_DomInfo1 *i1,
318 : struct samr_DomInfo3 *i3,
319 : struct samr_DomInfo12 *i12,
320 : int argc, const char **argv)
321 : {
322 0 : if (argc != 1) {
323 0 : d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
324 0 : return -1;
325 : }
326 :
327 0 : unix_to_nt_time_abs(&i12->lockout_window, atoi(argv[0]));
328 0 : d_printf(_("Setting bad password reset duration to %d seconds\n"),
329 0 : (int)nt_time_to_unix_abs(&i12->lockout_window));
330 :
331 0 : return 12;
332 : }
333 :
334 0 : static NTSTATUS rpc_sh_acct_set_resetduration(struct net_context *c,
335 : TALLOC_CTX *mem_ctx,
336 : struct rpc_sh_ctx *ctx,
337 : struct rpc_pipe_client *pipe_hnd,
338 : int argc, const char **argv)
339 : {
340 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
341 : account_set_resetduration);
342 : }
343 :
344 0 : static int account_set_minpwage(struct net_context *c,
345 : TALLOC_CTX *mem_ctx,
346 : struct rpc_sh_ctx *ctx,
347 : struct samr_DomInfo1 *i1,
348 : struct samr_DomInfo3 *i3,
349 : struct samr_DomInfo12 *i12,
350 : int argc, const char **argv)
351 : {
352 0 : if (argc != 1) {
353 0 : d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
354 0 : return -1;
355 : }
356 :
357 0 : unix_to_nt_time_abs((NTTIME *)&i1->min_password_age, atoi(argv[0]));
358 0 : d_printf(_("Setting minimum password age to %d seconds\n"),
359 0 : (int)nt_time_to_unix_abs((NTTIME *)&i1->min_password_age));
360 :
361 0 : return 1;
362 : }
363 :
364 0 : static NTSTATUS rpc_sh_acct_set_minpwage(struct net_context *c,
365 : TALLOC_CTX *mem_ctx,
366 : struct rpc_sh_ctx *ctx,
367 : struct rpc_pipe_client *pipe_hnd,
368 : int argc, const char **argv)
369 : {
370 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
371 : account_set_minpwage);
372 : }
373 :
374 0 : static int account_set_maxpwage(struct net_context *c,
375 : TALLOC_CTX *mem_ctx,
376 : struct rpc_sh_ctx *ctx,
377 : struct samr_DomInfo1 *i1,
378 : struct samr_DomInfo3 *i3,
379 : struct samr_DomInfo12 *i12,
380 : int argc, const char **argv)
381 : {
382 0 : if (argc != 1) {
383 0 : d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
384 0 : return -1;
385 : }
386 :
387 0 : unix_to_nt_time_abs((NTTIME *)&i1->max_password_age, atoi(argv[0]));
388 0 : d_printf(_("Setting maximum password age to %d seconds\n"),
389 0 : (int)nt_time_to_unix_abs((NTTIME *)&i1->max_password_age));
390 :
391 0 : return 1;
392 : }
393 :
394 0 : static NTSTATUS rpc_sh_acct_set_maxpwage(struct net_context *c,
395 : TALLOC_CTX *mem_ctx,
396 : struct rpc_sh_ctx *ctx,
397 : struct rpc_pipe_client *pipe_hnd,
398 : int argc, const char **argv)
399 : {
400 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
401 : account_set_maxpwage);
402 : }
403 :
404 0 : static int account_set_minpwlen(struct net_context *c,
405 : TALLOC_CTX *mem_ctx,
406 : struct rpc_sh_ctx *ctx,
407 : struct samr_DomInfo1 *i1,
408 : struct samr_DomInfo3 *i3,
409 : struct samr_DomInfo12 *i12,
410 : int argc, const char **argv)
411 : {
412 0 : if (argc != 1) {
413 0 : d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
414 0 : return -1;
415 : }
416 :
417 0 : i1->min_password_length = atoi(argv[0]);
418 0 : d_printf(_("Setting minimum password length to %d\n"),
419 0 : i1->min_password_length);
420 :
421 0 : return 1;
422 : }
423 :
424 0 : static NTSTATUS rpc_sh_acct_set_minpwlen(struct net_context *c,
425 : TALLOC_CTX *mem_ctx,
426 : struct rpc_sh_ctx *ctx,
427 : struct rpc_pipe_client *pipe_hnd,
428 : int argc, const char **argv)
429 : {
430 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
431 : account_set_minpwlen);
432 : }
433 :
434 0 : static int account_set_pwhistlen(struct net_context *c,
435 : TALLOC_CTX *mem_ctx,
436 : struct rpc_sh_ctx *ctx,
437 : struct samr_DomInfo1 *i1,
438 : struct samr_DomInfo3 *i3,
439 : struct samr_DomInfo12 *i12,
440 : int argc, const char **argv)
441 : {
442 0 : if (argc != 1) {
443 0 : d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
444 0 : return -1;
445 : }
446 :
447 0 : i1->password_history_length = atoi(argv[0]);
448 0 : d_printf(_("Setting password history length to %d\n"),
449 0 : i1->password_history_length);
450 :
451 0 : return 1;
452 : }
453 :
454 0 : static NTSTATUS rpc_sh_acct_set_pwhistlen(struct net_context *c,
455 : TALLOC_CTX *mem_ctx,
456 : struct rpc_sh_ctx *ctx,
457 : struct rpc_pipe_client *pipe_hnd,
458 : int argc, const char **argv)
459 : {
460 0 : return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
461 : account_set_pwhistlen);
462 : }
463 :
464 0 : struct rpc_sh_cmd *net_rpc_acct_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
465 : struct rpc_sh_ctx *ctx)
466 : {
467 0 : static struct rpc_sh_cmd cmds[9] = {
468 : { "show", NULL, &ndr_table_samr, rpc_sh_acct_pol_show,
469 : N_("Show current account policy settings") },
470 : { "badpw", NULL, &ndr_table_samr, rpc_sh_acct_set_badpw,
471 : N_("Set bad password count before lockout") },
472 : { "lockduration", NULL, &ndr_table_samr, rpc_sh_acct_set_lockduration,
473 : N_("Set account lockout duration") },
474 : { "resetduration", NULL, &ndr_table_samr,
475 : rpc_sh_acct_set_resetduration,
476 : N_("Set bad password count reset duration") },
477 : { "minpwage", NULL, &ndr_table_samr, rpc_sh_acct_set_minpwage,
478 : N_("Set minimum password age") },
479 : { "maxpwage", NULL, &ndr_table_samr, rpc_sh_acct_set_maxpwage,
480 : N_("Set maximum password age") },
481 : { "minpwlen", NULL, &ndr_table_samr, rpc_sh_acct_set_minpwlen,
482 : N_("Set minimum password length") },
483 : { "pwhistlen", NULL, &ndr_table_samr, rpc_sh_acct_set_pwhistlen,
484 : N_("Set the password history length") },
485 : { NULL, NULL, 0, NULL, NULL }
486 : };
487 :
488 0 : return cmds;
489 : }
|