selftest: Fix typo in comment.
[Samba.git] / source3 / passdb / pdb_get_set.c
blob57d95138e3ea99b4c969324afdd853d50bd8a38d
1 /*
2 Unix SMB/CIFS implementation.
3 struct samu access routines
4 Copyright (C) Jeremy Allison 1996-2001
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000-2006
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "../libcli/auth/libcli_auth.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
30 /**
31 * @todo Redefine this to NULL, but this changes the API because
32 * much of samba assumes that the pdb_get...() funtions
33 * return strings. (ie not null-pointers).
34 * See also pdb_fill_default_sam().
37 #define PDB_NOT_QUITE_NULL ""
39 /*********************************************************************
40 Collection of get...() functions for struct samu.
41 ********************************************************************/
43 uint32_t pdb_get_acct_ctrl(const struct samu *sampass)
45 return sampass->acct_ctrl;
48 time_t pdb_get_logon_time(const struct samu *sampass)
50 return sampass->logon_time;
53 time_t pdb_get_logoff_time(const struct samu *sampass)
55 return sampass->logoff_time;
58 time_t pdb_get_kickoff_time(const struct samu *sampass)
60 return sampass->kickoff_time;
63 time_t pdb_get_bad_password_time(const struct samu *sampass)
65 return sampass->bad_password_time;
68 time_t pdb_get_pass_last_set_time(const struct samu *sampass)
70 return sampass->pass_last_set_time;
73 time_t pdb_get_pass_can_change_time(const struct samu *sampass)
75 uint32_t allow;
77 /* if the last set time is zero, it means the user cannot
78 change their password, and this time must be zero. jmcd
80 if (sampass->pass_last_set_time == 0)
81 return (time_t) 0;
83 /* if the time is max, and the field has been changed,
84 we're trying to update this real value from the sampass
85 to indicate that the user cannot change their password. jmcd
87 if (sampass->pass_can_change_time == get_time_t_max() &&
88 IS_SAM_CHANGED(sampass, PDB_CANCHANGETIME))
89 return sampass->pass_can_change_time;
91 if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
92 allow = 0;
94 /* in normal cases, just calculate it from policy */
95 return sampass->pass_last_set_time + allow;
98 /* we need this for loading from the backend, so that we don't overwrite
99 non-changed max times, otherwise the pass_can_change checking won't work */
100 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
102 return sampass->pass_can_change_time;
105 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
107 uint32_t expire;
109 if (sampass->pass_last_set_time == 0)
110 return (time_t) 0;
112 if (sampass->acct_ctrl & ACB_PWNOEXP)
113 return get_time_t_max();
115 if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
116 || expire == (uint32_t)-1 || expire == 0)
117 return get_time_t_max();
119 return sampass->pass_last_set_time + expire;
122 bool pdb_get_pass_can_change(const struct samu *sampass)
124 if (sampass->pass_can_change_time == get_time_t_max() &&
125 sampass->pass_last_set_time != 0)
126 return False;
127 return True;
130 uint16_t pdb_get_logon_divs(const struct samu *sampass)
132 return sampass->logon_divs;
135 uint32_t pdb_get_hours_len(const struct samu *sampass)
137 return sampass->hours_len;
140 const uint8 *pdb_get_hours(const struct samu *sampass)
142 return (sampass->hours);
145 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
147 SMB_ASSERT((!sampass->nt_pw.data)
148 || sampass->nt_pw.length == NT_HASH_LEN);
149 return (uint8 *)sampass->nt_pw.data;
152 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
154 SMB_ASSERT((!sampass->lm_pw.data)
155 || sampass->lm_pw.length == LM_HASH_LEN);
156 return (uint8 *)sampass->lm_pw.data;
159 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32_t *current_hist_len)
161 SMB_ASSERT((!sampass->nt_pw_his.data)
162 || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
163 *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
164 return (uint8 *)sampass->nt_pw_his.data;
167 /* Return the plaintext password if known. Most of the time
168 it isn't, so don't assume anything magic about this function.
170 Used to pass the plaintext to passdb backends that might
171 want to store more than just the NTLM hashes.
173 const char *pdb_get_plaintext_passwd(const struct samu *sampass)
175 return sampass->plaintext_pw;
178 const struct dom_sid *pdb_get_user_sid(const struct samu *sampass)
180 return &sampass->user_sid;
183 const struct dom_sid *pdb_get_group_sid(struct samu *sampass)
185 struct dom_sid *gsid;
186 struct passwd *pwd;
187 bool need_lookup_sid = false;
189 /* Return the cached group SID if we have that */
190 if ( sampass->group_sid ) {
191 return sampass->group_sid;
194 /* generate the group SID from the user's primary Unix group */
196 if ( !(gsid = TALLOC_ZERO_P( sampass, struct dom_sid )) ) {
197 return NULL;
200 /* No algorithmic mapping, meaning that we have to figure out the
201 primary group SID according to group mapping and the user SID must
202 be a newly allocated one. We rely on the user's Unix primary gid.
203 We have no choice but to fail if we can't find it. */
205 if ( sampass->unix_pw ) {
206 pwd = sampass->unix_pw;
207 } else {
208 pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
209 sampass->unix_pw = pwd;
212 if ( !pwd ) {
213 DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
214 return NULL;
217 gid_to_sid(gsid, pwd->pw_gid);
218 if (!is_null_sid(gsid)) {
219 struct dom_sid dgsid;
220 uint32_t rid;
222 sid_copy(&dgsid, gsid);
223 sid_split_rid(&dgsid, &rid);
224 if (sid_equal(&dgsid, get_global_sam_sid())) {
226 * As shortcut for the expensive lookup_sid call
227 * compare the domain sid part
229 switch (rid) {
230 case DOMAIN_RID_ADMINS:
231 case DOMAIN_RID_USERS:
232 sampass->group_sid = gsid;
233 return sampass->group_sid;
234 default:
235 need_lookup_sid = true;
236 break;
238 } else {
239 ZERO_STRUCTP(gsid);
240 if (pdb_gid_to_sid(pwd->pw_gid, gsid)) {
241 need_lookup_sid = true;
246 if (need_lookup_sid) {
247 enum lsa_SidType type = SID_NAME_UNKNOWN;
248 TALLOC_CTX *mem_ctx;
249 bool lookup_ret;
250 const struct dom_sid *usid = pdb_get_user_sid(sampass);
252 mem_ctx = talloc_init("pdb_get_group_sid");
253 if (!mem_ctx) {
254 return NULL;
257 DEBUG(10,("do lookup_sid(%s) for group of user %s\n",
258 sid_string_dbg(gsid), sid_string_dbg(usid)));
260 /* Now check that it's actually a domain group and not something else */
262 lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
264 TALLOC_FREE( mem_ctx );
266 if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
267 sampass->group_sid = gsid;
268 return sampass->group_sid;
271 DEBUG(3, ("Primary group %s for user %s is a %s and not a domain group\n",
272 sid_string_dbg(gsid), pwd->pw_name, sid_type_lookup(type)));
275 /* Just set it to the 'Domain Users' RID of 513 which will
276 always resolve to a name */
278 sid_compose(gsid, get_global_sam_sid(), DOMAIN_RID_USERS);
280 sampass->group_sid = gsid;
282 return sampass->group_sid;
286 * Get flags showing what is initalised in the struct samu
287 * @param sampass the struct samu in question
288 * @return the flags indicating the members initialised in the struct.
291 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
293 enum pdb_value_state ret = PDB_DEFAULT;
295 if (!sampass->change_flags || !sampass->set_flags)
296 return ret;
298 if (bitmap_query(sampass->set_flags, element)) {
299 DEBUG(11, ("element %d: SET\n", element));
300 ret = PDB_SET;
303 if (bitmap_query(sampass->change_flags, element)) {
304 DEBUG(11, ("element %d: CHANGED\n", element));
305 ret = PDB_CHANGED;
308 if (ret == PDB_DEFAULT) {
309 DEBUG(11, ("element %d: DEFAULT\n", element));
312 return ret;
315 const char *pdb_get_username(const struct samu *sampass)
317 return sampass->username;
320 const char *pdb_get_domain(const struct samu *sampass)
322 return sampass->domain;
325 const char *pdb_get_nt_username(const struct samu *sampass)
327 return sampass->nt_username;
330 const char *pdb_get_fullname(const struct samu *sampass)
332 return sampass->full_name;
335 const char *pdb_get_homedir(const struct samu *sampass)
337 return sampass->home_dir;
340 const char *pdb_get_dir_drive(const struct samu *sampass)
342 return sampass->dir_drive;
345 const char *pdb_get_logon_script(const struct samu *sampass)
347 return sampass->logon_script;
350 const char *pdb_get_profile_path(const struct samu *sampass)
352 return sampass->profile_path;
355 const char *pdb_get_acct_desc(const struct samu *sampass)
357 return sampass->acct_desc;
360 const char *pdb_get_workstations(const struct samu *sampass)
362 return sampass->workstations;
365 const char *pdb_get_comment(const struct samu *sampass)
367 return sampass->comment;
370 const char *pdb_get_munged_dial(const struct samu *sampass)
372 return sampass->munged_dial;
375 uint16_t pdb_get_bad_password_count(const struct samu *sampass)
377 return sampass->bad_password_count;
380 uint16_t pdb_get_logon_count(const struct samu *sampass)
382 return sampass->logon_count;
385 uint32_t pdb_get_unknown_6(const struct samu *sampass)
387 return sampass->unknown_6;
390 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
392 if (my_methods == sampass->backend_private_methods) {
393 return sampass->backend_private_data;
394 } else {
395 return NULL;
399 /*********************************************************************
400 Collection of set...() functions for struct samu.
401 ********************************************************************/
403 bool pdb_set_acct_ctrl(struct samu *sampass, uint32_t acct_ctrl, enum pdb_value_state flag)
405 sampass->acct_ctrl = acct_ctrl;
406 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
409 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
411 sampass->logon_time = mytime;
412 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
415 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
417 sampass->logoff_time = mytime;
418 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
421 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
423 sampass->kickoff_time = mytime;
424 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
427 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
429 sampass->bad_password_time = mytime;
430 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
433 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
435 sampass->pass_can_change_time = mytime;
436 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
439 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
441 sampass->pass_must_change_time = mytime;
442 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
445 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
447 sampass->pass_last_set_time = mytime;
448 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
451 bool pdb_set_hours_len(struct samu *sampass, uint32_t len, enum pdb_value_state flag)
453 sampass->hours_len = len;
454 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
457 bool pdb_set_logon_divs(struct samu *sampass, uint16_t hours, enum pdb_value_state flag)
459 sampass->logon_divs = hours;
460 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
464 * Set flags showing what is initalised in the struct samu
465 * @param sampass the struct samu in question
466 * @param flag The *new* flag to be set. Old flags preserved
467 * this flag is only added.
470 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
472 if (!sampass->set_flags) {
473 if ((sampass->set_flags =
474 bitmap_talloc(sampass,
475 PDB_COUNT))==NULL) {
476 DEBUG(0,("bitmap_talloc failed\n"));
477 return False;
480 if (!sampass->change_flags) {
481 if ((sampass->change_flags =
482 bitmap_talloc(sampass,
483 PDB_COUNT))==NULL) {
484 DEBUG(0,("bitmap_talloc failed\n"));
485 return False;
489 switch(value_flag) {
490 case PDB_CHANGED:
491 if (!bitmap_set(sampass->change_flags, element)) {
492 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
493 return False;
495 if (!bitmap_set(sampass->set_flags, element)) {
496 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
497 return False;
499 DEBUG(11, ("element %d -> now CHANGED\n", element));
500 break;
501 case PDB_SET:
502 if (!bitmap_clear(sampass->change_flags, element)) {
503 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
504 return False;
506 if (!bitmap_set(sampass->set_flags, element)) {
507 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
508 return False;
510 DEBUG(11, ("element %d -> now SET\n", element));
511 break;
512 case PDB_DEFAULT:
513 default:
514 if (!bitmap_clear(sampass->change_flags, element)) {
515 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
516 return False;
518 if (!bitmap_clear(sampass->set_flags, element)) {
519 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
520 return False;
522 DEBUG(11, ("element %d -> now DEFAULT\n", element));
523 break;
526 return True;
529 bool pdb_set_user_sid(struct samu *sampass, const struct dom_sid *u_sid, enum pdb_value_state flag)
531 if (!u_sid)
532 return False;
534 sid_copy(&sampass->user_sid, u_sid);
536 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
537 sid_string_dbg(&sampass->user_sid)));
539 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
542 bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
544 struct dom_sid new_sid;
546 if (!u_sid)
547 return False;
549 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
550 u_sid));
552 if (!string_to_sid(&new_sid, u_sid)) {
553 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
554 return False;
557 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
558 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
559 return False;
562 return True;
565 /********************************************************************
566 We never fill this in from a passdb backend but rather set is
567 based on the user's primary group membership. However, the
568 struct samu* is overloaded and reused in domain memship code
569 as well and built from the netr_SamInfo3 or PAC so we
570 have to allow the explicitly setting of a group SID here.
571 ********************************************************************/
573 bool pdb_set_group_sid(struct samu *sampass, const struct dom_sid *g_sid, enum pdb_value_state flag)
575 gid_t gid;
576 struct dom_sid dug_sid;
578 if (!g_sid)
579 return False;
581 if ( !(sampass->group_sid = TALLOC_P( sampass, struct dom_sid )) ) {
582 return False;
585 /* if we cannot resolve the SID to gid, then just ignore it and
586 store DOMAIN_USERS as the primary groupSID */
588 sid_compose(&dug_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
590 if (sid_equal(&dug_sid, g_sid)) {
591 sid_copy(sampass->group_sid, &dug_sid);
592 } else if (sid_to_gid( g_sid, &gid ) ) {
593 sid_copy(sampass->group_sid, g_sid);
594 } else {
595 sid_copy(sampass->group_sid, &dug_sid);
598 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
599 sid_string_dbg(sampass->group_sid)));
601 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
604 /*********************************************************************
605 Set the user's UNIX name.
606 ********************************************************************/
608 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
610 if (username) {
611 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
612 (sampass->username)?(sampass->username):"NULL"));
614 sampass->username = talloc_strdup(sampass, username);
616 if (!sampass->username) {
617 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
618 return False;
620 } else {
621 sampass->username = PDB_NOT_QUITE_NULL;
624 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
627 /*********************************************************************
628 Set the domain name.
629 ********************************************************************/
631 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
633 if (domain) {
634 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
635 (sampass->domain)?(sampass->domain):"NULL"));
637 sampass->domain = talloc_strdup(sampass, domain);
639 if (!sampass->domain) {
640 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
641 return False;
643 } else {
644 sampass->domain = PDB_NOT_QUITE_NULL;
647 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
650 /*********************************************************************
651 Set the user's NT name.
652 ********************************************************************/
654 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
656 if (nt_username) {
657 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
658 (sampass->nt_username)?(sampass->nt_username):"NULL"));
660 sampass->nt_username = talloc_strdup(sampass, nt_username);
662 if (!sampass->nt_username) {
663 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
664 return False;
666 } else {
667 sampass->nt_username = PDB_NOT_QUITE_NULL;
670 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
673 /*********************************************************************
674 Set the user's full name.
675 ********************************************************************/
677 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
679 if (full_name) {
680 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
681 (sampass->full_name)?(sampass->full_name):"NULL"));
683 sampass->full_name = talloc_strdup(sampass, full_name);
685 if (!sampass->full_name) {
686 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
687 return False;
689 } else {
690 sampass->full_name = PDB_NOT_QUITE_NULL;
693 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
696 /*********************************************************************
697 Set the user's logon script.
698 ********************************************************************/
700 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
702 if (logon_script) {
703 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
704 (sampass->logon_script)?(sampass->logon_script):"NULL"));
706 sampass->logon_script = talloc_strdup(sampass, logon_script);
708 if (!sampass->logon_script) {
709 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
710 return False;
712 } else {
713 sampass->logon_script = PDB_NOT_QUITE_NULL;
716 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
719 /*********************************************************************
720 Set the user's profile path.
721 ********************************************************************/
723 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
725 if (profile_path) {
726 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
727 (sampass->profile_path)?(sampass->profile_path):"NULL"));
729 sampass->profile_path = talloc_strdup(sampass, profile_path);
731 if (!sampass->profile_path) {
732 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
733 return False;
735 } else {
736 sampass->profile_path = PDB_NOT_QUITE_NULL;
739 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
742 /*********************************************************************
743 Set the user's directory drive.
744 ********************************************************************/
746 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
748 if (dir_drive) {
749 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
750 (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
752 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
754 if (!sampass->dir_drive) {
755 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
756 return False;
759 } else {
760 sampass->dir_drive = PDB_NOT_QUITE_NULL;
763 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
766 /*********************************************************************
767 Set the user's home directory.
768 ********************************************************************/
770 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
772 if (home_dir) {
773 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
774 (sampass->home_dir)?(sampass->home_dir):"NULL"));
776 sampass->home_dir = talloc_strdup(sampass, home_dir);
778 if (!sampass->home_dir) {
779 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
780 return False;
782 } else {
783 sampass->home_dir = PDB_NOT_QUITE_NULL;
786 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
789 /*********************************************************************
790 Set the user's account description.
791 ********************************************************************/
793 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
795 if (acct_desc) {
796 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
798 if (!sampass->acct_desc) {
799 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
800 return False;
802 } else {
803 sampass->acct_desc = PDB_NOT_QUITE_NULL;
806 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
809 /*********************************************************************
810 Set the user's workstation allowed list.
811 ********************************************************************/
813 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
815 if (workstations) {
816 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
817 (sampass->workstations)?(sampass->workstations):"NULL"));
819 sampass->workstations = talloc_strdup(sampass, workstations);
821 if (!sampass->workstations) {
822 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
823 return False;
825 } else {
826 sampass->workstations = PDB_NOT_QUITE_NULL;
829 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
832 /*********************************************************************
833 ********************************************************************/
835 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
837 if (comment) {
838 sampass->comment = talloc_strdup(sampass, comment);
840 if (!sampass->comment) {
841 DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
842 return False;
844 } else {
845 sampass->comment = PDB_NOT_QUITE_NULL;
848 return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
851 /*********************************************************************
852 Set the user's dial string.
853 ********************************************************************/
855 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
857 if (munged_dial) {
858 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
860 if (!sampass->munged_dial) {
861 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
862 return False;
864 } else {
865 sampass->munged_dial = PDB_NOT_QUITE_NULL;
868 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
871 /*********************************************************************
872 Set the user's NT hash.
873 ********************************************************************/
875 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
877 data_blob_clear_free(&sampass->nt_pw);
879 if (pwd) {
880 sampass->nt_pw =
881 data_blob_talloc(sampass, pwd, NT_HASH_LEN);
882 } else {
883 sampass->nt_pw = data_blob_null;
886 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
889 /*********************************************************************
890 Set the user's LM hash.
891 ********************************************************************/
893 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
895 data_blob_clear_free(&sampass->lm_pw);
897 /* on keep the password if we are allowing LANMAN authentication */
899 if (pwd && lp_lanman_auth() ) {
900 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
901 } else {
902 sampass->lm_pw = data_blob_null;
905 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
908 /*********************************************************************
909 Set the user's password history hash. historyLen is the number of
910 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
911 entries to store in the history - this must match the size of the uint8 array
912 in pwd.
913 ********************************************************************/
915 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32_t historyLen, enum pdb_value_state flag)
917 if (historyLen && pwd){
918 data_blob_free(&(sampass->nt_pw_his));
919 sampass->nt_pw_his = data_blob_talloc(sampass,
920 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
921 if (!sampass->nt_pw_his.length) {
922 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
923 return False;
925 } else {
926 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
929 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
932 /*********************************************************************
933 Set the user's plaintext password only (base procedure, see helper
934 below)
935 ********************************************************************/
937 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
939 if (password) {
940 if (sampass->plaintext_pw!=NULL)
941 memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
943 sampass->plaintext_pw = talloc_strdup(sampass, password);
945 if (!sampass->plaintext_pw) {
946 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
947 return False;
949 } else {
950 sampass->plaintext_pw = NULL;
953 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
956 bool pdb_set_bad_password_count(struct samu *sampass, uint16_t bad_password_count, enum pdb_value_state flag)
958 sampass->bad_password_count = bad_password_count;
959 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
962 bool pdb_set_logon_count(struct samu *sampass, uint16_t logon_count, enum pdb_value_state flag)
964 sampass->logon_count = logon_count;
965 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
968 bool pdb_set_unknown_6(struct samu *sampass, uint32_t unkn, enum pdb_value_state flag)
970 sampass->unknown_6 = unkn;
971 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
974 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
976 if (!hours) {
977 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
978 } else {
979 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
982 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
985 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data,
986 void (*free_fn)(void **),
987 const struct pdb_methods *my_methods,
988 enum pdb_value_state flag)
990 if (sampass->backend_private_data &&
991 sampass->backend_private_data_free_fn) {
992 sampass->backend_private_data_free_fn(
993 &sampass->backend_private_data);
996 sampass->backend_private_data = private_data;
997 sampass->backend_private_data_free_fn = free_fn;
998 sampass->backend_private_methods = my_methods;
1000 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
1004 /* Helpful interfaces to the above */
1006 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
1008 return pdb_set_pass_can_change_time(sampass,
1009 canchange ? 0 : get_time_t_max(),
1010 PDB_CHANGED);
1014 /*********************************************************************
1015 Set the user's PLAINTEXT password. Used as an interface to the above.
1016 Also sets the last change time to NOW.
1017 ********************************************************************/
1019 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
1021 uchar new_lanman_p16[LM_HASH_LEN];
1022 uchar new_nt_p16[NT_HASH_LEN];
1023 uchar *pwhistory;
1024 uint32_t pwHistLen;
1025 uint32_t current_history_len;
1027 if (!plaintext)
1028 return False;
1030 /* Calculate the MD4 hash (NT compatible) of the password */
1031 E_md4hash(plaintext, new_nt_p16);
1033 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
1034 return False;
1036 if (!E_deshash(plaintext, new_lanman_p16)) {
1037 /* E_deshash returns false for 'long' passwords (> 14
1038 DOS chars). This allows us to match Win2k, which
1039 does not store a LM hash for these passwords (which
1040 would reduce the effective password length to 14 */
1042 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
1043 return False;
1044 } else {
1045 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
1046 return False;
1049 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
1050 return False;
1052 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1053 return False;
1055 if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
1057 * No password history for non-user accounts
1059 return true;
1062 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1064 if (pwHistLen == 0) {
1065 /* Set the history length to zero. */
1066 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1067 return true;
1071 * We need to make sure we don't have a race condition here -
1072 * the account policy history length can change between when
1073 * the pw_history was first loaded into the struct samu struct
1074 * and now.... JRA.
1076 pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1078 if ((current_history_len != 0) && (pwhistory == NULL)) {
1079 DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n"));
1080 return false;
1083 if (current_history_len < pwHistLen) {
1085 * Ensure we have space for the needed history. This
1086 * also takes care of an account which did not have
1087 * any history at all so far, i.e. pwhistory==NULL
1089 uchar *new_history = talloc_zero_array(
1090 sampass, uchar,
1091 pwHistLen*PW_HISTORY_ENTRY_LEN);
1093 if (!new_history) {
1094 return False;
1097 memcpy(new_history, pwhistory,
1098 current_history_len*PW_HISTORY_ENTRY_LEN);
1100 pwhistory = new_history;
1104 * Make room for the new password in the history list.
1106 if (pwHistLen > 1) {
1107 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory,
1108 (pwHistLen-1)*PW_HISTORY_ENTRY_LEN );
1112 * Fill the salt area with 0-s: this indicates that
1113 * a plain nt hash is stored in the has area.
1114 * The old format was to store a 16 byte salt and
1115 * then an md5hash of the nt_hash concatenated with
1116 * the salt.
1118 memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
1121 * Store the plain nt hash in the second 16 bytes.
1122 * The old format was to store the md5 hash of
1123 * the salt+newpw.
1125 memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN);
1127 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1129 return True;
1132 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1133 uint32_t pdb_build_fields_present(struct samu *sampass)
1135 /* value set to all for testing */
1136 return 0x00ffffff;