trying to get HEAD building again. If you want the code
[samba.git] / source / 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 void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods)
334 {
335         if (sampass && my_methods == sampass->private.backend_private_methods)
336                 return sampass->private.backend_private_data;
337         else
338                 return NULL;
339 }
340
341 /*********************************************************************
342  Collection of set...() functions for SAM_ACCOUNT.
343  ********************************************************************/
344
345 BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_state flag)
346 {
347         if (!sampass)
348                 return False;
349                 
350         sampass->private.acct_ctrl = acct_ctrl;
351
352         return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
353 }
354
355 BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
356 {
357         if (!sampass)
358                 return False;
359
360         sampass->private.logon_time = mytime;
361
362         return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
363 }
364
365 BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
366 {
367         if (!sampass)
368                 return False;
369
370         sampass->private.logoff_time = mytime;
371
372         return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
373 }
374
375 BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
376 {
377         if (!sampass)
378                 return False;
379
380         sampass->private.kickoff_time = mytime;
381
382         return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
383 }
384
385 BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
386 {
387         if (!sampass)
388                 return False;
389
390         sampass->private.pass_can_change_time = mytime;
391
392         return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
393 }
394
395 BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
396 {
397         if (!sampass)
398                 return False;
399
400         sampass->private.pass_must_change_time = mytime;
401
402         return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
403 }
404
405 BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
406 {
407         if (!sampass)
408                 return False;
409
410         sampass->private.pass_last_set_time = mytime;
411
412         return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
413 }
414
415 BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state flag)
416 {
417         if (!sampass)
418                 return False;
419
420         sampass->private.hours_len = len;
421
422         return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
423 }
424
425 BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_state flag)
426 {
427         if (!sampass)
428                 return False;
429
430         sampass->private.logon_divs = hours;
431
432         return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
433 }
434
435 /**
436  * Set flags showing what is initalised in the SAM_ACCOUNT
437  * @param sampass the SAM_ACCOUNT in question
438  * @param flag The *new* flag to be set.  Old flags preserved
439  *             this flag is only added.  
440  **/
441  
442 BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
443 {
444         if (!sampass || !sampass->mem_ctx)
445                 return False;
446
447         if (!sampass->private.set_flags) {
448                 if ((sampass->private.set_flags = 
449                         bitmap_talloc(sampass->mem_ctx, 
450                                         PDB_COUNT))==NULL) {
451                         DEBUG(0,("bitmap_talloc failed\n"));
452                         return False;
453                 }
454         }
455         if (!sampass->private.change_flags) {
456                 if ((sampass->private.change_flags = 
457                         bitmap_talloc(sampass->mem_ctx, 
458                                         PDB_COUNT))==NULL) {
459                         DEBUG(0,("bitmap_talloc failed\n"));
460                         return False;
461                 }
462         }
463         
464         switch(value_flag) {
465                 case PDB_CHANGED:
466                         if (!bitmap_set(sampass->private.change_flags, element)) {
467                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
468                                 return False;
469                         }
470                         if (!bitmap_set(sampass->private.set_flags, element)) {
471                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
472                                 return False;
473                         }
474                         DEBUG(11, ("element %d -> now CHANGED\n", element)); 
475                         break;
476                 case PDB_SET:
477                         if (!bitmap_clear(sampass->private.change_flags, element)) {
478                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
479                                 return False;
480                         }
481                         if (!bitmap_set(sampass->private.set_flags, element)) {
482                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
483                                 return False;
484                         }
485                         DEBUG(10, ("element %d -> now SET\n", element)); 
486                         break;
487                 case PDB_DEFAULT:
488                 default:
489                         if (!bitmap_clear(sampass->private.change_flags, element)) {
490                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
491                                 return False;
492                         }
493                         if (!bitmap_clear(sampass->private.set_flags, element)) {
494                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
495                                 return False;
496                         }
497                         DEBUG(11, ("element %d -> now DEFAULT\n", element)); 
498                         break;
499         }
500
501         return True;
502 }
503
504 BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid, enum pdb_value_state flag)
505 {
506         if (!sampass || !u_sid)
507                 return False;
508         
509         sid_copy(&sampass->private.user_sid, u_sid);
510
511         DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", 
512                     sid_string_static(&sampass->private.user_sid)));
513
514         return pdb_set_init_flags(sampass, PDB_USERSID, flag);
515 }
516
517 BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag)
518 {
519         DOM_SID new_sid;
520         
521         if (!sampass || !u_sid)
522                 return False;
523
524         DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
525                    u_sid));
526
527         if (!string_to_sid(&new_sid, u_sid)) { 
528                 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
529                 return False;
530         }
531          
532         if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
533                 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid));
534                 return False;
535         }
536
537         return True;
538 }
539
540 BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, DOM_SID *g_sid, enum pdb_value_state flag)
541 {
542         if (!sampass || !g_sid)
543                 return False;
544
545         sid_copy(&sampass->private.group_sid, g_sid);
546
547         DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 
548                     sid_string_static(&sampass->private.group_sid)));
549
550         return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
551 }
552
553 BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag)
554 {
555         DOM_SID new_sid;
556         if (!sampass || !g_sid)
557                 return False;
558
559         DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n",
560                    g_sid));
561
562         if (!string_to_sid(&new_sid, g_sid)) { 
563                 DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
564                 return False;
565         }
566          
567         if (!pdb_set_group_sid(sampass, &new_sid, flag)) {
568                 DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
569                 return False;
570         }
571         return True;
572 }
573
574 /*********************************************************************
575  Set the user's UNIX name.
576  ********************************************************************/
577
578 BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag)
579 {
580         if (!sampass)
581                 return False;
582  
583         if (username) { 
584                 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
585                         (sampass->private.username)?(sampass->private.username):"NULL"));
586
587                 sampass->private.username = talloc_strdup(sampass->mem_ctx, username);
588
589                 if (!sampass->private.username) {
590                         DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
591                         return False;
592                 }
593
594         } else {
595                 sampass->private.username = PDB_NOT_QUITE_NULL;
596         }
597         
598         return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
599 }
600
601 /*********************************************************************
602  Set the domain name.
603  ********************************************************************/
604
605 BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag)
606 {
607         if (!sampass)
608                 return False;
609
610         if (domain) { 
611                 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
612                         (sampass->private.domain)?(sampass->private.domain):"NULL"));
613
614                 sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain);
615
616                 if (!sampass->private.domain) {
617                         DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
618                         return False;
619                 }
620
621         } else {
622                 sampass->private.domain = PDB_NOT_QUITE_NULL;
623         }
624
625         return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
626 }
627
628 /*********************************************************************
629  Set the user's NT name.
630  ********************************************************************/
631
632 BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag)
633 {
634         if (!sampass)
635                 return False;
636
637         if (nt_username) { 
638                 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
639                         (sampass->private.nt_username)?(sampass->private.nt_username):"NULL"));
640  
641                 sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username);
642                 
643                 if (!sampass->private.nt_username) {
644                         DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
645                         return False;
646                 }
647
648         } else {
649                 sampass->private.nt_username = PDB_NOT_QUITE_NULL;
650         }
651
652         return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
653 }
654
655 /*********************************************************************
656  Set the user's full name.
657  ********************************************************************/
658
659 BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag)
660 {
661         if (!sampass)
662                 return False;
663
664         if (full_name) { 
665                 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
666                         (sampass->private.full_name)?(sampass->private.full_name):"NULL"));
667         
668                 sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name);
669
670                 if (!sampass->private.full_name) {
671                         DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
672                         return False;
673                 }
674
675         } else {
676                 sampass->private.full_name = PDB_NOT_QUITE_NULL;
677         }
678
679         return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
680 }
681
682 /*********************************************************************
683  Set the user's logon script.
684  ********************************************************************/
685
686 BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag)
687 {
688         if (!sampass)
689                 return False;
690
691         if (logon_script) { 
692                 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
693                         (sampass->private.logon_script)?(sampass->private.logon_script):"NULL"));
694  
695                 sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script);
696
697                 if (!sampass->private.logon_script) {
698                         DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
699                         return False;
700                 }
701
702         } else {
703                 sampass->private.logon_script = PDB_NOT_QUITE_NULL;
704         }
705         
706         return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
707 }
708
709 /*********************************************************************
710  Set the user's profile path.
711  ********************************************************************/
712
713 BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag)
714 {
715         if (!sampass)
716                 return False;
717
718         if (profile_path) { 
719                 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
720                         (sampass->private.profile_path)?(sampass->private.profile_path):"NULL"));
721  
722                 sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path);
723                 
724                 if (!sampass->private.profile_path) {
725                         DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
726                         return False;
727                 }
728
729         } else {
730                 sampass->private.profile_path = PDB_NOT_QUITE_NULL;
731         }
732
733         return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
734 }
735
736 /*********************************************************************
737  Set the user's directory drive.
738  ********************************************************************/
739
740 BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag)
741 {
742         if (!sampass)
743                 return False;
744
745         if (dir_drive) { 
746                 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
747                         (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL"));
748  
749                 sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive);
750                 
751                 if (!sampass->private.dir_drive) {
752                         DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
753                         return False;
754                 }
755
756         } else {
757                 sampass->private.dir_drive = PDB_NOT_QUITE_NULL;
758         }
759         
760         return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
761 }
762
763 /*********************************************************************
764  Set the user's home directory.
765  ********************************************************************/
766
767 BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag)
768 {
769         if (!sampass)
770                 return False;
771
772         if (home_dir) { 
773                 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
774                         (sampass->private.home_dir)?(sampass->private.home_dir):"NULL"));
775  
776                 sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir);
777                 
778                 if (!sampass->private.home_dir) {
779                         DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
780                         return False;
781                 }
782
783         } else {
784                 sampass->private.home_dir = PDB_NOT_QUITE_NULL;
785         }
786
787         return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
788 }
789
790 /*********************************************************************
791  Set the user's unix home directory.
792  ********************************************************************/
793
794 BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag)
795 {
796         if (!sampass)
797                 return False;
798
799         if (unix_home_dir) { 
800                 DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir,
801                         (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL"));
802  
803                 sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx, 
804                                                           unix_home_dir);
805                 
806                 if (!sampass->private.unix_home_dir) {
807                         DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
808                         return False;
809                 }
810
811         } else {
812                 sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL;
813         }
814
815         return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag);
816 }
817
818 /*********************************************************************
819  Set the user's account description.
820  ********************************************************************/
821
822 BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag)
823 {
824         if (!sampass)
825                 return False;
826
827         if (acct_desc) { 
828                 sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc);
829
830                 if (!sampass->private.acct_desc) {
831                         DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
832                         return False;
833                 }
834
835         } else {
836                 sampass->private.acct_desc = PDB_NOT_QUITE_NULL;
837         }
838
839         return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
840 }
841
842 /*********************************************************************
843  Set the user's workstation allowed list.
844  ********************************************************************/
845
846 BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag)
847 {
848         if (!sampass)
849                 return False;
850
851         if (workstations) { 
852                 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
853                         (sampass->private.workstations)?(sampass->private.workstations):"NULL"));
854  
855                 sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations);
856
857                 if (!sampass->private.workstations) {
858                         DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
859                         return False;
860                 }
861
862         } else {
863                 sampass->private.workstations = PDB_NOT_QUITE_NULL;
864         }
865
866         return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
867 }
868
869 /*********************************************************************
870  Set the user's 'unknown_str', whatever the heck this actually is...
871  ********************************************************************/
872
873 BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag)
874 {
875         if (!sampass)
876                 return False;
877
878         if (unknown_str) { 
879                 sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str);
880                 
881                 if (!sampass->private.unknown_str) {
882                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
883                         return False;
884                 }
885
886         } else {
887                 sampass->private.unknown_str = PDB_NOT_QUITE_NULL;
888         }
889
890         return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag);
891 }
892
893 /*********************************************************************
894  Set the user's dial string.
895  ********************************************************************/
896
897 BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag)
898 {
899         if (!sampass)
900                 return False;
901
902         if (munged_dial) { 
903                 sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial);
904                 
905                 if (!sampass->private.munged_dial) {
906                         DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
907                         return False;
908                 }
909
910         } else {
911                 sampass->private.munged_dial = PDB_NOT_QUITE_NULL;
912         }
913
914         return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
915 }
916
917 /*********************************************************************
918  Set the user's NT hash.
919  ********************************************************************/
920
921 BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
922 {
923         if (!sampass)
924                 return False;
925
926         data_blob_clear_free(&sampass->private.nt_pw);
927         
928         sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN);
929
930         return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
931 }
932
933 /*********************************************************************
934  Set the user's LM hash.
935  ********************************************************************/
936
937 BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
938 {
939         if (!sampass)
940                 return False;
941
942         data_blob_clear_free(&sampass->private.lm_pw);
943         
944         sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN);
945
946         return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
947 }
948
949 /*********************************************************************
950  Set the user's plaintext password only (base procedure, see helper
951  below)
952  ********************************************************************/
953
954 BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag)
955 {
956         if (!sampass)
957                 return False;
958
959         if (password) { 
960                 if (sampass->private.plaintext_pw!=NULL) 
961                         memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1);
962
963                 sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password);
964                 
965                 if (!sampass->private.plaintext_pw) {
966                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
967                         return False;
968                 }
969
970         } else {
971                 sampass->private.plaintext_pw = NULL;
972         }
973
974         return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
975 }
976
977 BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
978 {
979         if (!sampass)
980                 return False;
981
982         sampass->private.unknown_3 = unkn;
983         
984         return pdb_set_init_flags(sampass, PDB_UNKNOWN3, flag);
985 }
986
987 BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
988 {
989         if (!sampass)
990                 return False;
991
992         sampass->private.unknown_5 = unkn;
993
994         return pdb_set_init_flags(sampass, PDB_UNKNOWN5, flag);
995 }
996
997 BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
998 {
999         if (!sampass)
1000                 return False;
1001
1002         sampass->private.unknown_6 = unkn;
1003
1004         return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
1005 }
1006
1007 BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag)
1008 {
1009         if (!sampass)
1010                 return False;
1011
1012         if (!hours) {
1013                 memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN);
1014                 return True;
1015         }
1016         
1017         memcpy (sampass->private.hours, hours, MAX_HOURS_LEN);
1018
1019         return pdb_set_init_flags(sampass, PDB_HOURS, flag);
1020 }
1021
1022 BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, 
1023                                    void (*free_fn)(void **), 
1024                                    const struct pdb_methods *my_methods, 
1025                                    enum pdb_value_state flag)
1026 {
1027         if (!sampass)
1028                 return False;
1029
1030         /* does this backend 'own' this SAM_ACCOUNT? */
1031         if (my_methods != sampass->private.backend_private_methods)
1032                 return False;
1033
1034         if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) {
1035                 sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data);
1036         }
1037
1038         sampass->private.backend_private_data = private_data;
1039         sampass->private.backend_private_data_free_fn = free_fn;
1040         sampass->private.backend_private_methods = my_methods;
1041
1042         return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
1043 }
1044
1045
1046 /* Helpful interfaces to the above */
1047
1048 /*********************************************************************
1049  Sets the last changed times and must change times for a normal
1050  password change.
1051  ********************************************************************/
1052
1053 BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
1054 {
1055         uint32 expire;
1056         uint32 min_age;
1057
1058         if (!sampass)
1059                 return False;
1060         
1061         if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1062                 return False;
1063
1064         if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) 
1065             || (expire==(uint32)-1)) {
1066                 if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED))
1067                         return False;
1068         } else {
1069                 if (!pdb_set_pass_must_change_time (sampass, 
1070                                                     pdb_get_pass_last_set_time(sampass)
1071                                                     + expire, PDB_CHANGED))
1072                         return False;
1073         }
1074         
1075         if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age) 
1076             || (min_age==(uint32)-1)) {
1077                 if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
1078                         return False;
1079         } else {
1080                 if (!pdb_set_pass_can_change_time (sampass, 
1081                                                     pdb_get_pass_last_set_time(sampass)
1082                                                     + min_age, PDB_CHANGED))
1083                         return False;
1084         }
1085         return True;
1086 }
1087
1088 /*********************************************************************
1089  Set the user's PLAINTEXT password.  Used as an interface to the above.
1090  Also sets the last change time to NOW.
1091  ********************************************************************/
1092
1093 BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
1094 {
1095         uchar new_lanman_p16[16];
1096         uchar new_nt_p16[16];
1097
1098         if (!sampass || !plaintext)
1099                 return False;
1100         
1101         nt_lm_owf_gen (plaintext, new_nt_p16, new_lanman_p16);
1102
1103         if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) 
1104                 return False;
1105
1106         if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) 
1107                 return False;
1108
1109         if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) 
1110                 return False;
1111
1112         if (!pdb_set_pass_changed_now (sampass))
1113                 return False;
1114
1115         return True;
1116 }