source: branches/samba-3.2.x/source/passdb/pdb_get_set.c

Last change on this file was 133, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0pre3

File size: 31.1 KB
Line 
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
42uint32 pdb_get_acct_ctrl(const struct samu *sampass)
43{
44 return sampass->acct_ctrl;
45}
46
47time_t pdb_get_logon_time(const struct samu *sampass)
48{
49 return sampass->logon_time;
50}
51
52time_t pdb_get_logoff_time(const struct samu *sampass)
53{
54 return sampass->logoff_time;
55}
56
57time_t pdb_get_kickoff_time(const struct samu *sampass)
58{
59 return sampass->kickoff_time;
60}
61
62time_t pdb_get_bad_password_time(const struct samu *sampass)
63{
64 return sampass->bad_password_time;
65}
66
67time_t pdb_get_pass_last_set_time(const struct samu *sampass)
68{
69 return sampass->pass_last_set_time;
70}
71
72time_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 */
99time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
100{
101 return sampass->pass_can_change_time;
102}
103
104time_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
121bool 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
129uint16 pdb_get_logon_divs(const struct samu *sampass)
130{
131 return sampass->logon_divs;
132}
133
134uint32 pdb_get_hours_len(const struct samu *sampass)
135{
136 return sampass->hours_len;
137}
138
139const uint8 *pdb_get_hours(const struct samu *sampass)
140{
141 return (sampass->hours);
142}
143
144const 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
151const 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
158const 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*/
172const char *pdb_get_plaintext_passwd(const struct samu *sampass)
173{
174 return sampass->plaintext_pw;
175}
176
177const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
178{
179 return &sampass->user_sid;
180}
181
182const 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
255enum 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
279const char *pdb_get_username(const struct samu *sampass)
280{
281 return sampass->username;
282}
283
284const char *pdb_get_domain(const struct samu *sampass)
285{
286 return sampass->domain;
287}
288
289const char *pdb_get_nt_username(const struct samu *sampass)
290{
291 return sampass->nt_username;
292}
293
294const char *pdb_get_fullname(const struct samu *sampass)
295{
296 return sampass->full_name;
297}
298
299const char *pdb_get_homedir(const struct samu *sampass)
300{
301 return sampass->home_dir;
302}
303
304const 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
312const char *pdb_get_dir_drive(const struct samu *sampass)
313{
314 return sampass->dir_drive;
315}
316
317const char *pdb_get_logon_script(const struct samu *sampass)
318{
319 return sampass->logon_script;
320}
321
322const char *pdb_get_profile_path(const struct samu *sampass)
323{
324 return sampass->profile_path;
325}
326
327const char *pdb_get_acct_desc(const struct samu *sampass)
328{
329 return sampass->acct_desc;
330}
331
332const char *pdb_get_workstations(const struct samu *sampass)
333{
334 return sampass->workstations;
335}
336
337const char *pdb_get_comment(const struct samu *sampass)
338{
339 return sampass->comment;
340}
341
342const char *pdb_get_munged_dial(const struct samu *sampass)
343{
344 return sampass->munged_dial;
345}
346
347uint16 pdb_get_bad_password_count(const struct samu *sampass)
348{
349 return sampass->bad_password_count;
350}
351
352uint16 pdb_get_logon_count(const struct samu *sampass)
353{
354 return sampass->logon_count;
355}
356
357uint32 pdb_get_unknown_6(const struct samu *sampass)
358{
359 return sampass->unknown_6;
360}
361
362void *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
375bool 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
381bool 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
387bool 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
393bool 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
399bool 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
405bool 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
411bool 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
417bool 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
423bool 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
429bool 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
442bool 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
501bool 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
514bool 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
545bool 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
576bool 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
599bool 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
622bool 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
645bool 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
668bool 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
691bool 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
714bool 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
738bool 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
761bool 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
781bool 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
803bool 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
823bool 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
843bool 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
861bool 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
883bool 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
904bool 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
923bool 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
929bool 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
935bool 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
941bool 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
952bool 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
973bool 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
986bool 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 */
1085uint32 pdb_build_fields_present(struct samu *sampass)
1086{
1087 /* value set to all for testing */
1088 return 0x00ffffff;
1089}
Note: See TracBrowser for help on using the repository browser.