s3-passdb: make pdb_password_change_time_max static.
[mat/samba.git] / source3 / passdb / pdb_get_set.c
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
9
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.
14
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.
19
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/>.
22 */
23
24 #include "includes.h"
25 #include "passdb.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../libcli/security/security.h"
28 #include "../lib/util/bitmap.h"
29
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_PASSDB
32
33 /**
34  * @todo Redefine this to NULL, but this changes the API because
35  *       much of samba assumes that the pdb_get...() funtions 
36  *       return strings.  (ie not null-pointers).
37  *       See also pdb_fill_default_sam().
38  */
39
40 #define PDB_NOT_QUITE_NULL ""
41
42 /*********************************************************************
43  Test if a change time is a max value. Copes with old and new values
44  of max.
45  ********************************************************************/
46
47 bool pdb_is_password_change_time_max(time_t test_time)
48 {
49         if (test_time == get_time_t_max()) {
50                 return true;
51         }
52 #if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
53         if (test_time == 0x7FFFFFFFFFFFFFFFLL) {
54                 return true;
55         }
56 #endif
57         if (test_time == 0x7FFFFFFF) {
58                 return true;
59         }
60         return false;
61 }
62
63 /*********************************************************************
64  Return an unchanging version of max password change time - 0x7FFFFFFF.
65  ********************************************************************/
66
67 static time_t pdb_password_change_time_max(void)
68 {
69         return 0x7FFFFFFF;
70 }
71
72 /*********************************************************************
73  Collection of get...() functions for struct samu.
74  ********************************************************************/
75
76 uint32_t pdb_get_acct_ctrl(const struct samu *sampass)
77 {
78         return sampass->acct_ctrl;
79 }
80
81 time_t pdb_get_logon_time(const struct samu *sampass)
82 {
83         return sampass->logon_time;
84 }
85
86 time_t pdb_get_logoff_time(const struct samu *sampass)
87 {
88         return sampass->logoff_time;
89 }
90
91 time_t pdb_get_kickoff_time(const struct samu *sampass)
92 {
93         return sampass->kickoff_time;
94 }
95
96 time_t pdb_get_bad_password_time(const struct samu *sampass)
97 {
98         return sampass->bad_password_time;
99 }
100
101 time_t pdb_get_pass_last_set_time(const struct samu *sampass)
102 {
103         return sampass->pass_last_set_time;
104 }
105
106 time_t pdb_get_pass_can_change_time(const struct samu *sampass)
107 {
108         uint32_t allow;
109
110         /* if the last set time is zero, it means the user cannot 
111            change their password, and this time must be zero.   jmcd 
112         */
113         if (sampass->pass_last_set_time == 0)
114                 return (time_t) 0;
115
116         /* if the time is max, and the field has been changed,
117            we're trying to update this real value from the sampass
118            to indicate that the user cannot change their password.  jmcd
119         */
120         if (pdb_is_password_change_time_max(sampass->pass_can_change_time) &&
121             IS_SAM_CHANGED(sampass, PDB_CANCHANGETIME))
122                 return sampass->pass_can_change_time;
123
124         if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
125                 allow = 0;
126
127         /* in normal cases, just calculate it from policy */
128         return sampass->pass_last_set_time + allow;
129 }
130
131 /* we need this for loading from the backend, so that we don't overwrite
132    non-changed max times, otherwise the pass_can_change checking won't work */
133 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
134 {
135         return sampass->pass_can_change_time;
136 }
137
138 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
139 {
140         uint32_t expire;
141
142         if (sampass->pass_last_set_time == 0)
143                 return (time_t) 0;
144
145         if (sampass->acct_ctrl & ACB_PWNOEXP)
146                 return pdb_password_change_time_max();
147
148         if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
149             || expire == (uint32_t)-1 || expire == 0)
150                 return get_time_t_max();
151
152         return sampass->pass_last_set_time + expire;
153 }
154
155 bool pdb_get_pass_can_change(const struct samu *sampass)
156 {
157         if (pdb_is_password_change_time_max(sampass->pass_can_change_time))
158                 return False;
159         return True;
160 }
161
162 uint16_t pdb_get_logon_divs(const struct samu *sampass)
163 {
164         return sampass->logon_divs;
165 }
166
167 uint32_t pdb_get_hours_len(const struct samu *sampass)
168 {
169         return sampass->hours_len;
170 }
171
172 const uint8 *pdb_get_hours(const struct samu *sampass)
173 {
174         return (sampass->hours);
175 }
176
177 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
178 {
179         SMB_ASSERT((!sampass->nt_pw.data) 
180                    || sampass->nt_pw.length == NT_HASH_LEN);
181         return (uint8 *)sampass->nt_pw.data;
182 }
183
184 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
185 {
186         SMB_ASSERT((!sampass->lm_pw.data) 
187                    || sampass->lm_pw.length == LM_HASH_LEN);
188         return (uint8 *)sampass->lm_pw.data;
189 }
190
191 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32_t *current_hist_len)
192 {
193         SMB_ASSERT((!sampass->nt_pw_his.data) 
194            || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
195         *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
196         return (uint8 *)sampass->nt_pw_his.data;
197 }
198
199 /* Return the plaintext password if known.  Most of the time
200    it isn't, so don't assume anything magic about this function.
201
202    Used to pass the plaintext to passdb backends that might 
203    want to store more than just the NTLM hashes.
204 */
205 const char *pdb_get_plaintext_passwd(const struct samu *sampass)
206 {
207         return sampass->plaintext_pw;
208 }
209
210 const struct dom_sid *pdb_get_user_sid(const struct samu *sampass)
211 {
212         return &sampass->user_sid;
213 }
214
215 const struct dom_sid *pdb_get_group_sid(struct samu *sampass)
216 {
217         NTSTATUS status;
218
219         /* Return the cached group SID if we have that */
220         if (sampass->group_sid) {
221                 return sampass->group_sid;
222         }
223
224         /* No algorithmic mapping, meaning that we have to figure out the
225            primary group SID according to group mapping and the user SID must
226            be a newly allocated one.  We rely on the user's Unix primary gid.
227            We have no choice but to fail if we can't find it. */
228         status = get_primary_group_sid(sampass,
229                                         pdb_get_username(sampass),
230                                         &sampass->unix_pw,
231                                         &sampass->group_sid);
232         if (!NT_STATUS_IS_OK(status)) {
233                 return NULL;
234         }
235
236         return sampass->group_sid;
237 }
238
239 /**
240  * Get flags showing what is initalised in the struct samu
241  * @param sampass the struct samu in question
242  * @return the flags indicating the members initialised in the struct.
243  **/
244
245 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
246 {
247         enum pdb_value_state ret = PDB_DEFAULT;
248
249         if (!sampass->change_flags || !sampass->set_flags)
250                 return ret;
251
252         if (bitmap_query(sampass->set_flags, element)) {
253                 DEBUG(11, ("element %d: SET\n", element)); 
254                 ret = PDB_SET;
255         }
256
257         if (bitmap_query(sampass->change_flags, element)) {
258                 DEBUG(11, ("element %d: CHANGED\n", element)); 
259                 ret = PDB_CHANGED;
260         }
261
262         if (ret == PDB_DEFAULT) {
263                 DEBUG(11, ("element %d: DEFAULT\n", element)); 
264         }
265
266         return ret;
267 }
268
269 const char *pdb_get_username(const struct samu *sampass)
270 {
271         return sampass->username;
272 }
273
274 const char *pdb_get_domain(const struct samu *sampass)
275 {
276         return sampass->domain;
277 }
278
279 const char *pdb_get_nt_username(const struct samu *sampass)
280 {
281         return sampass->nt_username;
282 }
283
284 const char *pdb_get_fullname(const struct samu *sampass)
285 {
286         return sampass->full_name;
287 }
288
289 const char *pdb_get_homedir(const struct samu *sampass)
290 {
291         return sampass->home_dir;
292 }
293
294 const char *pdb_get_dir_drive(const struct samu *sampass)
295 {
296         return sampass->dir_drive;
297 }
298
299 const char *pdb_get_logon_script(const struct samu *sampass)
300 {
301         return sampass->logon_script;
302 }
303
304 const char *pdb_get_profile_path(const struct samu *sampass)
305 {
306         return sampass->profile_path;
307 }
308
309 const char *pdb_get_acct_desc(const struct samu *sampass)
310 {
311         return sampass->acct_desc;
312 }
313
314 const char *pdb_get_workstations(const struct samu *sampass)
315 {
316         return sampass->workstations;
317 }
318
319 const char *pdb_get_comment(const struct samu *sampass)
320 {
321         return sampass->comment;
322 }
323
324 const char *pdb_get_munged_dial(const struct samu *sampass)
325 {
326         return sampass->munged_dial;
327 }
328
329 uint16_t pdb_get_bad_password_count(const struct samu *sampass)
330 {
331         return sampass->bad_password_count;
332 }
333
334 uint16_t pdb_get_logon_count(const struct samu *sampass)
335 {
336         return sampass->logon_count;
337 }
338
339 uint16_t pdb_get_country_code(const struct samu *sampass)
340 {
341         return sampass->country_code;
342 }
343
344 uint16_t pdb_get_code_page(const struct samu *sampass)
345 {
346         return sampass->code_page;
347 }
348
349 uint32_t pdb_get_unknown_6(const struct samu *sampass)
350 {
351         return sampass->unknown_6;
352 }
353
354 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
355 {
356         if (my_methods == sampass->backend_private_methods) {
357                 return sampass->backend_private_data;
358         } else {
359                 return NULL;
360         }
361 }
362
363 /*********************************************************************
364  Collection of set...() functions for struct samu.
365  ********************************************************************/
366
367 bool pdb_set_acct_ctrl(struct samu *sampass, uint32_t acct_ctrl, enum pdb_value_state flag)
368 {
369         sampass->acct_ctrl = acct_ctrl;
370         return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
371 }
372
373 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
374 {
375         sampass->logon_time = mytime;
376         return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
377 }
378
379 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
380 {
381         sampass->logoff_time = mytime;
382         return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
383 }
384
385 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
386 {
387         sampass->kickoff_time = mytime;
388         return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
389 }
390
391 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
392 {
393         sampass->bad_password_time = mytime;
394         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
395 }
396
397 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
398 {
399         sampass->pass_can_change_time = mytime;
400         return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
401 }
402
403 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
404 {
405         sampass->pass_must_change_time = mytime;
406         return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
407 }
408
409 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
410 {
411         sampass->pass_last_set_time = mytime;
412         return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
413 }
414
415 bool pdb_set_hours_len(struct samu *sampass, uint32_t len, enum pdb_value_state flag)
416 {
417         sampass->hours_len = len;
418         return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
419 }
420
421 bool pdb_set_logon_divs(struct samu *sampass, uint16_t hours, enum pdb_value_state flag)
422 {
423         sampass->logon_divs = hours;
424         return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
425 }
426
427 /**
428  * Set flags showing what is initalised in the struct samu
429  * @param sampass the struct samu in question
430  * @param flag The *new* flag to be set.  Old flags preserved
431  *             this flag is only added.  
432  **/
433
434 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
435 {
436         if (!sampass->set_flags) {
437                 if ((sampass->set_flags = 
438                         bitmap_talloc(sampass, 
439                                         PDB_COUNT))==NULL) {
440                         DEBUG(0,("bitmap_talloc failed\n"));
441                         return False;
442                 }
443         }
444         if (!sampass->change_flags) {
445                 if ((sampass->change_flags = 
446                         bitmap_talloc(sampass, 
447                                         PDB_COUNT))==NULL) {
448                         DEBUG(0,("bitmap_talloc failed\n"));
449                         return False;
450                 }
451         }
452
453         switch(value_flag) {
454                 case PDB_CHANGED:
455                         if (!bitmap_set(sampass->change_flags, element)) {
456                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
457                                 return False;
458                         }
459                         if (!bitmap_set(sampass->set_flags, element)) {
460                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
461                                 return False;
462                         }
463                         DEBUG(11, ("element %d -> now CHANGED\n", element)); 
464                         break;
465                 case PDB_SET:
466                         if (!bitmap_clear(sampass->change_flags, element)) {
467                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
468                                 return False;
469                         }
470                         if (!bitmap_set(sampass->set_flags, element)) {
471                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
472                                 return False;
473                         }
474                         DEBUG(11, ("element %d -> now SET\n", element)); 
475                         break;
476                 case PDB_DEFAULT:
477                 default:
478                         if (!bitmap_clear(sampass->change_flags, element)) {
479                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
480                                 return False;
481                         }
482                         if (!bitmap_clear(sampass->set_flags, element)) {
483                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
484                                 return False;
485                         }
486                         DEBUG(11, ("element %d -> now DEFAULT\n", element)); 
487                         break;
488         }
489
490         return True;
491 }
492
493 bool pdb_set_user_sid(struct samu *sampass, const struct dom_sid *u_sid, enum pdb_value_state flag)
494 {
495         if (!u_sid)
496                 return False;
497
498         sid_copy(&sampass->user_sid, u_sid);
499
500         DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", 
501                     sid_string_dbg(&sampass->user_sid)));
502
503         return pdb_set_init_flags(sampass, PDB_USERSID, flag);
504 }
505
506 bool pdb_set_user_sid_from_string(struct samu *sampass, const char *u_sid, enum pdb_value_state flag)
507 {
508         struct dom_sid new_sid;
509
510         if (!u_sid)
511                 return False;
512
513         DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
514                    u_sid));
515
516         if (!string_to_sid(&new_sid, u_sid)) { 
517                 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
518                 return False;
519         }
520
521         if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
522                 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
523                 return False;
524         }
525
526         return True;
527 }
528
529 /********************************************************************
530  We never fill this in from a passdb backend but rather set is 
531  based on the user's primary group membership.  However, the 
532  struct samu* is overloaded and reused in domain memship code 
533  as well and built from the netr_SamInfo3 or PAC so we
534  have to allow the explicitly setting of a group SID here.
535 ********************************************************************/
536
537 bool pdb_set_group_sid(struct samu *sampass, const struct dom_sid *g_sid, enum pdb_value_state flag)
538 {
539         gid_t gid;
540         struct dom_sid dug_sid;
541
542         if (!g_sid)
543                 return False;
544
545         if ( !(sampass->group_sid = talloc( sampass, struct dom_sid )) ) {
546                 return False;
547         }
548
549         /* if we cannot resolve the SID to gid, then just ignore it and 
550            store DOMAIN_USERS as the primary groupSID */
551
552         sid_compose(&dug_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
553
554         if (dom_sid_equal(&dug_sid, g_sid)) {
555                 sid_copy(sampass->group_sid, &dug_sid);
556         } else if (sid_to_gid( g_sid, &gid ) ) {
557                 sid_copy(sampass->group_sid, g_sid);
558         } else {
559                 sid_copy(sampass->group_sid, &dug_sid);
560         }
561
562         DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 
563                    sid_string_dbg(sampass->group_sid)));
564
565         return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
566 }
567
568 /*********************************************************************
569  Set the user's UNIX name.
570  ********************************************************************/
571
572 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
573 {
574         if (username) { 
575                 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
576                         (sampass->username)?(sampass->username):"NULL"));
577
578                 sampass->username = talloc_strdup(sampass, username);
579
580                 if (!sampass->username) {
581                         DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
582                         return False;
583                 }
584         } else {
585                 sampass->username = PDB_NOT_QUITE_NULL;
586         }
587
588         return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
589 }
590
591 /*********************************************************************
592  Set the domain name.
593  ********************************************************************/
594
595 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
596 {
597         if (domain) { 
598                 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
599                         (sampass->domain)?(sampass->domain):"NULL"));
600
601                 sampass->domain = talloc_strdup(sampass, domain);
602
603                 if (!sampass->domain) {
604                         DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
605                         return False;
606                 }
607         } else {
608                 sampass->domain = PDB_NOT_QUITE_NULL;
609         }
610
611         return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
612 }
613
614 /*********************************************************************
615  Set the user's NT name.
616  ********************************************************************/
617
618 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
619 {
620         if (nt_username) { 
621                 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
622                         (sampass->nt_username)?(sampass->nt_username):"NULL"));
623  
624                 sampass->nt_username = talloc_strdup(sampass, nt_username);
625
626                 if (!sampass->nt_username) {
627                         DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
628                         return False;
629                 }
630         } else {
631                 sampass->nt_username = PDB_NOT_QUITE_NULL;
632         }
633
634         return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
635 }
636
637 /*********************************************************************
638  Set the user's full name.
639  ********************************************************************/
640
641 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
642 {
643         if (full_name) { 
644                 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
645                         (sampass->full_name)?(sampass->full_name):"NULL"));
646
647                 sampass->full_name = talloc_strdup(sampass, full_name);
648
649                 if (!sampass->full_name) {
650                         DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
651                         return False;
652                 }
653         } else {
654                 sampass->full_name = PDB_NOT_QUITE_NULL;
655         }
656
657         return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
658 }
659
660 /*********************************************************************
661  Set the user's logon script.
662  ********************************************************************/
663
664 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
665 {
666         if (logon_script) { 
667                 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
668                         (sampass->logon_script)?(sampass->logon_script):"NULL"));
669
670                 sampass->logon_script = talloc_strdup(sampass, logon_script);
671
672                 if (!sampass->logon_script) {
673                         DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
674                         return False;
675                 }
676         } else {
677                 sampass->logon_script = PDB_NOT_QUITE_NULL;
678         }
679
680         return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
681 }
682
683 /*********************************************************************
684  Set the user's profile path.
685  ********************************************************************/
686
687 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
688 {
689         if (profile_path) { 
690                 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
691                         (sampass->profile_path)?(sampass->profile_path):"NULL"));
692
693                 sampass->profile_path = talloc_strdup(sampass, profile_path);
694
695                 if (!sampass->profile_path) {
696                         DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
697                         return False;
698                 }
699         } else {
700                 sampass->profile_path = PDB_NOT_QUITE_NULL;
701         }
702
703         return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
704 }
705
706 /*********************************************************************
707  Set the user's directory drive.
708  ********************************************************************/
709
710 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
711 {
712         if (dir_drive) { 
713                 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
714                         (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
715
716                 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
717
718                 if (!sampass->dir_drive) {
719                         DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
720                         return False;
721                 }
722
723         } else {
724                 sampass->dir_drive = PDB_NOT_QUITE_NULL;
725         }
726
727         return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
728 }
729
730 /*********************************************************************
731  Set the user's home directory.
732  ********************************************************************/
733
734 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
735 {
736         if (home_dir) { 
737                 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
738                         (sampass->home_dir)?(sampass->home_dir):"NULL"));
739
740                 sampass->home_dir = talloc_strdup(sampass, home_dir);
741
742                 if (!sampass->home_dir) {
743                         DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
744                         return False;
745                 }
746         } else {
747                 sampass->home_dir = PDB_NOT_QUITE_NULL;
748         }
749
750         return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
751 }
752
753 /*********************************************************************
754  Set the user's account description.
755  ********************************************************************/
756
757 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
758 {
759         if (acct_desc) { 
760                 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
761
762                 if (!sampass->acct_desc) {
763                         DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
764                         return False;
765                 }
766         } else {
767                 sampass->acct_desc = PDB_NOT_QUITE_NULL;
768         }
769
770         return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
771 }
772
773 /*********************************************************************
774  Set the user's workstation allowed list.
775  ********************************************************************/
776
777 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
778 {
779         if (workstations) { 
780                 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
781                         (sampass->workstations)?(sampass->workstations):"NULL"));
782
783                 sampass->workstations = talloc_strdup(sampass, workstations);
784
785                 if (!sampass->workstations) {
786                         DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
787                         return False;
788                 }
789         } else {
790                 sampass->workstations = PDB_NOT_QUITE_NULL;
791         }
792
793         return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
794 }
795
796 /*********************************************************************
797  ********************************************************************/
798
799 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
800 {
801         if (comment) { 
802                 sampass->comment = talloc_strdup(sampass, comment);
803
804                 if (!sampass->comment) {
805                         DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
806                         return False;
807                 }
808         } else {
809                 sampass->comment = PDB_NOT_QUITE_NULL;
810         }
811
812         return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
813 }
814
815 /*********************************************************************
816  Set the user's dial string.
817  ********************************************************************/
818
819 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
820 {
821         if (munged_dial) { 
822                 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
823
824                 if (!sampass->munged_dial) {
825                         DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
826                         return False;
827                 }
828         } else {
829                 sampass->munged_dial = PDB_NOT_QUITE_NULL;
830         }
831
832         return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
833 }
834
835 /*********************************************************************
836  Set the user's NT hash.
837  ********************************************************************/
838
839 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
840 {
841         data_blob_clear_free(&sampass->nt_pw);
842
843        if (pwd) {
844                sampass->nt_pw =
845                        data_blob_talloc(sampass, pwd, NT_HASH_LEN);
846        } else {
847                sampass->nt_pw = data_blob_null;
848        }
849
850         return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
851 }
852
853 /*********************************************************************
854  Set the user's LM hash.
855  ********************************************************************/
856
857 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
858 {
859         data_blob_clear_free(&sampass->lm_pw);
860
861         /* on keep the password if we are allowing LANMAN authentication */
862
863         if (pwd && lp_lanman_auth() ) {
864                 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
865         } else {
866                 sampass->lm_pw = data_blob_null;
867         }
868
869         return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
870 }
871
872 /*********************************************************************
873  Set the user's password history hash. historyLen is the number of 
874  PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
875  entries to store in the history - this must match the size of the uint8 array
876  in pwd.
877 ********************************************************************/
878
879 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32_t historyLen, enum pdb_value_state flag)
880 {
881         if (historyLen && pwd){
882                 data_blob_free(&(sampass->nt_pw_his));
883                 sampass->nt_pw_his = data_blob_talloc(sampass,
884                                                 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
885                 if (!sampass->nt_pw_his.length) {
886                         DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
887                         return False;
888                 }
889         } else {
890                 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
891         }
892
893         return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
894 }
895
896 /*********************************************************************
897  Set the user's plaintext password only (base procedure, see helper
898  below)
899  ********************************************************************/
900
901 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
902 {
903         if (password) { 
904                 if (sampass->plaintext_pw!=NULL) 
905                         memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
906
907                 sampass->plaintext_pw = talloc_strdup(sampass, password);
908
909                 if (!sampass->plaintext_pw) {
910                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
911                         return False;
912                 }
913         } else {
914                 sampass->plaintext_pw = NULL;
915         }
916
917         return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
918 }
919
920 bool pdb_set_bad_password_count(struct samu *sampass, uint16_t bad_password_count, enum pdb_value_state flag)
921 {
922         sampass->bad_password_count = bad_password_count;
923         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
924 }
925
926 bool pdb_set_logon_count(struct samu *sampass, uint16_t logon_count, enum pdb_value_state flag)
927 {
928         sampass->logon_count = logon_count;
929         return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
930 }
931
932 bool pdb_set_country_code(struct samu *sampass, uint16_t country_code,
933                           enum pdb_value_state flag)
934 {
935         sampass->country_code = country_code;
936         return pdb_set_init_flags(sampass, PDB_COUNTRY_CODE, flag);
937 }
938
939 bool pdb_set_code_page(struct samu *sampass, uint16_t code_page,
940                        enum pdb_value_state flag)
941 {
942         sampass->code_page = code_page;
943         return pdb_set_init_flags(sampass, PDB_CODE_PAGE, flag);
944 }
945
946 bool pdb_set_unknown_6(struct samu *sampass, uint32_t unkn, enum pdb_value_state flag)
947 {
948         sampass->unknown_6 = unkn;
949         return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
950 }
951
952 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, int hours_len,
953                    enum pdb_value_state flag)
954 {
955         if (hours_len > sizeof(sampass->hours)) {
956                 return false;
957         }
958
959         if (!hours) {
960                 memset ((char *)sampass->hours, 0, hours_len);
961         } else {
962                 memcpy (sampass->hours, hours, hours_len);
963         }
964
965         return pdb_set_init_flags(sampass, PDB_HOURS, flag);
966 }
967
968 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data, 
969                                    void (*free_fn)(void **), 
970                                    const struct pdb_methods *my_methods, 
971                                    enum pdb_value_state flag)
972 {
973         if (sampass->backend_private_data &&
974             sampass->backend_private_data_free_fn) {
975                 sampass->backend_private_data_free_fn(
976                         &sampass->backend_private_data);
977         }
978
979         sampass->backend_private_data = private_data;
980         sampass->backend_private_data_free_fn = free_fn;
981         sampass->backend_private_methods = my_methods;
982
983         return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
984 }
985
986
987 /* Helpful interfaces to the above */
988
989 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
990 {
991         return pdb_set_pass_can_change_time(sampass, 
992                                      canchange ? 0 : pdb_password_change_time_max(),
993                                      PDB_CHANGED);
994 }
995
996
997 /*********************************************************************
998  Set the user's PLAINTEXT password.  Used as an interface to the above.
999  Also sets the last change time to NOW.
1000  ********************************************************************/
1001
1002 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
1003 {
1004         uchar new_lanman_p16[LM_HASH_LEN];
1005         uchar new_nt_p16[NT_HASH_LEN];
1006         uchar *pwhistory;
1007         uint32_t pwHistLen;
1008         uint32_t current_history_len;
1009
1010         if (!plaintext)
1011                 return False;
1012
1013         /* Calculate the MD4 hash (NT compatible) of the password */
1014         E_md4hash(plaintext, new_nt_p16);
1015
1016         if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) 
1017                 return False;
1018
1019         if (!E_deshash(plaintext, new_lanman_p16)) {
1020                 /* E_deshash returns false for 'long' passwords (> 14
1021                    DOS chars).  This allows us to match Win2k, which
1022                    does not store a LM hash for these passwords (which
1023                    would reduce the effective password length to 14 */
1024
1025                 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) 
1026                         return False;
1027         } else {
1028                 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) 
1029                         return False;
1030         }
1031
1032         if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) 
1033                 return False;
1034
1035         if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1036                 return False;
1037
1038         if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
1039                 /*
1040                  * No password history for non-user accounts
1041                  */
1042                 return true;
1043         }
1044
1045         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1046
1047         if (pwHistLen == 0) {
1048                 /* Set the history length to zero. */
1049                 pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1050                 return true;
1051         }
1052
1053         /*
1054          * We need to make sure we don't have a race condition here -
1055          * the account policy history length can change between when
1056          * the pw_history was first loaded into the struct samu struct
1057          * and now.... JRA.
1058          */
1059         pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1060
1061         if ((current_history_len != 0) && (pwhistory == NULL)) {
1062                 DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n"));
1063                 return false;
1064         }
1065
1066         if (current_history_len < pwHistLen) {
1067                 /*
1068                  * Ensure we have space for the needed history. This
1069                  * also takes care of an account which did not have
1070                  * any history at all so far, i.e. pwhistory==NULL
1071                  */
1072                 uchar *new_history = talloc_zero_array(
1073                         sampass, uchar,
1074                         pwHistLen*PW_HISTORY_ENTRY_LEN);
1075
1076                 if (!new_history) {
1077                         return False;
1078                 }
1079
1080                 memcpy(new_history, pwhistory,
1081                        current_history_len*PW_HISTORY_ENTRY_LEN);
1082
1083                 pwhistory = new_history;
1084         }
1085
1086         /*
1087          * Make room for the new password in the history list.
1088          */
1089         if (pwHistLen > 1) {
1090                 memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory,
1091                         (pwHistLen-1)*PW_HISTORY_ENTRY_LEN );
1092         }
1093
1094         /*
1095          * Fill the salt area with 0-s: this indicates that
1096          * a plain nt hash is stored in the has area.
1097          * The old format was to store a 16 byte salt and
1098          * then an md5hash of the nt_hash concatenated with
1099          * the salt.
1100          */
1101         memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
1102
1103         /*
1104          * Store the plain nt hash in the second 16 bytes.
1105          * The old format was to store the md5 hash of
1106          * the salt+newpw.
1107          */
1108         memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN);
1109
1110         pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1111
1112         return True;
1113 }
1114
1115 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1116 uint32_t pdb_build_fields_present(struct samu *sampass)
1117 {
1118         /* value set to all for testing */
1119         return 0x00ffffff;
1120 }
1121
1122 /**********************************************************************
1123  Helper function to determine for update_sam_account whether
1124  we need LDAP modification.
1125 *********************************************************************/
1126
1127 bool pdb_element_is_changed(const struct samu *sampass,
1128                             enum pdb_elements element)
1129 {
1130         return IS_SAM_CHANGED(sampass, element);
1131 }
1132
1133 /**********************************************************************
1134  Helper function to determine for update_sam_account whether
1135  we need LDAP modification.
1136  *********************************************************************/
1137
1138 bool pdb_element_is_set_or_changed(const struct samu *sampass,
1139                                    enum pdb_elements element)
1140 {
1141         return (IS_SAM_SET(sampass, element) ||
1142                 IS_SAM_CHANGED(sampass, element));
1143 }