s3-passdb: Fix typo in comment.
[Samba.git] / source3 / passdb / pdb_get_set.c
blob3e2510e74c89c2e1ae9404f46ab3b20239b298e4
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 NTSTATUS status;
187 /* Return the cached group SID if we have that */
188 if (sampass->group_sid) {
189 return sampass->group_sid;
192 /* No algorithmic mapping, meaning that we have to figure out the
193 primary group SID according to group mapping and the user SID must
194 be a newly allocated one. We rely on the user's Unix primary gid.
195 We have no choice but to fail if we can't find it. */
196 status = get_primary_group_sid(sampass,
197 pdb_get_username(sampass),
198 &sampass->unix_pw,
199 &sampass->group_sid);
200 if (!NT_STATUS_IS_OK(status)) {
201 return NULL;
204 return sampass->group_sid;
208 * Get flags showing what is initalised in the struct samu
209 * @param sampass the struct samu in question
210 * @return the flags indicating the members initialised in the struct.
213 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
215 enum pdb_value_state ret = PDB_DEFAULT;
217 if (!sampass->change_flags || !sampass->set_flags)
218 return ret;
220 if (bitmap_query(sampass->set_flags, element)) {
221 DEBUG(11, ("element %d: SET\n", element));
222 ret = PDB_SET;
225 if (bitmap_query(sampass->change_flags, element)) {
226 DEBUG(11, ("element %d: CHANGED\n", element));
227 ret = PDB_CHANGED;
230 if (ret == PDB_DEFAULT) {
231 DEBUG(11, ("element %d: DEFAULT\n", element));
234 return ret;
237 const char *pdb_get_username(const struct samu *sampass)
239 return sampass->username;
242 const char *pdb_get_domain(const struct samu *sampass)
244 return sampass->domain;
247 const char *pdb_get_nt_username(const struct samu *sampass)
249 return sampass->nt_username;
252 const char *pdb_get_fullname(const struct samu *sampass)
254 return sampass->full_name;
257 const char *pdb_get_homedir(const struct samu *sampass)
259 return sampass->home_dir;
262 const char *pdb_get_dir_drive(const struct samu *sampass)
264 return sampass->dir_drive;
267 const char *pdb_get_logon_script(const struct samu *sampass)
269 return sampass->logon_script;
272 const char *pdb_get_profile_path(const struct samu *sampass)
274 return sampass->profile_path;
277 const char *pdb_get_acct_desc(const struct samu *sampass)
279 return sampass->acct_desc;
282 const char *pdb_get_workstations(const struct samu *sampass)
284 return sampass->workstations;
287 const char *pdb_get_comment(const struct samu *sampass)
289 return sampass->comment;
292 const char *pdb_get_munged_dial(const struct samu *sampass)
294 return sampass->munged_dial;
297 uint16_t pdb_get_bad_password_count(const struct samu *sampass)
299 return sampass->bad_password_count;
302 uint16_t pdb_get_logon_count(const struct samu *sampass)
304 return sampass->logon_count;
307 uint32_t pdb_get_unknown_6(const struct samu *sampass)
309 return sampass->unknown_6;
312 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
314 if (my_methods == sampass->backend_private_methods) {
315 return sampass->backend_private_data;
316 } else {
317 return NULL;
321 /*********************************************************************
322 Collection of set...() functions for struct samu.
323 ********************************************************************/
325 bool pdb_set_acct_ctrl(struct samu *sampass, uint32_t acct_ctrl, enum pdb_value_state flag)
327 sampass->acct_ctrl = acct_ctrl;
328 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
331 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
333 sampass->logon_time = mytime;
334 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
337 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
339 sampass->logoff_time = mytime;
340 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
343 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
345 sampass->kickoff_time = mytime;
346 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
349 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
351 sampass->bad_password_time = mytime;
352 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
355 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
357 sampass->pass_can_change_time = mytime;
358 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
361 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
363 sampass->pass_must_change_time = mytime;
364 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
367 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
369 sampass->pass_last_set_time = mytime;
370 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
373 bool pdb_set_hours_len(struct samu *sampass, uint32_t len, enum pdb_value_state flag)
375 sampass->hours_len = len;
376 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
379 bool pdb_set_logon_divs(struct samu *sampass, uint16_t hours, enum pdb_value_state flag)
381 sampass->logon_divs = hours;
382 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
386 * Set flags showing what is initalised in the struct samu
387 * @param sampass the struct samu in question
388 * @param flag The *new* flag to be set. Old flags preserved
389 * this flag is only added.
392 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
394 if (!sampass->set_flags) {
395 if ((sampass->set_flags =
396 bitmap_talloc(sampass,
397 PDB_COUNT))==NULL) {
398 DEBUG(0,("bitmap_talloc failed\n"));
399 return False;
402 if (!sampass->change_flags) {
403 if ((sampass->change_flags =
404 bitmap_talloc(sampass,
405 PDB_COUNT))==NULL) {
406 DEBUG(0,("bitmap_talloc failed\n"));
407 return False;
411 switch(value_flag) {
412 case PDB_CHANGED:
413 if (!bitmap_set(sampass->change_flags, element)) {
414 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
415 return False;
417 if (!bitmap_set(sampass->set_flags, element)) {
418 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
419 return False;
421 DEBUG(11, ("element %d -> now CHANGED\n", element));
422 break;
423 case PDB_SET:
424 if (!bitmap_clear(sampass->change_flags, element)) {
425 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
426 return False;
428 if (!bitmap_set(sampass->set_flags, element)) {
429 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
430 return False;
432 DEBUG(11, ("element %d -> now SET\n", element));
433 break;
434 case PDB_DEFAULT:
435 default:
436 if (!bitmap_clear(sampass->change_flags, element)) {
437 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
438 return False;
440 if (!bitmap_clear(sampass->set_flags, element)) {
441 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
442 return False;
444 DEBUG(11, ("element %d -> now DEFAULT\n", element));
445 break;
448 return True;
451 bool pdb_set_user_sid(struct samu *sampass, const struct dom_sid *u_sid, enum pdb_value_state flag)
453 if (!u_sid)
454 return False;
456 sid_copy(&sampass->user_sid, u_sid);
458 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
459 sid_string_dbg(&sampass->user_sid)));
461 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
464 bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
466 struct dom_sid new_sid;
468 if (!u_sid)
469 return False;
471 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
472 u_sid));
474 if (!string_to_sid(&new_sid, u_sid)) {
475 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
476 return False;
479 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
480 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
481 return False;
484 return True;
487 /********************************************************************
488 We never fill this in from a passdb backend but rather set is
489 based on the user's primary group membership. However, the
490 struct samu* is overloaded and reused in domain memship code
491 as well and built from the netr_SamInfo3 or PAC so we
492 have to allow the explicitly setting of a group SID here.
493 ********************************************************************/
495 bool pdb_set_group_sid(struct samu *sampass, const struct dom_sid *g_sid, enum pdb_value_state flag)
497 gid_t gid;
498 struct dom_sid dug_sid;
500 if (!g_sid)
501 return False;
503 if ( !(sampass->group_sid = TALLOC_P( sampass, struct dom_sid )) ) {
504 return False;
507 /* if we cannot resolve the SID to gid, then just ignore it and
508 store DOMAIN_USERS as the primary groupSID */
510 sid_compose(&dug_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
512 if (sid_equal(&dug_sid, g_sid)) {
513 sid_copy(sampass->group_sid, &dug_sid);
514 } else if (sid_to_gid( g_sid, &gid ) ) {
515 sid_copy(sampass->group_sid, g_sid);
516 } else {
517 sid_copy(sampass->group_sid, &dug_sid);
520 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
521 sid_string_dbg(sampass->group_sid)));
523 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
526 /*********************************************************************
527 Set the user's UNIX name.
528 ********************************************************************/
530 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
532 if (username) {
533 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
534 (sampass->username)?(sampass->username):"NULL"));
536 sampass->username = talloc_strdup(sampass, username);
538 if (!sampass->username) {
539 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
540 return False;
542 } else {
543 sampass->username = PDB_NOT_QUITE_NULL;
546 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
549 /*********************************************************************
550 Set the domain name.
551 ********************************************************************/
553 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
555 if (domain) {
556 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
557 (sampass->domain)?(sampass->domain):"NULL"));
559 sampass->domain = talloc_strdup(sampass, domain);
561 if (!sampass->domain) {
562 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
563 return False;
565 } else {
566 sampass->domain = PDB_NOT_QUITE_NULL;
569 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
572 /*********************************************************************
573 Set the user's NT name.
574 ********************************************************************/
576 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
578 if (nt_username) {
579 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
580 (sampass->nt_username)?(sampass->nt_username):"NULL"));
582 sampass->nt_username = talloc_strdup(sampass, nt_username);
584 if (!sampass->nt_username) {
585 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
586 return False;
588 } else {
589 sampass->nt_username = PDB_NOT_QUITE_NULL;
592 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
595 /*********************************************************************
596 Set the user's full name.
597 ********************************************************************/
599 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
601 if (full_name) {
602 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
603 (sampass->full_name)?(sampass->full_name):"NULL"));
605 sampass->full_name = talloc_strdup(sampass, full_name);
607 if (!sampass->full_name) {
608 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
609 return False;
611 } else {
612 sampass->full_name = PDB_NOT_QUITE_NULL;
615 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
618 /*********************************************************************
619 Set the user's logon script.
620 ********************************************************************/
622 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
624 if (logon_script) {
625 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
626 (sampass->logon_script)?(sampass->logon_script):"NULL"));
628 sampass->logon_script = talloc_strdup(sampass, logon_script);
630 if (!sampass->logon_script) {
631 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
632 return False;
634 } else {
635 sampass->logon_script = PDB_NOT_QUITE_NULL;
638 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
641 /*********************************************************************
642 Set the user's profile path.
643 ********************************************************************/
645 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
647 if (profile_path) {
648 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
649 (sampass->profile_path)?(sampass->profile_path):"NULL"));
651 sampass->profile_path = talloc_strdup(sampass, profile_path);
653 if (!sampass->profile_path) {
654 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
655 return False;
657 } else {
658 sampass->profile_path = PDB_NOT_QUITE_NULL;
661 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
664 /*********************************************************************
665 Set the user's directory drive.
666 ********************************************************************/
668 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
670 if (dir_drive) {
671 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
672 (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
674 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
676 if (!sampass->dir_drive) {
677 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
678 return False;
681 } else {
682 sampass->dir_drive = PDB_NOT_QUITE_NULL;
685 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
688 /*********************************************************************
689 Set the user's home directory.
690 ********************************************************************/
692 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
694 if (home_dir) {
695 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
696 (sampass->home_dir)?(sampass->home_dir):"NULL"));
698 sampass->home_dir = talloc_strdup(sampass, home_dir);
700 if (!sampass->home_dir) {
701 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
702 return False;
704 } else {
705 sampass->home_dir = PDB_NOT_QUITE_NULL;
708 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
711 /*********************************************************************
712 Set the user's account description.
713 ********************************************************************/
715 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
717 if (acct_desc) {
718 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
720 if (!sampass->acct_desc) {
721 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
722 return False;
724 } else {
725 sampass->acct_desc = PDB_NOT_QUITE_NULL;
728 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
731 /*********************************************************************
732 Set the user's workstation allowed list.
733 ********************************************************************/
735 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
737 if (workstations) {
738 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
739 (sampass->workstations)?(sampass->workstations):"NULL"));
741 sampass->workstations = talloc_strdup(sampass, workstations);
743 if (!sampass->workstations) {
744 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
745 return False;
747 } else {
748 sampass->workstations = PDB_NOT_QUITE_NULL;
751 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
754 /*********************************************************************
755 ********************************************************************/
757 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
759 if (comment) {
760 sampass->comment = talloc_strdup(sampass, comment);
762 if (!sampass->comment) {
763 DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
764 return False;
766 } else {
767 sampass->comment = PDB_NOT_QUITE_NULL;
770 return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
773 /*********************************************************************
774 Set the user's dial string.
775 ********************************************************************/
777 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
779 if (munged_dial) {
780 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
782 if (!sampass->munged_dial) {
783 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
784 return False;
786 } else {
787 sampass->munged_dial = PDB_NOT_QUITE_NULL;
790 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
793 /*********************************************************************
794 Set the user's NT hash.
795 ********************************************************************/
797 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
799 data_blob_clear_free(&sampass->nt_pw);
801 if (pwd) {
802 sampass->nt_pw =
803 data_blob_talloc(sampass, pwd, NT_HASH_LEN);
804 } else {
805 sampass->nt_pw = data_blob_null;
808 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
811 /*********************************************************************
812 Set the user's LM hash.
813 ********************************************************************/
815 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
817 data_blob_clear_free(&sampass->lm_pw);
819 /* on keep the password if we are allowing LANMAN authentication */
821 if (pwd && lp_lanman_auth() ) {
822 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
823 } else {
824 sampass->lm_pw = data_blob_null;
827 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
830 /*********************************************************************
831 Set the user's password history hash. historyLen is the number of
832 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
833 entries to store in the history - this must match the size of the uint8 array
834 in pwd.
835 ********************************************************************/
837 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32_t historyLen, enum pdb_value_state flag)
839 if (historyLen && pwd){
840 data_blob_free(&(sampass->nt_pw_his));
841 sampass->nt_pw_his = data_blob_talloc(sampass,
842 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
843 if (!sampass->nt_pw_his.length) {
844 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
845 return False;
847 } else {
848 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
851 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
854 /*********************************************************************
855 Set the user's plaintext password only (base procedure, see helper
856 below)
857 ********************************************************************/
859 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
861 if (password) {
862 if (sampass->plaintext_pw!=NULL)
863 memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
865 sampass->plaintext_pw = talloc_strdup(sampass, password);
867 if (!sampass->plaintext_pw) {
868 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
869 return False;
871 } else {
872 sampass->plaintext_pw = NULL;
875 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
878 bool pdb_set_bad_password_count(struct samu *sampass, uint16_t bad_password_count, enum pdb_value_state flag)
880 sampass->bad_password_count = bad_password_count;
881 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
884 bool pdb_set_logon_count(struct samu *sampass, uint16_t logon_count, enum pdb_value_state flag)
886 sampass->logon_count = logon_count;
887 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
890 bool pdb_set_unknown_6(struct samu *sampass, uint32_t unkn, enum pdb_value_state flag)
892 sampass->unknown_6 = unkn;
893 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
896 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
898 if (!hours) {
899 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
900 } else {
901 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
904 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
907 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data,
908 void (*free_fn)(void **),
909 const struct pdb_methods *my_methods,
910 enum pdb_value_state flag)
912 if (sampass->backend_private_data &&
913 sampass->backend_private_data_free_fn) {
914 sampass->backend_private_data_free_fn(
915 &sampass->backend_private_data);
918 sampass->backend_private_data = private_data;
919 sampass->backend_private_data_free_fn = free_fn;
920 sampass->backend_private_methods = my_methods;
922 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
926 /* Helpful interfaces to the above */
928 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
930 return pdb_set_pass_can_change_time(sampass,
931 canchange ? 0 : get_time_t_max(),
932 PDB_CHANGED);
936 /*********************************************************************
937 Set the user's PLAINTEXT password. Used as an interface to the above.
938 Also sets the last change time to NOW.
939 ********************************************************************/
941 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
943 uchar new_lanman_p16[LM_HASH_LEN];
944 uchar new_nt_p16[NT_HASH_LEN];
945 uchar *pwhistory;
946 uint32_t pwHistLen;
947 uint32_t current_history_len;
949 if (!plaintext)
950 return False;
952 /* Calculate the MD4 hash (NT compatible) of the password */
953 E_md4hash(plaintext, new_nt_p16);
955 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
956 return False;
958 if (!E_deshash(plaintext, new_lanman_p16)) {
959 /* E_deshash returns false for 'long' passwords (> 14
960 DOS chars). This allows us to match Win2k, which
961 does not store a LM hash for these passwords (which
962 would reduce the effective password length to 14 */
964 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
965 return False;
966 } else {
967 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
968 return False;
971 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
972 return False;
974 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
975 return False;
977 if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
979 * No password history for non-user accounts
981 return true;
984 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
986 if (pwHistLen == 0) {
987 /* Set the history length to zero. */
988 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
989 return true;
993 * We need to make sure we don't have a race condition here -
994 * the account policy history length can change between when
995 * the pw_history was first loaded into the struct samu struct
996 * and now.... JRA.
998 pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1000 if ((current_history_len != 0) && (pwhistory == NULL)) {
1001 DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n"));
1002 return false;
1005 if (current_history_len < pwHistLen) {
1007 * Ensure we have space for the needed history. This
1008 * also takes care of an account which did not have
1009 * any history at all so far, i.e. pwhistory==NULL
1011 uchar *new_history = talloc_zero_array(
1012 sampass, uchar,
1013 pwHistLen*PW_HISTORY_ENTRY_LEN);
1015 if (!new_history) {
1016 return False;
1019 memcpy(new_history, pwhistory,
1020 current_history_len*PW_HISTORY_ENTRY_LEN);
1022 pwhistory = new_history;
1026 * Make room for the new password in the history list.
1028 if (pwHistLen > 1) {
1029 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory,
1030 (pwHistLen-1)*PW_HISTORY_ENTRY_LEN );
1034 * Fill the salt area with 0-s: this indicates that
1035 * a plain nt hash is stored in the has area.
1036 * The old format was to store a 16 byte salt and
1037 * then an md5hash of the nt_hash concatenated with
1038 * the salt.
1040 memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
1043 * Store the plain nt hash in the second 16 bytes.
1044 * The old format was to store the md5 hash of
1045 * the salt+newpw.
1047 memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN);
1049 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1051 return True;
1054 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1055 uint32_t pdb_build_fields_present(struct samu *sampass)
1057 /* value set to all for testing */
1058 return 0x00ffffff;