printing: explicitly clear PUBLISHED attribute
[Samba.git] / source3 / passdb / pdb_get_set.c
bloba276c16a8043382a76ae289b5558bc0074276f17
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 "passdb.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/security/security.h"
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_PASSDB
32 /**
33 * @todo Redefine this to NULL, but this changes the API because
34 * much of samba assumes that the pdb_get...() funtions
35 * return strings. (ie not null-pointers).
36 * See also pdb_fill_default_sam().
39 #define PDB_NOT_QUITE_NULL ""
41 /*********************************************************************
42 Test if a change time is a max value. Copes with old and new values
43 of max.
44 ********************************************************************/
46 bool pdb_is_password_change_time_max(time_t test_time)
48 if (test_time == get_time_t_max()) {
49 return true;
51 #if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
52 if (test_time == 0x7FFFFFFFFFFFFFFFLL) {
53 return true;
55 #endif
56 if (test_time == 0x7FFFFFFF) {
57 return true;
59 return false;
62 /*********************************************************************
63 Return an unchanging version of max password change time - 0x7FFFFFFF.
64 ********************************************************************/
66 time_t pdb_password_change_time_max(void)
68 return 0x7FFFFFFF;
71 /*********************************************************************
72 Collection of get...() functions for struct samu.
73 ********************************************************************/
75 uint32_t pdb_get_acct_ctrl(const struct samu *sampass)
77 return sampass->acct_ctrl;
80 time_t pdb_get_logon_time(const struct samu *sampass)
82 return sampass->logon_time;
85 time_t pdb_get_logoff_time(const struct samu *sampass)
87 return sampass->logoff_time;
90 time_t pdb_get_kickoff_time(const struct samu *sampass)
92 return sampass->kickoff_time;
95 time_t pdb_get_bad_password_time(const struct samu *sampass)
97 return sampass->bad_password_time;
100 time_t pdb_get_pass_last_set_time(const struct samu *sampass)
102 return sampass->pass_last_set_time;
105 time_t pdb_get_pass_can_change_time(const struct samu *sampass)
107 uint32_t allow;
109 /* if the last set time is zero, it means the user cannot
110 change their password, and this time must be zero. jmcd
112 if (sampass->pass_last_set_time == 0)
113 return (time_t) 0;
115 /* if the time is max, and the field has been changed,
116 we're trying to update this real value from the sampass
117 to indicate that the user cannot change their password. jmcd
119 if (pdb_is_password_change_time_max(sampass->pass_can_change_time) &&
120 IS_SAM_CHANGED(sampass, PDB_CANCHANGETIME))
121 return sampass->pass_can_change_time;
123 if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
124 allow = 0;
126 /* in normal cases, just calculate it from policy */
127 return sampass->pass_last_set_time + allow;
130 /* we need this for loading from the backend, so that we don't overwrite
131 non-changed max times, otherwise the pass_can_change checking won't work */
132 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
134 return sampass->pass_can_change_time;
137 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
139 uint32_t expire;
141 if (sampass->pass_last_set_time == 0)
142 return (time_t) 0;
144 if (sampass->acct_ctrl & ACB_PWNOEXP)
145 return pdb_password_change_time_max();
147 if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
148 || expire == (uint32_t)-1 || expire == 0)
149 return get_time_t_max();
151 return sampass->pass_last_set_time + expire;
154 bool pdb_get_pass_can_change(const struct samu *sampass)
156 if (pdb_is_password_change_time_max(sampass->pass_can_change_time))
157 return False;
158 return True;
161 uint16_t pdb_get_logon_divs(const struct samu *sampass)
163 return sampass->logon_divs;
166 uint32_t pdb_get_hours_len(const struct samu *sampass)
168 return sampass->hours_len;
171 const uint8 *pdb_get_hours(const struct samu *sampass)
173 return (sampass->hours);
176 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
178 SMB_ASSERT((!sampass->nt_pw.data)
179 || sampass->nt_pw.length == NT_HASH_LEN);
180 return (uint8 *)sampass->nt_pw.data;
183 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
185 SMB_ASSERT((!sampass->lm_pw.data)
186 || sampass->lm_pw.length == LM_HASH_LEN);
187 return (uint8 *)sampass->lm_pw.data;
190 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32_t *current_hist_len)
192 SMB_ASSERT((!sampass->nt_pw_his.data)
193 || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
194 *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
195 return (uint8 *)sampass->nt_pw_his.data;
198 /* Return the plaintext password if known. Most of the time
199 it isn't, so don't assume anything magic about this function.
201 Used to pass the plaintext to passdb backends that might
202 want to store more than just the NTLM hashes.
204 const char *pdb_get_plaintext_passwd(const struct samu *sampass)
206 return sampass->plaintext_pw;
209 const struct dom_sid *pdb_get_user_sid(const struct samu *sampass)
211 return &sampass->user_sid;
214 const struct dom_sid *pdb_get_group_sid(struct samu *sampass)
216 NTSTATUS status;
218 /* Return the cached group SID if we have that */
219 if (sampass->group_sid) {
220 return sampass->group_sid;
223 /* No algorithmic mapping, meaning that we have to figure out the
224 primary group SID according to group mapping and the user SID must
225 be a newly allocated one. We rely on the user's Unix primary gid.
226 We have no choice but to fail if we can't find it. */
227 status = get_primary_group_sid(sampass,
228 pdb_get_username(sampass),
229 &sampass->unix_pw,
230 &sampass->group_sid);
231 if (!NT_STATUS_IS_OK(status)) {
232 return NULL;
235 return sampass->group_sid;
239 * Get flags showing what is initalised in the struct samu
240 * @param sampass the struct samu in question
241 * @return the flags indicating the members initialised in the struct.
244 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
246 enum pdb_value_state ret = PDB_DEFAULT;
248 if (!sampass->change_flags || !sampass->set_flags)
249 return ret;
251 if (bitmap_query(sampass->set_flags, element)) {
252 DEBUG(11, ("element %d: SET\n", element));
253 ret = PDB_SET;
256 if (bitmap_query(sampass->change_flags, element)) {
257 DEBUG(11, ("element %d: CHANGED\n", element));
258 ret = PDB_CHANGED;
261 if (ret == PDB_DEFAULT) {
262 DEBUG(11, ("element %d: DEFAULT\n", element));
265 return ret;
268 const char *pdb_get_username(const struct samu *sampass)
270 return sampass->username;
273 const char *pdb_get_domain(const struct samu *sampass)
275 return sampass->domain;
278 const char *pdb_get_nt_username(const struct samu *sampass)
280 return sampass->nt_username;
283 const char *pdb_get_fullname(const struct samu *sampass)
285 return sampass->full_name;
288 const char *pdb_get_homedir(const struct samu *sampass)
290 return sampass->home_dir;
293 const char *pdb_get_dir_drive(const struct samu *sampass)
295 return sampass->dir_drive;
298 const char *pdb_get_logon_script(const struct samu *sampass)
300 return sampass->logon_script;
303 const char *pdb_get_profile_path(const struct samu *sampass)
305 return sampass->profile_path;
308 const char *pdb_get_acct_desc(const struct samu *sampass)
310 return sampass->acct_desc;
313 const char *pdb_get_workstations(const struct samu *sampass)
315 return sampass->workstations;
318 const char *pdb_get_comment(const struct samu *sampass)
320 return sampass->comment;
323 const char *pdb_get_munged_dial(const struct samu *sampass)
325 return sampass->munged_dial;
328 uint16_t pdb_get_bad_password_count(const struct samu *sampass)
330 return sampass->bad_password_count;
333 uint16_t pdb_get_logon_count(const struct samu *sampass)
335 return sampass->logon_count;
338 uint16_t pdb_get_country_code(const struct samu *sampass)
340 return sampass->country_code;
343 uint16_t pdb_get_code_page(const struct samu *sampass)
345 return sampass->code_page;
348 uint32_t pdb_get_unknown_6(const struct samu *sampass)
350 return sampass->unknown_6;
353 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
355 if (my_methods == sampass->backend_private_methods) {
356 return sampass->backend_private_data;
357 } else {
358 return NULL;
362 /*********************************************************************
363 Collection of set...() functions for struct samu.
364 ********************************************************************/
366 bool pdb_set_acct_ctrl(struct samu *sampass, uint32_t acct_ctrl, enum pdb_value_state flag)
368 sampass->acct_ctrl = acct_ctrl;
369 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
372 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
374 sampass->logon_time = mytime;
375 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
378 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
380 sampass->logoff_time = mytime;
381 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
384 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
386 sampass->kickoff_time = mytime;
387 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
390 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
392 sampass->bad_password_time = mytime;
393 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
396 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
398 sampass->pass_can_change_time = mytime;
399 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
402 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
404 sampass->pass_must_change_time = mytime;
405 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
408 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
410 sampass->pass_last_set_time = mytime;
411 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
414 bool pdb_set_hours_len(struct samu *sampass, uint32_t len, enum pdb_value_state flag)
416 sampass->hours_len = len;
417 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
420 bool pdb_set_logon_divs(struct samu *sampass, uint16_t hours, enum pdb_value_state flag)
422 sampass->logon_divs = hours;
423 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
427 * Set flags showing what is initalised in the struct samu
428 * @param sampass the struct samu in question
429 * @param flag The *new* flag to be set. Old flags preserved
430 * this flag is only added.
433 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
435 if (!sampass->set_flags) {
436 if ((sampass->set_flags =
437 bitmap_talloc(sampass,
438 PDB_COUNT))==NULL) {
439 DEBUG(0,("bitmap_talloc failed\n"));
440 return False;
443 if (!sampass->change_flags) {
444 if ((sampass->change_flags =
445 bitmap_talloc(sampass,
446 PDB_COUNT))==NULL) {
447 DEBUG(0,("bitmap_talloc failed\n"));
448 return False;
452 switch(value_flag) {
453 case PDB_CHANGED:
454 if (!bitmap_set(sampass->change_flags, element)) {
455 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
456 return False;
458 if (!bitmap_set(sampass->set_flags, element)) {
459 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
460 return False;
462 DEBUG(11, ("element %d -> now CHANGED\n", element));
463 break;
464 case PDB_SET:
465 if (!bitmap_clear(sampass->change_flags, element)) {
466 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
467 return False;
469 if (!bitmap_set(sampass->set_flags, element)) {
470 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
471 return False;
473 DEBUG(11, ("element %d -> now SET\n", element));
474 break;
475 case PDB_DEFAULT:
476 default:
477 if (!bitmap_clear(sampass->change_flags, element)) {
478 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
479 return False;
481 if (!bitmap_clear(sampass->set_flags, element)) {
482 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
483 return False;
485 DEBUG(11, ("element %d -> now DEFAULT\n", element));
486 break;
489 return True;
492 bool pdb_set_user_sid(struct samu *sampass, const struct dom_sid *u_sid, enum pdb_value_state flag)
494 if (!u_sid)
495 return False;
497 sid_copy(&sampass->user_sid, u_sid);
499 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
500 sid_string_dbg(&sampass->user_sid)));
502 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
505 bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
507 struct dom_sid new_sid;
509 if (!u_sid)
510 return False;
512 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
513 u_sid));
515 if (!string_to_sid(&new_sid, u_sid)) {
516 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
517 return False;
520 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
521 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
522 return False;
525 return True;
528 /********************************************************************
529 We never fill this in from a passdb backend but rather set is
530 based on the user's primary group membership. However, the
531 struct samu* is overloaded and reused in domain memship code
532 as well and built from the netr_SamInfo3 or PAC so we
533 have to allow the explicitly setting of a group SID here.
534 ********************************************************************/
536 bool pdb_set_group_sid(struct samu *sampass, const struct dom_sid *g_sid, enum pdb_value_state flag)
538 gid_t gid;
539 struct dom_sid dug_sid;
541 if (!g_sid)
542 return False;
544 if ( !(sampass->group_sid = TALLOC_P( sampass, struct dom_sid )) ) {
545 return False;
548 /* if we cannot resolve the SID to gid, then just ignore it and
549 store DOMAIN_USERS as the primary groupSID */
551 sid_compose(&dug_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
553 if (dom_sid_equal(&dug_sid, g_sid)) {
554 sid_copy(sampass->group_sid, &dug_sid);
555 } else if (sid_to_gid( g_sid, &gid ) ) {
556 sid_copy(sampass->group_sid, g_sid);
557 } else {
558 sid_copy(sampass->group_sid, &dug_sid);
561 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
562 sid_string_dbg(sampass->group_sid)));
564 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
567 /*********************************************************************
568 Set the user's UNIX name.
569 ********************************************************************/
571 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
573 if (username) {
574 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
575 (sampass->username)?(sampass->username):"NULL"));
577 sampass->username = talloc_strdup(sampass, username);
579 if (!sampass->username) {
580 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
581 return False;
583 } else {
584 sampass->username = PDB_NOT_QUITE_NULL;
587 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
590 /*********************************************************************
591 Set the domain name.
592 ********************************************************************/
594 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
596 if (domain) {
597 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
598 (sampass->domain)?(sampass->domain):"NULL"));
600 sampass->domain = talloc_strdup(sampass, domain);
602 if (!sampass->domain) {
603 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
604 return False;
606 } else {
607 sampass->domain = PDB_NOT_QUITE_NULL;
610 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
613 /*********************************************************************
614 Set the user's NT name.
615 ********************************************************************/
617 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
619 if (nt_username) {
620 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
621 (sampass->nt_username)?(sampass->nt_username):"NULL"));
623 sampass->nt_username = talloc_strdup(sampass, nt_username);
625 if (!sampass->nt_username) {
626 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
627 return False;
629 } else {
630 sampass->nt_username = PDB_NOT_QUITE_NULL;
633 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
636 /*********************************************************************
637 Set the user's full name.
638 ********************************************************************/
640 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
642 if (full_name) {
643 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
644 (sampass->full_name)?(sampass->full_name):"NULL"));
646 sampass->full_name = talloc_strdup(sampass, full_name);
648 if (!sampass->full_name) {
649 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
650 return False;
652 } else {
653 sampass->full_name = PDB_NOT_QUITE_NULL;
656 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
659 /*********************************************************************
660 Set the user's logon script.
661 ********************************************************************/
663 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
665 if (logon_script) {
666 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
667 (sampass->logon_script)?(sampass->logon_script):"NULL"));
669 sampass->logon_script = talloc_strdup(sampass, logon_script);
671 if (!sampass->logon_script) {
672 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
673 return False;
675 } else {
676 sampass->logon_script = PDB_NOT_QUITE_NULL;
679 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
682 /*********************************************************************
683 Set the user's profile path.
684 ********************************************************************/
686 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
688 if (profile_path) {
689 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
690 (sampass->profile_path)?(sampass->profile_path):"NULL"));
692 sampass->profile_path = talloc_strdup(sampass, profile_path);
694 if (!sampass->profile_path) {
695 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
696 return False;
698 } else {
699 sampass->profile_path = PDB_NOT_QUITE_NULL;
702 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
705 /*********************************************************************
706 Set the user's directory drive.
707 ********************************************************************/
709 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
711 if (dir_drive) {
712 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
713 (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
715 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
717 if (!sampass->dir_drive) {
718 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
719 return False;
722 } else {
723 sampass->dir_drive = PDB_NOT_QUITE_NULL;
726 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
729 /*********************************************************************
730 Set the user's home directory.
731 ********************************************************************/
733 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
735 if (home_dir) {
736 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
737 (sampass->home_dir)?(sampass->home_dir):"NULL"));
739 sampass->home_dir = talloc_strdup(sampass, home_dir);
741 if (!sampass->home_dir) {
742 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
743 return False;
745 } else {
746 sampass->home_dir = PDB_NOT_QUITE_NULL;
749 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
752 /*********************************************************************
753 Set the user's account description.
754 ********************************************************************/
756 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
758 if (acct_desc) {
759 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
761 if (!sampass->acct_desc) {
762 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
763 return False;
765 } else {
766 sampass->acct_desc = PDB_NOT_QUITE_NULL;
769 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
772 /*********************************************************************
773 Set the user's workstation allowed list.
774 ********************************************************************/
776 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
778 if (workstations) {
779 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
780 (sampass->workstations)?(sampass->workstations):"NULL"));
782 sampass->workstations = talloc_strdup(sampass, workstations);
784 if (!sampass->workstations) {
785 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
786 return False;
788 } else {
789 sampass->workstations = PDB_NOT_QUITE_NULL;
792 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
795 /*********************************************************************
796 ********************************************************************/
798 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
800 if (comment) {
801 sampass->comment = talloc_strdup(sampass, comment);
803 if (!sampass->comment) {
804 DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
805 return False;
807 } else {
808 sampass->comment = PDB_NOT_QUITE_NULL;
811 return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
814 /*********************************************************************
815 Set the user's dial string.
816 ********************************************************************/
818 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
820 if (munged_dial) {
821 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
823 if (!sampass->munged_dial) {
824 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
825 return False;
827 } else {
828 sampass->munged_dial = PDB_NOT_QUITE_NULL;
831 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
834 /*********************************************************************
835 Set the user's NT hash.
836 ********************************************************************/
838 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
840 data_blob_clear_free(&sampass->nt_pw);
842 if (pwd) {
843 sampass->nt_pw =
844 data_blob_talloc(sampass, pwd, NT_HASH_LEN);
845 } else {
846 sampass->nt_pw = data_blob_null;
849 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
852 /*********************************************************************
853 Set the user's LM hash.
854 ********************************************************************/
856 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
858 data_blob_clear_free(&sampass->lm_pw);
860 /* on keep the password if we are allowing LANMAN authentication */
862 if (pwd && lp_lanman_auth() ) {
863 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
864 } else {
865 sampass->lm_pw = data_blob_null;
868 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
871 /*********************************************************************
872 Set the user's password history hash. historyLen is the number of
873 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
874 entries to store in the history - this must match the size of the uint8 array
875 in pwd.
876 ********************************************************************/
878 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32_t historyLen, enum pdb_value_state flag)
880 if (historyLen && pwd){
881 data_blob_free(&(sampass->nt_pw_his));
882 sampass->nt_pw_his = data_blob_talloc(sampass,
883 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
884 if (!sampass->nt_pw_his.length) {
885 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
886 return False;
888 } else {
889 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
892 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
895 /*********************************************************************
896 Set the user's plaintext password only (base procedure, see helper
897 below)
898 ********************************************************************/
900 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
902 if (password) {
903 if (sampass->plaintext_pw!=NULL)
904 memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
906 sampass->plaintext_pw = talloc_strdup(sampass, password);
908 if (!sampass->plaintext_pw) {
909 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
910 return False;
912 } else {
913 sampass->plaintext_pw = NULL;
916 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
919 bool pdb_set_bad_password_count(struct samu *sampass, uint16_t bad_password_count, enum pdb_value_state flag)
921 sampass->bad_password_count = bad_password_count;
922 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
925 bool pdb_set_logon_count(struct samu *sampass, uint16_t logon_count, enum pdb_value_state flag)
927 sampass->logon_count = logon_count;
928 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
931 bool pdb_set_country_code(struct samu *sampass, uint16_t country_code,
932 enum pdb_value_state flag)
934 sampass->country_code = country_code;
935 return pdb_set_init_flags(sampass, PDB_COUNTRY_CODE, flag);
938 bool pdb_set_code_page(struct samu *sampass, uint16_t code_page,
939 enum pdb_value_state flag)
941 sampass->code_page = code_page;
942 return pdb_set_init_flags(sampass, PDB_CODE_PAGE, flag);
945 bool pdb_set_unknown_6(struct samu *sampass, uint32_t unkn, enum pdb_value_state flag)
947 sampass->unknown_6 = unkn;
948 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
951 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, int hours_len,
952 enum pdb_value_state flag)
954 if (hours_len > sizeof(sampass->hours)) {
955 return false;
958 if (!hours) {
959 memset ((char *)sampass->hours, 0, hours_len);
960 } else {
961 memcpy (sampass->hours, hours, hours_len);
964 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
967 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data,
968 void (*free_fn)(void **),
969 const struct pdb_methods *my_methods,
970 enum pdb_value_state flag)
972 if (sampass->backend_private_data &&
973 sampass->backend_private_data_free_fn) {
974 sampass->backend_private_data_free_fn(
975 &sampass->backend_private_data);
978 sampass->backend_private_data = private_data;
979 sampass->backend_private_data_free_fn = free_fn;
980 sampass->backend_private_methods = my_methods;
982 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
986 /* Helpful interfaces to the above */
988 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
990 return pdb_set_pass_can_change_time(sampass,
991 canchange ? 0 : pdb_password_change_time_max(),
992 PDB_CHANGED);
996 /*********************************************************************
997 Set the user's PLAINTEXT password. Used as an interface to the above.
998 Also sets the last change time to NOW.
999 ********************************************************************/
1001 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
1003 uchar new_lanman_p16[LM_HASH_LEN];
1004 uchar new_nt_p16[NT_HASH_LEN];
1005 uchar *pwhistory;
1006 uint32_t pwHistLen;
1007 uint32_t current_history_len;
1009 if (!plaintext)
1010 return False;
1012 /* Calculate the MD4 hash (NT compatible) of the password */
1013 E_md4hash(plaintext, new_nt_p16);
1015 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
1016 return False;
1018 if (!E_deshash(plaintext, new_lanman_p16)) {
1019 /* E_deshash returns false for 'long' passwords (> 14
1020 DOS chars). This allows us to match Win2k, which
1021 does not store a LM hash for these passwords (which
1022 would reduce the effective password length to 14 */
1024 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
1025 return False;
1026 } else {
1027 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
1028 return False;
1031 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
1032 return False;
1034 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1035 return False;
1037 if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
1039 * No password history for non-user accounts
1041 return true;
1044 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1046 if (pwHistLen == 0) {
1047 /* Set the history length to zero. */
1048 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1049 return true;
1053 * We need to make sure we don't have a race condition here -
1054 * the account policy history length can change between when
1055 * the pw_history was first loaded into the struct samu struct
1056 * and now.... JRA.
1058 pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1060 if ((current_history_len != 0) && (pwhistory == NULL)) {
1061 DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n"));
1062 return false;
1065 if (current_history_len < pwHistLen) {
1067 * Ensure we have space for the needed history. This
1068 * also takes care of an account which did not have
1069 * any history at all so far, i.e. pwhistory==NULL
1071 uchar *new_history = talloc_zero_array(
1072 sampass, uchar,
1073 pwHistLen*PW_HISTORY_ENTRY_LEN);
1075 if (!new_history) {
1076 return False;
1079 memcpy(new_history, pwhistory,
1080 current_history_len*PW_HISTORY_ENTRY_LEN);
1082 pwhistory = new_history;
1086 * Make room for the new password in the history list.
1088 if (pwHistLen > 1) {
1089 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory,
1090 (pwHistLen-1)*PW_HISTORY_ENTRY_LEN );
1094 * Fill the salt area with 0-s: this indicates that
1095 * a plain nt hash is stored in the has area.
1096 * The old format was to store a 16 byte salt and
1097 * then an md5hash of the nt_hash concatenated with
1098 * the salt.
1100 memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
1103 * Store the plain nt hash in the second 16 bytes.
1104 * The old format was to store the md5 hash of
1105 * the salt+newpw.
1107 memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN);
1109 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1111 return True;
1114 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1115 uint32_t pdb_build_fields_present(struct samu *sampass)
1117 /* value set to all for testing */
1118 return 0x00ffffff;