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