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