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