Fix a memleak -- Coverity ID 222
[samba.git] / source3 / passdb / pdb_get_set.c
1 /* 
2    Unix SMB/CIFS implementation.
3    struct samu 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-2006
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 3 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, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_PASSDB
28
29 /**
30  * @todo Redefine this to NULL, but this changes the API because
31  *       much of samba assumes that the pdb_get...() funtions 
32  *       return strings.  (ie not null-pointers).
33  *       See also pdb_fill_default_sam().
34  */
35
36 #define PDB_NOT_QUITE_NULL ""
37
38 /*********************************************************************
39  Collection of get...() functions for struct samu.
40  ********************************************************************/
41
42 uint32 pdb_get_acct_ctrl(const struct samu *sampass)
43 {
44         return sampass->acct_ctrl;
45 }
46
47 time_t pdb_get_logon_time(const struct samu *sampass)
48 {
49         return sampass->logon_time;
50 }
51
52 time_t pdb_get_logoff_time(const struct samu *sampass)
53 {
54         return sampass->logoff_time;
55 }
56
57 time_t pdb_get_kickoff_time(const struct samu *sampass)
58 {
59         return sampass->kickoff_time;
60 }
61
62 time_t pdb_get_bad_password_time(const struct samu *sampass)
63 {
64         return sampass->bad_password_time;
65 }
66
67 time_t pdb_get_pass_last_set_time(const struct samu *sampass)
68 {
69         return sampass->pass_last_set_time;
70 }
71
72 time_t pdb_get_pass_can_change_time(const struct samu *sampass)
73 {
74         uint32 allow;
75
76         /* if the last set time is zero, it means the user cannot 
77            change their password, and this time must be zero.   jmcd 
78         */
79         if (sampass->pass_last_set_time == 0)
80                 return (time_t) 0;
81         
82         /* if the time is max, and the field has been changed,
83            we're trying to update this real value from the sampass
84            to indicate that the user cannot change their password.  jmcd
85         */
86         if (sampass->pass_can_change_time == get_time_t_max() &&
87             pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
88                 return sampass->pass_can_change_time;
89
90         if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
91                 allow = 0;
92
93         /* in normal cases, just calculate it from policy */
94         return sampass->pass_last_set_time + allow;
95 }
96
97 /* we need this for loading from the backend, so that we don't overwrite
98    non-changed max times, otherwise the pass_can_change checking won't work */
99 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
100 {
101         return sampass->pass_can_change_time;
102 }
103
104 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
105 {
106         uint32 expire;
107
108         if (sampass->pass_last_set_time == 0)
109                 return (time_t) 0;
110
111         if (sampass->acct_ctrl & ACB_PWNOEXP)
112                 return get_time_t_max();
113
114         if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
115             || expire == (uint32)-1 || expire == 0) 
116                 return get_time_t_max();
117
118         return sampass->pass_last_set_time + expire;
119 }
120
121 bool pdb_get_pass_can_change(const struct samu *sampass)
122 {
123         if (sampass->pass_can_change_time == get_time_t_max() &&
124             sampass->pass_last_set_time != 0)
125                 return False;
126         return True;
127 }
128
129 uint16 pdb_get_logon_divs(const struct samu *sampass)
130 {
131         return sampass->logon_divs;
132 }
133
134 uint32 pdb_get_hours_len(const struct samu *sampass)
135 {
136         return sampass->hours_len;
137 }
138
139 const uint8 *pdb_get_hours(const struct samu *sampass)
140 {
141         return (sampass->hours);
142 }
143
144 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
145 {
146         SMB_ASSERT((!sampass->nt_pw.data) 
147                    || sampass->nt_pw.length == NT_HASH_LEN);
148         return (uint8 *)sampass->nt_pw.data;
149 }
150
151 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
152 {
153         SMB_ASSERT((!sampass->lm_pw.data) 
154                    || sampass->lm_pw.length == LM_HASH_LEN);
155         return (uint8 *)sampass->lm_pw.data;
156 }
157
158 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32 *current_hist_len)
159 {
160         SMB_ASSERT((!sampass->nt_pw_his.data) 
161            || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
162         *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
163         return (uint8 *)sampass->nt_pw_his.data;
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 struct samu *sampass)
173 {
174         return sampass->plaintext_pw;
175 }
176
177 const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
178 {
179         return &sampass->user_sid;
180 }
181
182 const DOM_SID *pdb_get_group_sid(struct samu *sampass)
183 {
184         DOM_SID *gsid;
185         struct passwd *pwd;
186         
187         /* Return the cached group SID if we have that */
188         if ( sampass->group_sid ) {
189                 return sampass->group_sid;
190         }
191                 
192         /* generate the group SID from the user's primary Unix group */
193         
194         if ( !(gsid  = TALLOC_P( sampass, DOM_SID )) ) {
195                 return NULL;
196         }
197         
198         /* No algorithmic mapping, meaning that we have to figure out the
199            primary group SID according to group mapping and the user SID must
200            be a newly allocated one.  We rely on the user's Unix primary gid.
201            We have no choice but to fail if we can't find it. */
202
203         if ( sampass->unix_pw ) {
204                 pwd = sampass->unix_pw;
205         } else {
206                 pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
207         }
208
209         if ( !pwd ) {
210                 DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
211                 return NULL;
212         }
213         
214         if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
215                 enum lsa_SidType type = SID_NAME_UNKNOWN;
216                 TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
217                 bool lookup_ret;
218                 
219                 if (!mem_ctx) {
220                         return NULL;
221                 }
222
223                 /* Now check that it's actually a domain group and not something else */
224
225                 lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
226
227                 TALLOC_FREE( mem_ctx );
228
229                 if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
230                         sampass->group_sid = gsid;
231                         return sampass->group_sid;
232                 }
233
234                 DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n", 
235                         pwd->pw_name, sid_type_lookup(type)));
236         }
237
238         /* Just set it to the 'Domain Users' RID of 512 which will 
239            always resolve to a name */
240                    
241         sid_copy( gsid, get_global_sam_sid() );
242         sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
243                 
244         sampass->group_sid = gsid;
245                 
246         return sampass->group_sid;
247 }       
248
249 /**
250  * Get flags showing what is initalised in the struct samu
251  * @param sampass the struct samu in question
252  * @return the flags indicating the members initialised in the struct.
253  **/
254  
255 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
256 {
257         enum pdb_value_state ret = PDB_DEFAULT;
258         
259         if (!sampass->change_flags || !sampass->set_flags)
260                 return ret;
261                 
262         if (bitmap_query(sampass->set_flags, element)) {
263                 DEBUG(11, ("element %d: SET\n", element)); 
264                 ret = PDB_SET;
265         }
266                 
267         if (bitmap_query(sampass->change_flags, element)) {
268                 DEBUG(11, ("element %d: CHANGED\n", element)); 
269                 ret = PDB_CHANGED;
270         }
271
272         if (ret == PDB_DEFAULT) {
273                 DEBUG(11, ("element %d: DEFAULT\n", element)); 
274         }
275
276         return ret;
277 }
278
279 const char *pdb_get_username(const struct samu *sampass)
280 {
281         return sampass->username;
282 }
283
284 const char *pdb_get_domain(const struct samu *sampass)
285 {
286         return sampass->domain;
287 }
288
289 const char *pdb_get_nt_username(const struct samu *sampass)
290 {
291         return sampass->nt_username;
292 }
293
294 const char *pdb_get_fullname(const struct samu *sampass)
295 {
296         return sampass->full_name;
297 }
298
299 const char *pdb_get_homedir(const struct samu *sampass)
300 {
301         return sampass->home_dir;
302 }
303
304 const char *pdb_get_unix_homedir(const struct samu *sampass)
305 {
306         if (sampass->unix_pw ) {
307                 return sampass->unix_pw->pw_dir;
308         }
309         return NULL;
310 }
311
312 const char *pdb_get_dir_drive(const struct samu *sampass)
313 {
314         return sampass->dir_drive;
315 }
316
317 const char *pdb_get_logon_script(const struct samu *sampass)
318 {
319         return sampass->logon_script;
320 }
321
322 const char *pdb_get_profile_path(const struct samu *sampass)
323 {
324         return sampass->profile_path;
325 }
326
327 const char *pdb_get_acct_desc(const struct samu *sampass)
328 {
329         return sampass->acct_desc;
330 }
331
332 const char *pdb_get_workstations(const struct samu *sampass)
333 {
334         return sampass->workstations;
335 }
336
337 const char *pdb_get_comment(const struct samu *sampass)
338 {
339         return sampass->comment;
340 }
341
342 const char *pdb_get_munged_dial(const struct samu *sampass)
343 {
344         return sampass->munged_dial;
345 }
346
347 uint16 pdb_get_bad_password_count(const struct samu *sampass)
348 {
349         return sampass->bad_password_count;
350 }
351
352 uint16 pdb_get_logon_count(const struct samu *sampass)
353 {
354         return sampass->logon_count;
355 }
356
357 uint32 pdb_get_unknown_6(const struct samu *sampass)
358 {
359         return sampass->unknown_6;
360 }
361
362 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
363 {
364         if (my_methods == sampass->backend_private_methods) {
365                 return sampass->backend_private_data;
366         } else {
367                 return NULL;
368         }
369 }
370
371 /*********************************************************************
372  Collection of set...() functions for struct samu.
373  ********************************************************************/
374
375 bool pdb_set_acct_ctrl(struct samu *sampass, uint32 acct_ctrl, enum pdb_value_state flag)
376 {
377         sampass->acct_ctrl = acct_ctrl;
378         return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
379 }
380
381 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
382 {
383         sampass->logon_time = mytime;
384         return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
385 }
386
387 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
388 {
389         sampass->logoff_time = mytime;
390         return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
391 }
392
393 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
394 {
395         sampass->kickoff_time = mytime;
396         return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
397 }
398
399 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
400 {
401         sampass->bad_password_time = mytime;
402         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
403 }
404
405 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
406 {
407         sampass->pass_can_change_time = mytime;
408         return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
409 }
410
411 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
412 {
413         sampass->pass_must_change_time = mytime;
414         return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
415 }
416
417 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
418 {
419         sampass->pass_last_set_time = mytime;
420         return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
421 }
422
423 bool pdb_set_hours_len(struct samu *sampass, uint32 len, enum pdb_value_state flag)
424 {
425         sampass->hours_len = len;
426         return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
427 }
428
429 bool pdb_set_logon_divs(struct samu *sampass, uint16 hours, enum pdb_value_state flag)
430 {
431         sampass->logon_divs = hours;
432         return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
433 }
434
435 /**
436  * Set flags showing what is initalised in the struct samu
437  * @param sampass the struct samu in question
438  * @param flag The *new* flag to be set.  Old flags preserved
439  *             this flag is only added.  
440  **/
441  
442 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
443 {
444         if (!sampass->set_flags) {
445                 if ((sampass->set_flags = 
446                         bitmap_talloc(sampass, 
447                                         PDB_COUNT))==NULL) {
448                         DEBUG(0,("bitmap_talloc failed\n"));
449                         return False;
450                 }
451         }
452         if (!sampass->change_flags) {
453                 if ((sampass->change_flags = 
454                         bitmap_talloc(sampass, 
455                                         PDB_COUNT))==NULL) {
456                         DEBUG(0,("bitmap_talloc failed\n"));
457                         return False;
458                 }
459         }
460         
461         switch(value_flag) {
462                 case PDB_CHANGED:
463                         if (!bitmap_set(sampass->change_flags, element)) {
464                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
465                                 return False;
466                         }
467                         if (!bitmap_set(sampass->set_flags, element)) {
468                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
469                                 return False;
470                         }
471                         DEBUG(11, ("element %d -> now CHANGED\n", element)); 
472                         break;
473                 case PDB_SET:
474                         if (!bitmap_clear(sampass->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->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 SET\n", element)); 
483                         break;
484                 case PDB_DEFAULT:
485                 default:
486                         if (!bitmap_clear(sampass->change_flags, element)) {
487                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
488                                 return False;
489                         }
490                         if (!bitmap_clear(sampass->set_flags, element)) {
491                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
492                                 return False;
493                         }
494                         DEBUG(11, ("element %d -> now DEFAULT\n", element)); 
495                         break;
496         }
497
498         return True;
499 }
500
501 bool pdb_set_user_sid(struct samu *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
502 {
503         if (!u_sid)
504                 return False;
505         
506         sid_copy(&sampass->user_sid, u_sid);
507
508         DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", 
509                     sid_string_dbg(&sampass->user_sid)));
510
511         return pdb_set_init_flags(sampass, PDB_USERSID, flag);
512 }
513
514 bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
515 {
516         DOM_SID new_sid;
517         
518         if (!u_sid)
519                 return False;
520
521         DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
522                    u_sid));
523
524         if (!string_to_sid(&new_sid, u_sid)) { 
525                 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
526                 return False;
527         }
528          
529         if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
530                 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
531                 return False;
532         }
533
534         return True;
535 }
536
537 /********************************************************************
538  We never fill this in from a passdb backend but rather set is 
539  based on the user's primary group membership.  However, the 
540  struct samu* is overloaded and reused in domain memship code 
541  as well and built from the netr_SamInfo3 or PAC so we
542  have to allow the explicitly setting of a group SID here.
543 ********************************************************************/
544
545 bool pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
546 {
547         gid_t gid;
548
549         if (!g_sid)
550                 return False;
551
552         if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
553                 return False;
554         }
555
556         /* if we cannot resolve the SID to gid, then just ignore it and 
557            store DOMAIN_USERS as the primary groupSID */
558
559         if ( sid_to_gid( g_sid, &gid ) ) {
560                 sid_copy(sampass->group_sid, g_sid);
561         } else {
562                 sid_copy( sampass->group_sid, get_global_sam_sid() );
563                 sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
564         }
565
566         DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 
567                    sid_string_dbg(sampass->group_sid)));
568
569         return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
570 }
571
572 /*********************************************************************
573  Set the user's UNIX name.
574  ********************************************************************/
575
576 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
577 {
578         if (username) { 
579                 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
580                         (sampass->username)?(sampass->username):"NULL"));
581
582                 sampass->username = talloc_strdup(sampass, username);
583
584                 if (!sampass->username) {
585                         DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
586                         return False;
587                 }
588         } else {
589                 sampass->username = PDB_NOT_QUITE_NULL;
590         }
591         
592         return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
593 }
594
595 /*********************************************************************
596  Set the domain name.
597  ********************************************************************/
598
599 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
600 {
601         if (domain) { 
602                 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
603                         (sampass->domain)?(sampass->domain):"NULL"));
604
605                 sampass->domain = talloc_strdup(sampass, domain);
606
607                 if (!sampass->domain) {
608                         DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
609                         return False;
610                 }
611         } else {
612                 sampass->domain = PDB_NOT_QUITE_NULL;
613         }
614
615         return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
616 }
617
618 /*********************************************************************
619  Set the user's NT name.
620  ********************************************************************/
621
622 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
623 {
624         if (nt_username) { 
625                 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
626                         (sampass->nt_username)?(sampass->nt_username):"NULL"));
627  
628                 sampass->nt_username = talloc_strdup(sampass, nt_username);
629                 
630                 if (!sampass->nt_username) {
631                         DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
632                         return False;
633                 }
634         } else {
635                 sampass->nt_username = PDB_NOT_QUITE_NULL;
636         }
637
638         return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
639 }
640
641 /*********************************************************************
642  Set the user's full name.
643  ********************************************************************/
644
645 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
646 {
647         if (full_name) { 
648                 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
649                         (sampass->full_name)?(sampass->full_name):"NULL"));
650         
651                 sampass->full_name = talloc_strdup(sampass, full_name);
652
653                 if (!sampass->full_name) {
654                         DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
655                         return False;
656                 }
657         } else {
658                 sampass->full_name = PDB_NOT_QUITE_NULL;
659         }
660
661         return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
662 }
663
664 /*********************************************************************
665  Set the user's logon script.
666  ********************************************************************/
667
668 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
669 {
670         if (logon_script) { 
671                 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
672                         (sampass->logon_script)?(sampass->logon_script):"NULL"));
673  
674                 sampass->logon_script = talloc_strdup(sampass, logon_script);
675
676                 if (!sampass->logon_script) {
677                         DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
678                         return False;
679                 }
680         } else {
681                 sampass->logon_script = PDB_NOT_QUITE_NULL;
682         }
683         
684         return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
685 }
686
687 /*********************************************************************
688  Set the user's profile path.
689  ********************************************************************/
690
691 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
692 {
693         if (profile_path) { 
694                 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
695                         (sampass->profile_path)?(sampass->profile_path):"NULL"));
696  
697                 sampass->profile_path = talloc_strdup(sampass, profile_path);
698                 
699                 if (!sampass->profile_path) {
700                         DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
701                         return False;
702                 }
703         } else {
704                 sampass->profile_path = PDB_NOT_QUITE_NULL;
705         }
706
707         return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
708 }
709
710 /*********************************************************************
711  Set the user's directory drive.
712  ********************************************************************/
713
714 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
715 {
716         if (dir_drive) { 
717                 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
718                         (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
719  
720                 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
721                 
722                 if (!sampass->dir_drive) {
723                         DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
724                         return False;
725                 }
726
727         } else {
728                 sampass->dir_drive = PDB_NOT_QUITE_NULL;
729         }
730         
731         return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
732 }
733
734 /*********************************************************************
735  Set the user's home directory.
736  ********************************************************************/
737
738 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
739 {
740         if (home_dir) { 
741                 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
742                         (sampass->home_dir)?(sampass->home_dir):"NULL"));
743  
744                 sampass->home_dir = talloc_strdup(sampass, home_dir);
745                 
746                 if (!sampass->home_dir) {
747                         DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
748                         return False;
749                 }
750         } else {
751                 sampass->home_dir = PDB_NOT_QUITE_NULL;
752         }
753
754         return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
755 }
756
757 /*********************************************************************
758  Set the user's account description.
759  ********************************************************************/
760
761 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
762 {
763         if (acct_desc) { 
764                 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
765
766                 if (!sampass->acct_desc) {
767                         DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
768                         return False;
769                 }
770         } else {
771                 sampass->acct_desc = PDB_NOT_QUITE_NULL;
772         }
773
774         return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
775 }
776
777 /*********************************************************************
778  Set the user's workstation allowed list.
779  ********************************************************************/
780
781 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
782 {
783         if (workstations) { 
784                 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
785                         (sampass->workstations)?(sampass->workstations):"NULL"));
786  
787                 sampass->workstations = talloc_strdup(sampass, workstations);
788
789                 if (!sampass->workstations) {
790                         DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
791                         return False;
792                 }
793         } else {
794                 sampass->workstations = PDB_NOT_QUITE_NULL;
795         }
796
797         return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
798 }
799
800 /*********************************************************************
801  ********************************************************************/
802
803 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
804 {
805         if (comment) { 
806                 sampass->comment = talloc_strdup(sampass, comment);
807                 
808                 if (!sampass->comment) {
809                         DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
810                         return False;
811                 }
812         } else {
813                 sampass->comment = PDB_NOT_QUITE_NULL;
814         }
815
816         return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
817 }
818
819 /*********************************************************************
820  Set the user's dial string.
821  ********************************************************************/
822
823 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
824 {
825         if (munged_dial) { 
826                 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
827                 
828                 if (!sampass->munged_dial) {
829                         DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
830                         return False;
831                 }
832         } else {
833                 sampass->munged_dial = PDB_NOT_QUITE_NULL;
834         }
835
836         return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
837 }
838
839 /*********************************************************************
840  Set the user's NT hash.
841  ********************************************************************/
842
843 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
844 {
845         data_blob_clear_free(&sampass->nt_pw);
846         
847        if (pwd) {
848                sampass->nt_pw =
849                        data_blob_talloc(sampass, pwd, NT_HASH_LEN);
850        } else {
851                sampass->nt_pw = data_blob_null;
852        }
853
854         return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
855 }
856
857 /*********************************************************************
858  Set the user's LM hash.
859  ********************************************************************/
860
861 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
862 {
863         data_blob_clear_free(&sampass->lm_pw);
864         
865         /* on keep the password if we are allowing LANMAN authentication */
866
867         if (pwd && lp_lanman_auth() ) {
868                 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
869         } else {
870                 sampass->lm_pw = data_blob_null;
871         }
872
873         return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
874 }
875
876 /*********************************************************************
877  Set the user's password history hash. historyLen is the number of 
878  PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
879  entries to store in the history - this must match the size of the uint8 array
880  in pwd.
881 ********************************************************************/
882
883 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
884 {
885         if (historyLen && pwd){
886                 sampass->nt_pw_his = data_blob_talloc(sampass,
887                                                 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
888                 if (!sampass->nt_pw_his.length) {
889                         DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
890                         return False;
891                 }
892         } else {
893                 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
894         }
895
896         return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
897 }
898
899 /*********************************************************************
900  Set the user's plaintext password only (base procedure, see helper
901  below)
902  ********************************************************************/
903
904 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
905 {
906         if (password) { 
907                 if (sampass->plaintext_pw!=NULL) 
908                         memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
909
910                 sampass->plaintext_pw = talloc_strdup(sampass, password);
911                 
912                 if (!sampass->plaintext_pw) {
913                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
914                         return False;
915                 }
916         } else {
917                 sampass->plaintext_pw = NULL;
918         }
919
920         return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
921 }
922
923 bool pdb_set_bad_password_count(struct samu *sampass, uint16 bad_password_count, enum pdb_value_state flag)
924 {
925         sampass->bad_password_count = bad_password_count;
926         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
927 }
928
929 bool pdb_set_logon_count(struct samu *sampass, uint16 logon_count, enum pdb_value_state flag)
930 {
931         sampass->logon_count = logon_count;
932         return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
933 }
934
935 bool pdb_set_unknown_6(struct samu *sampass, uint32 unkn, enum pdb_value_state flag)
936 {
937         sampass->unknown_6 = unkn;
938         return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
939 }
940
941 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
942 {
943         if (!hours) {
944                 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
945         } else {
946                 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
947         }
948
949         return pdb_set_init_flags(sampass, PDB_HOURS, flag);
950 }
951
952 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data, 
953                                    void (*free_fn)(void **), 
954                                    const struct pdb_methods *my_methods, 
955                                    enum pdb_value_state flag)
956 {
957         if (sampass->backend_private_data &&
958             sampass->backend_private_data_free_fn) {
959                 sampass->backend_private_data_free_fn(
960                         &sampass->backend_private_data);
961         }
962
963         sampass->backend_private_data = private_data;
964         sampass->backend_private_data_free_fn = free_fn;
965         sampass->backend_private_methods = my_methods;
966
967         return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
968 }
969
970
971 /* Helpful interfaces to the above */
972
973 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
974 {
975         return pdb_set_pass_can_change_time(sampass, 
976                                      canchange ? 0 : get_time_t_max(),
977                                      PDB_CHANGED);
978 }
979
980
981 /*********************************************************************
982  Set the user's PLAINTEXT password.  Used as an interface to the above.
983  Also sets the last change time to NOW.
984  ********************************************************************/
985
986 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
987 {
988         uchar new_lanman_p16[LM_HASH_LEN];
989         uchar new_nt_p16[NT_HASH_LEN];
990
991         if (!plaintext)
992                 return False;
993
994         /* Calculate the MD4 hash (NT compatible) of the password */
995         E_md4hash(plaintext, new_nt_p16);
996
997         if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) 
998                 return False;
999
1000         if (!E_deshash(plaintext, new_lanman_p16)) {
1001                 /* E_deshash returns false for 'long' passwords (> 14
1002                    DOS chars).  This allows us to match Win2k, which
1003                    does not store a LM hash for these passwords (which
1004                    would reduce the effective password length to 14 */
1005
1006                 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) 
1007                         return False;
1008         } else {
1009                 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) 
1010                         return False;
1011         }
1012
1013         if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) 
1014                 return False;
1015
1016         if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1017                 return False;
1018
1019         /* Store the password history. */
1020         if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
1021                 uchar *pwhistory;
1022                 uint32 pwHistLen;
1023                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1024                 if (pwHistLen != 0){
1025                         uint32 current_history_len;
1026                         /* We need to make sure we don't have a race condition here - the
1027                            account policy history length can change between when the pw_history
1028                            was first loaded into the struct samu struct and now.... JRA. */
1029                         pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1030
1031                         if (current_history_len != pwHistLen) {
1032                                 /* After closing and reopening struct samu the history
1033                                         values will sync up. We can't do this here. */
1034
1035                                 /* current_history_len > pwHistLen is not a problem - we
1036                                         have more history than we need. */
1037
1038                                 if (current_history_len < pwHistLen) {
1039                                         /* Ensure we have space for the needed history. */
1040                                         uchar *new_history = (uchar *)TALLOC(sampass,
1041                                                                 pwHistLen*PW_HISTORY_ENTRY_LEN);
1042                                         if (!new_history) {
1043                                                 return False;
1044                                         }
1045
1046                                         /* And copy it into the new buffer. */
1047                                         if (current_history_len) {
1048                                                 memcpy(new_history, pwhistory,
1049                                                         current_history_len*PW_HISTORY_ENTRY_LEN);
1050                                         }
1051                                         /* Clearing out any extra space. */
1052                                         memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
1053                                                 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
1054                                         /* Finally replace it. */
1055                                         pwhistory = new_history;
1056                                 }
1057                         }
1058                         if (pwhistory && pwHistLen){
1059                                 /* Make room for the new password in the history list. */
1060                                 if (pwHistLen > 1) {
1061                                         memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
1062                                                 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
1063                                 }
1064                                 /* Create the new salt as the first part of the history entry. */
1065                                 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
1066
1067                                 /* Generate the md5 hash of the salt+new password as the second
1068                                         part of the history entry. */
1069
1070                                 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
1071                                 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1072                         } else {
1073                                 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
1074                         }
1075                 } else {
1076                         /* Set the history length to zero. */
1077                         pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1078                 }
1079         }
1080
1081         return True;
1082 }
1083
1084 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1085 uint32 pdb_build_fields_present(struct samu *sampass)
1086 {
1087         /* value set to all for testing */
1088         return 0x00ffffff;
1089 }