s3/docs: Fix serveral typos.
[Samba.git] / source / passdb / pdb_get_set.c
blobc427d41e239d5a93a7fd8f8bfd9820c6b7c84991
1 /*
2 Unix SMB/CIFS implementation.
3 struct samu access routines
4 Copyright (C) Jeremy Allison 1996-2001
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000-2006
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_PASSDB
29 /**
30 * @todo Redefine this to NULL, but this changes the API because
31 * much of samba assumes that the pdb_get...() funtions
32 * return strings. (ie not null-pointers).
33 * See also pdb_fill_default_sam().
36 #define PDB_NOT_QUITE_NULL ""
38 /*********************************************************************
39 Collection of get...() functions for struct samu.
40 ********************************************************************/
42 uint32 pdb_get_acct_ctrl(const struct samu *sampass)
44 return sampass->acct_ctrl;
47 time_t pdb_get_logon_time(const struct samu *sampass)
49 return sampass->logon_time;
52 time_t pdb_get_logoff_time(const struct samu *sampass)
54 return sampass->logoff_time;
57 time_t pdb_get_kickoff_time(const struct samu *sampass)
59 return sampass->kickoff_time;
62 time_t pdb_get_bad_password_time(const struct samu *sampass)
64 return sampass->bad_password_time;
67 time_t pdb_get_pass_last_set_time(const struct samu *sampass)
69 return sampass->pass_last_set_time;
72 time_t pdb_get_pass_can_change_time(const struct samu *sampass)
74 uint32 allow;
76 /* if the last set time is zero, it means the user cannot
77 change their password, and this time must be zero. jmcd
79 if (sampass->pass_last_set_time == 0)
80 return (time_t) 0;
82 /* if the time is max, and the field has been changed,
83 we're trying to update this real value from the sampass
84 to indicate that the user cannot change their password. jmcd
86 if (sampass->pass_can_change_time == get_time_t_max() &&
87 pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
88 return sampass->pass_can_change_time;
90 if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
91 allow = 0;
93 /* in normal cases, just calculate it from policy */
94 return sampass->pass_last_set_time + allow;
97 /* we need this for loading from the backend, so that we don't overwrite
98 non-changed max times, otherwise the pass_can_change checking won't work */
99 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
101 return sampass->pass_can_change_time;
104 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
106 uint32 expire;
108 if (sampass->pass_last_set_time == 0)
109 return (time_t) 0;
111 if (sampass->acct_ctrl & ACB_PWNOEXP)
112 return get_time_t_max();
114 if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
115 || expire == (uint32)-1 || expire == 0)
116 return get_time_t_max();
118 return sampass->pass_last_set_time + expire;
121 bool pdb_get_pass_can_change(const struct samu *sampass)
123 if (sampass->pass_can_change_time == get_time_t_max() &&
124 sampass->pass_last_set_time != 0)
125 return False;
126 return True;
129 uint16 pdb_get_logon_divs(const struct samu *sampass)
131 return sampass->logon_divs;
134 uint32 pdb_get_hours_len(const struct samu *sampass)
136 return sampass->hours_len;
139 const uint8 *pdb_get_hours(const struct samu *sampass)
141 return (sampass->hours);
144 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
146 SMB_ASSERT((!sampass->nt_pw.data)
147 || sampass->nt_pw.length == NT_HASH_LEN);
148 return (uint8 *)sampass->nt_pw.data;
151 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
153 SMB_ASSERT((!sampass->lm_pw.data)
154 || sampass->lm_pw.length == LM_HASH_LEN);
155 return (uint8 *)sampass->lm_pw.data;
158 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32 *current_hist_len)
160 SMB_ASSERT((!sampass->nt_pw_his.data)
161 || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
162 *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
163 return (uint8 *)sampass->nt_pw_his.data;
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 struct samu *sampass)
174 return sampass->plaintext_pw;
177 const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
179 return &sampass->user_sid;
182 const DOM_SID *pdb_get_group_sid(struct samu *sampass)
184 DOM_SID *gsid;
185 struct passwd *pwd;
187 /* Return the cached group SID if we have that */
188 if ( sampass->group_sid ) {
189 return sampass->group_sid;
192 /* generate the group SID from the user's primary Unix group */
194 if ( !(gsid = TALLOC_P( sampass, DOM_SID )) ) {
195 return NULL;
198 /* No algorithmic mapping, meaning that we have to figure out the
199 primary group SID according to group mapping and the user SID must
200 be a newly allocated one. We rely on the user's Unix primary gid.
201 We have no choice but to fail if we can't find it. */
203 if ( sampass->unix_pw ) {
204 pwd = sampass->unix_pw;
205 } else {
206 pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
209 if ( !pwd ) {
210 DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
211 return NULL;
214 if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
215 enum lsa_SidType type = SID_NAME_UNKNOWN;
216 TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
217 bool lookup_ret;
219 if (!mem_ctx) {
220 return NULL;
223 /* Now check that it's actually a domain group and not something else */
225 lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
227 TALLOC_FREE( mem_ctx );
229 if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
230 sampass->group_sid = gsid;
231 return sampass->group_sid;
234 DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n",
235 pwd->pw_name, sid_type_lookup(type)));
238 /* Just set it to the 'Domain Users' RID of 512 which will
239 always resolve to a name */
241 sid_copy( gsid, get_global_sam_sid() );
242 sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
244 sampass->group_sid = gsid;
246 return sampass->group_sid;
250 * Get flags showing what is initalised in the struct samu
251 * @param sampass the struct samu in question
252 * @return the flags indicating the members initialised in the struct.
255 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
257 enum pdb_value_state ret = PDB_DEFAULT;
259 if (!sampass->change_flags || !sampass->set_flags)
260 return ret;
262 if (bitmap_query(sampass->set_flags, element)) {
263 DEBUG(11, ("element %d: SET\n", element));
264 ret = PDB_SET;
267 if (bitmap_query(sampass->change_flags, element)) {
268 DEBUG(11, ("element %d: CHANGED\n", element));
269 ret = PDB_CHANGED;
272 if (ret == PDB_DEFAULT) {
273 DEBUG(11, ("element %d: DEFAULT\n", element));
276 return ret;
279 const char *pdb_get_username(const struct samu *sampass)
281 return sampass->username;
284 const char *pdb_get_domain(const struct samu *sampass)
286 return sampass->domain;
289 const char *pdb_get_nt_username(const struct samu *sampass)
291 return sampass->nt_username;
294 const char *pdb_get_fullname(const struct samu *sampass)
296 return sampass->full_name;
299 const char *pdb_get_homedir(const struct samu *sampass)
301 return sampass->home_dir;
304 const char *pdb_get_unix_homedir(const struct samu *sampass)
306 if (sampass->unix_pw ) {
307 return sampass->unix_pw->pw_dir;
309 return NULL;
312 const char *pdb_get_dir_drive(const struct samu *sampass)
314 return sampass->dir_drive;
317 const char *pdb_get_logon_script(const struct samu *sampass)
319 return sampass->logon_script;
322 const char *pdb_get_profile_path(const struct samu *sampass)
324 return sampass->profile_path;
327 const char *pdb_get_acct_desc(const struct samu *sampass)
329 return sampass->acct_desc;
332 const char *pdb_get_workstations(const struct samu *sampass)
334 return sampass->workstations;
337 const char *pdb_get_comment(const struct samu *sampass)
339 return sampass->comment;
342 const char *pdb_get_munged_dial(const struct samu *sampass)
344 return sampass->munged_dial;
347 uint16 pdb_get_bad_password_count(const struct samu *sampass)
349 return sampass->bad_password_count;
352 uint16 pdb_get_logon_count(const struct samu *sampass)
354 return sampass->logon_count;
357 uint32 pdb_get_unknown_6(const struct samu *sampass)
359 return sampass->unknown_6;
362 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
364 if (my_methods == sampass->backend_private_methods) {
365 return sampass->backend_private_data;
366 } else {
367 return NULL;
371 /*********************************************************************
372 Collection of set...() functions for struct samu.
373 ********************************************************************/
375 bool pdb_set_acct_ctrl(struct samu *sampass, uint32 acct_ctrl, enum pdb_value_state flag)
377 sampass->acct_ctrl = acct_ctrl;
378 return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
381 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
383 sampass->logon_time = mytime;
384 return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
387 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
389 sampass->logoff_time = mytime;
390 return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
393 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
395 sampass->kickoff_time = mytime;
396 return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
399 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
401 sampass->bad_password_time = mytime;
402 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
405 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
407 sampass->pass_can_change_time = mytime;
408 return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
411 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
413 sampass->pass_must_change_time = mytime;
414 return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
417 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
419 sampass->pass_last_set_time = mytime;
420 return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
423 bool pdb_set_hours_len(struct samu *sampass, uint32 len, enum pdb_value_state flag)
425 sampass->hours_len = len;
426 return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
429 bool pdb_set_logon_divs(struct samu *sampass, uint16 hours, enum pdb_value_state flag)
431 sampass->logon_divs = hours;
432 return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
436 * Set flags showing what is initalised in the struct samu
437 * @param sampass the struct samu in question
438 * @param flag The *new* flag to be set. Old flags preserved
439 * this flag is only added.
442 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
444 if (!sampass->set_flags) {
445 if ((sampass->set_flags =
446 bitmap_talloc(sampass,
447 PDB_COUNT))==NULL) {
448 DEBUG(0,("bitmap_talloc failed\n"));
449 return False;
452 if (!sampass->change_flags) {
453 if ((sampass->change_flags =
454 bitmap_talloc(sampass,
455 PDB_COUNT))==NULL) {
456 DEBUG(0,("bitmap_talloc failed\n"));
457 return False;
461 switch(value_flag) {
462 case PDB_CHANGED:
463 if (!bitmap_set(sampass->change_flags, element)) {
464 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
465 return False;
467 if (!bitmap_set(sampass->set_flags, element)) {
468 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
469 return False;
471 DEBUG(11, ("element %d -> now CHANGED\n", element));
472 break;
473 case PDB_SET:
474 if (!bitmap_clear(sampass->change_flags, element)) {
475 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
476 return False;
478 if (!bitmap_set(sampass->set_flags, element)) {
479 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
480 return False;
482 DEBUG(11, ("element %d -> now SET\n", element));
483 break;
484 case PDB_DEFAULT:
485 default:
486 if (!bitmap_clear(sampass->change_flags, element)) {
487 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
488 return False;
490 if (!bitmap_clear(sampass->set_flags, element)) {
491 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
492 return False;
494 DEBUG(11, ("element %d -> now DEFAULT\n", element));
495 break;
498 return True;
501 bool pdb_set_user_sid(struct samu *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
503 if (!u_sid)
504 return False;
506 sid_copy(&sampass->user_sid, u_sid);
508 DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
509 sid_string_dbg(&sampass->user_sid)));
511 return pdb_set_init_flags(sampass, PDB_USERSID, flag);
514 bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
516 DOM_SID new_sid;
518 if (!u_sid)
519 return False;
521 DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
522 u_sid));
524 if (!string_to_sid(&new_sid, u_sid)) {
525 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
526 return False;
529 if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
530 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
531 return False;
534 return True;
537 /********************************************************************
538 We never fill this in from a passdb backend but rather set is
539 based on the user's primary group membership. However, the
540 struct samu* is overloaded and reused in domain memship code
541 as well and built from the netr_SamInfo3 or PAC so we
542 have to allow the explicitly setting of a group SID here.
543 ********************************************************************/
545 bool pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
547 gid_t gid;
549 if (!g_sid)
550 return False;
552 if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
553 return False;
556 /* if we cannot resolve the SID to gid, then just ignore it and
557 store DOMAIN_USERS as the primary groupSID */
559 if ( sid_to_gid( g_sid, &gid ) ) {
560 sid_copy(sampass->group_sid, g_sid);
561 } else {
562 sid_copy( sampass->group_sid, get_global_sam_sid() );
563 sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
566 DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
567 sid_string_dbg(sampass->group_sid)));
569 return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
572 /*********************************************************************
573 Set the user's UNIX name.
574 ********************************************************************/
576 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
578 if (username) {
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"));
586 return False;
588 } else {
589 sampass->username = PDB_NOT_QUITE_NULL;
592 return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
595 /*********************************************************************
596 Set the domain name.
597 ********************************************************************/
599 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
601 if (domain) {
602 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
603 (sampass->domain)?(sampass->domain):"NULL"));
605 sampass->domain = talloc_strdup(sampass, domain);
607 if (!sampass->domain) {
608 DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
609 return False;
611 } else {
612 sampass->domain = PDB_NOT_QUITE_NULL;
615 return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
618 /*********************************************************************
619 Set the user's NT name.
620 ********************************************************************/
622 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
624 if (nt_username) {
625 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
626 (sampass->nt_username)?(sampass->nt_username):"NULL"));
628 sampass->nt_username = talloc_strdup(sampass, nt_username);
630 if (!sampass->nt_username) {
631 DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
632 return False;
634 } else {
635 sampass->nt_username = PDB_NOT_QUITE_NULL;
638 return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
641 /*********************************************************************
642 Set the user's full name.
643 ********************************************************************/
645 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
647 if (full_name) {
648 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
649 (sampass->full_name)?(sampass->full_name):"NULL"));
651 sampass->full_name = talloc_strdup(sampass, full_name);
653 if (!sampass->full_name) {
654 DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
655 return False;
657 } else {
658 sampass->full_name = PDB_NOT_QUITE_NULL;
661 return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
664 /*********************************************************************
665 Set the user's logon script.
666 ********************************************************************/
668 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
670 if (logon_script) {
671 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
672 (sampass->logon_script)?(sampass->logon_script):"NULL"));
674 sampass->logon_script = talloc_strdup(sampass, logon_script);
676 if (!sampass->logon_script) {
677 DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
678 return False;
680 } else {
681 sampass->logon_script = PDB_NOT_QUITE_NULL;
684 return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
687 /*********************************************************************
688 Set the user's profile path.
689 ********************************************************************/
691 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
693 if (profile_path) {
694 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
695 (sampass->profile_path)?(sampass->profile_path):"NULL"));
697 sampass->profile_path = talloc_strdup(sampass, profile_path);
699 if (!sampass->profile_path) {
700 DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
701 return False;
703 } else {
704 sampass->profile_path = PDB_NOT_QUITE_NULL;
707 return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
710 /*********************************************************************
711 Set the user's directory drive.
712 ********************************************************************/
714 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
716 if (dir_drive) {
717 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
718 (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
720 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
722 if (!sampass->dir_drive) {
723 DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
724 return False;
727 } else {
728 sampass->dir_drive = PDB_NOT_QUITE_NULL;
731 return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
734 /*********************************************************************
735 Set the user's home directory.
736 ********************************************************************/
738 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
740 if (home_dir) {
741 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
742 (sampass->home_dir)?(sampass->home_dir):"NULL"));
744 sampass->home_dir = talloc_strdup(sampass, home_dir);
746 if (!sampass->home_dir) {
747 DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
748 return False;
750 } else {
751 sampass->home_dir = PDB_NOT_QUITE_NULL;
754 return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
757 /*********************************************************************
758 Set the user's account description.
759 ********************************************************************/
761 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
763 if (acct_desc) {
764 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
766 if (!sampass->acct_desc) {
767 DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
768 return False;
770 } else {
771 sampass->acct_desc = PDB_NOT_QUITE_NULL;
774 return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
777 /*********************************************************************
778 Set the user's workstation allowed list.
779 ********************************************************************/
781 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
783 if (workstations) {
784 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
785 (sampass->workstations)?(sampass->workstations):"NULL"));
787 sampass->workstations = talloc_strdup(sampass, workstations);
789 if (!sampass->workstations) {
790 DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
791 return False;
793 } else {
794 sampass->workstations = PDB_NOT_QUITE_NULL;
797 return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
800 /*********************************************************************
801 ********************************************************************/
803 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
805 if (comment) {
806 sampass->comment = talloc_strdup(sampass, comment);
808 if (!sampass->comment) {
809 DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
810 return False;
812 } else {
813 sampass->comment = PDB_NOT_QUITE_NULL;
816 return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
819 /*********************************************************************
820 Set the user's dial string.
821 ********************************************************************/
823 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
825 if (munged_dial) {
826 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
828 if (!sampass->munged_dial) {
829 DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
830 return False;
832 } else {
833 sampass->munged_dial = PDB_NOT_QUITE_NULL;
836 return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
839 /*********************************************************************
840 Set the user's NT hash.
841 ********************************************************************/
843 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
845 data_blob_clear_free(&sampass->nt_pw);
847 if (pwd) {
848 sampass->nt_pw =
849 data_blob_talloc(sampass, pwd, NT_HASH_LEN);
850 } else {
851 sampass->nt_pw = data_blob_null;
854 return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
857 /*********************************************************************
858 Set the user's LM hash.
859 ********************************************************************/
861 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
863 data_blob_clear_free(&sampass->lm_pw);
865 /* on keep the password if we are allowing LANMAN authentication */
867 if (pwd && lp_lanman_auth() ) {
868 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
869 } else {
870 sampass->lm_pw = data_blob_null;
873 return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
876 /*********************************************************************
877 Set the user's password history hash. historyLen is the number of
878 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
879 entries to store in the history - this must match the size of the uint8 array
880 in pwd.
881 ********************************************************************/
883 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
885 if (historyLen && pwd){
886 sampass->nt_pw_his = data_blob_talloc(sampass,
887 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
888 if (!sampass->nt_pw_his.length) {
889 DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
890 return False;
892 } else {
893 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
896 return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
899 /*********************************************************************
900 Set the user's plaintext password only (base procedure, see helper
901 below)
902 ********************************************************************/
904 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
906 if (password) {
907 if (sampass->plaintext_pw!=NULL)
908 memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
910 sampass->plaintext_pw = talloc_strdup(sampass, password);
912 if (!sampass->plaintext_pw) {
913 DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
914 return False;
916 } else {
917 sampass->plaintext_pw = NULL;
920 return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
923 bool pdb_set_bad_password_count(struct samu *sampass, uint16 bad_password_count, enum pdb_value_state flag)
925 sampass->bad_password_count = bad_password_count;
926 return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
929 bool pdb_set_logon_count(struct samu *sampass, uint16 logon_count, enum pdb_value_state flag)
931 sampass->logon_count = logon_count;
932 return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
935 bool pdb_set_unknown_6(struct samu *sampass, uint32 unkn, enum pdb_value_state flag)
937 sampass->unknown_6 = unkn;
938 return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
941 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
943 if (!hours) {
944 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
945 } else {
946 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
949 return pdb_set_init_flags(sampass, PDB_HOURS, flag);
952 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data,
953 void (*free_fn)(void **),
954 const struct pdb_methods *my_methods,
955 enum pdb_value_state flag)
957 if (sampass->backend_private_data &&
958 sampass->backend_private_data_free_fn) {
959 sampass->backend_private_data_free_fn(
960 &sampass->backend_private_data);
963 sampass->backend_private_data = private_data;
964 sampass->backend_private_data_free_fn = free_fn;
965 sampass->backend_private_methods = my_methods;
967 return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
971 /* Helpful interfaces to the above */
973 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
975 return pdb_set_pass_can_change_time(sampass,
976 canchange ? 0 : get_time_t_max(),
977 PDB_CHANGED);
981 /*********************************************************************
982 Set the user's PLAINTEXT password. Used as an interface to the above.
983 Also sets the last change time to NOW.
984 ********************************************************************/
986 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
988 uchar new_lanman_p16[LM_HASH_LEN];
989 uchar new_nt_p16[NT_HASH_LEN];
991 if (!plaintext)
992 return False;
994 /* Calculate the MD4 hash (NT compatible) of the password */
995 E_md4hash(plaintext, new_nt_p16);
997 if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED))
998 return False;
1000 if (!E_deshash(plaintext, new_lanman_p16)) {
1001 /* E_deshash returns false for 'long' passwords (> 14
1002 DOS chars). This allows us to match Win2k, which
1003 does not store a LM hash for these passwords (which
1004 would reduce the effective password length to 14 */
1006 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED))
1007 return False;
1008 } else {
1009 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED))
1010 return False;
1013 if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED))
1014 return False;
1016 if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1017 return False;
1019 /* Store the password history. */
1020 if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
1021 uchar *pwhistory;
1022 uint32 pwHistLen;
1023 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1024 if (pwHistLen != 0){
1025 uint32 current_history_len;
1026 /* We need to make sure we don't have a race condition here - the
1027 account policy history length can change between when the pw_history
1028 was first loaded into the struct samu struct and now.... JRA. */
1029 pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1031 if (current_history_len != pwHistLen) {
1032 /* After closing and reopening struct samu the history
1033 values will sync up. We can't do this here. */
1035 /* current_history_len > pwHistLen is not a problem - we
1036 have more history than we need. */
1038 if (current_history_len < pwHistLen) {
1039 /* Ensure we have space for the needed history. */
1040 uchar *new_history = (uchar *)TALLOC(sampass,
1041 pwHistLen*PW_HISTORY_ENTRY_LEN);
1042 if (!new_history) {
1043 return False;
1046 /* And copy it into the new buffer. */
1047 if (current_history_len) {
1048 memcpy(new_history, pwhistory,
1049 current_history_len*PW_HISTORY_ENTRY_LEN);
1051 /* Clearing out any extra space. */
1052 memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
1053 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
1054 /* Finally replace it. */
1055 pwhistory = new_history;
1058 if (pwhistory && pwHistLen){
1059 /* Make room for the new password in the history list. */
1060 if (pwHistLen > 1) {
1061 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
1062 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
1064 /* Create the new salt as the first part of the history entry. */
1065 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
1067 /* Generate the md5 hash of the salt+new password as the second
1068 part of the history entry. */
1070 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
1071 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1072 } else {
1073 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
1075 } else {
1076 /* Set the history length to zero. */
1077 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1081 return True;
1084 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1085 uint32 pdb_build_fields_present(struct samu *sampass)
1087 /* value set to all for testing */
1088 return 0x00ffffff;