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