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