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 2 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, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define DBGC_CLASS DBGC_PASSDB
31 * @todo Redefine this to NULL, but this changes the API because
32 * much of samba assumes that the pdb_get...() funtions
33 * return pstrings. (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 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 return sampass->pass_can_change_time;
78 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
80 return sampass->pass_must_change_time;
83 uint16 pdb_get_logon_divs(const struct samu *sampass)
85 return sampass->logon_divs;
88 uint32 pdb_get_hours_len(const struct samu *sampass)
90 return sampass->hours_len;
93 const uint8 *pdb_get_hours(const struct samu *sampass)
95 return (sampass->hours);
98 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
100 SMB_ASSERT((!sampass->nt_pw.data)
101 || sampass->nt_pw.length == NT_HASH_LEN);
102 return (uint8 *)sampass->nt_pw.data;
105 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
107 SMB_ASSERT((!sampass->lm_pw.data)
108 || sampass->lm_pw.length == LM_HASH_LEN);
109 return (uint8 *)sampass->lm_pw.data;
112 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32 *current_hist_len)
114 SMB_ASSERT((!sampass->nt_pw_his.data)
115 || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
116 *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
117 return (uint8 *)sampass->nt_pw_his.data;
120 /* Return the plaintext password if known. Most of the time
121 it isn't, so don't assume anything magic about this function.
123 Used to pass the plaintext to passdb backends that might
124 want to store more than just the NTLM hashes.
126 const char *pdb_get_plaintext_passwd(const struct samu *sampass)
128 return sampass->plaintext_pw;
131 const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
133 return &sampass->user_sid;
136 const DOM_SID *pdb_get_group_sid(struct samu *sampass)
141 /* Return the cached group SID if we have that */
142 if ( sampass->group_sid ) {
143 return sampass->group_sid;
146 /* generate the group SID from the user's primary Unix group */
148 if ( !(gsid = TALLOC_P( sampass, DOM_SID )) ) {
152 /* No algorithmic mapping, meaning that we have to figure out the
153 primary group SID according to group mapping and the user SID must
154 be a newly allocated one. We rely on the user's Unix primary gid.
155 We have no choice but to fail if we can't find it. */
157 if ( sampass->unix_pw ) {
158 pwd = sampass->unix_pw;
160 pwd = getpwnam_alloc( sampass, pdb_get_username(sampass) );
164 DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
168 if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
169 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
170 TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
177 /* Now check that it's actually a domain group and not something else */
179 lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
181 TALLOC_FREE( mem_ctx );
183 if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
184 sampass->group_sid = gsid;
185 return sampass->group_sid;
188 DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n",
189 pwd->pw_name, sid_type_lookup(type)));
192 /* Just set it to the 'Domain Users' RID of 512 which will
193 always resolve to a name */
195 sid_copy( gsid, get_global_sam_sid() );
196 sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
198 sampass->group_sid = gsid;
200 return sampass->group_sid;
204 * Get flags showing what is initalised in the struct samu
205 * @param sampass the struct samu in question
206 * @return the flags indicating the members initialised in the struct.
209 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
211 enum pdb_value_state ret = PDB_DEFAULT;
213 if (!sampass->change_flags || !sampass->set_flags)
216 if (bitmap_query(sampass->set_flags, element)) {
217 DEBUG(11, ("element %d: SET\n", element));
221 if (bitmap_query(sampass->change_flags, element)) {
222 DEBUG(11, ("element %d: CHANGED\n", element));
226 if (ret == PDB_DEFAULT) {
227 DEBUG(11, ("element %d: DEFAULT\n", element));
233 const char *pdb_get_username(const struct samu *sampass)
235 return sampass->username;
238 const char *pdb_get_domain(const struct samu *sampass)
240 return sampass->domain;
243 const char *pdb_get_nt_username(const struct samu *sampass)
245 return sampass->nt_username;
248 const char *pdb_get_fullname(const struct samu *sampass)
250 return sampass->full_name;
253 const char *pdb_get_homedir(const struct samu *sampass)
255 return sampass->home_dir;
258 const char *pdb_get_unix_homedir(const struct samu *sampass)
260 if (sampass->unix_pw ) {
261 return sampass->unix_pw->pw_dir;
266 const char *pdb_get_dir_drive(const struct samu *sampass)
268 return sampass->dir_drive;
271 const char *pdb_get_logon_script(const struct samu *sampass)
273 return sampass->logon_script;
276 const char *pdb_get_profile_path(const struct samu *sampass)
278 return sampass->profile_path;
281 const char *pdb_get_acct_desc(const struct samu *sampass)
283 return sampass->acct_desc;
286 const char *pdb_get_workstations(const struct samu *sampass)
288 return sampass->workstations;
291 const char *pdb_get_unknown_str(const struct samu *sampass)
293 return sampass->unknown_str;
296 const char *pdb_get_munged_dial(const struct samu *sampass)
298 return sampass->munged_dial;
301 uint16 pdb_get_bad_password_count(const struct samu *sampass)
303 return sampass->bad_password_count;
306 uint16 pdb_get_logon_count(const struct samu *sampass)
308 return sampass->logon_count;
311 uint32 pdb_get_unknown_6(const struct samu *sampass)
313 return sampass->unknown_6;
316 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
318 if (my_methods == sampass->backend_private_methods) {
319 return sampass->backend_private_data;
325 /*********************************************************************
326 Collection of set...() functions for struct samu.
327 ********************************************************************/
329 BOOL pdb_set_acct_ctrl(struct samu *sampass, uint32 acct_ctrl, enum pdb_value_state flag)
334 sampass->acct_ctrl = acct_ctrl;
336 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
339 BOOL pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
344 sampass->logon_time = mytime;
346 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
349 BOOL pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
354 sampass->logoff_time = mytime;
356 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
359 BOOL pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
364 sampass->kickoff_time = mytime;
366 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
369 BOOL pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
374 sampass->bad_password_time = mytime;
376 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
379 BOOL pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
384 sampass->pass_can_change_time = mytime;
386 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
389 BOOL pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
394 sampass->pass_must_change_time = mytime;
396 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
399 BOOL pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
404 sampass->pass_last_set_time = mytime;
406 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
409 BOOL pdb_set_hours_len(struct samu *sampass, uint32 len, enum pdb_value_state flag)
414 sampass->hours_len = len;
416 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
419 BOOL pdb_set_logon_divs(struct samu *sampass, uint16 hours, enum pdb_value_state flag)
424 sampass->logon_divs = hours;
426 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
430 * Set flags showing what is initalised in the struct samu
431 * @param sampass the struct samu in question
432 * @param flag The *new* flag to be set. Old flags preserved
433 * this flag is only added.
436 BOOL pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
438 if (!sampass || !sampass)
441 if (!sampass->set_flags) {
442 if ((sampass->set_flags =
443 bitmap_talloc(sampass,
445 DEBUG(0,("bitmap_talloc failed\n"));
449 if (!sampass->change_flags) {
450 if ((sampass->change_flags =
451 bitmap_talloc(sampass,
453 DEBUG(0,("bitmap_talloc failed\n"));
460 if (!bitmap_set(sampass->change_flags, element)) {
461 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
464 if (!bitmap_set(sampass->set_flags, element)) {
465 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
468 DEBUG(11, ("element %d -> now CHANGED\n", element));
471 if (!bitmap_clear(sampass->change_flags, element)) {
472 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
475 if (!bitmap_set(sampass->set_flags, element)) {
476 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
479 DEBUG(11, ("element %d -> now SET\n", element));
483 if (!bitmap_clear(sampass->change_flags, element)) {
484 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
487 if (!bitmap_clear(sampass->set_flags, element)) {
488 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
491 DEBUG(11, ("element %d -> now DEFAULT\n", element));
498 BOOL pdb_set_user_sid(struct samu *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
500 if (!sampass || !u_sid)
503 sid_copy(&sampass->user_sid, u_sid);
505 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
506 sid_string_static(&sampass->user_sid)));
508 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
511 BOOL pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
515 if (!sampass || !u_sid)
518 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
521 if (!string_to_sid(&new_sid, u_sid)) {
522 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
526 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
527 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
534 /********************************************************************
535 We never fill this in from a passdb backend but rather set is
536 based on the user's primary group membership. However, the
537 struct samu* is overloaded and reused in domain memship code
538 as well and built from the NET_USER_INFO_3 or PAC so we
539 have to allow the explicitly setting of a group SID here.
540 ********************************************************************/
542 BOOL pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
546 if (!sampass || !g_sid)
549 if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
553 /* if we cannot resolve the SID to gid, then just ignore it and
554 store DOMAIN_USERS as the primary groupSID */
556 if ( sid_to_gid( g_sid, &gid ) ) {
557 sid_copy(sampass->group_sid, g_sid);
559 sid_copy( sampass->group_sid, get_global_sam_sid() );
560 sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
563 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
564 sid_string_static(sampass->group_sid)));
566 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
569 /*********************************************************************
570 Set the user's UNIX name.
571 ********************************************************************/
573 BOOL pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
579 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
580 (sampass->username)?(sampass->username):"NULL"));
582 sampass->username = talloc_strdup(sampass, username);
584 if (!sampass->username) {
585 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
590 sampass->username = PDB_NOT_QUITE_NULL;
593 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
596 /*********************************************************************
598 ********************************************************************/
600 BOOL pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
606 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
607 (sampass->domain)?(sampass->domain):"NULL"));
609 sampass->domain = talloc_strdup(sampass, domain);
611 if (!sampass->domain) {
612 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
617 sampass->domain = PDB_NOT_QUITE_NULL;
620 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
623 /*********************************************************************
624 Set the user's NT name.
625 ********************************************************************/
627 BOOL pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
633 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
634 (sampass->nt_username)?(sampass->nt_username):"NULL"));
636 sampass->nt_username = talloc_strdup(sampass, nt_username);
638 if (!sampass->nt_username) {
639 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
644 sampass->nt_username = PDB_NOT_QUITE_NULL;
647 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
650 /*********************************************************************
651 Set the user's full name.
652 ********************************************************************/
654 BOOL pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
660 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
661 (sampass->full_name)?(sampass->full_name):"NULL"));
663 sampass->full_name = talloc_strdup(sampass, full_name);
665 if (!sampass->full_name) {
666 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
671 sampass->full_name = PDB_NOT_QUITE_NULL;
674 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
677 /*********************************************************************
678 Set the user's logon script.
679 ********************************************************************/
681 BOOL pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
687 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
688 (sampass->logon_script)?(sampass->logon_script):"NULL"));
690 sampass->logon_script = talloc_strdup(sampass, logon_script);
692 if (!sampass->logon_script) {
693 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
698 sampass->logon_script = PDB_NOT_QUITE_NULL;
701 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
704 /*********************************************************************
705 Set the user's profile path.
706 ********************************************************************/
708 BOOL pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
714 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
715 (sampass->profile_path)?(sampass->profile_path):"NULL"));
717 sampass->profile_path = talloc_strdup(sampass, profile_path);
719 if (!sampass->profile_path) {
720 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
725 sampass->profile_path = PDB_NOT_QUITE_NULL;
728 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
731 /*********************************************************************
732 Set the user's directory drive.
733 ********************************************************************/
735 BOOL pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
741 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
742 (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
744 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
746 if (!sampass->dir_drive) {
747 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
752 sampass->dir_drive = PDB_NOT_QUITE_NULL;
755 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
758 /*********************************************************************
759 Set the user's home directory.
760 ********************************************************************/
762 BOOL pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
768 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
769 (sampass->home_dir)?(sampass->home_dir):"NULL"));
771 sampass->home_dir = talloc_strdup(sampass, home_dir);
773 if (!sampass->home_dir) {
774 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
779 sampass->home_dir = PDB_NOT_QUITE_NULL;
782 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
785 /*********************************************************************
786 Set the user's account description.
787 ********************************************************************/
789 BOOL pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
795 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
797 if (!sampass->acct_desc) {
798 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
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)
819 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
820 (sampass->workstations)?(sampass->workstations):"NULL"));
822 sampass->workstations = talloc_strdup(sampass, workstations);
824 if (!sampass->workstations) {
825 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
830 sampass->workstations = PDB_NOT_QUITE_NULL;
833 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
836 /*********************************************************************
837 Set the user's 'unknown_str', whatever the heck this actually is...
838 ********************************************************************/
840 BOOL pdb_set_unknown_str(struct samu *sampass, const char *unknown_str, enum pdb_value_state flag)
846 sampass->unknown_str = talloc_strdup(sampass, unknown_str);
848 if (!sampass->unknown_str) {
849 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
854 sampass->unknown_str = PDB_NOT_QUITE_NULL;
857 return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag);
860 /*********************************************************************
861 Set the user's dial string.
862 ********************************************************************/
864 BOOL pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
870 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
872 if (!sampass->munged_dial) {
873 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
878 sampass->munged_dial = PDB_NOT_QUITE_NULL;
881 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
884 /*********************************************************************
885 Set the user's NT hash.
886 ********************************************************************/
888 BOOL pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
893 data_blob_clear_free(&sampass->nt_pw);
897 data_blob_talloc(sampass, pwd, NT_HASH_LEN);
899 sampass->nt_pw = data_blob(NULL, 0);
902 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
905 /*********************************************************************
906 Set the user's LM hash.
907 ********************************************************************/
909 BOOL pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
914 data_blob_clear_free(&sampass->lm_pw);
916 /* on keep the password if we are allowing LANMAN authentication */
918 if (pwd && lp_lanman_auth() ) {
919 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
921 sampass->lm_pw = data_blob(NULL, 0);
924 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
927 /*********************************************************************
928 Set the user's password history hash. historyLen is the number of
929 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
930 entries to store in the history - this must match the size of the uint8 array
932 ********************************************************************/
934 BOOL pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
939 if (historyLen && pwd){
940 sampass->nt_pw_his = data_blob_talloc(sampass,
941 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
942 if (!sampass->nt_pw_his.length) {
943 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
947 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
950 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
953 /*********************************************************************
954 Set the user's plaintext password only (base procedure, see helper
956 ********************************************************************/
958 BOOL pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
964 if (sampass->plaintext_pw!=NULL)
965 memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
967 sampass->plaintext_pw = talloc_strdup(sampass, password);
969 if (!sampass->plaintext_pw) {
970 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
975 sampass->plaintext_pw = NULL;
978 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
981 BOOL pdb_set_bad_password_count(struct samu *sampass, uint16 bad_password_count, enum pdb_value_state flag)
986 sampass->bad_password_count = bad_password_count;
988 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
991 BOOL pdb_set_logon_count(struct samu *sampass, uint16 logon_count, enum pdb_value_state flag)
996 sampass->logon_count = logon_count;
998 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
1001 BOOL pdb_set_unknown_6(struct samu *sampass, uint32 unkn, enum pdb_value_state flag)
1006 sampass->unknown_6 = unkn;
1008 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
1011 BOOL pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
1017 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
1021 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
1023 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
1026 BOOL pdb_set_backend_private_data(struct samu *sampass, void *private_data,
1027 void (*free_fn)(void **),
1028 const struct pdb_methods *my_methods,
1029 enum pdb_value_state flag)
1034 if (sampass->backend_private_data &&
1035 sampass->backend_private_data_free_fn) {
1036 sampass->backend_private_data_free_fn(
1037 &sampass->backend_private_data);
1040 sampass->backend_private_data = private_data;
1041 sampass->backend_private_data_free_fn = free_fn;
1042 sampass->backend_private_methods = my_methods;
1044 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
1048 /* Helpful interfaces to the above */
1050 /*********************************************************************
1051 Sets the last changed times and must change times for a normal
1053 ********************************************************************/
1055 BOOL pdb_set_pass_changed_now(struct samu *sampass)
1063 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1066 if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
1067 || (expire==(uint32)-1) || (expire == 0)) {
1068 if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED))
1071 if (!pdb_set_pass_must_change_time (sampass,
1072 pdb_get_pass_last_set_time(sampass)
1073 + expire, PDB_CHANGED))
1077 if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age)
1078 || (min_age==(uint32)-1)) {
1079 if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
1082 if (!pdb_set_pass_can_change_time (sampass,
1083 pdb_get_pass_last_set_time(sampass)
1084 + min_age, PDB_CHANGED))
1090 /*********************************************************************
1091 Set the user's PLAINTEXT password. Used as an interface to the above.
1092 Also sets the last change time to NOW.
1093 ********************************************************************/
1095 BOOL pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
1097 uchar new_lanman_p16[LM_HASH_LEN];
1098 uchar new_nt_p16[NT_HASH_LEN];
1100 if (!sampass || !plaintext)
1103 /* Calculate the MD4 hash (NT compatible) of the password */
1104 E_md4hash(plaintext, new_nt_p16);
1106 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
1109 if (!E_deshash(plaintext, new_lanman_p16)) {
1110 /* E_deshash returns false for 'long' passwords (> 14
1111 DOS chars). This allows us to match Win2k, which
1112 does not store a LM hash for these passwords (which
1113 would reduce the effective password length to 14 */
1115 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
1118 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
1122 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
1125 if (!pdb_set_pass_changed_now (sampass))
1128 /* Store the password history. */
1129 if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
1132 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1133 if (pwHistLen != 0){
1134 uint32 current_history_len;
1135 /* We need to make sure we don't have a race condition here - the
1136 account policy history length can change between when the pw_history
1137 was first loaded into the struct samu struct and now.... JRA. */
1138 pwhistory = (uchar *)pdb_get_pw_history(sampass, ¤t_history_len);
1140 if (current_history_len != pwHistLen) {
1141 /* After closing and reopening struct samu the history
1142 values will sync up. We can't do this here. */
1144 /* current_history_len > pwHistLen is not a problem - we
1145 have more history than we need. */
1147 if (current_history_len < pwHistLen) {
1148 /* Ensure we have space for the needed history. */
1149 uchar *new_history = TALLOC(sampass,
1150 pwHistLen*PW_HISTORY_ENTRY_LEN);
1155 /* And copy it into the new buffer. */
1156 if (current_history_len) {
1157 memcpy(new_history, pwhistory,
1158 current_history_len*PW_HISTORY_ENTRY_LEN);
1160 /* Clearing out any extra space. */
1161 memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
1162 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
1163 /* Finally replace it. */
1164 pwhistory = new_history;
1167 if (pwhistory && pwHistLen){
1168 /* Make room for the new password in the history list. */
1169 if (pwHistLen > 1) {
1170 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
1171 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
1173 /* Create the new salt as the first part of the history entry. */
1174 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
1176 /* Generate the md5 hash of the salt+new password as the second
1177 part of the history entry. */
1179 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
1180 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1182 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
1185 /* Set the history length to zero. */
1186 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1193 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1194 uint32 pdb_build_fields_present(struct samu *sampass)
1196 /* value set to all for testing */