The "unknown_5" 32 bit field in the user structs is actually 2 16-bit
[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 because
32  *       much of samba assumes that the pdb_get...() funtions 
33  *       return pstrings.  (ie not null-pointers).
34  *       See also pdb_fill_default_sam().
35  */
36
37 #define PDB_NOT_QUITE_NULL ""
38
39 /*********************************************************************
40  Collection of get...() functions for SAM_ACCOUNT.
41  ********************************************************************/
42
43 uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass)
44 {
45         if (sampass)
46                 return (sampass->private.acct_ctrl);
47         else
48                 return (ACB_DISABLED);
49 }
50
51 time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass)
52 {
53         if (sampass)
54                 return (sampass->private.logon_time);
55         else
56                 return (0);
57 }
58
59 time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass)
60 {
61         if (sampass)
62                 return (sampass->private.logoff_time);
63         else
64                 return (-1);
65 }
66
67 time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass)
68 {
69         if (sampass)
70                 return (sampass->private.kickoff_time);
71         else
72                 return (-1);
73 }
74
75 time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass)
76 {
77         if (sampass)
78                 return (sampass->private.pass_last_set_time);
79         else
80                 return (-1);
81 }
82
83 time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass)
84 {
85         if (sampass)
86                 return (sampass->private.pass_can_change_time);
87         else
88                 return (-1);
89 }
90
91 time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass)
92 {
93         if (sampass)
94                 return (sampass->private.pass_must_change_time);
95         else
96                 return (-1);
97 }
98
99 uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass)
100 {
101         if (sampass)
102                 return (sampass->private.logon_divs);
103         else
104                 return (-1);
105 }
106
107 uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass)
108 {
109         if (sampass)
110                 return (sampass->private.hours_len);
111         else
112                 return (-1);
113 }
114
115 const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass)
116 {
117         if (sampass)
118                 return (sampass->private.hours);
119         else
120                 return (NULL);
121 }
122
123 const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass)
124 {
125         if (sampass) {
126                 SMB_ASSERT((!sampass->private.nt_pw.data) 
127                            || sampass->private.nt_pw.length == NT_HASH_LEN);
128                 return ((uint8*)sampass->private.nt_pw.data);
129         }
130         else
131                 return (NULL);
132 }
133
134 const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
135 {
136         if (sampass) {
137                 SMB_ASSERT((!sampass->private.lm_pw.data) 
138                            || sampass->private.lm_pw.length == LM_HASH_LEN);
139                 return ((uint8*)sampass->private.lm_pw.data);
140         }
141         else
142                 return (NULL);
143 }
144
145 /* Return the plaintext password if known.  Most of the time
146    it isn't, so don't assume anything magic about this function.
147    
148    Used to pass the plaintext to passdb backends that might 
149    want to store more than just the NTLM hashes.
150 */
151 const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass)
152 {
153         if (sampass) {
154                 return (sampass->private.plaintext_pw);
155         }
156         else
157                 return (NULL);
158 }
159 const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass)
160 {
161         if (sampass) 
162                 return &sampass->private.user_sid;
163         else
164                 return (NULL);
165 }
166
167 const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass)
168 {
169         if (sampass)
170                 return &sampass->private.group_sid;
171         else    
172                 return (NULL);
173 }       
174
175 /**
176  * Get flags showing what is initalised in the SAM_ACCOUNT
177  * @param sampass the SAM_ACCOUNT in question
178  * @return the flags indicating the members initialised in the struct.
179  **/
180  
181 enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_elements element)
182 {
183         enum pdb_value_state ret = PDB_DEFAULT;
184         
185         if (!sampass || !sampass->private.change_flags || !sampass->private.set_flags)
186                 return ret;
187                 
188         if (bitmap_query(sampass->private.set_flags, element)) {
189                 DEBUG(11, ("element %d: SET\n", element)); 
190                 ret = PDB_SET;
191         }
192                 
193         if (bitmap_query(sampass->private.change_flags, element)) {
194                 DEBUG(11, ("element %d: CHANGED\n", element)); 
195                 ret = PDB_CHANGED;
196         }
197
198         if (ret == PDB_DEFAULT) {
199                 DEBUG(11, ("element %d: DEFAULT\n", element)); 
200         }
201
202         return ret;
203 }
204
205 const char* pdb_get_username (const SAM_ACCOUNT *sampass)
206 {
207         if (sampass)
208                 return (sampass->private.username);
209         else
210                 return (NULL);
211 }
212
213 const char* pdb_get_domain (const SAM_ACCOUNT *sampass)
214 {
215         if (sampass)
216                 return (sampass->private.domain);
217         else
218                 return (NULL);
219 }
220
221 const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass)
222 {
223         if (sampass)
224                 return (sampass->private.nt_username);
225         else
226                 return (NULL);
227 }
228
229 const char* pdb_get_fullname (const SAM_ACCOUNT *sampass)
230 {
231         if (sampass)
232                 return (sampass->private.full_name);
233         else
234                 return (NULL);
235 }
236
237 const char* pdb_get_homedir (const SAM_ACCOUNT *sampass)
238 {
239         if (sampass)
240                 return (sampass->private.home_dir);
241         else
242                 return (NULL);
243 }
244
245 const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
246 {
247         if (sampass)
248                 return (sampass->private.unix_home_dir);
249         else
250                 return (NULL);
251 }
252
253 const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
254 {
255         if (sampass)
256                 return (sampass->private.dir_drive);
257         else
258                 return (NULL);
259 }
260
261 const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass)
262 {
263         if (sampass)
264                 return (sampass->private.logon_script);
265         else
266                 return (NULL);
267 }
268
269 const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass)
270 {
271         if (sampass)
272                 return (sampass->private.profile_path);
273         else
274                 return (NULL);
275 }
276
277 const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass)
278 {
279         if (sampass)
280                 return (sampass->private.acct_desc);
281         else
282                 return (NULL);
283 }
284
285 const char* pdb_get_workstations (const SAM_ACCOUNT *sampass)
286 {
287         if (sampass)
288                 return (sampass->private.workstations);
289         else
290                 return (NULL);
291 }
292
293 const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass)
294 {
295         if (sampass)
296                 return (sampass->private.unknown_str);
297         else
298                 return (NULL);
299 }
300
301 const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass)
302 {
303         if (sampass)
304                 return (sampass->private.munged_dial);
305         else
306                 return (NULL);
307 }
308
309 uint32 pdb_get_unknown_3 (const SAM_ACCOUNT *sampass)
310 {
311         if (sampass)
312                 return (sampass->private.unknown_3);
313         else
314                 return (-1);
315 }
316
317 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_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(10, ("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(11, ("element %d -> now DEFAULT\n", element)); 
506                         break;
507         }
508
509         return True;
510 }
511
512 BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid, enum pdb_value_state flag)
513 {
514         if (!sampass || !u_sid)
515                 return False;
516         
517         sid_copy(&sampass->private.user_sid, u_sid);
518
519         DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", 
520                     sid_string_static(&sampass->private.user_sid)));
521
522         return pdb_set_init_flags(sampass, PDB_USERSID, flag);
523 }
524
525 BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag)
526 {
527         DOM_SID new_sid;
528         
529         if (!sampass || !u_sid)
530                 return False;
531
532         DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
533                    u_sid));
534
535         if (!string_to_sid(&new_sid, u_sid)) { 
536                 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
537                 return False;
538         }
539          
540         if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
541                 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid));
542                 return False;
543         }
544
545         return True;
546 }
547
548 BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, DOM_SID *g_sid, enum pdb_value_state flag)
549 {
550         if (!sampass || !g_sid)
551                 return False;
552
553         sid_copy(&sampass->private.group_sid, g_sid);
554
555         DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 
556                     sid_string_static(&sampass->private.group_sid)));
557
558         return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
559 }
560
561 BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag)
562 {
563         DOM_SID new_sid;
564         if (!sampass || !g_sid)
565                 return False;
566
567         DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n",
568                    g_sid));
569
570         if (!string_to_sid(&new_sid, g_sid)) { 
571                 DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
572                 return False;
573         }
574          
575         if (!pdb_set_group_sid(sampass, &new_sid, flag)) {
576                 DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
577                 return False;
578         }
579         return True;
580 }
581
582 /*********************************************************************
583  Set the user's UNIX name.
584  ********************************************************************/
585
586 BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag)
587 {
588         if (!sampass)
589                 return False;
590  
591         if (username) { 
592                 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
593                         (sampass->private.username)?(sampass->private.username):"NULL"));
594
595                 sampass->private.username = talloc_strdup(sampass->mem_ctx, username);
596
597                 if (!sampass->private.username) {
598                         DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
599                         return False;
600                 }
601
602         } else {
603                 sampass->private.username = PDB_NOT_QUITE_NULL;
604         }
605         
606         return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
607 }
608
609 /*********************************************************************
610  Set the domain name.
611  ********************************************************************/
612
613 BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag)
614 {
615         if (!sampass)
616                 return False;
617
618         if (domain) { 
619                 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
620                         (sampass->private.domain)?(sampass->private.domain):"NULL"));
621
622                 sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain);
623
624                 if (!sampass->private.domain) {
625                         DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
626                         return False;
627                 }
628
629         } else {
630                 sampass->private.domain = PDB_NOT_QUITE_NULL;
631         }
632
633         return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
634 }
635
636 /*********************************************************************
637  Set the user's NT name.
638  ********************************************************************/
639
640 BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag)
641 {
642         if (!sampass)
643                 return False;
644
645         if (nt_username) { 
646                 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
647                         (sampass->private.nt_username)?(sampass->private.nt_username):"NULL"));
648  
649                 sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username);
650                 
651                 if (!sampass->private.nt_username) {
652                         DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
653                         return False;
654                 }
655
656         } else {
657                 sampass->private.nt_username = PDB_NOT_QUITE_NULL;
658         }
659
660         return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
661 }
662
663 /*********************************************************************
664  Set the user's full name.
665  ********************************************************************/
666
667 BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag)
668 {
669         if (!sampass)
670                 return False;
671
672         if (full_name) { 
673                 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
674                         (sampass->private.full_name)?(sampass->private.full_name):"NULL"));
675         
676                 sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name);
677
678                 if (!sampass->private.full_name) {
679                         DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
680                         return False;
681                 }
682
683         } else {
684                 sampass->private.full_name = PDB_NOT_QUITE_NULL;
685         }
686
687         return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
688 }
689
690 /*********************************************************************
691  Set the user's logon script.
692  ********************************************************************/
693
694 BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag)
695 {
696         if (!sampass)
697                 return False;
698
699         if (logon_script) { 
700                 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
701                         (sampass->private.logon_script)?(sampass->private.logon_script):"NULL"));
702  
703                 sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script);
704
705                 if (!sampass->private.logon_script) {
706                         DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
707                         return False;
708                 }
709
710         } else {
711                 sampass->private.logon_script = PDB_NOT_QUITE_NULL;
712         }
713         
714         return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
715 }
716
717 /*********************************************************************
718  Set the user's profile path.
719  ********************************************************************/
720
721 BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag)
722 {
723         if (!sampass)
724                 return False;
725
726         if (profile_path) { 
727                 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
728                         (sampass->private.profile_path)?(sampass->private.profile_path):"NULL"));
729  
730                 sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path);
731                 
732                 if (!sampass->private.profile_path) {
733                         DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
734                         return False;
735                 }
736
737         } else {
738                 sampass->private.profile_path = PDB_NOT_QUITE_NULL;
739         }
740
741         return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
742 }
743
744 /*********************************************************************
745  Set the user's directory drive.
746  ********************************************************************/
747
748 BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag)
749 {
750         if (!sampass)
751                 return False;
752
753         if (dir_drive) { 
754                 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
755                         (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL"));
756  
757                 sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive);
758                 
759                 if (!sampass->private.dir_drive) {
760                         DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
761                         return False;
762                 }
763
764         } else {
765                 sampass->private.dir_drive = PDB_NOT_QUITE_NULL;
766         }
767         
768         return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
769 }
770
771 /*********************************************************************
772  Set the user's home directory.
773  ********************************************************************/
774
775 BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag)
776 {
777         if (!sampass)
778                 return False;
779
780         if (home_dir) { 
781                 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
782                         (sampass->private.home_dir)?(sampass->private.home_dir):"NULL"));
783  
784                 sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir);
785                 
786                 if (!sampass->private.home_dir) {
787                         DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
788                         return False;
789                 }
790
791         } else {
792                 sampass->private.home_dir = PDB_NOT_QUITE_NULL;
793         }
794
795         return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
796 }
797
798 /*********************************************************************
799  Set the user's unix home directory.
800  ********************************************************************/
801
802 BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag)
803 {
804         if (!sampass)
805                 return False;
806
807         if (unix_home_dir) { 
808                 DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir,
809                         (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL"));
810  
811                 sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx, 
812                                                           unix_home_dir);
813                 
814                 if (!sampass->private.unix_home_dir) {
815                         DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
816                         return False;
817                 }
818
819         } else {
820                 sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL;
821         }
822
823         return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag);
824 }
825
826 /*********************************************************************
827  Set the user's account description.
828  ********************************************************************/
829
830 BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag)
831 {
832         if (!sampass)
833                 return False;
834
835         if (acct_desc) { 
836                 sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc);
837
838                 if (!sampass->private.acct_desc) {
839                         DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
840                         return False;
841                 }
842
843         } else {
844                 sampass->private.acct_desc = PDB_NOT_QUITE_NULL;
845         }
846
847         return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
848 }
849
850 /*********************************************************************
851  Set the user's workstation allowed list.
852  ********************************************************************/
853
854 BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag)
855 {
856         if (!sampass)
857                 return False;
858
859         if (workstations) { 
860                 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
861                         (sampass->private.workstations)?(sampass->private.workstations):"NULL"));
862  
863                 sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations);
864
865                 if (!sampass->private.workstations) {
866                         DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
867                         return False;
868                 }
869
870         } else {
871                 sampass->private.workstations = PDB_NOT_QUITE_NULL;
872         }
873
874         return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
875 }
876
877 /*********************************************************************
878  Set the user's 'unknown_str', whatever the heck this actually is...
879  ********************************************************************/
880
881 BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag)
882 {
883         if (!sampass)
884                 return False;
885
886         if (unknown_str) { 
887                 sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str);
888                 
889                 if (!sampass->private.unknown_str) {
890                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
891                         return False;
892                 }
893
894         } else {
895                 sampass->private.unknown_str = PDB_NOT_QUITE_NULL;
896         }
897
898         return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag);
899 }
900
901 /*********************************************************************
902  Set the user's dial string.
903  ********************************************************************/
904
905 BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag)
906 {
907         if (!sampass)
908                 return False;
909
910         if (munged_dial) { 
911                 sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial);
912                 
913                 if (!sampass->private.munged_dial) {
914                         DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
915                         return False;
916                 }
917
918         } else {
919                 sampass->private.munged_dial = PDB_NOT_QUITE_NULL;
920         }
921
922         return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
923 }
924
925 /*********************************************************************
926  Set the user's NT hash.
927  ********************************************************************/
928
929 BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
930 {
931         if (!sampass)
932                 return False;
933
934         data_blob_clear_free(&sampass->private.nt_pw);
935         
936         sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN);
937
938         return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
939 }
940
941 /*********************************************************************
942  Set the user's LM hash.
943  ********************************************************************/
944
945 BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
946 {
947         if (!sampass)
948                 return False;
949
950         data_blob_clear_free(&sampass->private.lm_pw);
951         
952         sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN);
953
954         return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
955 }
956
957 /*********************************************************************
958  Set the user's plaintext password only (base procedure, see helper
959  below)
960  ********************************************************************/
961
962 BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag)
963 {
964         if (!sampass)
965                 return False;
966
967         if (password) { 
968                 if (sampass->private.plaintext_pw!=NULL) 
969                         memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1);
970
971                 sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password);
972                 
973                 if (!sampass->private.plaintext_pw) {
974                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
975                         return False;
976                 }
977
978         } else {
979                 sampass->private.plaintext_pw = NULL;
980         }
981
982         return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
983 }
984
985 BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
986 {
987         if (!sampass)
988                 return False;
989
990         sampass->private.unknown_3 = unkn;
991         
992         return pdb_set_init_flags(sampass, PDB_UNKNOWN3, flag);
993 }
994
995 BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag)
996 {
997         if (!sampass)
998                 return False;
999
1000         sampass->private.bad_password_count = bad_password_count;
1001
1002         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
1003 }
1004
1005 BOOL pdb_set_logon_count(SAM_ACCOUNT *sampass, uint16 logon_count, enum pdb_value_state flag)
1006 {
1007         if (!sampass)
1008                 return False;
1009
1010         sampass->private.logon_count = logon_count;
1011
1012         return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
1013 }
1014
1015 BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
1016 {
1017         if (!sampass)
1018                 return False;
1019
1020         sampass->private.unknown_6 = unkn;
1021
1022         return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
1023 }
1024
1025 BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag)
1026 {
1027         if (!sampass)
1028                 return False;
1029
1030         if (!hours) {
1031                 memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN);
1032                 return True;
1033         }
1034         
1035         memcpy (sampass->private.hours, hours, MAX_HOURS_LEN);
1036
1037         return pdb_set_init_flags(sampass, PDB_HOURS, flag);
1038 }
1039
1040 BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data, 
1041                                    void (*free_fn)(void **), 
1042                                    const struct pdb_methods *my_methods, 
1043                                    enum pdb_value_state flag)
1044 {
1045         if (!sampass)
1046                 return False;
1047
1048 #if 0
1049         /* With this check backend_private_data_free_fn is *never* set
1050            as the methods are never set anywhere. What is this
1051            supposed to do ????
1052
1053            Volker
1054         */
1055
1056         /* does this backend 'own' this SAM_ACCOUNT? */
1057         if (my_methods != sampass->private.backend_private_methods)
1058                 return False;
1059 #endif
1060
1061         if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) {
1062                 sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data);
1063         }
1064
1065         sampass->private.backend_private_data = private_data;
1066         sampass->private.backend_private_data_free_fn = free_fn;
1067         sampass->private.backend_private_methods = my_methods;
1068
1069         return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
1070 }
1071
1072
1073 /* Helpful interfaces to the above */
1074
1075 /*********************************************************************
1076  Sets the last changed times and must change times for a normal
1077  password change.
1078  ********************************************************************/
1079
1080 BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
1081 {
1082         uint32 expire;
1083         uint32 min_age;
1084
1085         if (!sampass)
1086                 return False;
1087         
1088         if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1089                 return False;
1090
1091         if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) 
1092             || (expire==(uint32)-1)) {
1093                 if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED))
1094                         return False;
1095         } else {
1096                 if (!pdb_set_pass_must_change_time (sampass, 
1097                                                     pdb_get_pass_last_set_time(sampass)
1098                                                     + expire, PDB_CHANGED))
1099                         return False;
1100         }
1101         
1102         if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age) 
1103             || (min_age==(uint32)-1)) {
1104                 if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
1105                         return False;
1106         } else {
1107                 if (!pdb_set_pass_can_change_time (sampass, 
1108                                                     pdb_get_pass_last_set_time(sampass)
1109                                                     + min_age, PDB_CHANGED))
1110                         return False;
1111         }
1112         return True;
1113 }
1114
1115 /*********************************************************************
1116  Set the user's PLAINTEXT password.  Used as an interface to the above.
1117  Also sets the last change time to NOW.
1118  ********************************************************************/
1119
1120 BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
1121 {
1122         uchar new_lanman_p16[16];
1123         uchar new_nt_p16[16];
1124
1125         if (!sampass || !plaintext)
1126                 return False;
1127         
1128         nt_lm_owf_gen (plaintext, new_nt_p16, new_lanman_p16);
1129
1130         if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) 
1131                 return False;
1132
1133         if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) 
1134                 return False;
1135
1136         if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) 
1137                 return False;
1138
1139         if (!pdb_set_pass_changed_now (sampass))
1140                 return False;
1141
1142         return True;
1143 }