2 Unix SMB/CIFS implementation.
3 SAM_ACCOUNT_HANDLE access routines
4 Copyright (C) Andrew Bartlett 2002
5 Copyright (C) Stefan (metze) Metzmacher 2002
6 Copyright (C) Jelmer Vernooij 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define DBGC_CLASS DBGC_SAM
28 NTSTATUS sam_get_account_domain_sid(const SAM_ACCOUNT_HANDLE *sampass, const DOM_SID **sid)
31 SAM_DOMAIN_HANDLE *domain;
32 SAM_ASSERT(!sampass || !sid);
34 if (!NT_STATUS_IS_OK(status = sam_get_account_domain(sampass, &domain))){
35 DEBUG(0, ("sam_get_account_domain_sid: Can't get domain for account\n"));
39 return sam_get_domain_sid(domain, sid);
42 NTSTATUS sam_get_account_domain_name(const SAM_ACCOUNT_HANDLE *sampass, const char **domain_name)
45 SAM_DOMAIN_HANDLE *domain;
46 SAM_ASSERT(sampass && domain_name);
48 if (!NT_STATUS_IS_OK(status = sam_get_account_domain(sampass, &domain))){
49 DEBUG(0, ("sam_get_account_domain_name: Can't get domain for account\n"));
53 return sam_get_domain_name(domain, domain_name);
56 NTSTATUS sam_get_account_acct_ctrl(const SAM_ACCOUNT_HANDLE *sampass, uint16 *acct_ctrl)
58 SAM_ASSERT(sampass && acct_ctrl);
60 *acct_ctrl = sampass->private.acct_ctrl;
65 NTSTATUS sam_get_account_logon_time(const SAM_ACCOUNT_HANDLE *sampass, NTTIME *logon_time)
67 SAM_ASSERT(sampass && logon_time) ;
69 *logon_time = sampass->private.logon_time;
74 NTSTATUS sam_get_account_logoff_time(const SAM_ACCOUNT_HANDLE *sampass, NTTIME *logoff_time)
76 SAM_ASSERT(sampass && logoff_time) ;
78 *logoff_time = sampass->private.logoff_time;
83 NTSTATUS sam_get_account_kickoff_time(const SAM_ACCOUNT_HANDLE *sampass, NTTIME *kickoff_time)
85 SAM_ASSERT(sampass && kickoff_time);
87 *kickoff_time = sampass->private.kickoff_time;
92 NTSTATUS sam_get_account_pass_last_set_time(const SAM_ACCOUNT_HANDLE *sampass, NTTIME *pass_last_set_time)
94 SAM_ASSERT(sampass && pass_last_set_time);
96 *pass_last_set_time = sampass->private.pass_last_set_time;
101 NTSTATUS sam_get_account_pass_can_change_time(const SAM_ACCOUNT_HANDLE *sampass, NTTIME *pass_can_change_time)
103 SAM_ASSERT(sampass && pass_can_change_time);
105 *pass_can_change_time = sampass->private.pass_can_change_time;
110 NTSTATUS sam_get_account_pass_must_change_time(const SAM_ACCOUNT_HANDLE *sampass, NTTIME *pass_must_change_time)
112 SAM_ASSERT(sampass && pass_must_change_time);
114 *pass_must_change_time = sampass->private.pass_must_change_time;
119 NTSTATUS sam_get_account_logon_divs(const SAM_ACCOUNT_HANDLE *sampass, uint16 *logon_divs)
121 SAM_ASSERT(sampass && logon_divs);
123 *logon_divs = sampass->private.logon_divs;
128 NTSTATUS sam_get_account_hours_len(const SAM_ACCOUNT_HANDLE *sampass, uint32 *hours_len)
130 SAM_ASSERT(sampass && hours_len);
132 *hours_len = sampass->private.hours_len;
137 NTSTATUS sam_get_account_hours(const SAM_ACCOUNT_HANDLE *sampass, const uint8 **hours)
139 SAM_ASSERT(sampass && hours);
141 *hours = sampass->private.hours;
146 NTSTATUS sam_get_account_nt_pwd(const SAM_ACCOUNT_HANDLE *sampass, DATA_BLOB *nt_pwd)
150 SMB_ASSERT((!sampass->private.nt_pw.data)
151 || sampass->private.nt_pw.length == NT_HASH_LEN);
153 *nt_pwd = sampass->private.nt_pw;
158 NTSTATUS sam_get_account_lm_pwd(const SAM_ACCOUNT_HANDLE *sampass, DATA_BLOB *lm_pwd)
162 SMB_ASSERT((!sampass->private.lm_pw.data)
163 || sampass->private.lm_pw.length == LM_HASH_LEN);
165 *lm_pwd = sampass->private.lm_pw;
170 /* Return the plaintext password if known. Most of the time
171 it isn't, so don't assume anything magic about this function.
173 Used to pass the plaintext to sam backends that might
174 want to store more than just the NTLM hashes.
177 NTSTATUS sam_get_account_plaintext_pwd(const SAM_ACCOUNT_HANDLE *sampass, char **plain_pwd)
179 SAM_ASSERT(sampass && plain_pwd);
181 *plain_pwd = sampass->private.plaintext_pw;
186 NTSTATUS sam_get_account_sid(const SAM_ACCOUNT_HANDLE *sampass, const DOM_SID **sid)
190 *sid = &(sampass->private.account_sid);
195 NTSTATUS sam_get_account_pgroup(const SAM_ACCOUNT_HANDLE *sampass, const DOM_SID **sid)
199 *sid = &(sampass->private.group_sid);
205 * Get flags showing what is initalised in the SAM_ACCOUNT_HANDLE
206 * @param sampass the SAM_ACCOUNT_HANDLE in question
207 * @return the flags indicating the members initialised in the struct.
210 NTSTATUS sam_get_account_init_flag(const SAM_ACCOUNT_HANDLE *sampass, uint32 *initflag)
214 *initflag = sampass->private.init_flag;
219 NTSTATUS sam_get_account_name(const SAM_ACCOUNT_HANDLE *sampass, char **account_name)
223 *account_name = sampass->private.account_name;
228 NTSTATUS sam_get_account_domain(const SAM_ACCOUNT_HANDLE *sampass, SAM_DOMAIN_HANDLE **domain)
232 *domain = sampass->private.domain;
237 NTSTATUS sam_get_account_fullname(const SAM_ACCOUNT_HANDLE *sampass, char **fullname)
241 *fullname = sampass->private.full_name;
246 NTSTATUS sam_get_account_homedir(const SAM_ACCOUNT_HANDLE *sampass, char **homedir)
250 *homedir = sampass->private.home_dir;
255 NTSTATUS sam_get_account_unix_home_dir(const SAM_ACCOUNT_HANDLE *sampass, char **uhomedir)
259 *uhomedir = sampass->private.unix_home_dir;
264 NTSTATUS sam_get_account_dir_drive(const SAM_ACCOUNT_HANDLE *sampass, char **dirdrive)
268 *dirdrive = sampass->private.dir_drive;
273 NTSTATUS sam_get_account_logon_script(const SAM_ACCOUNT_HANDLE *sampass, char **logon_script)
277 *logon_script = sampass->private.logon_script;
282 NTSTATUS sam_get_account_profile_path(const SAM_ACCOUNT_HANDLE *sampass, char **profile_path)
286 *profile_path = sampass->private.profile_path;
291 NTSTATUS sam_get_account_description(const SAM_ACCOUNT_HANDLE *sampass, char **description)
295 *description = sampass->private.acct_desc;
300 NTSTATUS sam_get_account_workstations(const SAM_ACCOUNT_HANDLE *sampass, char **workstations)
304 *workstations = sampass->private.workstations;
309 NTSTATUS sam_get_account_unknown_str(const SAM_ACCOUNT_HANDLE *sampass, char **unknown_str)
313 *unknown_str = sampass->private.unknown_str;
318 NTSTATUS sam_get_account_munged_dial(const SAM_ACCOUNT_HANDLE *sampass, char **munged_dial)
322 *munged_dial = sampass->private.munged_dial;
327 NTSTATUS sam_get_account_unknown_1(const SAM_ACCOUNT_HANDLE *sampass, uint32 *unknown1)
329 SAM_ASSERT(sampass && unknown1);
331 *unknown1 = sampass->private.unknown_1;
336 NTSTATUS sam_get_account_unknown_2(const SAM_ACCOUNT_HANDLE *sampass, uint32 *unknown2)
338 SAM_ASSERT(sampass && unknown2);
340 *unknown2 = sampass->private.unknown_2;
345 NTSTATUS sam_get_account_unknown_3(const SAM_ACCOUNT_HANDLE *sampass, uint32 *unknown3)
347 SAM_ASSERT(sampass && unknown3);
349 *unknown3 = sampass->private.unknown_3;
354 /*********************************************************************
355 Collection of set...() functions for SAM_ACCOUNT_HANDLE_INFO.
356 ********************************************************************/
358 NTSTATUS sam_set_account_acct_ctrl(SAM_ACCOUNT_HANDLE *sampass, uint16 flags)
362 sampass->private.acct_ctrl = flags;
367 NTSTATUS sam_set_account_logon_time(SAM_ACCOUNT_HANDLE *sampass, NTTIME mytime, BOOL store)
371 sampass->private.logon_time = mytime;
374 sam_set_account_init_flag(sampass, FLAG_SAM_LOGONTIME);
376 return NT_STATUS_UNSUCCESSFUL;
379 NTSTATUS sam_set_account_logoff_time(SAM_ACCOUNT_HANDLE *sampass, NTTIME mytime, BOOL store)
383 sampass->private.logoff_time = mytime;
386 sam_set_account_init_flag(sampass, FLAG_SAM_LOGOFFTIME);
391 NTSTATUS sam_set_account_kickoff_time(SAM_ACCOUNT_HANDLE *sampass, NTTIME mytime, BOOL store)
395 sampass->private.kickoff_time = mytime;
398 sam_set_account_init_flag(sampass, FLAG_SAM_KICKOFFTIME);
403 NTSTATUS sam_set_account_pass_can_change_time(SAM_ACCOUNT_HANDLE *sampass, NTTIME mytime, BOOL store)
407 sampass->private.pass_can_change_time = mytime;
410 sam_set_account_init_flag(sampass, FLAG_SAM_CANCHANGETIME);
415 NTSTATUS sam_set_account_pass_must_change_time(SAM_ACCOUNT_HANDLE *sampass, NTTIME mytime, BOOL store)
419 sampass->private.pass_must_change_time = mytime;
422 sam_set_account_init_flag(sampass, FLAG_SAM_MUSTCHANGETIME);
427 NTSTATUS sam_set_account_pass_last_set_time(SAM_ACCOUNT_HANDLE *sampass, NTTIME mytime)
431 sampass->private.pass_last_set_time = mytime;
436 NTSTATUS sam_set_account_hours_len(SAM_ACCOUNT_HANDLE *sampass, uint32 len)
440 sampass->private.hours_len = len;
444 NTSTATUS sam_set_account_logon_divs(SAM_ACCOUNT_HANDLE *sampass, uint16 hours)
448 sampass->private.logon_divs = hours;
453 * Set flags showing what is initalised in the SAM_ACCOUNT_HANDLE
454 * @param sampass the SAM_ACCOUNT_HANDLE in question
455 * @param flag The *new* flag to be set. Old flags preserved
456 * this flag is only added.
459 NTSTATUS sam_set_account_init_flag(SAM_ACCOUNT_HANDLE *sampass, uint32 flag)
463 sampass->private.init_flag |= flag;
468 NTSTATUS sam_set_account_sid(SAM_ACCOUNT_HANDLE *sampass, const DOM_SID *u_sid)
470 SAM_ASSERT(sampass && u_sid);
472 sid_copy(&sampass->private.account_sid, u_sid);
474 DEBUG(10, ("sam_set_account_sid: setting account sid %s\n",
475 sid_string_static(&sampass->private.account_sid)));
480 NTSTATUS sam_set_account_sid_from_string(SAM_ACCOUNT_HANDLE *sampass, const char *u_sid)
483 SAM_ASSERT(sampass && u_sid);
485 DEBUG(10, ("sam_set_account_sid_from_string: setting account sid %s\n",
488 if (!string_to_sid(&new_sid, u_sid)) {
489 DEBUG(1, ("sam_set_account_sid_from_string: %s isn't a valid SID!\n", u_sid));
490 return NT_STATUS_UNSUCCESSFUL;
493 if (!NT_STATUS_IS_OK(sam_set_account_sid(sampass, &new_sid))) {
494 DEBUG(1, ("sam_set_account_sid_from_string: could not set sid %s on SAM_ACCOUNT_HANDLE!\n", u_sid));
495 return NT_STATUS_UNSUCCESSFUL;
501 NTSTATUS sam_set_account_pgroup_sid(SAM_ACCOUNT_HANDLE *sampass, const DOM_SID *g_sid)
503 SAM_ASSERT(sampass && g_sid);
505 sid_copy(&sampass->private.group_sid, g_sid);
507 DEBUG(10, ("sam_set_group_sid: setting group sid %s\n",
508 sid_string_static(&sampass->private.group_sid)));
513 NTSTATUS sam_set_account_pgroup_string(SAM_ACCOUNT_HANDLE *sampass, const char *g_sid)
516 SAM_ASSERT(sampass && g_sid);
518 DEBUG(10, ("sam_set_group_sid_from_string: setting group sid %s\n",
521 if (!string_to_sid(&new_sid, g_sid)) {
522 DEBUG(1, ("sam_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
523 return NT_STATUS_UNSUCCESSFUL;
526 if (!NT_STATUS_IS_OK(sam_set_account_pgroup_sid(sampass, &new_sid))) {
527 DEBUG(1, ("sam_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT_HANDLE!\n", g_sid));
528 return NT_STATUS_UNSUCCESSFUL;
533 /*********************************************************************
535 ********************************************************************/
537 NTSTATUS sam_set_account_domain(SAM_ACCOUNT_HANDLE *sampass, SAM_DOMAIN_HANDLE *domain)
541 sampass->private.domain = domain;
546 /*********************************************************************
547 Set the account's NT name.
548 ********************************************************************/
550 NTSTATUS sam_set_account_name(SAM_ACCOUNT_HANDLE *sampass, const char *account_name)
554 DEBUG(10, ("sam_set_account_name: setting nt account_name %s, was %s\n", account_name, sampass->private.account_name));
556 sampass->private.account_name = talloc_strdup(sampass->mem_ctx, account_name);
561 /*********************************************************************
562 Set the account's full name.
563 ********************************************************************/
565 NTSTATUS sam_set_account_fullname(SAM_ACCOUNT_HANDLE *sampass, const char *full_name)
569 DEBUG(10, ("sam_set_account_fullname: setting full name %s, was %s\n", full_name, sampass->private.full_name));
571 sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name);
576 /*********************************************************************
577 Set the account's logon script.
578 ********************************************************************/
580 NTSTATUS sam_set_account_logon_script(SAM_ACCOUNT_HANDLE *sampass, const char *logon_script, BOOL store)
584 DEBUG(10, ("sam_set_logon_script: from %s to %s\n", logon_script, sampass->private.logon_script));
586 sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script);
588 sam_set_account_init_flag(sampass, FLAG_SAM_LOGONSCRIPT);
593 /*********************************************************************
594 Set the account's profile path.
595 ********************************************************************/
597 NTSTATUS sam_set_account_profile_path(SAM_ACCOUNT_HANDLE *sampass, const char *profile_path, BOOL store)
601 DEBUG(10, ("sam_set_profile_path: setting profile path %s, was %s\n", profile_path, sampass->private.profile_path));
603 sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path);
606 DEBUG(10, ("sam_set_profile_path: setting profile path sam flag!\n"));
607 sam_set_account_init_flag(sampass, FLAG_SAM_PROFILE);
613 /*********************************************************************
614 Set the account's directory drive.
615 ********************************************************************/
617 NTSTATUS sam_set_account_dir_drive(SAM_ACCOUNT_HANDLE *sampass, const char *dir_drive, BOOL store)
621 DEBUG(10, ("sam_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
622 sampass->private.dir_drive));
624 sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive);
627 DEBUG(10, ("sam_set_dir_drive: setting dir drive sam flag!\n"));
628 sam_set_account_init_flag(sampass, FLAG_SAM_DRIVE);
634 /*********************************************************************
635 Set the account's home directory.
636 ********************************************************************/
638 NTSTATUS sam_set_account_homedir(SAM_ACCOUNT_HANDLE *sampass, const char *home_dir, BOOL store)
642 DEBUG(10, ("sam_set_homedir: setting home dir %s, was %s\n", home_dir,
643 sampass->private.home_dir));
645 sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir);
648 DEBUG(10, ("sam_set_homedir: setting home dir sam flag!\n"));
649 sam_set_account_init_flag(sampass, FLAG_SAM_SMBHOME);
655 /*********************************************************************
656 Set the account's unix home directory.
657 ********************************************************************/
659 NTSTATUS sam_set_account_unix_homedir(SAM_ACCOUNT_HANDLE *sampass, const char *unix_home_dir)
663 DEBUG(10, ("sam_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir,
664 sampass->private.unix_home_dir));
666 sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx, unix_home_dir);
671 /*********************************************************************
672 Set the account's account description.
673 ********************************************************************/
675 NTSTATUS sam_set_account_acct_desc(SAM_ACCOUNT_HANDLE *sampass, const char *acct_desc)
679 sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc);
684 /*********************************************************************
685 Set the account's workstation allowed list.
686 ********************************************************************/
688 NTSTATUS sam_set_account_workstations(SAM_ACCOUNT_HANDLE *sampass, const char *workstations)
692 DEBUG(10, ("sam_set_workstations: setting workstations %s, was %s\n", workstations,
693 sampass->private.workstations));
695 sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations);
700 /*********************************************************************
701 Set the account's 'unknown_str', whatever the heck this actually is...
702 ********************************************************************/
704 NTSTATUS sam_set_account_unknown_str(SAM_ACCOUNT_HANDLE *sampass, const char *unknown_str)
708 sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str);
713 /*********************************************************************
714 Set the account's dial string.
715 ********************************************************************/
717 NTSTATUS sam_set_account_munged_dial(SAM_ACCOUNT_HANDLE *sampass, const char *munged_dial)
721 sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial);
725 /*********************************************************************
726 Set the account's NT hash.
727 ********************************************************************/
729 NTSTATUS sam_set_account_nt_pwd(SAM_ACCOUNT_HANDLE *sampass, const DATA_BLOB data)
733 sampass->private.nt_pw = data;
738 /*********************************************************************
739 Set the account's LM hash.
740 ********************************************************************/
742 NTSTATUS sam_set_account_lm_pwd(SAM_ACCOUNT_HANDLE *sampass, const DATA_BLOB data)
746 sampass->private.lm_pw = data;
751 /*********************************************************************
752 Set the account's plaintext password only (base procedure, see helper
754 ********************************************************************/
756 NTSTATUS sam_set_account_plaintext_pwd(SAM_ACCOUNT_HANDLE *sampass, const char *plain_pwd)
760 sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, plain_pwd);
765 NTSTATUS sam_set_account_unknown_1(SAM_ACCOUNT_HANDLE *sampass, uint32 unkn)
769 sampass->private.unknown_1 = unkn;
774 NTSTATUS sam_set_account_unknown_2(SAM_ACCOUNT_HANDLE *sampass, uint32 unkn)
778 sampass->private.unknown_2 = unkn;
783 NTSTATUS sam_set_account_unknown_3(SAM_ACCOUNT_HANDLE *sampass, uint32 unkn)
787 sampass->private.unknown_3 = unkn;
791 NTSTATUS sam_set_account_hours(SAM_ACCOUNT_HANDLE *sampass, const uint8 *hours)
796 memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN);
800 memcpy(sampass->private.hours, hours, MAX_HOURS_LEN);
805 /* Helpful interfaces to the above */
807 /*********************************************************************
808 Sets the last changed times and must change times for a normal
810 ********************************************************************/
812 NTSTATUS sam_set_account_pass_changed_now(SAM_ACCOUNT_HANDLE *sampass)
819 unix_to_nt_time(&temptime, time(NULL));
820 if (!NT_STATUS_IS_OK(sam_set_account_pass_last_set_time(sampass, temptime)))
821 return NT_STATUS_UNSUCCESSFUL;
823 if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
824 || (expire==(uint32)-1)) {
826 get_nttime_max(&temptime);
827 if (!NT_STATUS_IS_OK(sam_set_account_pass_must_change_time(sampass, temptime, False)))
828 return NT_STATUS_UNSUCCESSFUL;
831 /* FIXME: Add expire to temptime */
833 if (!NT_STATUS_IS_OK(sam_get_account_pass_last_set_time(sampass,&temptime)) || !NT_STATUS_IS_OK(sam_set_account_pass_must_change_time(sampass, temptime,True)))
834 return NT_STATUS_UNSUCCESSFUL;
840 /*********************************************************************
841 Set the account's PLAINTEXT password. Used as an interface to the above.
842 Also sets the last change time to NOW.
843 ********************************************************************/
845 NTSTATUS sam_set_account_passwd(SAM_ACCOUNT_HANDLE *sampass, const char *plaintext)
848 uchar new_lanman_p16[16];
849 uchar new_nt_p16[16];
851 SAM_ASSERT(sampass && plaintext);
853 nt_lm_owf_gen(plaintext, new_nt_p16, new_lanman_p16);
855 data = data_blob(new_nt_p16, 16);
856 if (!NT_STATUS_IS_OK(sam_set_account_nt_pwd(sampass, data)))
857 return NT_STATUS_UNSUCCESSFUL;
859 data = data_blob(new_lanman_p16, 16);
861 if (!NT_STATUS_IS_OK(sam_set_account_lm_pwd(sampass, data)))
862 return NT_STATUS_UNSUCCESSFUL;
864 if (!NT_STATUS_IS_OK(sam_set_account_plaintext_pwd(sampass, plaintext)))
865 return NT_STATUS_UNSUCCESSFUL;
867 if (!NT_STATUS_IS_OK(sam_set_account_pass_changed_now(sampass)))
868 return NT_STATUS_UNSUCCESSFUL;