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