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