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