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 acct_ctrl
)
362 sampass
->private.acct_ctrl
= acct_ctrl
;
367 NTSTATUS
sam_set_account_logon_time(SAM_ACCOUNT_HANDLE
*sampass
, NTTIME mytime
, BOOL store
)
371 sampass
->private.logon_time
= mytime
;
374 return NT_STATUS_UNSUCCESSFUL
;
377 NTSTATUS
sam_set_account_logoff_time(SAM_ACCOUNT_HANDLE
*sampass
, NTTIME mytime
, BOOL store
)
381 sampass
->private.logoff_time
= mytime
;
386 NTSTATUS
sam_set_account_kickoff_time(SAM_ACCOUNT_HANDLE
*sampass
, NTTIME mytime
, BOOL store
)
390 sampass
->private.kickoff_time
= mytime
;
396 NTSTATUS
sam_set_account_pass_can_change_time(SAM_ACCOUNT_HANDLE
*sampass
, NTTIME mytime
, BOOL store
)
400 sampass
->private.pass_can_change_time
= mytime
;
406 NTSTATUS
sam_set_account_pass_must_change_time(SAM_ACCOUNT_HANDLE
*sampass
, NTTIME mytime
, BOOL store
)
410 sampass
->private.pass_must_change_time
= mytime
;
415 NTSTATUS
sam_set_account_pass_last_set_time(SAM_ACCOUNT_HANDLE
*sampass
, NTTIME mytime
)
419 sampass
->private.pass_last_set_time
= mytime
;
424 NTSTATUS
sam_set_account_hours_len(SAM_ACCOUNT_HANDLE
*sampass
, uint32 len
)
428 sampass
->private.hours_len
= len
;
432 NTSTATUS
sam_set_account_logon_divs(SAM_ACCOUNT_HANDLE
*sampass
, uint16 hours
)
436 sampass
->private.logon_divs
= hours
;
441 * Set flags showing what is initalised in the SAM_ACCOUNT_HANDLE
442 * @param sampass the SAM_ACCOUNT_HANDLE in question
443 * @param flag The *new* flag to be set. Old flags preserved
444 * this flag is only added.
447 NTSTATUS
sam_set_account_init_flag(SAM_ACCOUNT_HANDLE
*sampass
, uint32 flag
)
451 sampass
->private.init_flag
|= flag
;
456 NTSTATUS
sam_set_account_sid(SAM_ACCOUNT_HANDLE
*sampass
, const DOM_SID
*u_sid
)
458 SAM_ASSERT(sampass
&& u_sid
);
460 sid_copy(&sampass
->private.account_sid
, u_sid
);
462 DEBUG(10, ("sam_set_account_sid: setting account sid %s\n",
463 sid_string_static(&sampass
->private.account_sid
)));
468 NTSTATUS
sam_set_account_sid_from_string(SAM_ACCOUNT_HANDLE
*sampass
, const char *u_sid
)
471 SAM_ASSERT(sampass
&& u_sid
);
473 DEBUG(10, ("sam_set_account_sid_from_string: setting account sid %s\n",
476 if (!string_to_sid(&new_sid
, u_sid
)) {
477 DEBUG(1, ("sam_set_account_sid_from_string: %s isn't a valid SID!\n", u_sid
));
478 return NT_STATUS_UNSUCCESSFUL
;
481 if (!NT_STATUS_IS_OK(sam_set_account_sid(sampass
, &new_sid
))) {
482 DEBUG(1, ("sam_set_account_sid_from_string: could not set sid %s on SAM_ACCOUNT_HANDLE!\n", u_sid
));
483 return NT_STATUS_UNSUCCESSFUL
;
489 NTSTATUS
sam_set_account_pgroup_sid(SAM_ACCOUNT_HANDLE
*sampass
, const DOM_SID
*g_sid
)
491 SAM_ASSERT(sampass
&& g_sid
);
493 sid_copy(&sampass
->private.group_sid
, g_sid
);
495 DEBUG(10, ("sam_set_group_sid: setting group sid %s\n",
496 sid_string_static(&sampass
->private.group_sid
)));
501 NTSTATUS
sam_set_account_pgroup_string(SAM_ACCOUNT_HANDLE
*sampass
, const char *g_sid
)
504 SAM_ASSERT(sampass
&& g_sid
);
506 DEBUG(10, ("sam_set_group_sid_from_string: setting group sid %s\n",
509 if (!string_to_sid(&new_sid
, g_sid
)) {
510 DEBUG(1, ("sam_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid
));
511 return NT_STATUS_UNSUCCESSFUL
;
514 if (!NT_STATUS_IS_OK(sam_set_account_pgroup_sid(sampass
, &new_sid
))) {
515 DEBUG(1, ("sam_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT_HANDLE!\n", g_sid
));
516 return NT_STATUS_UNSUCCESSFUL
;
521 /*********************************************************************
523 ********************************************************************/
525 NTSTATUS
sam_set_account_domain(SAM_ACCOUNT_HANDLE
*sampass
, SAM_DOMAIN_HANDLE
*domain
)
529 sampass
->private.domain
= domain
;
534 /*********************************************************************
535 Set the account's NT name.
536 ********************************************************************/
538 NTSTATUS
sam_set_account_name(SAM_ACCOUNT_HANDLE
*sampass
, const char *account_name
)
542 DEBUG(10, ("sam_set_account_name: setting nt account_name %s, was %s\n", account_name
, sampass
->private.account_name
));
544 sampass
->private.account_name
= talloc_strdup(sampass
->mem_ctx
, account_name
);
549 /*********************************************************************
550 Set the account's full name.
551 ********************************************************************/
553 NTSTATUS
sam_set_account_fullname(SAM_ACCOUNT_HANDLE
*sampass
, const char *full_name
)
557 DEBUG(10, ("sam_set_account_fullname: setting full name %s, was %s\n", full_name
, sampass
->private.full_name
));
559 sampass
->private.full_name
= talloc_strdup(sampass
->mem_ctx
, full_name
);
564 /*********************************************************************
565 Set the account's logon script.
566 ********************************************************************/
568 NTSTATUS
sam_set_account_logon_script(SAM_ACCOUNT_HANDLE
*sampass
, const char *logon_script
, BOOL store
)
572 DEBUG(10, ("sam_set_logon_script: from %s to %s\n", logon_script
, sampass
->private.logon_script
));
574 sampass
->private.logon_script
= talloc_strdup(sampass
->mem_ctx
, logon_script
);
580 /*********************************************************************
581 Set the account's profile path.
582 ********************************************************************/
584 NTSTATUS
sam_set_account_profile_path(SAM_ACCOUNT_HANDLE
*sampass
, const char *profile_path
, BOOL store
)
588 DEBUG(10, ("sam_set_profile_path: setting profile path %s, was %s\n", profile_path
, sampass
->private.profile_path
));
590 sampass
->private.profile_path
= talloc_strdup(sampass
->mem_ctx
, profile_path
);
595 /*********************************************************************
596 Set the account's directory drive.
597 ********************************************************************/
599 NTSTATUS
sam_set_account_dir_drive(SAM_ACCOUNT_HANDLE
*sampass
, const char *dir_drive
, BOOL store
)
603 DEBUG(10, ("sam_set_dir_drive: setting dir drive %s, was %s\n", dir_drive
,
604 sampass
->private.dir_drive
));
606 sampass
->private.dir_drive
= talloc_strdup(sampass
->mem_ctx
, dir_drive
);
611 /*********************************************************************
612 Set the account's home directory.
613 ********************************************************************/
615 NTSTATUS
sam_set_account_homedir(SAM_ACCOUNT_HANDLE
*sampass
, const char *home_dir
, BOOL store
)
619 DEBUG(10, ("sam_set_homedir: setting home dir %s, was %s\n", home_dir
,
620 sampass
->private.home_dir
));
622 sampass
->private.home_dir
= talloc_strdup(sampass
->mem_ctx
, home_dir
);
627 /*********************************************************************
628 Set the account's unix home directory.
629 ********************************************************************/
631 NTSTATUS
sam_set_account_unix_homedir(SAM_ACCOUNT_HANDLE
*sampass
, const char *unix_home_dir
)
635 DEBUG(10, ("sam_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir
,
636 sampass
->private.unix_home_dir
));
638 sampass
->private.unix_home_dir
= talloc_strdup(sampass
->mem_ctx
, unix_home_dir
);
643 /*********************************************************************
644 Set the account's account description.
645 ********************************************************************/
647 NTSTATUS
sam_set_account_acct_desc(SAM_ACCOUNT_HANDLE
*sampass
, const char *acct_desc
)
651 sampass
->private.acct_desc
= talloc_strdup(sampass
->mem_ctx
, acct_desc
);
656 /*********************************************************************
657 Set the account's workstation allowed list.
658 ********************************************************************/
660 NTSTATUS
sam_set_account_workstations(SAM_ACCOUNT_HANDLE
*sampass
, const char *workstations
)
664 DEBUG(10, ("sam_set_workstations: setting workstations %s, was %s\n", workstations
,
665 sampass
->private.workstations
));
667 sampass
->private.workstations
= talloc_strdup(sampass
->mem_ctx
, workstations
);
672 /*********************************************************************
673 Set the account's 'unknown_str', whatever the heck this actually is...
674 ********************************************************************/
676 NTSTATUS
sam_set_account_unknown_str(SAM_ACCOUNT_HANDLE
*sampass
, const char *unknown_str
)
680 sampass
->private.unknown_str
= talloc_strdup(sampass
->mem_ctx
, unknown_str
);
685 /*********************************************************************
686 Set the account's dial string.
687 ********************************************************************/
689 NTSTATUS
sam_set_account_munged_dial(SAM_ACCOUNT_HANDLE
*sampass
, const char *munged_dial
)
693 sampass
->private.munged_dial
= talloc_strdup(sampass
->mem_ctx
, munged_dial
);
698 /*********************************************************************
699 Set the account's NT hash.
700 ********************************************************************/
702 NTSTATUS
sam_set_account_nt_pwd(SAM_ACCOUNT_HANDLE
*sampass
, const DATA_BLOB data
)
706 sampass
->private.nt_pw
= data
;
711 /*********************************************************************
712 Set the account's LM hash.
713 ********************************************************************/
715 NTSTATUS
sam_set_account_lm_pwd(SAM_ACCOUNT_HANDLE
*sampass
, const DATA_BLOB data
)
719 sampass
->private.lm_pw
= data
;
724 /*********************************************************************
725 Set the account's plaintext password only (base procedure, see helper
727 ********************************************************************/
729 NTSTATUS
sam_set_account_plaintext_pwd(SAM_ACCOUNT_HANDLE
*sampass
, const char *plain_pwd
)
733 sampass
->private.plaintext_pw
= talloc_strdup(sampass
->mem_ctx
, plain_pwd
);
738 NTSTATUS
sam_set_account_unknown_1(SAM_ACCOUNT_HANDLE
*sampass
, uint32 unkn
)
742 sampass
->private.unknown_1
= unkn
;
747 NTSTATUS
sam_set_account_unknown_2(SAM_ACCOUNT_HANDLE
*sampass
, uint32 unkn
)
751 sampass
->private.unknown_2
= unkn
;
756 NTSTATUS
sam_set_account_unknown_3(SAM_ACCOUNT_HANDLE
*sampass
, uint32 unkn
)
760 sampass
->private.unknown_3
= unkn
;
764 NTSTATUS
sam_set_account_hours(SAM_ACCOUNT_HANDLE
*sampass
, const uint8
*hours
)
769 memset ((char *)sampass
->private.hours
, 0, MAX_HOURS_LEN
);
773 memcpy(sampass
->private.hours
, hours
, MAX_HOURS_LEN
);
778 /* Helpful interfaces to the above */
780 /*********************************************************************
781 Sets the last changed times and must change times for a normal
783 ********************************************************************/
785 NTSTATUS
sam_set_account_pass_changed_now(SAM_ACCOUNT_HANDLE
*sampass
)
792 unix_to_nt_time(&temptime
, time(NULL
));
793 if (!NT_STATUS_IS_OK(sam_set_account_pass_last_set_time(sampass
, temptime
)))
794 return NT_STATUS_UNSUCCESSFUL
;
796 if (!account_policy_get(AP_MAX_PASSWORD_AGE
, &expire
)
797 || (expire
==(uint32
)-1)) {
799 get_nttime_max(&temptime
);
800 if (!NT_STATUS_IS_OK(sam_set_account_pass_must_change_time(sampass
, temptime
, False
)))
801 return NT_STATUS_UNSUCCESSFUL
;
804 /* FIXME: Add expire to temptime */
806 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
)))
807 return NT_STATUS_UNSUCCESSFUL
;
813 /*********************************************************************
814 Set the account's PLAINTEXT password. Used as an interface to the above.
815 Also sets the last change time to NOW.
816 ********************************************************************/
818 NTSTATUS
sam_set_account_passwd(SAM_ACCOUNT_HANDLE
*sampass
, const char *plaintext
)
821 uchar new_lanman_p16
[16];
822 uchar new_nt_p16
[16];
824 SAM_ASSERT(sampass
&& plaintext
);
826 nt_lm_owf_gen(plaintext
, new_nt_p16
, new_lanman_p16
);
828 data
= data_blob(new_nt_p16
, 16);
829 if (!NT_STATUS_IS_OK(sam_set_account_nt_pwd(sampass
, data
)))
830 return NT_STATUS_UNSUCCESSFUL
;
832 data
= data_blob(new_lanman_p16
, 16);
834 if (!NT_STATUS_IS_OK(sam_set_account_lm_pwd(sampass
, data
)))
835 return NT_STATUS_UNSUCCESSFUL
;
837 if (!NT_STATUS_IS_OK(sam_set_account_plaintext_pwd(sampass
, plaintext
)))
838 return NT_STATUS_UNSUCCESSFUL
;
840 if (!NT_STATUS_IS_OK(sam_set_account_pass_changed_now(sampass
)))
841 return NT_STATUS_UNSUCCESSFUL
;