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