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