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