r4231: commiting changes to 3.0.10
[Samba.git] / source / passdb / pdb_get_set.c
blob2ca76384721e7de8696b2773c9d0385729329e39
1 /*
2 Unix SMB/CIFS implementation.
3 SAM_ACCOUNT 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-2001
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.
25 #include "includes.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 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 SAM_ACCOUNT.
41 ********************************************************************/
43 uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass)
45 if (sampass)
46 return (sampass->private.acct_ctrl);
47 else
48 return (ACB_DISABLED);
51 time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass)
53 if (sampass)
54 return (sampass->private.logon_time);
55 else
56 return (0);
59 time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass)
61 if (sampass)
62 return (sampass->private.logoff_time);
63 else
64 return (-1);
67 time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass)
69 if (sampass)
70 return (sampass->private.kickoff_time);
71 else
72 return (-1);
75 time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass)
77 if (sampass)
78 return (sampass->private.bad_password_time);
79 else
80 return (-1);
83 time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass)
85 if (sampass)
86 return (sampass->private.pass_last_set_time);
87 else
88 return (-1);
91 time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass)
93 if (sampass)
94 return (sampass->private.pass_can_change_time);
95 else
96 return (-1);
99 time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass)
101 if (sampass)
102 return (sampass->private.pass_must_change_time);
103 else
104 return (-1);
107 uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass)
109 if (sampass)
110 return (sampass->private.logon_divs);
111 else
112 return (-1);
115 uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass)
117 if (sampass)
118 return (sampass->private.hours_len);
119 else
120 return (-1);
123 const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass)
125 if (sampass)
126 return (sampass->private.hours);
127 else
128 return (NULL);
131 const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass)
133 if (sampass) {
134 SMB_ASSERT((!sampass->private.nt_pw.data)
135 || sampass->private.nt_pw.length == NT_HASH_LEN);
136 return ((uint8*)sampass->private.nt_pw.data);
138 else
139 return (NULL);
142 const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
144 if (sampass) {
145 SMB_ASSERT((!sampass->private.lm_pw.data)
146 || sampass->private.lm_pw.length == LM_HASH_LEN);
147 return ((uint8*)sampass->private.lm_pw.data);
149 else
150 return (NULL);
153 const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_hist_len)
155 if (sampass) {
156 SMB_ASSERT((!sampass->private.nt_pw_his.data)
157 || ((sampass->private.nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
158 *current_hist_len = sampass->private.nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
159 return ((uint8*)sampass->private.nt_pw_his.data);
160 } else {
161 *current_hist_len = 0;
162 return (NULL);
166 /* Return the plaintext password if known. Most of the time
167 it isn't, so don't assume anything magic about this function.
169 Used to pass the plaintext to passdb backends that might
170 want to store more than just the NTLM hashes.
172 const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass)
174 if (sampass) {
175 return (sampass->private.plaintext_pw);
177 else
178 return (NULL);
180 const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass)
182 if (sampass)
183 return &sampass->private.user_sid;
184 else
185 return (NULL);
188 const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass)
190 if (sampass)
191 return &sampass->private.group_sid;
192 else
193 return (NULL);
197 * Get flags showing what is initalised in the SAM_ACCOUNT
198 * @param sampass the SAM_ACCOUNT in question
199 * @return the flags indicating the members initialised in the struct.
202 enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_elements element)
204 enum pdb_value_state ret = PDB_DEFAULT;
206 if (!sampass || !sampass->private.change_flags || !sampass->private.set_flags)
207 return ret;
209 if (bitmap_query(sampass->private.set_flags, element)) {
210 DEBUG(11, ("element %d: SET\n", element));
211 ret = PDB_SET;
214 if (bitmap_query(sampass->private.change_flags, element)) {
215 DEBUG(11, ("element %d: CHANGED\n", element));
216 ret = PDB_CHANGED;
219 if (ret == PDB_DEFAULT) {
220 DEBUG(11, ("element %d: DEFAULT\n", element));
223 return ret;
226 const char* pdb_get_username (const SAM_ACCOUNT *sampass)
228 if (sampass)
229 return (sampass->private.username);
230 else
231 return (NULL);
234 const char* pdb_get_domain (const SAM_ACCOUNT *sampass)
236 if (sampass)
237 return (sampass->private.domain);
238 else
239 return (NULL);
242 const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass)
244 if (sampass)
245 return (sampass->private.nt_username);
246 else
247 return (NULL);
250 const char* pdb_get_fullname (const SAM_ACCOUNT *sampass)
252 if (sampass)
253 return (sampass->private.full_name);
254 else
255 return (NULL);
258 const char* pdb_get_homedir (const SAM_ACCOUNT *sampass)
260 if (sampass)
261 return (sampass->private.home_dir);
262 else
263 return (NULL);
266 const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
268 if (sampass)
269 return (sampass->private.unix_home_dir);
270 else
271 return (NULL);
274 const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
276 if (sampass)
277 return (sampass->private.dir_drive);
278 else
279 return (NULL);
282 const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass)
284 if (sampass)
285 return (sampass->private.logon_script);
286 else
287 return (NULL);
290 const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass)
292 if (sampass)
293 return (sampass->private.profile_path);
294 else
295 return (NULL);
298 const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass)
300 if (sampass)
301 return (sampass->private.acct_desc);
302 else
303 return (NULL);
306 const char* pdb_get_workstations (const SAM_ACCOUNT *sampass)
308 if (sampass)
309 return (sampass->private.workstations);
310 else
311 return (NULL);
314 const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass)
316 if (sampass)
317 return (sampass->private.unknown_str);
318 else
319 return (NULL);
322 const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass)
324 if (sampass)
325 return (sampass->private.munged_dial);
326 else
327 return (NULL);
330 uint32 pdb_get_fields_present (const SAM_ACCOUNT *sampass)
332 if (sampass)
333 return (sampass->private.fields_present);
334 else
335 return (-1);
338 uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass)
340 if (sampass)
341 return (sampass->private.bad_password_count);
342 else
343 return 0;
346 uint16 pdb_get_logon_count(const SAM_ACCOUNT *sampass)
348 if (sampass)
349 return (sampass->private.logon_count);
350 else
351 return 0;
354 uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass)
356 if (sampass)
357 return (sampass->private.unknown_6);
358 else
359 return (-1);
362 void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods)
364 if (sampass && my_methods == sampass->private.backend_private_methods)
365 return sampass->private.backend_private_data;
366 else
367 return NULL;
370 /*********************************************************************
371 Collection of set...() functions for SAM_ACCOUNT.
372 ********************************************************************/
374 BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_state flag)
376 if (!sampass)
377 return False;
379 sampass->private.acct_ctrl = acct_ctrl;
381 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
384 BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
386 if (!sampass)
387 return False;
389 sampass->private.logon_time = mytime;
391 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
394 BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
396 if (!sampass)
397 return False;
399 sampass->private.logoff_time = mytime;
401 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
404 BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
406 if (!sampass)
407 return False;
409 sampass->private.kickoff_time = mytime;
411 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
414 BOOL pdb_set_bad_password_time (SAM_ACCOUNT *sampass, time_t mytime,
415 enum pdb_value_state flag)
417 if (!sampass)
418 return False;
420 sampass->private.bad_password_time = mytime;
422 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
425 BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
427 if (!sampass)
428 return False;
430 sampass->private.pass_can_change_time = mytime;
432 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
435 BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
437 if (!sampass)
438 return False;
440 sampass->private.pass_must_change_time = mytime;
442 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
445 BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
447 if (!sampass)
448 return False;
450 sampass->private.pass_last_set_time = mytime;
452 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
455 BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state flag)
457 if (!sampass)
458 return False;
460 sampass->private.hours_len = len;
462 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
465 BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_state flag)
467 if (!sampass)
468 return False;
470 sampass->private.logon_divs = hours;
472 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
476 * Set flags showing what is initalised in the SAM_ACCOUNT
477 * @param sampass the SAM_ACCOUNT in question
478 * @param flag The *new* flag to be set. Old flags preserved
479 * this flag is only added.
482 BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
484 if (!sampass || !sampass->mem_ctx)
485 return False;
487 if (!sampass->private.set_flags) {
488 if ((sampass->private.set_flags =
489 bitmap_talloc(sampass->mem_ctx,
490 PDB_COUNT))==NULL) {
491 DEBUG(0,("bitmap_talloc failed\n"));
492 return False;
495 if (!sampass->private.change_flags) {
496 if ((sampass->private.change_flags =
497 bitmap_talloc(sampass->mem_ctx,
498 PDB_COUNT))==NULL) {
499 DEBUG(0,("bitmap_talloc failed\n"));
500 return False;
504 switch(value_flag) {
505 case PDB_CHANGED:
506 if (!bitmap_set(sampass->private.change_flags, element)) {
507 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
508 return False;
510 if (!bitmap_set(sampass->private.set_flags, element)) {
511 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
512 return False;
514 DEBUG(11, ("element %d -> now CHANGED\n", element));
515 break;
516 case PDB_SET:
517 if (!bitmap_clear(sampass->private.change_flags, element)) {
518 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
519 return False;
521 if (!bitmap_set(sampass->private.set_flags, element)) {
522 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
523 return False;
525 DEBUG(10, ("element %d -> now SET\n", element));
526 break;
527 case PDB_DEFAULT:
528 default:
529 if (!bitmap_clear(sampass->private.change_flags, element)) {
530 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
531 return False;
533 if (!bitmap_clear(sampass->private.set_flags, element)) {
534 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
535 return False;
537 DEBUG(11, ("element %d -> now DEFAULT\n", element));
538 break;
541 return True;
544 BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
546 if (!sampass || !u_sid)
547 return False;
549 sid_copy(&sampass->private.user_sid, u_sid);
551 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
552 sid_string_static(&sampass->private.user_sid)));
554 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
557 BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag)
559 DOM_SID new_sid;
561 if (!sampass || !u_sid)
562 return False;
564 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
565 u_sid));
567 if (!string_to_sid(&new_sid, u_sid)) {
568 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
569 return False;
572 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
573 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid));
574 return False;
577 return True;
580 BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
582 if (!sampass || !g_sid)
583 return False;
585 sid_copy(&sampass->private.group_sid, g_sid);
587 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
588 sid_string_static(&sampass->private.group_sid)));
590 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
593 BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag)
595 DOM_SID new_sid;
596 if (!sampass || !g_sid)
597 return False;
599 DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n",
600 g_sid));
602 if (!string_to_sid(&new_sid, g_sid)) {
603 DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
604 return False;
607 if (!pdb_set_group_sid(sampass, &new_sid, flag)) {
608 DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
609 return False;
611 return True;
614 /*********************************************************************
615 Set the user's UNIX name.
616 ********************************************************************/
618 BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag)
620 if (!sampass)
621 return False;
623 if (username) {
624 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
625 (sampass->private.username)?(sampass->private.username):"NULL"));
627 sampass->private.username = talloc_strdup(sampass->mem_ctx, username);
629 if (!sampass->private.username) {
630 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
631 return False;
634 } else {
635 sampass->private.username = PDB_NOT_QUITE_NULL;
638 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
641 /*********************************************************************
642 Set the domain name.
643 ********************************************************************/
645 BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag)
647 if (!sampass)
648 return False;
650 if (domain) {
651 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
652 (sampass->private.domain)?(sampass->private.domain):"NULL"));
654 sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain);
656 if (!sampass->private.domain) {
657 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
658 return False;
661 } else {
662 sampass->private.domain = PDB_NOT_QUITE_NULL;
665 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
668 /*********************************************************************
669 Set the user's NT name.
670 ********************************************************************/
672 BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag)
674 if (!sampass)
675 return False;
677 if (nt_username) {
678 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
679 (sampass->private.nt_username)?(sampass->private.nt_username):"NULL"));
681 sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username);
683 if (!sampass->private.nt_username) {
684 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
685 return False;
688 } else {
689 sampass->private.nt_username = PDB_NOT_QUITE_NULL;
692 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
695 /*********************************************************************
696 Set the user's full name.
697 ********************************************************************/
699 BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag)
701 if (!sampass)
702 return False;
704 if (full_name) {
705 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
706 (sampass->private.full_name)?(sampass->private.full_name):"NULL"));
708 sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name);
710 if (!sampass->private.full_name) {
711 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
712 return False;
715 } else {
716 sampass->private.full_name = PDB_NOT_QUITE_NULL;
719 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
722 /*********************************************************************
723 Set the user's logon script.
724 ********************************************************************/
726 BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag)
728 if (!sampass)
729 return False;
731 if (logon_script) {
732 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
733 (sampass->private.logon_script)?(sampass->private.logon_script):"NULL"));
735 sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script);
737 if (!sampass->private.logon_script) {
738 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
739 return False;
742 } else {
743 sampass->private.logon_script = PDB_NOT_QUITE_NULL;
746 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
749 /*********************************************************************
750 Set the user's profile path.
751 ********************************************************************/
753 BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag)
755 if (!sampass)
756 return False;
758 if (profile_path) {
759 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
760 (sampass->private.profile_path)?(sampass->private.profile_path):"NULL"));
762 sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path);
764 if (!sampass->private.profile_path) {
765 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
766 return False;
769 } else {
770 sampass->private.profile_path = PDB_NOT_QUITE_NULL;
773 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
776 /*********************************************************************
777 Set the user's directory drive.
778 ********************************************************************/
780 BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag)
782 if (!sampass)
783 return False;
785 if (dir_drive) {
786 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
787 (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL"));
789 sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive);
791 if (!sampass->private.dir_drive) {
792 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
793 return False;
796 } else {
797 sampass->private.dir_drive = PDB_NOT_QUITE_NULL;
800 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
803 /*********************************************************************
804 Set the user's home directory.
805 ********************************************************************/
807 BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag)
809 if (!sampass)
810 return False;
812 if (home_dir) {
813 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
814 (sampass->private.home_dir)?(sampass->private.home_dir):"NULL"));
816 sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir);
818 if (!sampass->private.home_dir) {
819 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
820 return False;
823 } else {
824 sampass->private.home_dir = PDB_NOT_QUITE_NULL;
827 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
830 /*********************************************************************
831 Set the user's unix home directory.
832 ********************************************************************/
834 BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag)
836 if (!sampass)
837 return False;
839 if (unix_home_dir) {
840 DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir,
841 (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL"));
843 sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx,
844 unix_home_dir);
846 if (!sampass->private.unix_home_dir) {
847 DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
848 return False;
851 } else {
852 sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL;
855 return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag);
858 /*********************************************************************
859 Set the user's account description.
860 ********************************************************************/
862 BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag)
864 if (!sampass)
865 return False;
867 if (acct_desc) {
868 sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc);
870 if (!sampass->private.acct_desc) {
871 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
872 return False;
875 } else {
876 sampass->private.acct_desc = PDB_NOT_QUITE_NULL;
879 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
882 /*********************************************************************
883 Set the user's workstation allowed list.
884 ********************************************************************/
886 BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag)
888 if (!sampass)
889 return False;
891 if (workstations) {
892 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
893 (sampass->private.workstations)?(sampass->private.workstations):"NULL"));
895 sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations);
897 if (!sampass->private.workstations) {
898 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
899 return False;
902 } else {
903 sampass->private.workstations = PDB_NOT_QUITE_NULL;
906 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
909 /*********************************************************************
910 Set the user's 'unknown_str', whatever the heck this actually is...
911 ********************************************************************/
913 BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag)
915 if (!sampass)
916 return False;
918 if (unknown_str) {
919 sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str);
921 if (!sampass->private.unknown_str) {
922 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
923 return False;
926 } else {
927 sampass->private.unknown_str = PDB_NOT_QUITE_NULL;
930 return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag);
933 /*********************************************************************
934 Set the user's dial string.
935 ********************************************************************/
937 BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag)
939 if (!sampass)
940 return False;
942 if (munged_dial) {
943 sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial);
945 if (!sampass->private.munged_dial) {
946 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
947 return False;
950 } else {
951 sampass->private.munged_dial = PDB_NOT_QUITE_NULL;
954 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
957 /*********************************************************************
958 Set the user's NT hash.
959 ********************************************************************/
961 BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
963 if (!sampass)
964 return False;
966 data_blob_clear_free(&sampass->private.nt_pw);
968 if (pwd) {
969 sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN);
970 } else {
971 sampass->private.nt_pw = data_blob(NULL, 0);
974 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
977 /*********************************************************************
978 Set the user's LM hash.
979 ********************************************************************/
981 BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
983 if (!sampass)
984 return False;
986 data_blob_clear_free(&sampass->private.lm_pw);
988 if (pwd) {
989 sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN);
990 } else {
991 sampass->private.lm_pw = data_blob(NULL, 0);
994 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
997 /*********************************************************************
998 Set the user's password history hash. historyLen is the number of
999 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
1000 entries to store in the history - this must match the size of the uint8 array
1001 in pwd.
1002 ********************************************************************/
1004 BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
1006 if (!sampass)
1007 return False;
1009 if (historyLen && pwd){
1010 sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx,
1011 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
1012 if (!sampass->private.nt_pw_his.length) {
1013 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
1014 return False;
1016 } else {
1017 sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, NULL, 0);
1020 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
1023 /*********************************************************************
1024 Set the user's plaintext password only (base procedure, see helper
1025 below)
1026 ********************************************************************/
1028 BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag)
1030 if (!sampass)
1031 return False;
1033 if (password) {
1034 if (sampass->private.plaintext_pw!=NULL)
1035 memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1);
1037 sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password);
1039 if (!sampass->private.plaintext_pw) {
1040 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
1041 return False;
1044 } else {
1045 sampass->private.plaintext_pw = NULL;
1048 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
1051 BOOL pdb_set_fields_present (SAM_ACCOUNT *sampass, uint32 fields_present, enum pdb_value_state flag)
1053 if (!sampass)
1054 return False;
1056 sampass->private.fields_present = fields_present;
1058 return pdb_set_init_flags(sampass, PDB_FIELDS_PRESENT, flag);
1061 BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag)
1063 if (!sampass)
1064 return False;
1066 sampass->private.bad_password_count = bad_password_count;
1068 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
1071 BOOL pdb_set_logon_count(SAM_ACCOUNT *sampass, uint16 logon_count, enum pdb_value_state flag)
1073 if (!sampass)
1074 return False;
1076 sampass->private.logon_count = logon_count;
1078 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
1081 BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
1083 if (!sampass)
1084 return False;
1086 sampass->private.unknown_6 = unkn;
1088 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
1091 BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag)
1093 if (!sampass)
1094 return False;
1096 if (!hours) {
1097 memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN);
1098 return True;
1101 memcpy (sampass->private.hours, hours, MAX_HOURS_LEN);
1103 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
1106 BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data,
1107 void (*free_fn)(void **),
1108 const struct pdb_methods *my_methods,
1109 enum pdb_value_state flag)
1111 if (!sampass)
1112 return False;
1114 if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) {
1115 sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data);
1118 sampass->private.backend_private_data = private_data;
1119 sampass->private.backend_private_data_free_fn = free_fn;
1120 sampass->private.backend_private_methods = my_methods;
1122 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
1126 /* Helpful interfaces to the above */
1128 /*********************************************************************
1129 Sets the last changed times and must change times for a normal
1130 password change.
1131 ********************************************************************/
1133 BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
1135 uint32 expire;
1136 uint32 min_age;
1138 if (!sampass)
1139 return False;
1141 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1142 return False;
1144 if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
1145 || (expire==(uint32)-1) || (expire == 0)) {
1146 if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED))
1147 return False;
1148 } else {
1149 if (!pdb_set_pass_must_change_time (sampass,
1150 pdb_get_pass_last_set_time(sampass)
1151 + expire, PDB_CHANGED))
1152 return False;
1155 if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age)
1156 || (min_age==(uint32)-1)) {
1157 if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
1158 return False;
1159 } else {
1160 if (!pdb_set_pass_can_change_time (sampass,
1161 pdb_get_pass_last_set_time(sampass)
1162 + min_age, PDB_CHANGED))
1163 return False;
1165 return True;
1168 /*********************************************************************
1169 Set the user's PLAINTEXT password. Used as an interface to the above.
1170 Also sets the last change time to NOW.
1171 ********************************************************************/
1173 BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
1175 uchar new_lanman_p16[LM_HASH_LEN];
1176 uchar new_nt_p16[NT_HASH_LEN];
1178 if (!sampass || !plaintext)
1179 return False;
1181 /* Calculate the MD4 hash (NT compatible) of the password */
1182 E_md4hash(plaintext, new_nt_p16);
1184 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
1185 return False;
1187 if (!E_deshash(plaintext, new_lanman_p16)) {
1188 /* E_deshash returns false for 'long' passwords (> 14
1189 DOS chars). This allows us to match Win2k, which
1190 does not store a LM hash for these passwords (which
1191 would reduce the effective password length to 14 */
1193 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
1194 return False;
1195 } else {
1196 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
1197 return False;
1200 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
1201 return False;
1203 if (!pdb_set_pass_changed_now (sampass))
1204 return False;
1206 /* Store the password history. */
1207 if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
1208 uchar *pwhistory;
1209 uint32 pwHistLen;
1210 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
1211 if (pwHistLen != 0){
1212 uint32 current_history_len;
1213 /* We need to make sure we don't have a race condition here - the
1214 account policy history length can change between when the pw_history
1215 was first loaded into the SAM_ACCOUNT struct and now.... JRA. */
1216 pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1218 if (current_history_len != pwHistLen) {
1219 /* After closing and reopening SAM_ACCOUNT the history
1220 values will sync up. We can't do this here. */
1222 /* current_history_len > pwHistLen is not a problem - we
1223 have more history than we need. */
1225 if (current_history_len < pwHistLen) {
1226 /* Ensure we have space for the needed history. */
1227 uchar *new_history = TALLOC(sampass->mem_ctx,
1228 pwHistLen*PW_HISTORY_ENTRY_LEN);
1229 /* And copy it into the new buffer. */
1230 if (current_history_len) {
1231 memcpy(new_history, pwhistory,
1232 current_history_len*PW_HISTORY_ENTRY_LEN);
1234 /* Clearing out any extra space. */
1235 memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
1236 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
1237 /* Finally replace it. */
1238 pwhistory = new_history;
1241 if (pwhistory && pwHistLen){
1242 /* Make room for the new password in the history list. */
1243 if (pwHistLen > 1) {
1244 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
1245 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
1247 /* Create the new salt as the first part of the history entry. */
1248 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
1250 /* Generate the md5 hash of the salt+new password as the second
1251 part of the history entry. */
1253 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
1254 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1255 } else {
1256 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
1258 } else {
1259 /* Set the history length to zero. */
1260 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1264 return True;
1267 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1268 uint32 pdb_build_fields_present (SAM_ACCOUNT *sampass)
1270 /* value set to all for testing */
1271 return 0x00ffffff;