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