5d0ce73664884f3c87789e4afd48c5af81ecc340
[jra/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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19  
20 #include "includes.h"
21 #include "utils/net.h"
22
23 /*
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.
27  */
28
29 static NTSTATUS rpc_sh_acct_do(TALLOC_CTX *mem_ctx,
30                                struct rpc_sh_ctx *ctx,
31                                struct rpc_pipe_client *pipe_hnd,
32                                int argc, const char **argv,
33                                BOOL (*fn)(TALLOC_CTX *mem_ctx,
34                                           struct rpc_sh_ctx *ctx,
35                                           SAM_UNK_INFO_1 *i1,
36                                           SAM_UNK_INFO_3 *i3,
37                                           SAM_UNK_INFO_12 *i12,
38                                           int argc, const char **argv))
39 {
40         POLICY_HND connect_pol, domain_pol;
41         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
42         SAM_UNK_CTR ctr1, ctr3, ctr12;
43         int store;
44
45         ZERO_STRUCT(connect_pol);
46         ZERO_STRUCT(domain_pol);
47
48         /* Get sam policy handle */
49         
50         result = rpccli_samr_connect(pipe_hnd, mem_ctx,
51                                      MAXIMUM_ALLOWED_ACCESS, 
52                                      &connect_pol);
53         if (!NT_STATUS_IS_OK(result)) {
54                 goto done;
55         }
56         
57         /* Get domain policy handle */
58         
59         result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
60                                          MAXIMUM_ALLOWED_ACCESS,
61                                          ctx->domain_sid, &domain_pol);
62         if (!NT_STATUS_IS_OK(result)) {
63                 goto done;
64         }
65
66         result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
67                                             1, &ctr1);
68
69         if (!NT_STATUS_IS_OK(result)) {
70                 d_fprintf(stderr, "query_domain_info level 1 failed: %s\n",
71                           nt_errstr(result));
72                 goto done;
73         }
74
75         result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
76                                             3, &ctr3);
77
78         if (!NT_STATUS_IS_OK(result)) {
79                 d_fprintf(stderr, "query_domain_info level 3 failed: %s\n",
80                           nt_errstr(result));
81                 goto done;
82         }
83
84         result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
85                                             12, &ctr12);
86
87         if (!NT_STATUS_IS_OK(result)) {
88                 d_fprintf(stderr, "query_domain_info level 12 failed: %s\n",
89                           nt_errstr(result));
90                 goto done;
91         }
92
93         store = fn(mem_ctx, ctx, &ctr1.info.inf1, &ctr3.info.inf3,
94                    &ctr12.info.inf12, argc, argv);
95
96         if (store <= 0) {
97                 /* Don't save anything */
98                 goto done;
99         }
100
101         switch (store) {
102         case 1:
103                 result = rpccli_samr_set_domain_info(pipe_hnd, mem_ctx,
104                                                      &domain_pol, 1, &ctr1);
105                 break;
106         case 3:
107                 result = rpccli_samr_set_domain_info(pipe_hnd, mem_ctx,
108                                                      &domain_pol, 3, &ctr3);
109                 break;
110         case 12:
111                 result = rpccli_samr_set_domain_info(pipe_hnd, mem_ctx,
112                                                      &domain_pol, 12, &ctr12);
113                 break;
114         default:
115                 d_fprintf(stderr, "Got unexpected info level %d\n", store);
116                 result = NT_STATUS_INTERNAL_ERROR;
117                 goto done;
118         }
119
120  done:
121         if (is_valid_policy_hnd(&domain_pol)) {
122                 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
123         }
124         if (is_valid_policy_hnd(&connect_pol)) {
125                 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
126         }
127
128         return result;
129 }
130
131 static int account_show(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
132                         SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
133                         SAM_UNK_INFO_12 *i12,
134                         int argc, const char **argv)
135 {
136         if (argc != 0) {
137                 d_fprintf(stderr, "usage: %s\n", ctx->whoami);
138                 return -1;
139         }
140
141         d_printf("Minimum password length: %d\n", i1->min_length_password);
142         d_printf("Password history length: %d\n", i1->password_history);
143
144         d_printf("Minimum password age: ");
145         if (!nt_time_is_zero(&i1->min_passwordage)) {
146                 time_t t = nt_time_to_unix_abs(&i1->min_passwordage);
147                 d_printf("%d seconds\n", (int)t);
148         } else {
149                 d_printf("not set\n");
150         }
151
152         d_printf("Maximum password age: ");
153         if (nt_time_is_set(&i1->expire)) {
154                 time_t t = nt_time_to_unix_abs(&i1->expire);
155                 d_printf("%d seconds\n", (int)t);
156         } else {
157                 d_printf("not set\n");
158         }
159
160         d_printf("Bad logon attempts: %d\n", i12->bad_attempt_lockout);
161
162         if (i12->bad_attempt_lockout != 0) {
163
164                 d_printf("Account lockout duration: ");
165                 if (nt_time_is_set(&i12->duration)) {
166                         time_t t = nt_time_to_unix_abs(&i12->duration);
167                         d_printf("%d seconds\n", (int)t);
168                 } else {
169                         d_printf("not set\n");
170                 }
171
172                 d_printf("Bad password count reset after: ");
173                 if (nt_time_is_set(&i12->reset_count)) {
174                         time_t t = nt_time_to_unix_abs(&i12->reset_count);
175                         d_printf("%d seconds\n", (int)t);
176                 } else {
177                         d_printf("not set\n");
178                 }
179         }
180
181         d_printf("Disconnect users when logon hours expire: %s\n",
182                  nt_time_is_zero(&i3->logout) ? "yes" : "no");
183
184         d_printf("User must logon to change password: %s\n",
185                  (i1->password_properties & 0x2) ? "yes" : "no");
186         
187         return 0;               /* Don't save */
188 }
189
190 static NTSTATUS rpc_sh_acct_pol_show(TALLOC_CTX *mem_ctx,
191                                      struct rpc_sh_ctx *ctx,
192                                      struct rpc_pipe_client *pipe_hnd,
193                                      int argc, const char **argv) {
194         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
195                               account_show);
196 }
197
198 static int account_set_badpw(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx,
199                              SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
200                              SAM_UNK_INFO_12 *i12,
201                              int argc, const char **argv)
202 {
203         if (argc != 1) {
204                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
205                 return -1;
206         }
207
208         i12->bad_attempt_lockout = atoi(argv[0]);
209         d_printf("Setting bad password count to %d\n",
210                  i12->bad_attempt_lockout);
211
212         return 12;
213 }
214
215 static NTSTATUS rpc_sh_acct_set_badpw(TALLOC_CTX *mem_ctx,
216                                       struct rpc_sh_ctx *ctx,
217                                       struct rpc_pipe_client *pipe_hnd,
218                                       int argc, const char **argv)
219 {
220         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
221                               account_set_badpw);
222 }
223
224 static int account_set_lockduration(TALLOC_CTX *mem_ctx,
225                                     struct rpc_sh_ctx *ctx,
226                                     SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
227                                     SAM_UNK_INFO_12 *i12,
228                                     int argc, const char **argv)
229 {
230         if (argc != 1) {
231                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
232                 return -1;
233         }
234
235         unix_to_nt_time_abs(&i12->duration, atoi(argv[0]));
236         d_printf("Setting lockout duration to %d seconds\n",
237                  (int)nt_time_to_unix_abs(&i12->duration));
238
239         return 12;
240 }
241
242 static NTSTATUS rpc_sh_acct_set_lockduration(TALLOC_CTX *mem_ctx,
243                                              struct rpc_sh_ctx *ctx,
244                                              struct rpc_pipe_client *pipe_hnd,
245                                              int argc, const char **argv)
246 {
247         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
248                               account_set_lockduration);
249 }
250
251 static int account_set_resetduration(TALLOC_CTX *mem_ctx,
252                                      struct rpc_sh_ctx *ctx,
253                                      SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
254                                      SAM_UNK_INFO_12 *i12,
255                                      int argc, const char **argv)
256 {
257         if (argc != 1) {
258                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
259                 return -1;
260         }
261
262         unix_to_nt_time_abs(&i12->reset_count, atoi(argv[0]));
263         d_printf("Setting bad password reset duration to %d seconds\n",
264                  (int)nt_time_to_unix_abs(&i12->reset_count));
265
266         return 12;
267 }
268
269 static NTSTATUS rpc_sh_acct_set_resetduration(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(mem_ctx, ctx, pipe_hnd, argc, argv,
275                               account_set_resetduration);
276 }
277
278 static int account_set_minpwage(TALLOC_CTX *mem_ctx,
279                                 struct rpc_sh_ctx *ctx,
280                                 SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
281                                 SAM_UNK_INFO_12 *i12,
282                                 int argc, const char **argv)
283 {
284         if (argc != 1) {
285                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
286                 return -1;
287         }
288
289         unix_to_nt_time_abs(&i1->min_passwordage, atoi(argv[0]));
290         d_printf("Setting minimum password age to %d seconds\n",
291                  (int)nt_time_to_unix_abs(&i1->min_passwordage));
292
293         return 1;
294 }
295
296 static NTSTATUS rpc_sh_acct_set_minpwage(TALLOC_CTX *mem_ctx,
297                                          struct rpc_sh_ctx *ctx,
298                                          struct rpc_pipe_client *pipe_hnd,
299                                          int argc, const char **argv)
300 {
301         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
302                               account_set_minpwage);
303 }
304
305 static int account_set_maxpwage(TALLOC_CTX *mem_ctx,
306                                 struct rpc_sh_ctx *ctx,
307                                 SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
308                                 SAM_UNK_INFO_12 *i12,
309                                 int argc, const char **argv)
310 {
311         if (argc != 1) {
312                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
313                 return -1;
314         }
315
316         unix_to_nt_time_abs(&i1->expire, atoi(argv[0]));
317         d_printf("Setting maximum password age to %d seconds\n",
318                  (int)nt_time_to_unix_abs(&i1->expire));
319
320         return 1;
321 }
322
323 static NTSTATUS rpc_sh_acct_set_maxpwage(TALLOC_CTX *mem_ctx,
324                                          struct rpc_sh_ctx *ctx,
325                                          struct rpc_pipe_client *pipe_hnd,
326                                          int argc, const char **argv)
327 {
328         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
329                               account_set_maxpwage);
330 }
331
332 static int account_set_minpwlen(TALLOC_CTX *mem_ctx,
333                                 struct rpc_sh_ctx *ctx,
334                                 SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
335                                 SAM_UNK_INFO_12 *i12,
336                                 int argc, const char **argv)
337 {
338         if (argc != 1) {
339                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
340                 return -1;
341         }
342
343         i1->min_length_password = atoi(argv[0]);
344         d_printf("Setting minimum password length to %d\n",
345                  i1->min_length_password);
346
347         return 1;
348 }
349
350 static NTSTATUS rpc_sh_acct_set_minpwlen(TALLOC_CTX *mem_ctx,
351                                          struct rpc_sh_ctx *ctx,
352                                          struct rpc_pipe_client *pipe_hnd,
353                                          int argc, const char **argv)
354 {
355         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
356                               account_set_minpwlen);
357 }
358
359 static int account_set_pwhistlen(TALLOC_CTX *mem_ctx,
360                                  struct rpc_sh_ctx *ctx,
361                                  SAM_UNK_INFO_1 *i1, SAM_UNK_INFO_3 *i3,
362                                  SAM_UNK_INFO_12 *i12,
363                                  int argc, const char **argv)
364 {
365         if (argc != 1) {
366                 d_fprintf(stderr, "usage: %s <count>\n", ctx->whoami);
367                 return -1;
368         }
369
370         i1->password_history = atoi(argv[0]);
371         d_printf("Setting password history length to %d\n",
372                  i1->password_history);
373
374         return 1;
375 }
376
377 static NTSTATUS rpc_sh_acct_set_pwhistlen(TALLOC_CTX *mem_ctx,
378                                           struct rpc_sh_ctx *ctx,
379                                           struct rpc_pipe_client *pipe_hnd,
380                                           int argc, const char **argv)
381 {
382         return rpc_sh_acct_do(mem_ctx, ctx, pipe_hnd, argc, argv,
383                               account_set_pwhistlen);
384 }
385
386 struct rpc_sh_cmd *net_rpc_acct_cmds(TALLOC_CTX *mem_ctx,
387                                      struct rpc_sh_ctx *ctx)
388 {
389         static struct rpc_sh_cmd cmds[9] = {
390                 { "show", NULL, PI_SAMR, rpc_sh_acct_pol_show,
391                   "Show current account policy settings" },
392                 { "badpw", NULL, PI_SAMR, rpc_sh_acct_set_badpw,
393                   "Set bad password count before lockout" },
394                 { "lockduration", NULL, PI_SAMR, rpc_sh_acct_set_lockduration,
395                   "Set account lockout duration" },
396                 { "resetduration", NULL, PI_SAMR,
397                   rpc_sh_acct_set_resetduration,
398                   "Set bad password count reset duration" },
399                 { "minpwage", NULL, PI_SAMR, rpc_sh_acct_set_minpwage,
400                   "Set minimum password age" },
401                 { "maxpwage", NULL, PI_SAMR, rpc_sh_acct_set_maxpwage,
402                   "Set maximum password age" },
403                 { "minpwlen", NULL, PI_SAMR, rpc_sh_acct_set_minpwlen,
404                   "Set minimum password length" },
405                 { "pwhistlen", NULL, PI_SAMR, rpc_sh_acct_set_pwhistlen,
406                   "Set the password history length" },
407                 { NULL, NULL, 0, NULL, NULL }
408         };
409
410         return cmds;
411 }