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