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