Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : passdb editing frontend
4 :
5 : Copyright (C) Simo Sorce 2000-2009
6 : Copyright (C) Andrew Bartlett 2001
7 : Copyright (C) Jelmer Vernooij 2002
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "lib/cmdline/cmdline.h"
25 : #include "../librpc/gen_ndr/samr.h"
26 : #include "../libcli/security/security.h"
27 : #include "passdb.h"
28 : #include "cmdline_contexts.h"
29 : #include "passwd_proto.h"
30 : #include "lib/util/smb_strtox.h"
31 : #include "lib/param/param.h"
32 :
33 : #define BIT_BACKEND 0x00000004
34 : #define BIT_VERBOSE 0x00000008
35 : #define BIT_SPSTYLE 0x00000010
36 : #define BIT_CAN_CHANGE 0x00000020
37 : #define BIT_MUST_CHANGE 0x00000040
38 : #define BIT_USERSIDS 0x00000080
39 : #define BIT_FULLNAME 0x00000100
40 : #define BIT_HOMEDIR 0x00000200
41 : #define BIT_HDIRDRIVE 0x00000400
42 : #define BIT_LOGSCRIPT 0x00000800
43 : #define BIT_PROFILE 0x00001000
44 : #define BIT_MACHINE 0x00002000
45 : #define BIT_USERDOMAIN 0x00004000
46 : #define BIT_USER 0x00008000
47 : #define BIT_LIST 0x00010000
48 : #define BIT_MODIFY 0x00020000
49 : #define BIT_CREATE 0x00040000
50 : #define BIT_DELETE 0x00080000
51 : #define BIT_ACCPOLICY 0x00100000
52 : #define BIT_ACCPOLVAL 0x00200000
53 : #define BIT_ACCTCTRL 0x00400000
54 : #define BIT_RESERV_7 0x00800000
55 : #define BIT_IMPORT 0x01000000
56 : #define BIT_EXPORT 0x02000000
57 : #define BIT_FIX_INIT 0x04000000
58 : #define BIT_BADPWRESET 0x08000000
59 : #define BIT_LOGONHOURS 0x10000000
60 : #define BIT_KICKOFFTIME 0x20000000
61 : #define BIT_DESCRIPTION 0x40000000
62 : #define BIT_PWSETNTHASH 0x80000000
63 :
64 : #define MASK_ALWAYS_GOOD 0x0000001F
65 : #define MASK_USER_GOOD 0xE0405FE0
66 :
67 0 : static int get_sid_from_cli_string(struct dom_sid *sid, const char *str_sid)
68 : {
69 : uint32_t rid;
70 :
71 0 : if (!string_to_sid(sid, str_sid)) {
72 : /* not a complete sid, may be a RID,
73 : * try building a SID */
74 :
75 0 : if (sscanf(str_sid, "%u", &rid) != 1) {
76 0 : fprintf(stderr, "Error passed string is not "
77 : "a complete SID or RID!\n");
78 0 : return -1;
79 : }
80 0 : sid_compose(sid, get_global_sam_sid(), rid);
81 : }
82 :
83 0 : return 0;
84 : }
85 :
86 : /*********************************************************
87 : Add all currently available users to another db
88 : ********************************************************/
89 :
90 0 : static int export_database (struct pdb_methods *in,
91 : struct pdb_methods *out,
92 : const char *username)
93 : {
94 : NTSTATUS status;
95 : struct pdb_search *u_search;
96 : struct samr_displayentry userentry;
97 :
98 0 : DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "(NULL)"));
99 :
100 0 : u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
101 0 : if (u_search == NULL) {
102 0 : DEBUG(0, ("pdb_search_init failed\n"));
103 0 : return 1;
104 : }
105 :
106 0 : if (!in->search_users(in, u_search, 0)) {
107 0 : DEBUG(0, ("Could not start searching users\n"));
108 0 : TALLOC_FREE(u_search);
109 0 : return 1;
110 : }
111 :
112 0 : while (u_search->next_entry(u_search, &userentry)) {
113 : struct samu *user;
114 : struct samu *account;
115 : struct dom_sid user_sid;
116 :
117 0 : DEBUG(4, ("Processing account %s\n", userentry.account_name));
118 :
119 0 : if ((username != NULL)
120 0 : && (strcmp(username, userentry.account_name) != 0)) {
121 : /*
122 : * ignore unwanted users
123 : */
124 0 : continue;
125 : }
126 :
127 0 : user = samu_new(talloc_tos());
128 0 : if (user == NULL) {
129 0 : DEBUG(0, ("talloc failed\n"));
130 0 : break;
131 : }
132 :
133 0 : sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
134 :
135 0 : status = in->getsampwsid(in, user, &user_sid);
136 :
137 0 : if (!NT_STATUS_IS_OK(status)) {
138 0 : DEBUG(2, ("getsampwsid failed: %s\n",
139 : nt_errstr(status)));
140 0 : TALLOC_FREE(user);
141 0 : continue;
142 : }
143 :
144 0 : account = samu_new(NULL);
145 0 : if (account == NULL) {
146 0 : fprintf(stderr, "export_database: Memory allocation "
147 : "failure!\n");
148 0 : TALLOC_FREE( user );
149 0 : TALLOC_FREE(u_search);
150 0 : return 1;
151 : }
152 :
153 0 : printf("Importing account for %s...", user->username);
154 0 : status = out->getsampwnam(out, account, user->username);
155 :
156 0 : if (NT_STATUS_IS_OK(status)) {
157 0 : status = out->update_sam_account( out, user );
158 : } else {
159 0 : status = out->add_sam_account(out, user);
160 : }
161 :
162 0 : if ( NT_STATUS_IS_OK(status) ) {
163 0 : printf( "ok\n");
164 : } else {
165 0 : printf( "failed\n");
166 : }
167 :
168 0 : TALLOC_FREE( account );
169 0 : TALLOC_FREE( user );
170 : }
171 :
172 0 : TALLOC_FREE(u_search);
173 :
174 0 : return 0;
175 : }
176 :
177 : /*********************************************************
178 : Add all currently available group mappings to another db
179 : ********************************************************/
180 :
181 0 : static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
182 : {
183 0 : GROUP_MAP **maps = NULL;
184 0 : size_t i, entries = 0;
185 : NTSTATUS status;
186 :
187 0 : status = in->enum_group_mapping(in, get_global_sam_sid(),
188 : SID_NAME_DOM_GRP, &maps, &entries, False);
189 :
190 0 : if ( NT_STATUS_IS_ERR(status) ) {
191 0 : fprintf(stderr, "Unable to enumerate group map entries.\n");
192 0 : return 1;
193 : }
194 :
195 0 : for (i=0; i<entries; i++) {
196 0 : out->add_group_mapping_entry(out, maps[i]);
197 : }
198 :
199 0 : TALLOC_FREE(maps);
200 :
201 0 : return 0;
202 : }
203 :
204 : /*********************************************************
205 : Reset account policies to their default values and remove marker
206 : ********************************************************/
207 :
208 0 : static int reinit_account_policies (void)
209 : {
210 : int i;
211 :
212 0 : for (i=1; decode_account_policy_name(i) != NULL; i++) {
213 : uint32_t policy_value;
214 0 : if (!account_policy_get_default(i, &policy_value)) {
215 0 : fprintf(stderr, "Can't get default account policy\n");
216 0 : return -1;
217 : }
218 0 : if (!account_policy_set(i, policy_value)) {
219 0 : fprintf(stderr, "Can't set account policy in tdb\n");
220 0 : return -1;
221 : }
222 : }
223 :
224 0 : return 0;
225 : }
226 :
227 :
228 : /*********************************************************
229 : Add all currently available account policy from tdb to one backend
230 : ********************************************************/
231 :
232 0 : static int export_account_policies (struct pdb_methods *in, struct pdb_methods *out)
233 : {
234 : int i;
235 :
236 0 : for ( i=1; decode_account_policy_name(i) != NULL; i++ ) {
237 : uint32_t policy_value;
238 : NTSTATUS status;
239 :
240 0 : status = in->get_account_policy(in, i, &policy_value);
241 :
242 0 : if ( NT_STATUS_IS_ERR(status) ) {
243 0 : fprintf(stderr, "Unable to get account policy from %s\n", in->name);
244 0 : return -1;
245 : }
246 :
247 0 : status = out->set_account_policy(out, i, policy_value);
248 :
249 0 : if ( NT_STATUS_IS_ERR(status) ) {
250 0 : fprintf(stderr, "Unable to migrate account policy to %s\n", out->name);
251 0 : return -1;
252 : }
253 : }
254 :
255 0 : return 0;
256 : }
257 :
258 :
259 : /*********************************************************
260 : Print info from sam structure
261 : **********************************************************/
262 :
263 9 : static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdstyle)
264 : {
265 : uid_t uid;
266 : time_t tmp;
267 :
268 : /* TODO: check if entry is a user or a workstation */
269 9 : if (!sam_pwent) return -1;
270 :
271 9 : if (verbosity) {
272 : char temp[44];
273 : const uint8_t *hours;
274 : struct dom_sid_buf buf;
275 :
276 9 : printf ("Unix username: %s\n", pdb_get_username(sam_pwent));
277 9 : printf ("NT username: %s\n", pdb_get_nt_username(sam_pwent));
278 9 : printf ("Account Flags: %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN));
279 9 : printf ("User SID: %s\n",
280 : dom_sid_str_buf(pdb_get_user_sid(sam_pwent), &buf));
281 9 : printf ("Primary Group SID: %s\n",
282 : dom_sid_str_buf(pdb_get_group_sid(sam_pwent), &buf));
283 9 : printf ("Full Name: %s\n", pdb_get_fullname(sam_pwent));
284 9 : printf ("Home Directory: %s\n", pdb_get_homedir(sam_pwent));
285 9 : printf ("HomeDir Drive: %s\n", pdb_get_dir_drive(sam_pwent));
286 9 : printf ("Logon Script: %s\n", pdb_get_logon_script(sam_pwent));
287 9 : printf ("Profile Path: %s\n", pdb_get_profile_path(sam_pwent));
288 9 : printf ("Domain: %s\n", pdb_get_domain(sam_pwent));
289 9 : printf ("Account desc: %s\n", pdb_get_acct_desc(sam_pwent));
290 9 : printf ("Workstations: %s\n", pdb_get_workstations(sam_pwent));
291 9 : printf ("Munged dial: %s\n", pdb_get_munged_dial(sam_pwent));
292 :
293 9 : tmp = pdb_get_logon_time(sam_pwent);
294 11 : printf ("Logon time: %s\n",
295 2 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
296 :
297 9 : tmp = pdb_get_logoff_time(sam_pwent);
298 15 : printf ("Logoff time: %s\n",
299 6 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
300 :
301 9 : tmp = pdb_get_kickoff_time(sam_pwent);
302 18 : printf ("Kickoff time: %s\n",
303 9 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
304 :
305 9 : tmp = pdb_get_pass_last_set_time(sam_pwent);
306 18 : printf ("Password last set: %s\n",
307 9 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
308 :
309 9 : tmp = pdb_get_pass_can_change_time(sam_pwent);
310 18 : printf ("Password can change: %s\n",
311 9 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
312 :
313 9 : tmp = pdb_get_pass_must_change_time(sam_pwent);
314 18 : printf ("Password must change: %s\n",
315 9 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
316 :
317 9 : tmp = pdb_get_bad_password_time(sam_pwent);
318 9 : printf ("Last bad password : %s\n",
319 0 : tmp ? http_timestring(talloc_tos(), tmp) : "0");
320 9 : printf ("Bad password count : %d\n",
321 9 : pdb_get_bad_password_count(sam_pwent));
322 :
323 9 : hours = pdb_get_hours(sam_pwent);
324 9 : pdb_sethexhours(temp, hours);
325 9 : printf ("Logon hours : %s\n", temp);
326 9 : if (smbpwdstyle){
327 3 : pdb_sethexpwd(temp, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
328 3 : printf ("LM hash : %s\n", temp);
329 3 : pdb_sethexpwd(temp, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
330 3 : printf ("NT hash : %s\n", temp);
331 : }
332 :
333 0 : } else if (smbpwdstyle) {
334 : char lm_passwd[33];
335 : char nt_passwd[33];
336 :
337 0 : uid = nametouid(pdb_get_username(sam_pwent));
338 0 : pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
339 0 : pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
340 :
341 0 : printf("%s:%lu:%s:%s:%s:LCT-%08X:\n",
342 : pdb_get_username(sam_pwent),
343 : (unsigned long)uid,
344 : lm_passwd,
345 : nt_passwd,
346 : pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
347 0 : (uint32_t)convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sam_pwent)));
348 : } else {
349 0 : uid = nametouid(pdb_get_username(sam_pwent));
350 0 : printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
351 : pdb_get_fullname(sam_pwent));
352 : }
353 :
354 9 : return 0;
355 : }
356 :
357 : /*********************************************************
358 : Get an Print User Info
359 : **********************************************************/
360 :
361 9 : static int print_user_info(const char *username,
362 : bool verbosity, bool smbpwdstyle)
363 : {
364 9 : struct samu *sam_pwent = NULL;
365 : bool bret;
366 : int ret;
367 :
368 9 : sam_pwent = samu_new(NULL);
369 9 : if (!sam_pwent) {
370 0 : return -1;
371 : }
372 :
373 9 : bret = pdb_getsampwnam(sam_pwent, username);
374 9 : if (!bret) {
375 0 : fprintf (stderr, "Username not found!\n");
376 0 : TALLOC_FREE(sam_pwent);
377 0 : return -1;
378 : }
379 :
380 9 : ret = print_sam_info(sam_pwent, verbosity, smbpwdstyle);
381 :
382 9 : TALLOC_FREE(sam_pwent);
383 9 : return ret;
384 : }
385 :
386 : /*********************************************************
387 : List Users
388 : **********************************************************/
389 0 : static int print_users_list(bool verbosity, bool smbpwdstyle)
390 : {
391 : struct pdb_search *u_search;
392 : struct samr_displayentry userentry;
393 : struct samu *sam_pwent;
394 : TALLOC_CTX *tosctx;
395 : struct dom_sid user_sid;
396 : bool bret;
397 : int ret;
398 :
399 0 : tosctx = talloc_tos();
400 0 : if (!tosctx) {
401 0 : DEBUG(0, ("talloc failed\n"));
402 0 : return 1;
403 : }
404 :
405 0 : u_search = pdb_search_users(tosctx, 0);
406 0 : if (!u_search) {
407 0 : DEBUG(0, ("User Search failed!\n"));
408 0 : ret = 1;
409 0 : goto done;
410 : }
411 :
412 0 : while (u_search->next_entry(u_search, &userentry)) {
413 :
414 0 : sam_pwent = samu_new(tosctx);
415 0 : if (sam_pwent == NULL) {
416 0 : DEBUG(0, ("talloc failed\n"));
417 0 : ret = 1;
418 0 : goto done;
419 : }
420 :
421 0 : sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
422 :
423 0 : bret = pdb_getsampwsid(sam_pwent, &user_sid);
424 0 : if (!bret) {
425 0 : DEBUG(2, ("getsampwsid failed\n"));
426 0 : TALLOC_FREE(sam_pwent);
427 0 : continue;
428 : }
429 :
430 0 : if (verbosity) {
431 0 : printf ("---------------\n");
432 : }
433 0 : print_sam_info(sam_pwent, verbosity, smbpwdstyle);
434 0 : TALLOC_FREE(sam_pwent);
435 : }
436 :
437 0 : ret = 0;
438 :
439 0 : done:
440 0 : TALLOC_FREE(tosctx);
441 0 : return ret;
442 : }
443 :
444 : /*********************************************************
445 : Fix a list of Users for uninitialised passwords
446 : **********************************************************/
447 0 : static int fix_users_list(void)
448 : {
449 : struct pdb_search *u_search;
450 : struct samr_displayentry userentry;
451 : struct samu *sam_pwent;
452 : TALLOC_CTX *tosctx;
453 : struct dom_sid user_sid;
454 : NTSTATUS status;
455 : bool bret;
456 : int ret;
457 :
458 0 : tosctx = talloc_tos();
459 0 : if (!tosctx) {
460 0 : fprintf(stderr, "Out of memory!\n");
461 0 : return 1;
462 : }
463 :
464 0 : u_search = pdb_search_users(tosctx, 0);
465 0 : if (!u_search) {
466 0 : fprintf(stderr, "User Search failed!\n");
467 0 : ret = 1;
468 0 : goto done;
469 : }
470 :
471 0 : while (u_search->next_entry(u_search, &userentry)) {
472 :
473 0 : sam_pwent = samu_new(tosctx);
474 0 : if (sam_pwent == NULL) {
475 0 : fprintf(stderr, "Out of memory!\n");
476 0 : ret = 1;
477 0 : goto done;
478 : }
479 :
480 0 : sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
481 :
482 0 : bret = pdb_getsampwsid(sam_pwent, &user_sid);
483 0 : if (!bret) {
484 0 : DEBUG(2, ("getsampwsid failed\n"));
485 0 : TALLOC_FREE(sam_pwent);
486 0 : continue;
487 : }
488 :
489 0 : status = pdb_update_sam_account(sam_pwent);
490 0 : if (!NT_STATUS_IS_OK(status)) {
491 0 : printf("Update of user %s failed!\n",
492 : pdb_get_username(sam_pwent));
493 : }
494 0 : TALLOC_FREE(sam_pwent);
495 : }
496 :
497 0 : ret = 0;
498 :
499 0 : done:
500 0 : TALLOC_FREE(tosctx);
501 0 : return ret;
502 : }
503 :
504 : /*********************************************************
505 : Set User Info
506 : **********************************************************/
507 :
508 6 : static int set_user_info(const char *username, const char *fullname,
509 : const char *homedir, const char *acct_desc,
510 : const char *drive, const char *script,
511 : const char *profile, const char *account_control,
512 : const char *user_sid, const char *user_domain,
513 : const bool badpw, const bool hours,
514 : const char *kickoff_time, const char *str_hex_pwd)
515 : {
516 6 : bool updated_autolock = False, updated_badpw = False;
517 : struct samu *sam_pwent;
518 : uint8_t hours_array[MAX_HOURS_LEN];
519 : uint32_t hours_len;
520 : uint32_t acb_flags;
521 : uint32_t not_settable;
522 : uint32_t new_flags;
523 : struct dom_sid u_sid;
524 : bool ret;
525 :
526 6 : sam_pwent = samu_new(NULL);
527 6 : if (!sam_pwent) {
528 0 : return 1;
529 : }
530 :
531 6 : ret = pdb_getsampwnam(sam_pwent, username);
532 6 : if (!ret) {
533 0 : fprintf (stderr, "Username not found!\n");
534 0 : TALLOC_FREE(sam_pwent);
535 0 : return -1;
536 : }
537 :
538 6 : if (hours) {
539 0 : hours_len = pdb_get_hours_len(sam_pwent);
540 0 : memset(hours_array, 0xff, hours_len);
541 :
542 0 : pdb_set_hours(sam_pwent, hours_array, hours_len, PDB_CHANGED);
543 : }
544 :
545 6 : if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
546 0 : DEBUG(2,("pdb_update_autolock_flag failed.\n"));
547 : }
548 :
549 6 : if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
550 0 : DEBUG(2,("pdb_update_bad_password_count failed.\n"));
551 : }
552 :
553 6 : if (fullname)
554 0 : pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
555 6 : if (acct_desc)
556 0 : pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED);
557 6 : if (homedir)
558 0 : pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
559 6 : if (drive)
560 3 : pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
561 6 : if (script)
562 0 : pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
563 6 : if (profile)
564 0 : pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
565 6 : if (user_domain)
566 0 : pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);
567 :
568 6 : if (account_control) {
569 0 : not_settable = ~(ACB_DISABLED | ACB_HOMDIRREQ |
570 : ACB_PWNOTREQ | ACB_PWNOEXP | ACB_AUTOLOCK);
571 :
572 0 : new_flags = pdb_decode_acct_ctrl(account_control);
573 :
574 0 : if (new_flags & not_settable) {
575 0 : fprintf(stderr, "Can only set [NDHLX] flags\n");
576 0 : TALLOC_FREE(sam_pwent);
577 0 : return -1;
578 : }
579 :
580 0 : acb_flags = pdb_get_acct_ctrl(sam_pwent);
581 :
582 0 : pdb_set_acct_ctrl(sam_pwent,
583 0 : (acb_flags & not_settable) | new_flags,
584 : PDB_CHANGED);
585 : }
586 6 : if (user_sid) {
587 0 : if (get_sid_from_cli_string(&u_sid, user_sid)) {
588 0 : fprintf(stderr, "Failed to parse SID\n");
589 0 : return -1;
590 : }
591 0 : pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
592 : }
593 :
594 6 : if (badpw) {
595 0 : pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
596 0 : pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
597 : }
598 :
599 6 : if (kickoff_time) {
600 0 : time_t value = get_time_t_max();
601 :
602 0 : if (strcmp(kickoff_time, "never") != 0) {
603 0 : int error = 0;
604 : uint32_t num;
605 :
606 0 : num = smb_strtoul(kickoff_time,
607 : NULL,
608 : 10,
609 : &error,
610 : SMB_STR_FULL_STR_CONV);
611 0 : if (error != 0) {
612 0 : fprintf(stderr, "Failed to parse kickoff time\n");
613 0 : return -1;
614 : }
615 :
616 0 : value = convert_uint32_t_to_time_t(num);
617 : }
618 :
619 0 : pdb_set_kickoff_time(sam_pwent, value, PDB_CHANGED);
620 : }
621 6 : if (str_hex_pwd) {
622 : unsigned char new_nt_p16[NT_HASH_LEN];
623 3 : if(strlen(str_hex_pwd) != (NT_HASH_LEN *2)){
624 0 : fprintf(stderr, "Invalid hash\n");
625 0 : return -1;
626 : }
627 :
628 3 : pdb_gethexpwd(str_hex_pwd, new_nt_p16);
629 :
630 3 : if (!pdb_set_nt_passwd (sam_pwent, new_nt_p16 , PDB_CHANGED)) {
631 0 : fprintf(stderr, "Failed to set password from nt-hash\n");
632 0 : return -1;
633 : }
634 :
635 3 : if (!pdb_set_pass_last_set_time (sam_pwent, time(NULL), PDB_CHANGED)){
636 0 : fprintf(stderr, "Failed to set last password set time\n");
637 0 : return -1;
638 : }
639 3 : if (!pdb_update_history(sam_pwent, new_nt_p16)){
640 0 : fprintf(stderr, "Failed to update password history\n");
641 0 : return -1;
642 : }
643 : }
644 :
645 6 : if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
646 :
647 6 : print_user_info(username, True, (str_hex_pwd != NULL ));
648 : } else {
649 0 : fprintf (stderr, "Unable to modify entry!\n");
650 0 : TALLOC_FREE(sam_pwent);
651 0 : return -1;
652 : }
653 6 : TALLOC_FREE(sam_pwent);
654 6 : return 0;
655 : }
656 :
657 0 : static int set_machine_info(const char *machinename,
658 : const char *account_control,
659 : const char *machine_sid)
660 : {
661 0 : struct samu *sam_pwent = NULL;
662 : TALLOC_CTX *tosctx;
663 : uint32_t acb_flags;
664 : uint32_t not_settable;
665 : uint32_t new_flags;
666 : struct dom_sid m_sid;
667 : char *name;
668 : int len;
669 : bool ret;
670 :
671 0 : len = strlen(machinename);
672 0 : if (len == 0) {
673 0 : fprintf(stderr, "No machine name given\n");
674 0 : return -1;
675 : }
676 :
677 0 : tosctx = talloc_tos();
678 0 : if (!tosctx) {
679 0 : fprintf(stderr, "Out of memory!\n");
680 0 : return -1;
681 : }
682 :
683 0 : sam_pwent = samu_new(tosctx);
684 0 : if (!sam_pwent) {
685 0 : return 1;
686 : }
687 :
688 0 : if (machinename[len-1] == '$') {
689 0 : name = talloc_strdup(sam_pwent, machinename);
690 : } else {
691 0 : name = talloc_asprintf(sam_pwent, "%s$", machinename);
692 : }
693 0 : if (!name) {
694 0 : fprintf(stderr, "Out of memory!\n");
695 0 : TALLOC_FREE(sam_pwent);
696 0 : return -1;
697 : }
698 :
699 0 : if (!strlower_m(name)) {
700 0 : fprintf(stderr, "strlower_m %s failed\n", name);
701 0 : TALLOC_FREE(sam_pwent);
702 0 : return -1;
703 : }
704 :
705 0 : ret = pdb_getsampwnam(sam_pwent, name);
706 0 : if (!ret) {
707 0 : fprintf (stderr, "Username not found!\n");
708 0 : TALLOC_FREE(sam_pwent);
709 0 : return -1;
710 : }
711 :
712 0 : if (account_control) {
713 0 : not_settable = ~(ACB_DISABLED);
714 :
715 0 : new_flags = pdb_decode_acct_ctrl(account_control);
716 :
717 0 : if (new_flags & not_settable) {
718 0 : fprintf(stderr, "Can only set [D] flags\n");
719 0 : TALLOC_FREE(sam_pwent);
720 0 : return -1;
721 : }
722 :
723 0 : acb_flags = pdb_get_acct_ctrl(sam_pwent);
724 :
725 0 : pdb_set_acct_ctrl(sam_pwent,
726 0 : (acb_flags & not_settable) | new_flags,
727 : PDB_CHANGED);
728 : }
729 0 : if (machine_sid) {
730 0 : if (get_sid_from_cli_string(&m_sid, machine_sid)) {
731 0 : fprintf(stderr, "Failed to parse SID\n");
732 0 : return -1;
733 : }
734 0 : pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
735 : }
736 :
737 0 : if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
738 0 : print_user_info(name, True, False);
739 : } else {
740 0 : fprintf (stderr, "Unable to modify entry!\n");
741 0 : TALLOC_FREE(sam_pwent);
742 0 : return -1;
743 : }
744 0 : TALLOC_FREE(sam_pwent);
745 0 : return 0;
746 : }
747 :
748 : /*********************************************************
749 : Add New User
750 : **********************************************************/
751 3 : static int new_user(const char *username, const char *fullname,
752 : const char *homedir, const char *drive,
753 : const char *script, const char *profile,
754 : char *user_sid, bool stdin_get)
755 : {
756 3 : char *pwd1 = NULL, *pwd2 = NULL;
757 3 : char *err = NULL, *msg = NULL;
758 3 : struct samu *sam_pwent = NULL;
759 : TALLOC_CTX *tosctx;
760 : NTSTATUS status;
761 : struct dom_sid u_sid;
762 : int flags;
763 3 : int ret = -1;
764 : uint32_t value;
765 :
766 3 : tosctx = talloc_tos();
767 3 : if (!tosctx) {
768 0 : fprintf(stderr, "Out of memory!\n");
769 0 : return -1;
770 : }
771 :
772 3 : if (user_sid) {
773 0 : if (get_sid_from_cli_string(&u_sid, user_sid)) {
774 0 : fprintf(stderr, "Failed to parse SID\n");
775 0 : return -1;
776 : }
777 : }
778 :
779 3 : pwd1 = get_pass( "new password:", stdin_get);
780 3 : if (pwd1 == NULL) {
781 0 : fprintf(stderr, "Failed to read passwords.\n");
782 0 : goto done;
783 : }
784 3 : pwd2 = get_pass( "retype new password:", stdin_get);
785 3 : if (pwd2 == NULL) {
786 0 : fprintf(stderr, "Failed to read passwords.\n");
787 0 : goto done;
788 : }
789 3 : ret = strcmp(pwd1, pwd2);
790 3 : if (ret != 0) {
791 0 : fprintf (stderr, "Passwords do not match!\n");
792 0 : goto done;
793 : }
794 :
795 3 : if(!account_policy_get(PDB_POLICY_MIN_PASSWORD_LEN, &value)) {
796 0 : fprintf (stderr, "Failed to get min password length!\n");
797 0 : goto done;
798 : }
799 :
800 3 : if(value > strlen(pwd1)) {
801 0 : fprintf (stderr, "Password is too short!\n");
802 0 : goto done;
803 : }
804 :
805 3 : flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD;
806 :
807 3 : status = local_password_change(username, flags, pwd1, &err, &msg);
808 3 : if (!NT_STATUS_IS_OK(status)) {
809 0 : if (err) fprintf(stderr, "%s", err);
810 0 : ret = -1;
811 0 : goto done;
812 : }
813 :
814 3 : sam_pwent = samu_new(tosctx);
815 3 : if (!sam_pwent) {
816 0 : fprintf(stderr, "Out of memory!\n");
817 0 : ret = -1;
818 0 : goto done;
819 : }
820 :
821 3 : if (!pdb_getsampwnam(sam_pwent, username)) {
822 0 : fprintf(stderr, "User %s not found!\n", username);
823 0 : ret = -1;
824 0 : goto done;
825 : }
826 :
827 3 : if (fullname)
828 0 : pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
829 3 : if (homedir)
830 0 : pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
831 3 : if (drive)
832 0 : pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED);
833 3 : if (script)
834 0 : pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
835 3 : if (profile)
836 0 : pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED);
837 3 : if (user_sid)
838 0 : pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
839 :
840 3 : status = pdb_update_sam_account(sam_pwent);
841 3 : if (!NT_STATUS_IS_OK(status)) {
842 0 : fprintf(stderr,
843 : "Failed to modify entry for user %s.!\n",
844 : username);
845 0 : ret = -1;
846 0 : goto done;
847 : }
848 :
849 3 : print_user_info(username, True, False);
850 3 : ret = 0;
851 :
852 3 : done:
853 3 : if (pwd1) memset(pwd1, 0, strlen(pwd1));
854 3 : if (pwd2) memset(pwd2, 0, strlen(pwd2));
855 3 : SAFE_FREE(pwd1);
856 3 : SAFE_FREE(pwd2);
857 3 : SAFE_FREE(err);
858 3 : SAFE_FREE(msg);
859 3 : TALLOC_FREE(sam_pwent);
860 3 : return ret;
861 : }
862 :
863 : /*********************************************************
864 : Add New Machine
865 : **********************************************************/
866 :
867 0 : static int new_machine(const char *machinename, char *machine_sid)
868 : {
869 0 : char *err = NULL, *msg = NULL;
870 0 : struct samu *sam_pwent = NULL;
871 : TALLOC_CTX *tosctx;
872 : NTSTATUS status;
873 : struct dom_sid m_sid;
874 : char *compatpwd;
875 : char *name;
876 : int flags;
877 : int len;
878 : int ret;
879 :
880 0 : len = strlen(machinename);
881 0 : if (len == 0) {
882 0 : fprintf(stderr, "No machine name given\n");
883 0 : return -1;
884 : }
885 :
886 0 : tosctx = talloc_tos();
887 0 : if (!tosctx) {
888 0 : fprintf(stderr, "Out of memory!\n");
889 0 : return -1;
890 : }
891 :
892 0 : if (machine_sid) {
893 0 : if (get_sid_from_cli_string(&m_sid, machine_sid)) {
894 0 : fprintf(stderr, "Failed to parse SID\n");
895 0 : return -1;
896 : }
897 : }
898 :
899 0 : compatpwd = talloc_strdup(tosctx, machinename);
900 0 : if (!compatpwd) {
901 0 : fprintf(stderr, "Out of memory!\n");
902 0 : return -1;
903 : }
904 :
905 0 : if (machinename[len-1] == '$') {
906 0 : name = talloc_strdup(tosctx, machinename);
907 0 : compatpwd[len-1] = '\0';
908 : } else {
909 0 : name = talloc_asprintf(tosctx, "%s$", machinename);
910 : }
911 0 : if (!name) {
912 0 : fprintf(stderr, "Out of memory!\n");
913 0 : return -1;
914 : }
915 :
916 0 : if (!strlower_m(name)) {
917 0 : fprintf(stderr, "strlower_m %s failed\n", name);
918 0 : return -1;
919 : }
920 :
921 0 : flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;
922 :
923 0 : status = local_password_change(name, flags, compatpwd, &err, &msg);
924 :
925 0 : if (!NT_STATUS_IS_OK(status)) {
926 0 : if (err) fprintf(stderr, "%s", err);
927 0 : ret = -1;
928 : }
929 :
930 0 : sam_pwent = samu_new(tosctx);
931 0 : if (!sam_pwent) {
932 0 : fprintf(stderr, "Out of memory!\n");
933 0 : ret = -1;
934 0 : goto done;
935 : }
936 :
937 0 : if (!pdb_getsampwnam(sam_pwent, name)) {
938 0 : fprintf(stderr, "Machine %s not found!\n", name);
939 0 : ret = -1;
940 0 : goto done;
941 : }
942 :
943 0 : if (machine_sid)
944 0 : pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
945 :
946 0 : status = pdb_update_sam_account(sam_pwent);
947 0 : if (!NT_STATUS_IS_OK(status)) {
948 0 : fprintf(stderr,
949 : "Failed to modify entry for %s.!\n", name);
950 0 : ret = -1;
951 0 : goto done;
952 : }
953 :
954 0 : print_user_info(name, True, False);
955 0 : ret = 0;
956 :
957 0 : done:
958 0 : SAFE_FREE(err);
959 0 : SAFE_FREE(msg);
960 0 : TALLOC_FREE(sam_pwent);
961 0 : return ret;
962 : }
963 :
964 : /*********************************************************
965 : Delete user entry
966 : **********************************************************/
967 :
968 3 : static int delete_user_entry(const char *username)
969 : {
970 : struct samu *samaccount;
971 :
972 3 : samaccount = samu_new(NULL);
973 3 : if (!samaccount) {
974 0 : fprintf(stderr, "Out of memory!\n");
975 0 : return -1;
976 : }
977 :
978 3 : if (!pdb_getsampwnam(samaccount, username)) {
979 0 : fprintf (stderr,
980 : "user %s does not exist in the passdb\n", username);
981 0 : TALLOC_FREE(samaccount);
982 0 : return -1;
983 : }
984 :
985 3 : if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
986 0 : fprintf (stderr, "Unable to delete user %s\n", username);
987 0 : TALLOC_FREE(samaccount);
988 0 : return -1;
989 : }
990 :
991 3 : TALLOC_FREE(samaccount);
992 3 : return 0;
993 : }
994 :
995 : /*********************************************************
996 : Delete machine entry
997 : **********************************************************/
998 :
999 0 : static int delete_machine_entry(const char *machinename)
1000 : {
1001 0 : struct samu *samaccount = NULL;
1002 : const char *name;
1003 :
1004 0 : if (strlen(machinename) == 0) {
1005 0 : fprintf(stderr, "No machine name given\n");
1006 0 : return -1;
1007 : }
1008 :
1009 0 : samaccount = samu_new(NULL);
1010 0 : if (!samaccount) {
1011 0 : fprintf(stderr, "Out of memory!\n");
1012 0 : return -1;
1013 : }
1014 :
1015 0 : if (machinename[strlen(machinename)-1] != '$') {
1016 0 : name = talloc_asprintf(samaccount, "%s$", machinename);
1017 : } else {
1018 0 : name = machinename;
1019 : }
1020 :
1021 0 : if (!pdb_getsampwnam(samaccount, name)) {
1022 0 : fprintf (stderr,
1023 : "machine %s does not exist in the passdb\n", name);
1024 0 : TALLOC_FREE(samaccount);
1025 0 : return -1;
1026 : }
1027 :
1028 0 : if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
1029 0 : fprintf (stderr, "Unable to delete machine %s\n", name);
1030 0 : TALLOC_FREE(samaccount);
1031 0 : return -1;
1032 : }
1033 :
1034 0 : TALLOC_FREE(samaccount);
1035 0 : return 0;
1036 : }
1037 :
1038 : /*********************************************************
1039 : Start here.
1040 : **********************************************************/
1041 :
1042 12 : int main(int argc, const char **argv)
1043 : {
1044 : static int list_users = False;
1045 : static int verbose = False;
1046 : static int spstyle = False;
1047 : static int machine = False;
1048 : static int add_user = False;
1049 : static int delete_user = False;
1050 : static int modify_user = False;
1051 : uint32_t setparms, checkparms;
1052 : int opt;
1053 : static char *full_name = NULL;
1054 : static char *acct_desc = NULL;
1055 : static const char *user_name = NULL;
1056 : static char *home_dir = NULL;
1057 : static char *home_drive = NULL;
1058 : static const char *backend = NULL;
1059 : static char *backend_in = NULL;
1060 : static char *backend_out = NULL;
1061 : static int transfer_groups = False;
1062 : static int transfer_account_policies = False;
1063 : static int reset_account_policies = False;
1064 : static int force_initialised_password = False;
1065 : static char *logon_script = NULL;
1066 : static char *profile_path = NULL;
1067 : static char *user_domain = NULL;
1068 : static char *account_control = NULL;
1069 : static char *account_policy = NULL;
1070 : static char *user_sid = NULL;
1071 : static char *machine_sid = NULL;
1072 : static long int account_policy_value = 0;
1073 12 : bool account_policy_value_set = False;
1074 : static int badpw_reset = False;
1075 : static int hours_reset = False;
1076 : static char *pwd_time_format = NULL;
1077 : static int pw_from_stdin = False;
1078 : struct pdb_methods *bin, *bout;
1079 : static char *kickoff_time = NULL;
1080 : static char *str_hex_pwd = NULL;
1081 12 : TALLOC_CTX *frame = talloc_stackframe();
1082 12 : struct loadparm_context *lp_ctx = NULL;
1083 : NTSTATUS status;
1084 : poptContext pc;
1085 : bool ok;
1086 36 : struct poptOption long_options[] = {
1087 : POPT_AUTOHELP
1088 : {"list", 'L', POPT_ARG_NONE, &list_users, 0, "list all users", NULL},
1089 : {"verbose", 'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL },
1090 : {"smbpasswd-style", 'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL},
1091 : {"user", 'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" },
1092 : {"account-desc", 'N', POPT_ARG_STRING, &acct_desc, 0, "set account description", NULL},
1093 : {"fullname", 'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL},
1094 : {"homedir", 'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL},
1095 : {"drive", 'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL},
1096 : {"script", 'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL},
1097 : {"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
1098 : {"domain", 'I', POPT_ARG_STRING, &user_domain, 0, "set a users' domain", NULL},
1099 : {"user SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
1100 : {"machine SID", 'M', POPT_ARG_STRING, &machine_sid, 0, "set machine SID or RID", NULL},
1101 : {"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
1102 : {"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
1103 : {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
1104 : {"delete", 'x', POPT_ARG_NONE, &delete_user, 0, "delete user", NULL},
1105 : {"backend", 'b', POPT_ARG_STRING, &backend, 0, "use different passdb backend as default backend", NULL},
1106 : {"import", 'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL},
1107 : {"export", 'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL},
1108 : {"group", 'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL},
1109 : {"policies", 'y', POPT_ARG_NONE, &transfer_account_policies, 0, "use -i and -e to move account policies between backends", NULL},
1110 : {"policies-reset", 0, POPT_ARG_NONE, &reset_account_policies, 0, "restore default policies", NULL},
1111 : {"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
1112 : {"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
1113 : {"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
1114 : {"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
1115 : {"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
1116 : {"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
1117 : {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
1118 : {"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL},
1119 : {"kickoff-time", 'K', POPT_ARG_STRING, &kickoff_time, 0, "set the kickoff time", NULL},
1120 : {"set-nt-hash", 0, POPT_ARG_STRING, &str_hex_pwd, 0, "set password from nt-hash", NULL},
1121 12 : POPT_COMMON_SAMBA
1122 12 : POPT_COMMON_VERSION
1123 : POPT_TABLEEND
1124 : };
1125 :
1126 12 : bin = bout = NULL;
1127 :
1128 12 : smb_init_locale();
1129 :
1130 12 : ok = samba_cmdline_init(frame,
1131 : SAMBA_CMDLINE_CONFIG_CLIENT,
1132 : false /* require_smbconf */);
1133 12 : if (!ok) {
1134 0 : DBG_ERR("Failed to init cmdline parser!\n");
1135 0 : TALLOC_FREE(frame);
1136 0 : exit(1);
1137 : }
1138 12 : lp_ctx = samba_cmdline_get_lp_ctx();
1139 :
1140 12 : pc = samba_popt_get_context(getprogname(),
1141 : argc,
1142 : argv,
1143 : long_options,
1144 : POPT_CONTEXT_KEEP_FIRST);
1145 12 : if (pc == NULL) {
1146 0 : DBG_ERR("Failed to setup popt context!\n");
1147 0 : TALLOC_FREE(frame);
1148 0 : exit(1);
1149 : }
1150 :
1151 12 : while((opt = poptGetNextOpt(pc)) != -1) {
1152 0 : switch (opt) {
1153 0 : case 'C':
1154 0 : account_policy_value_set = True;
1155 0 : break;
1156 0 : case POPT_ERROR_BADOPT:
1157 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
1158 : poptBadOption(pc, 0), poptStrerror(opt));
1159 0 : poptPrintUsage(pc, stderr, 0);
1160 0 : exit(1);
1161 : }
1162 : }
1163 :
1164 12 : poptGetArg(pc); /* Drop argv[0], the program name */
1165 :
1166 12 : if (user_name == NULL) {
1167 9 : if (poptPeekArg(pc)) {
1168 9 : user_name = talloc_strdup(frame, poptGetArg(pc));
1169 9 : if (user_name == NULL) {
1170 0 : fprintf(stderr, "out of memory\n");
1171 0 : TALLOC_FREE(frame);
1172 0 : exit(1);
1173 : }
1174 : }
1175 : }
1176 :
1177 12 : setparms = (backend ? BIT_BACKEND : 0) +
1178 12 : (verbose ? BIT_VERBOSE : 0) +
1179 12 : (spstyle ? BIT_SPSTYLE : 0) +
1180 12 : (full_name ? BIT_FULLNAME : 0) +
1181 12 : (home_dir ? BIT_HOMEDIR : 0) +
1182 12 : (home_drive ? BIT_HDIRDRIVE : 0) +
1183 12 : (logon_script ? BIT_LOGSCRIPT : 0) +
1184 12 : (profile_path ? BIT_PROFILE : 0) +
1185 12 : (user_domain ? BIT_USERDOMAIN : 0) +
1186 12 : (machine ? BIT_MACHINE : 0) +
1187 12 : (user_name ? BIT_USER : 0) +
1188 12 : (list_users ? BIT_LIST : 0) +
1189 12 : (force_initialised_password ? BIT_FIX_INIT : 0) +
1190 12 : (user_sid ? BIT_USERSIDS : 0) +
1191 12 : (machine_sid ? BIT_USERSIDS : 0) +
1192 12 : (modify_user ? BIT_MODIFY : 0) +
1193 12 : (add_user ? BIT_CREATE : 0) +
1194 12 : (delete_user ? BIT_DELETE : 0) +
1195 12 : (account_control ? BIT_ACCTCTRL : 0) +
1196 12 : (account_policy ? BIT_ACCPOLICY : 0) +
1197 12 : (account_policy_value_set ? BIT_ACCPOLVAL : 0) +
1198 12 : (backend_in ? BIT_IMPORT : 0) +
1199 12 : (backend_out ? BIT_EXPORT : 0) +
1200 12 : (badpw_reset ? BIT_BADPWRESET : 0) +
1201 12 : (hours_reset ? BIT_LOGONHOURS : 0) +
1202 12 : (kickoff_time ? BIT_KICKOFFTIME : 0) +
1203 12 : (str_hex_pwd ? BIT_PWSETNTHASH : 0 ) +
1204 12 : (acct_desc ? BIT_DESCRIPTION : 0);
1205 :
1206 :
1207 12 : if (setparms & BIT_BACKEND) {
1208 : /* HACK: set the global passdb backend by overwriting globals.
1209 : * This way we can use regular pdb functions for default
1210 : * operations that do not involve passdb migrations */
1211 0 : lpcfg_set_cmdline(lp_ctx, "passdb backend", backend);
1212 : } else {
1213 12 : backend = lp_passdb_backend();
1214 : }
1215 :
1216 12 : if (!initialize_password_db(False, NULL)) {
1217 0 : fprintf(stderr, "Can't initialize passdb backend.\n");
1218 0 : exit(1);
1219 : }
1220 :
1221 : /* the lowest bit options are always accepted */
1222 12 : checkparms = setparms & ~MASK_ALWAYS_GOOD;
1223 :
1224 12 : if (checkparms & BIT_FIX_INIT) {
1225 0 : poptFreeContext(pc);
1226 0 : return fix_users_list();
1227 : }
1228 :
1229 : /* account policy operations */
1230 12 : if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
1231 : uint32_t value;
1232 0 : enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
1233 0 : if (field == 0) {
1234 : const char **names;
1235 : int count;
1236 : int i;
1237 0 : account_policy_names_list(talloc_tos(), &names, &count);
1238 0 : fprintf(stderr, "No account policy by that name!\n");
1239 0 : if (count !=0) {
1240 0 : fprintf(stderr, "Account policy names are:\n");
1241 0 : for (i = 0; i < count ; i++) {
1242 0 : d_fprintf(stderr, "%s\n", names[i]);
1243 : }
1244 : }
1245 0 : TALLOC_FREE(names);
1246 0 : exit(1);
1247 : }
1248 0 : if (!pdb_get_account_policy(field, &value)) {
1249 0 : fprintf(stderr, "valid account policy, but unable to fetch value!\n");
1250 0 : if (!account_policy_value_set)
1251 0 : exit(1);
1252 : }
1253 0 : printf("account policy \"%s\" description: %s\n", account_policy, account_policy_get_desc(field));
1254 0 : if (account_policy_value_set) {
1255 0 : printf("account policy \"%s\" value was: %u\n", account_policy, value);
1256 0 : if (!pdb_set_account_policy(field, account_policy_value)) {
1257 0 : fprintf(stderr, "valid account policy, but unable to set value!\n");
1258 0 : exit(1);
1259 : }
1260 0 : printf("account policy \"%s\" value is now: %lu\n", account_policy, account_policy_value);
1261 0 : exit(0);
1262 : } else {
1263 0 : printf("account policy \"%s\" value is: %u\n", account_policy, value);
1264 0 : exit(0);
1265 : }
1266 : }
1267 :
1268 12 : if (reset_account_policies) {
1269 0 : if (reinit_account_policies()) {
1270 0 : exit(1);
1271 : }
1272 :
1273 0 : exit(0);
1274 : }
1275 :
1276 : /* import and export operations */
1277 :
1278 12 : if (((checkparms & BIT_IMPORT) ||
1279 12 : (checkparms & BIT_EXPORT)) &&
1280 0 : !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) {
1281 :
1282 0 : poptFreeContext(pc);
1283 :
1284 0 : if (backend_in) {
1285 0 : status = make_pdb_method_name(&bin, backend_in);
1286 : } else {
1287 0 : status = make_pdb_method_name(&bin, backend);
1288 : }
1289 :
1290 0 : if (!NT_STATUS_IS_OK(status)) {
1291 0 : fprintf(stderr, "Unable to initialize %s.\n",
1292 0 : backend_in ? backend_in : backend);
1293 0 : return 1;
1294 : }
1295 :
1296 0 : if (backend_out) {
1297 0 : status = make_pdb_method_name(&bout, backend_out);
1298 : } else {
1299 0 : status = make_pdb_method_name(&bout, backend);
1300 : }
1301 :
1302 0 : if (!NT_STATUS_IS_OK(status)) {
1303 0 : fprintf(stderr, "Unable to initialize %s.\n",
1304 0 : backend_out ? backend_out : backend);
1305 0 : return 1;
1306 : }
1307 :
1308 0 : if (transfer_account_policies) {
1309 :
1310 0 : if (!(checkparms & BIT_USER)) {
1311 0 : return export_account_policies(bin, bout);
1312 : }
1313 :
1314 0 : } else if (transfer_groups) {
1315 :
1316 0 : if (!(checkparms & BIT_USER)) {
1317 0 : return export_groups(bin, bout);
1318 : }
1319 :
1320 : } else {
1321 0 : return export_database(bin, bout,
1322 0 : (checkparms & BIT_USER) ? user_name : NULL);
1323 : }
1324 : }
1325 :
1326 : /* if BIT_USER is defined but nothing else then threat it as -l -u for compatibility */
1327 : /* fake up BIT_LIST if only BIT_USER is defined */
1328 12 : if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) {
1329 0 : checkparms += BIT_LIST;
1330 : }
1331 :
1332 : /* modify flag is optional to maintain backwards compatibility */
1333 : /* fake up BIT_MODIFY if BIT_USER and at least one of MASK_USER_GOOD is defined */
1334 12 : if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) {
1335 3 : checkparms += BIT_MODIFY;
1336 : }
1337 :
1338 : /* list users operations */
1339 12 : if (checkparms & BIT_LIST) {
1340 0 : if (!(checkparms & ~BIT_LIST)) {
1341 0 : poptFreeContext(pc);
1342 0 : return print_users_list(verbose, spstyle);
1343 : }
1344 0 : if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
1345 0 : poptFreeContext(pc);
1346 0 : return print_user_info(user_name, verbose, spstyle);
1347 : }
1348 : }
1349 :
1350 : /* mask out users options */
1351 12 : checkparms &= ~MASK_USER_GOOD;
1352 :
1353 : /* if bad password count is reset, we must be modifying */
1354 12 : if (checkparms & BIT_BADPWRESET) {
1355 0 : checkparms |= BIT_MODIFY;
1356 0 : checkparms &= ~BIT_BADPWRESET;
1357 : }
1358 :
1359 : /* if logon hours is reset, must modify */
1360 12 : if (checkparms & BIT_LOGONHOURS) {
1361 0 : checkparms |= BIT_MODIFY;
1362 0 : checkparms &= ~BIT_LOGONHOURS;
1363 : }
1364 :
1365 : /* account operation */
1366 12 : if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
1367 : /* check use of -u option */
1368 12 : if (!(checkparms & BIT_USER)) {
1369 0 : fprintf (stderr, "Username not specified! (use -u option)\n");
1370 0 : poptFreeContext(pc);
1371 0 : return -1;
1372 : }
1373 :
1374 : /* account creation operations */
1375 12 : if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
1376 3 : poptFreeContext(pc);
1377 3 : if (checkparms & BIT_MACHINE) {
1378 0 : return new_machine(user_name, machine_sid);
1379 : } else {
1380 3 : return new_user(user_name, full_name,
1381 : home_dir, home_drive,
1382 : logon_script, profile_path,
1383 : user_sid, pw_from_stdin);
1384 : }
1385 : }
1386 :
1387 : /* account deletion operations */
1388 9 : if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
1389 3 : poptFreeContext(pc);
1390 3 : if (checkparms & BIT_MACHINE) {
1391 0 : return delete_machine_entry(user_name);
1392 : } else {
1393 3 : return delete_user_entry(user_name);
1394 : }
1395 : }
1396 :
1397 : /* account modification operations */
1398 6 : if (!(checkparms & ~(BIT_MODIFY + BIT_USER + BIT_MACHINE))) {
1399 6 : poptFreeContext(pc);
1400 6 : if (checkparms & BIT_MACHINE) {
1401 0 : return set_machine_info(user_name,
1402 : account_control,
1403 : machine_sid);
1404 : } else {
1405 6 : return set_user_info(user_name, full_name,
1406 : home_dir, acct_desc,
1407 : home_drive, logon_script,
1408 : profile_path, account_control,
1409 : user_sid, user_domain,
1410 : badpw_reset, hours_reset,
1411 : kickoff_time, str_hex_pwd);
1412 : }
1413 : }
1414 : }
1415 :
1416 0 : if (setparms >= 0x20) {
1417 0 : fprintf (stderr, "Incompatible or insufficient options on command line!\n");
1418 : }
1419 0 : poptPrintHelp(pc, stderr, 0);
1420 :
1421 0 : gfree_all();
1422 0 : poptFreeContext(pc);
1423 0 : TALLOC_FREE(frame);
1424 0 : return 1;
1425 : }
|