[GLUE] Rsync SAMBA_3_0 SVN r25598 in order to create the v3-0-test branch.
[Samba.git] / source / passdb / pdb_get_set.c
blob62898f3dac80e8e1a974e792cf229548f25d3088
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 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 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 uint32 allow;
77 /* if the last set time is zero, it means the user cannot
78 change their password, and this time must be zero. jmcd
80 if (sampass->pass_last_set_time == 0)
81 return (time_t) 0;
83 /* if the time is max, and the field has been changed,
84 we're trying to update this real value from the sampass
85 to indicate that the user cannot change their password. jmcd
87 if (sampass->pass_can_change_time == get_time_t_max() &&
88 pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
89 return sampass->pass_can_change_time;
91 if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
92 allow = 0;
94 /* in normal cases, just calculate it from policy */
95 return sampass->pass_last_set_time + allow;
98 /* we need this for loading from the backend, so that we don't overwrite
99 non-changed max times, otherwise the pass_can_change checking won't work */
100 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
102 return sampass->pass_can_change_time;
105 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
107 uint32 expire;
109 if (sampass->pass_last_set_time == 0)
110 return (time_t) 0;
112 if (sampass->acct_ctrl & ACB_PWNOEXP)
113 return get_time_t_max();
115 if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
116 || expire == (uint32)-1 || expire == 0)
117 return get_time_t_max();
119 return sampass->pass_last_set_time + expire;
122 BOOL pdb_get_pass_can_change(const struct samu *sampass)
124 if (sampass->pass_can_change_time == get_time_t_max() &&
125 sampass->pass_last_set_time != 0)
126 return False;
127 return True;
130 uint16 pdb_get_logon_divs(const struct samu *sampass)
132 return sampass->logon_divs;
135 uint32 pdb_get_hours_len(const struct samu *sampass)
137 return sampass->hours_len;
140 const uint8 *pdb_get_hours(const struct samu *sampass)
142 return (sampass->hours);
145 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
147 SMB_ASSERT((!sampass->nt_pw.data)
148 || sampass->nt_pw.length == NT_HASH_LEN);
149 return (uint8 *)sampass->nt_pw.data;
152 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
154 SMB_ASSERT((!sampass->lm_pw.data)
155 || sampass->lm_pw.length == LM_HASH_LEN);
156 return (uint8 *)sampass->lm_pw.data;
159 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32 *current_hist_len)
161 SMB_ASSERT((!sampass->nt_pw_his.data)
162 || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
163 *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
164 return (uint8 *)sampass->nt_pw_his.data;
167 /* Return the plaintext password if known. Most of the time
168 it isn't, so don't assume anything magic about this function.
170 Used to pass the plaintext to passdb backends that might
171 want to store more than just the NTLM hashes.
173 const char *pdb_get_plaintext_passwd(const struct samu *sampass)
175 return sampass->plaintext_pw;
178 const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
180 return &sampass->user_sid;
183 const DOM_SID *pdb_get_group_sid(struct samu *sampass)
185 DOM_SID *gsid;
186 struct passwd *pwd;
188 /* Return the cached group SID if we have that */
189 if ( sampass->group_sid ) {
190 return sampass->group_sid;
193 /* generate the group SID from the user's primary Unix group */
195 if ( !(gsid = TALLOC_P( sampass, DOM_SID )) ) {
196 return NULL;
199 /* No algorithmic mapping, meaning that we have to figure out the
200 primary group SID according to group mapping and the user SID must
201 be a newly allocated one. We rely on the user's Unix primary gid.
202 We have no choice but to fail if we can't find it. */
204 if ( sampass->unix_pw ) {
205 pwd = sampass->unix_pw;
206 } else {
207 pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
210 if ( !pwd ) {
211 DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
212 return NULL;
215 if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
216 enum lsa_SidType type = SID_NAME_UNKNOWN;
217 TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
218 BOOL lookup_ret;
220 if (!mem_ctx) {
221 return NULL;
224 /* Now check that it's actually a domain group and not something else */
226 lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
228 TALLOC_FREE( mem_ctx );
230 if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
231 sampass->group_sid = gsid;
232 return sampass->group_sid;
235 DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n",
236 pwd->pw_name, sid_type_lookup(type)));
239 /* Just set it to the 'Domain Users' RID of 512 which will
240 always resolve to a name */
242 sid_copy( gsid, get_global_sam_sid() );
243 sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
245 sampass->group_sid = gsid;
247 return sampass->group_sid;
251 * Get flags showing what is initalised in the struct samu
252 * @param sampass the struct samu in question
253 * @return the flags indicating the members initialised in the struct.
256 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
258 enum pdb_value_state ret = PDB_DEFAULT;
260 if (!sampass->change_flags || !sampass->set_flags)
261 return ret;
263 if (bitmap_query(sampass->set_flags, element)) {
264 DEBUG(11, ("element %d: SET\n", element));
265 ret = PDB_SET;
268 if (bitmap_query(sampass->change_flags, element)) {
269 DEBUG(11, ("element %d: CHANGED\n", element));
270 ret = PDB_CHANGED;
273 if (ret == PDB_DEFAULT) {
274 DEBUG(11, ("element %d: DEFAULT\n", element));
277 return ret;
280 const char *pdb_get_username(const struct samu *sampass)
282 return sampass->username;
285 const char *pdb_get_domain(const struct samu *sampass)
287 return sampass->domain;
290 const char *pdb_get_nt_username(const struct samu *sampass)
292 return sampass->nt_username;
295 const char *pdb_get_fullname(const struct samu *sampass)
297 return sampass->full_name;
300 const char *pdb_get_homedir(const struct samu *sampass)
302 return sampass->home_dir;
305 const char *pdb_get_unix_homedir(const struct samu *sampass)
307 if (sampass->unix_pw ) {
308 return sampass->unix_pw->pw_dir;
310 return NULL;
313 const char *pdb_get_dir_drive(const struct samu *sampass)
315 return sampass->dir_drive;
318 const char *pdb_get_logon_script(const struct samu *sampass)
320 return sampass->logon_script;
323 const char *pdb_get_profile_path(const struct samu *sampass)
325 return sampass->profile_path;
328 const char *pdb_get_acct_desc(const struct samu *sampass)
330 return sampass->acct_desc;
333 const char *pdb_get_workstations(const struct samu *sampass)
335 return sampass->workstations;
338 const char *pdb_get_comment(const struct samu *sampass)
340 return sampass->comment;
343 const char *pdb_get_munged_dial(const struct samu *sampass)
345 return sampass->munged_dial;
348 uint16 pdb_get_bad_password_count(const struct samu *sampass)
350 return sampass->bad_password_count;
353 uint16 pdb_get_logon_count(const struct samu *sampass)
355 return sampass->logon_count;
358 uint32 pdb_get_unknown_6(const struct samu *sampass)
360 return sampass->unknown_6;
363 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
365 if (my_methods == sampass->backend_private_methods) {
366 return sampass->backend_private_data;
367 } else {
368 return NULL;
372 /*********************************************************************
373 Collection of set...() functions for struct samu.
374 ********************************************************************/
376 BOOL pdb_set_acct_ctrl(struct samu *sampass, uint32 acct_ctrl, enum pdb_value_state flag)
378 sampass->acct_ctrl = acct_ctrl;
379 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
382 BOOL pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
384 sampass->logon_time = mytime;
385 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
388 BOOL pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
390 sampass->logoff_time = mytime;
391 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
394 BOOL pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
396 sampass->kickoff_time = mytime;
397 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
400 BOOL pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
402 sampass->bad_password_time = mytime;
403 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
406 BOOL pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
408 sampass->pass_can_change_time = mytime;
409 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
412 BOOL pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
414 sampass->pass_must_change_time = mytime;
415 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
418 BOOL pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
420 sampass->pass_last_set_time = mytime;
421 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
424 BOOL pdb_set_hours_len(struct samu *sampass, uint32 len, enum pdb_value_state flag)
426 sampass->hours_len = len;
427 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
430 BOOL pdb_set_logon_divs(struct samu *sampass, uint16 hours, enum pdb_value_state flag)
432 sampass->logon_divs = hours;
433 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
437 * Set flags showing what is initalised in the struct samu
438 * @param sampass the struct samu in question
439 * @param flag The *new* flag to be set. Old flags preserved
440 * this flag is only added.
443 BOOL pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
445 if (!sampass->set_flags) {
446 if ((sampass->set_flags =
447 bitmap_talloc(sampass,
448 PDB_COUNT))==NULL) {
449 DEBUG(0,("bitmap_talloc failed\n"));
450 return False;
453 if (!sampass->change_flags) {
454 if ((sampass->change_flags =
455 bitmap_talloc(sampass,
456 PDB_COUNT))==NULL) {
457 DEBUG(0,("bitmap_talloc failed\n"));
458 return False;
462 switch(value_flag) {
463 case PDB_CHANGED:
464 if (!bitmap_set(sampass->change_flags, element)) {
465 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
466 return False;
468 if (!bitmap_set(sampass->set_flags, element)) {
469 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
470 return False;
472 DEBUG(11, ("element %d -> now CHANGED\n", element));
473 break;
474 case PDB_SET:
475 if (!bitmap_clear(sampass->change_flags, element)) {
476 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
477 return False;
479 if (!bitmap_set(sampass->set_flags, element)) {
480 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
481 return False;
483 DEBUG(11, ("element %d -> now SET\n", element));
484 break;
485 case PDB_DEFAULT:
486 default:
487 if (!bitmap_clear(sampass->change_flags, element)) {
488 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
489 return False;
491 if (!bitmap_clear(sampass->set_flags, element)) {
492 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
493 return False;
495 DEBUG(11, ("element %d -> now DEFAULT\n", element));
496 break;
499 return True;
502 BOOL pdb_set_user_sid(struct samu *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
504 if (!u_sid)
505 return False;
507 sid_copy(&sampass->user_sid, u_sid);
509 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
510 sid_string_static(&sampass->user_sid)));
512 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
515 BOOL pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
517 DOM_SID new_sid;
519 if (!u_sid)
520 return False;
522 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
523 u_sid));
525 if (!string_to_sid(&new_sid, u_sid)) {
526 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
527 return False;
530 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
531 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
532 return False;
535 return True;
538 /********************************************************************
539 We never fill this in from a passdb backend but rather set is
540 based on the user's primary group membership. However, the
541 struct samu* is overloaded and reused in domain memship code
542 as well and built from the NET_USER_INFO_3 or PAC so we
543 have to allow the explicitly setting of a group SID here.
544 ********************************************************************/
546 BOOL pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
548 gid_t gid;
550 if (!g_sid)
551 return False;
553 if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
554 return False;
557 /* if we cannot resolve the SID to gid, then just ignore it and
558 store DOMAIN_USERS as the primary groupSID */
560 if ( sid_to_gid( g_sid, &gid ) ) {
561 sid_copy(sampass->group_sid, g_sid);
562 } else {
563 sid_copy( sampass->group_sid, get_global_sam_sid() );
564 sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
567 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
568 sid_string_static(sampass->group_sid)));
570 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
573 /*********************************************************************
574 Set the user's UNIX name.
575 ********************************************************************/
577 BOOL pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
579 if (username) {
580 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
581 (sampass->username)?(sampass->username):"NULL"));
583 sampass->username = talloc_strdup(sampass, username);
585 if (!sampass->username) {
586 DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
587 return False;
589 } else {
590 sampass->username = PDB_NOT_QUITE_NULL;
593 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
596 /*********************************************************************
597 Set the domain name.
598 ********************************************************************/
600 BOOL pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
602 if (domain) {
603 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
604 (sampass->domain)?(sampass->domain):"NULL"));
606 sampass->domain = talloc_strdup(sampass, domain);
608 if (!sampass->domain) {
609 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
610 return False;
612 } else {
613 sampass->domain = PDB_NOT_QUITE_NULL;
616 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
619 /*********************************************************************
620 Set the user's NT name.
621 ********************************************************************/
623 BOOL pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
625 if (nt_username) {
626 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
627 (sampass->nt_username)?(sampass->nt_username):"NULL"));
629 sampass->nt_username = talloc_strdup(sampass, nt_username);
631 if (!sampass->nt_username) {
632 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
633 return False;
635 } else {
636 sampass->nt_username = PDB_NOT_QUITE_NULL;
639 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
642 /*********************************************************************
643 Set the user's full name.
644 ********************************************************************/
646 BOOL pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
648 if (full_name) {
649 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
650 (sampass->full_name)?(sampass->full_name):"NULL"));
652 sampass->full_name = talloc_strdup(sampass, full_name);
654 if (!sampass->full_name) {
655 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
656 return False;
658 } else {
659 sampass->full_name = PDB_NOT_QUITE_NULL;
662 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
665 /*********************************************************************
666 Set the user's logon script.
667 ********************************************************************/
669 BOOL pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
671 if (logon_script) {
672 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
673 (sampass->logon_script)?(sampass->logon_script):"NULL"));
675 sampass->logon_script = talloc_strdup(sampass, logon_script);
677 if (!sampass->logon_script) {
678 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
679 return False;
681 } else {
682 sampass->logon_script = PDB_NOT_QUITE_NULL;
685 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
688 /*********************************************************************
689 Set the user's profile path.
690 ********************************************************************/
692 BOOL pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
694 if (profile_path) {
695 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
696 (sampass->profile_path)?(sampass->profile_path):"NULL"));
698 sampass->profile_path = talloc_strdup(sampass, profile_path);
700 if (!sampass->profile_path) {
701 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
702 return False;
704 } else {
705 sampass->profile_path = PDB_NOT_QUITE_NULL;
708 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
711 /*********************************************************************
712 Set the user's directory drive.
713 ********************************************************************/
715 BOOL pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
717 if (dir_drive) {
718 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
719 (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
721 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
723 if (!sampass->dir_drive) {
724 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
725 return False;
728 } else {
729 sampass->dir_drive = PDB_NOT_QUITE_NULL;
732 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
735 /*********************************************************************
736 Set the user's home directory.
737 ********************************************************************/
739 BOOL pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
741 if (home_dir) {
742 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
743 (sampass->home_dir)?(sampass->home_dir):"NULL"));
745 sampass->home_dir = talloc_strdup(sampass, home_dir);
747 if (!sampass->home_dir) {
748 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
749 return False;
751 } else {
752 sampass->home_dir = PDB_NOT_QUITE_NULL;
755 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
758 /*********************************************************************
759 Set the user's account description.
760 ********************************************************************/
762 BOOL pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
764 if (acct_desc) {
765 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
767 if (!sampass->acct_desc) {
768 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
769 return False;
771 } else {
772 sampass->acct_desc = PDB_NOT_QUITE_NULL;
775 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
778 /*********************************************************************
779 Set the user's workstation allowed list.
780 ********************************************************************/
782 BOOL pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
784 if (workstations) {
785 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
786 (sampass->workstations)?(sampass->workstations):"NULL"));
788 sampass->workstations = talloc_strdup(sampass, workstations);
790 if (!sampass->workstations) {
791 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
792 return False;
794 } else {
795 sampass->workstations = PDB_NOT_QUITE_NULL;
798 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
801 /*********************************************************************
802 ********************************************************************/
804 BOOL pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
806 if (comment) {
807 sampass->comment = talloc_strdup(sampass, comment);
809 if (!sampass->comment) {
810 DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
811 return False;
813 } else {
814 sampass->comment = PDB_NOT_QUITE_NULL;
817 return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
820 /*********************************************************************
821 Set the user's dial string.
822 ********************************************************************/
824 BOOL pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
826 if (munged_dial) {
827 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
829 if (!sampass->munged_dial) {
830 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
831 return False;
833 } else {
834 sampass->munged_dial = PDB_NOT_QUITE_NULL;
837 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
840 /*********************************************************************
841 Set the user's NT hash.
842 ********************************************************************/
844 BOOL pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
846 data_blob_clear_free(&sampass->nt_pw);
848 if (pwd) {
849 sampass->nt_pw =
850 data_blob_talloc(sampass, pwd, NT_HASH_LEN);
851 } else {
852 sampass->nt_pw = data_blob(NULL, 0);
855 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
858 /*********************************************************************
859 Set the user's LM hash.
860 ********************************************************************/
862 BOOL pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
864 data_blob_clear_free(&sampass->lm_pw);
866 /* on keep the password if we are allowing LANMAN authentication */
868 if (pwd && lp_lanman_auth() ) {
869 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
870 } else {
871 sampass->lm_pw = data_blob(NULL, 0);
874 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
877 /*********************************************************************
878 Set the user's password history hash. historyLen is the number of
879 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
880 entries to store in the history - this must match the size of the uint8 array
881 in pwd.
882 ********************************************************************/
884 BOOL pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
886 if (historyLen && pwd){
887 sampass->nt_pw_his = data_blob_talloc(sampass,
888 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
889 if (!sampass->nt_pw_his.length) {
890 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
891 return False;
893 } else {
894 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
897 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
900 /*********************************************************************
901 Set the user's plaintext password only (base procedure, see helper
902 below)
903 ********************************************************************/
905 BOOL pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
907 if (password) {
908 if (sampass->plaintext_pw!=NULL)
909 memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
911 sampass->plaintext_pw = talloc_strdup(sampass, password);
913 if (!sampass->plaintext_pw) {
914 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
915 return False;
917 } else {
918 sampass->plaintext_pw = NULL;
921 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
924 BOOL pdb_set_bad_password_count(struct samu *sampass, uint16 bad_password_count, enum pdb_value_state flag)
926 sampass->bad_password_count = bad_password_count;
927 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
930 BOOL pdb_set_logon_count(struct samu *sampass, uint16 logon_count, enum pdb_value_state flag)
932 sampass->logon_count = logon_count;
933 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
936 BOOL pdb_set_unknown_6(struct samu *sampass, uint32 unkn, enum pdb_value_state flag)
938 sampass->unknown_6 = unkn;
939 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
942 BOOL pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
944 if (!hours) {
945 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
946 } else {
947 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
950 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
953 BOOL pdb_set_backend_private_data(struct samu *sampass, void *private_data,
954 void (*free_fn)(void **),
955 const struct pdb_methods *my_methods,
956 enum pdb_value_state flag)
958 if (sampass->backend_private_data &&
959 sampass->backend_private_data_free_fn) {
960 sampass->backend_private_data_free_fn(
961 &sampass->backend_private_data);
964 sampass->backend_private_data = private_data;
965 sampass->backend_private_data_free_fn = free_fn;
966 sampass->backend_private_methods = my_methods;
968 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
972 /* Helpful interfaces to the above */
974 BOOL pdb_set_pass_can_change(struct samu *sampass, BOOL canchange)
976 return pdb_set_pass_can_change_time(sampass,
977 canchange ? 0 : get_time_t_max(),
978 PDB_CHANGED);
982 /*********************************************************************
983 Set the user's PLAINTEXT password. Used as an interface to the above.
984 Also sets the last change time to NOW.
985 ********************************************************************/
987 BOOL pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
989 uchar new_lanman_p16[LM_HASH_LEN];
990 uchar new_nt_p16[NT_HASH_LEN];
992 if (!plaintext)
993 return False;
995 /* Calculate the MD4 hash (NT compatible) of the password */
996 E_md4hash(plaintext, new_nt_p16);
998 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
999 return False;
1001 if (!E_deshash(plaintext, new_lanman_p16)) {
1002 /* E_deshash returns false for 'long' passwords (> 14
1003 DOS chars). This allows us to match Win2k, which
1004 does not store a LM hash for these passwords (which
1005 would reduce the effective password length to 14 */
1007 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
1008 return False;
1009 } else {
1010 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
1011 return False;
1014 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
1015 return False;
1017 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1018 return False;
1020 /* Store the password history. */
1021 if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
1022 uchar *pwhistory;
1023 uint32 pwHistLen;
1024 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1025 if (pwHistLen != 0){
1026 uint32 current_history_len;
1027 /* We need to make sure we don't have a race condition here - the
1028 account policy history length can change between when the pw_history
1029 was first loaded into the struct samu struct and now.... JRA. */
1030 pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1032 if (current_history_len != pwHistLen) {
1033 /* After closing and reopening struct samu the history
1034 values will sync up. We can't do this here. */
1036 /* current_history_len > pwHistLen is not a problem - we
1037 have more history than we need. */
1039 if (current_history_len < pwHistLen) {
1040 /* Ensure we have space for the needed history. */
1041 uchar *new_history = (uchar *)TALLOC(sampass,
1042 pwHistLen*PW_HISTORY_ENTRY_LEN);
1043 if (!new_history) {
1044 return False;
1047 /* And copy it into the new buffer. */
1048 if (current_history_len) {
1049 memcpy(new_history, pwhistory,
1050 current_history_len*PW_HISTORY_ENTRY_LEN);
1052 /* Clearing out any extra space. */
1053 memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
1054 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
1055 /* Finally replace it. */
1056 pwhistory = new_history;
1059 if (pwhistory && pwHistLen){
1060 /* Make room for the new password in the history list. */
1061 if (pwHistLen > 1) {
1062 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
1063 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
1065 /* Create the new salt as the first part of the history entry. */
1066 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
1068 /* Generate the md5 hash of the salt+new password as the second
1069 part of the history entry. */
1071 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
1072 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1073 } else {
1074 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
1076 } else {
1077 /* Set the history length to zero. */
1078 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1082 return True;
1085 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1086 uint32 pdb_build_fields_present(struct samu *sampass)
1088 /* value set to all for testing */
1089 return 0x00ffffff;