s3: Fix bug #9085.
[Samba.git] / source3 / utils / net_rpc_sh_acct.c
blob3e93fc503c7a57e5277403f15c5a57a351f4286b
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2006 Volker Lendecke (vl@samba.org)
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/>.
19 #include "includes.h"
20 #include "utils/net.h"
21 #include "../librpc/gen_ndr/cli_samr.h"
24 * Do something with the account policies. Read them all, run a function on
25 * them and possibly write them back. "fn" has to return the container index
26 * it has modified, it can return 0 for no change.
29 static NTSTATUS rpc_sh_acct_do(struct net_context *c,
30 TALLOC_CTX *mem_ctx,
31 struct rpc_sh_ctx *ctx,
32 struct rpc_pipe_client *pipe_hnd,
33 int argc, const char **argv,
34 int (*fn)(struct net_context *c,
35 TALLOC_CTX *mem_ctx,
36 struct rpc_sh_ctx *ctx,
37 struct samr_DomInfo1 *i1,
38 struct samr_DomInfo3 *i3,
39 struct samr_DomInfo12 *i12,
40 int argc, const char **argv))
42 struct policy_handle connect_pol, domain_pol;
43 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
44 union samr_DomainInfo *info1 = NULL;
45 union samr_DomainInfo *info3 = NULL;
46 union samr_DomainInfo *info12 = NULL;
47 int store;
49 ZERO_STRUCT(connect_pol);
50 ZERO_STRUCT(domain_pol);
52 /* Get sam policy handle */
54 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
55 pipe_hnd->desthost,
56 MAXIMUM_ALLOWED_ACCESS,
57 &connect_pol);
58 if (!NT_STATUS_IS_OK(result)) {
59 goto done;
62 /* Get domain policy handle */
64 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
65 &connect_pol,
66 MAXIMUM_ALLOWED_ACCESS,
67 ctx->domain_sid,
68 &domain_pol);
69 if (!NT_STATUS_IS_OK(result)) {
70 goto done;
73 result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx,
74 &domain_pol,
76 &info1);
78 if (!NT_STATUS_IS_OK(result)) {
79 d_fprintf(stderr, _("query_domain_info level 1 failed: %s\n"),
80 nt_errstr(result));
81 goto done;
84 result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx,
85 &domain_pol,
87 &info3);
89 if (!NT_STATUS_IS_OK(result)) {
90 d_fprintf(stderr, _("query_domain_info level 3 failed: %s\n"),
91 nt_errstr(result));
92 goto done;
95 result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx,
96 &domain_pol,
97 12,
98 &info12);
100 if (!NT_STATUS_IS_OK(result)) {
101 d_fprintf(stderr, _("query_domain_info level 12 failed: %s\n"),
102 nt_errstr(result));
103 goto done;
106 store = fn(c, mem_ctx, ctx, &info1->info1, &info3->info3,
107 &info12->info12, argc, argv);
109 if (store <= 0) {
110 /* Don't save anything */
111 goto done;
114 switch (store) {
115 case 1:
116 result = rpccli_samr_SetDomainInfo(pipe_hnd, mem_ctx,
117 &domain_pol,
119 info1);
120 break;
121 case 3:
122 result = rpccli_samr_SetDomainInfo(pipe_hnd, mem_ctx,
123 &domain_pol,
125 info3);
126 break;
127 case 12:
128 result = rpccli_samr_SetDomainInfo(pipe_hnd, mem_ctx,
129 &domain_pol,
131 info12);
132 break;
133 default:
134 d_fprintf(stderr, _("Got unexpected info level %d\n"), store);
135 result = NT_STATUS_INTERNAL_ERROR;
136 goto done;
139 done:
140 if (is_valid_policy_hnd(&domain_pol)) {
141 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
143 if (is_valid_policy_hnd(&connect_pol)) {
144 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
147 return result;
150 static int account_show(struct net_context *c,
151 TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
152 struct samr_DomInfo1 *i1,
153 struct samr_DomInfo3 *i3,
154 struct samr_DomInfo12 *i12,
155 int argc, const char **argv)
157 if (argc != 0) {
158 d_fprintf(stderr, "%s %s\n", _("Usage:"), ctx->whoami);
159 return -1;
162 d_printf(_("Minimum password length: %d\n"), i1->min_password_length);
163 d_printf(_("Password history length: %d\n"),
164 i1->password_history_length);
166 d_printf(_("Minimum password age: "));
167 if (!nt_time_is_zero((NTTIME *)&i1->min_password_age)) {
168 time_t t = nt_time_to_unix_abs((NTTIME *)&i1->min_password_age);
169 d_printf(_("%d seconds\n"), (int)t);
170 } else {
171 d_printf(_("not set\n"));
174 d_printf(_("Maximum password age: "));
175 if (nt_time_is_set((NTTIME *)&i1->max_password_age)) {
176 time_t t = nt_time_to_unix_abs((NTTIME *)&i1->max_password_age);
177 d_printf(_("%d seconds\n"), (int)t);
178 } else {
179 d_printf(_("not set\n"));
182 d_printf(_("Bad logon attempts: %d\n"), i12->lockout_threshold);
184 if (i12->lockout_threshold != 0) {
186 d_printf(_("Account lockout duration: "));
187 if (nt_time_is_set(&i12->lockout_duration)) {
188 time_t t = nt_time_to_unix_abs(&i12->lockout_duration);
189 d_printf(_("%d seconds\n"), (int)t);
190 } else {
191 d_printf(_("not set\n"));
194 d_printf(_("Bad password count reset after: "));
195 if (nt_time_is_set(&i12->lockout_window)) {
196 time_t t = nt_time_to_unix_abs(&i12->lockout_window);
197 d_printf(_("%d seconds\n"), (int)t);
198 } else {
199 d_printf(_("not set\n"));
203 d_printf(_("Disconnect users when logon hours expire: %s\n"),
204 nt_time_is_zero(&i3->force_logoff_time) ? _("yes") : _("no"));
206 d_printf(_("User must logon to change password: %s\n"),
207 (i1->password_properties & 0x2) ? _("yes") : _("no"));
209 return 0; /* Don't save */
212 static NTSTATUS rpc_sh_acct_pol_show(struct net_context *c,
213 TALLOC_CTX *mem_ctx,
214 struct rpc_sh_ctx *ctx,
215 struct rpc_pipe_client *pipe_hnd,
216 int argc, const char **argv) {
217 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
218 account_show);
221 static int account_set_badpw(struct net_context *c,
222 TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
223 struct samr_DomInfo1 *i1,
224 struct samr_DomInfo3 *i3,
225 struct samr_DomInfo12 *i12,
226 int argc, const char **argv)
228 if (argc != 1) {
229 d_fprintf(stderr, "%s %s <count>\n", _("Usage:"), ctx->whoami);
230 return -1;
233 i12->lockout_threshold = atoi(argv[0]);
234 d_printf(_("Setting bad password count to %d\n"),
235 i12->lockout_threshold);
237 return 12;
240 static NTSTATUS rpc_sh_acct_set_badpw(struct net_context *c,
241 TALLOC_CTX *mem_ctx,
242 struct rpc_sh_ctx *ctx,
243 struct rpc_pipe_client *pipe_hnd,
244 int argc, const char **argv)
246 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
247 account_set_badpw);
250 static int account_set_lockduration(struct net_context *c,
251 TALLOC_CTX *mem_ctx,
252 struct rpc_sh_ctx *ctx,
253 struct samr_DomInfo1 *i1,
254 struct samr_DomInfo3 *i3,
255 struct samr_DomInfo12 *i12,
256 int argc, const char **argv)
258 if (argc != 1) {
259 d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
260 return -1;
263 unix_to_nt_time_abs(&i12->lockout_duration, atoi(argv[0]));
264 d_printf(_("Setting lockout duration to %d seconds\n"),
265 (int)nt_time_to_unix_abs(&i12->lockout_duration));
267 return 12;
270 static NTSTATUS rpc_sh_acct_set_lockduration(struct net_context *c,
271 TALLOC_CTX *mem_ctx,
272 struct rpc_sh_ctx *ctx,
273 struct rpc_pipe_client *pipe_hnd,
274 int argc, const char **argv)
276 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
277 account_set_lockduration);
280 static int account_set_resetduration(struct net_context *c,
281 TALLOC_CTX *mem_ctx,
282 struct rpc_sh_ctx *ctx,
283 struct samr_DomInfo1 *i1,
284 struct samr_DomInfo3 *i3,
285 struct samr_DomInfo12 *i12,
286 int argc, const char **argv)
288 if (argc != 1) {
289 d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
290 return -1;
293 unix_to_nt_time_abs(&i12->lockout_window, atoi(argv[0]));
294 d_printf(_("Setting bad password reset duration to %d seconds\n"),
295 (int)nt_time_to_unix_abs(&i12->lockout_window));
297 return 12;
300 static NTSTATUS rpc_sh_acct_set_resetduration(struct net_context *c,
301 TALLOC_CTX *mem_ctx,
302 struct rpc_sh_ctx *ctx,
303 struct rpc_pipe_client *pipe_hnd,
304 int argc, const char **argv)
306 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
307 account_set_resetduration);
310 static int account_set_minpwage(struct net_context *c,
311 TALLOC_CTX *mem_ctx,
312 struct rpc_sh_ctx *ctx,
313 struct samr_DomInfo1 *i1,
314 struct samr_DomInfo3 *i3,
315 struct samr_DomInfo12 *i12,
316 int argc, const char **argv)
318 if (argc != 1) {
319 d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
320 return -1;
323 unix_to_nt_time_abs((NTTIME *)&i1->min_password_age, atoi(argv[0]));
324 d_printf(_("Setting minimum password age to %d seconds\n"),
325 (int)nt_time_to_unix_abs((NTTIME *)&i1->min_password_age));
327 return 1;
330 static NTSTATUS rpc_sh_acct_set_minpwage(struct net_context *c,
331 TALLOC_CTX *mem_ctx,
332 struct rpc_sh_ctx *ctx,
333 struct rpc_pipe_client *pipe_hnd,
334 int argc, const char **argv)
336 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
337 account_set_minpwage);
340 static int account_set_maxpwage(struct net_context *c,
341 TALLOC_CTX *mem_ctx,
342 struct rpc_sh_ctx *ctx,
343 struct samr_DomInfo1 *i1,
344 struct samr_DomInfo3 *i3,
345 struct samr_DomInfo12 *i12,
346 int argc, const char **argv)
348 if (argc != 1) {
349 d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
350 return -1;
353 unix_to_nt_time_abs((NTTIME *)&i1->max_password_age, atoi(argv[0]));
354 d_printf(_("Setting maximum password age to %d seconds\n"),
355 (int)nt_time_to_unix_abs((NTTIME *)&i1->max_password_age));
357 return 1;
360 static NTSTATUS rpc_sh_acct_set_maxpwage(struct net_context *c,
361 TALLOC_CTX *mem_ctx,
362 struct rpc_sh_ctx *ctx,
363 struct rpc_pipe_client *pipe_hnd,
364 int argc, const char **argv)
366 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
367 account_set_maxpwage);
370 static int account_set_minpwlen(struct net_context *c,
371 TALLOC_CTX *mem_ctx,
372 struct rpc_sh_ctx *ctx,
373 struct samr_DomInfo1 *i1,
374 struct samr_DomInfo3 *i3,
375 struct samr_DomInfo12 *i12,
376 int argc, const char **argv)
378 if (argc != 1) {
379 d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
380 return -1;
383 i1->min_password_length = atoi(argv[0]);
384 d_printf(_("Setting minimum password length to %d\n"),
385 i1->min_password_length);
387 return 1;
390 static NTSTATUS rpc_sh_acct_set_minpwlen(struct net_context *c,
391 TALLOC_CTX *mem_ctx,
392 struct rpc_sh_ctx *ctx,
393 struct rpc_pipe_client *pipe_hnd,
394 int argc, const char **argv)
396 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
397 account_set_minpwlen);
400 static int account_set_pwhistlen(struct net_context *c,
401 TALLOC_CTX *mem_ctx,
402 struct rpc_sh_ctx *ctx,
403 struct samr_DomInfo1 *i1,
404 struct samr_DomInfo3 *i3,
405 struct samr_DomInfo12 *i12,
406 int argc, const char **argv)
408 if (argc != 1) {
409 d_fprintf(stderr, _("Usage: %s <count>\n"), ctx->whoami);
410 return -1;
413 i1->password_history_length = atoi(argv[0]);
414 d_printf(_("Setting password history length to %d\n"),
415 i1->password_history_length);
417 return 1;
420 static NTSTATUS rpc_sh_acct_set_pwhistlen(struct net_context *c,
421 TALLOC_CTX *mem_ctx,
422 struct rpc_sh_ctx *ctx,
423 struct rpc_pipe_client *pipe_hnd,
424 int argc, const char **argv)
426 return rpc_sh_acct_do(c, mem_ctx, ctx, pipe_hnd, argc, argv,
427 account_set_pwhistlen);
430 struct rpc_sh_cmd *net_rpc_acct_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
431 struct rpc_sh_ctx *ctx)
433 static struct rpc_sh_cmd cmds[9] = {
434 { "show", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_pol_show,
435 N_("Show current account policy settings") },
436 { "badpw", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_set_badpw,
437 N_("Set bad password count before lockout") },
438 { "lockduration", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_set_lockduration,
439 N_("Set account lockout duration") },
440 { "resetduration", NULL, &ndr_table_samr.syntax_id,
441 rpc_sh_acct_set_resetduration,
442 N_("Set bad password count reset duration") },
443 { "minpwage", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_set_minpwage,
444 N_("Set minimum password age") },
445 { "maxpwage", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_set_maxpwage,
446 N_("Set maximum password age") },
447 { "minpwlen", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_set_minpwlen,
448 N_("Set minimum password length") },
449 { "pwhistlen", NULL, &ndr_table_samr.syntax_id, rpc_sh_acct_set_pwhistlen,
450 N_("Set the password history length") },
451 { NULL, NULL, 0, NULL, NULL }
454 return cmds;