diff options
author | Gerald Carter <jerry@samba.org> | 2000-11-21 05:55:16 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2000-11-21 05:55:16 +0000 |
commit | 0dcbafe2b97035df779f2e0742a130c4c79e3241 (patch) | |
tree | 0d556fda89c3ce7423430186618e71a5790c0359 /source3/passdb | |
parent | 2130ced345a6f3ecffe61c3622aceb8986925baa (diff) | |
download | samba-0dcbafe2b97035df779f2e0742a130c4c79e3241.tar.gz samba-0dcbafe2b97035df779f2e0742a130c4c79e3241.tar.bz2 samba-0dcbafe2b97035df779f2e0742a130c4c79e3241.zip |
Another large patch for the passdb rewrite.
o added BOOL own_memory flag in SAM_ACCOUNT so we could
use static memory for string pointer assignment or
allocate a new string
o added a reference TDB passdb backend. This is only a reference
and should not be used in production because
- RID's are generated using the same algorithm as with smbpasswd
- a TDB can only have one key (w/o getting into problems) and we
need three. Therefore the pdb_sam-getpwuid() and
pdb_getsampwrid() functions are interative searches :-(
we need transaction support, multiple indexes, and a nice open
source DBM. The Berkeley DB (from sleepycat.com seems to fit
this criteria now)
o added a new parameter "private dir" as many places in the code were
using lp_smb_passwd_file() and chopping off the filename part.
This makes more sense to me and I will docuement it in the man pages
o Ran through Insure-lite and corrected memory leaks. Need for
a public flogging this time Jeremy (-:
-- jerry
(This used to be commit 4792029a2991bd84251d152a62b1033dec62cee2)
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/passdb.c | 568 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 16 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 1015 | ||||
-rw-r--r-- | source3/passdb/secrets.c | 6 | ||||
-rw-r--r-- | source3/passdb/smbpassfile.c | 8 |
5 files changed, 867 insertions, 746 deletions
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 7b7179b1ec..217916bc98 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -36,30 +36,6 @@ extern DOM_SID global_sam_sid; extern pstring global_myname; extern fstring global_myworkgroup; -/* - * NOTE. All these functions are abstracted into a structure - * that points to the correct function for the selected database. JRA. - * - * NOTE. for the get/mod/add functions, there are two sets of functions. - * one supports struct sam_passwd, the other supports struct smb_passwd. - * for speed optimisation it is best to support both these sets. - * - * it is, however, optional to support one set but not the other: there - * is conversion-capability built in to passdb.c, and run-time error - * detection for when neither are supported. - * - * password database writers are recommended to implement the sam_passwd - * functions in a first pass, as struct sam_passwd contains more - * information, needed by the NT Domain support. - * - * a full example set of derivative functions are listed below. an API - * writer is expected to cut/paste these into their module, replace - * either one set (struct smb_passwd) or the other (struct sam_passwd) - * OR both, and optionally also to write display info routines - * (struct sam_disp_info). lkcl - * - */ - struct passdb_ops *pdb_ops; static void* pdb_handle = NULL; @@ -152,36 +128,30 @@ void pdb_init_sam(SAM_ACCOUNT *user) ***********************************************************/ void pdb_clear_sam(SAM_ACCOUNT *user) { - if (user == NULL) + /* do we have a SAM_CCOUTN struct to work with? */ + if (user == NULL) return; - /* clear all pointer members */ - if (user->username) - free(user->username); - if (user->full_name) - free(user->full_name); - if (user->home_dir) - free(user->home_dir); - if (user->dir_drive) - free(user->dir_drive); - if (user->logon_script) - free(user->logon_script); - if (user->profile_path) - free(user->profile_path); - if (user->acct_desc) - free(user->acct_desc); - if (user->workstations) - free(user->workstations); - if (user->unknown_str) - free(user->unknown_str); - if (user->munged_dial) - free(user->munged_dial); - - if (user->lm_pw) - free(user->lm_pw); - if (user->nt_pw) - free(user->nt_pw); - + /* do we own the memory? */ + if (user->own_memory) + { + /* clear all pointer members */ + if (user->username) free(user->username); + if (user->full_name) free(user->full_name); + if (user->domain) free(user->domain); + if (user->nt_username) free(user->nt_username); + if (user->home_dir) free(user->home_dir); + if (user->dir_drive) free(user->dir_drive); + if (user->logon_script) free(user->logon_script); + if (user->profile_path) free(user->profile_path); + if (user->acct_desc) free(user->acct_desc); + if (user->workstations) free(user->workstations); + if (user->unknown_str) free(user->unknown_str); + if (user->munged_dial) free(user->munged_dial); + + if (user->lm_pw) free(user->lm_pw); + if (user->nt_pw) free(user->nt_pw); + } /* now initialize */ pdb_init_sam(user); @@ -664,9 +634,9 @@ static void select_name(fstring *string, char **name, const UNISTR2 *from) } /************************************************************* - copies a sam passwd. + copies a SAM_USER_INFO_23 to a SAM_ACCOUNT **************************************************************/ -void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from) +void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) { static fstring smb_name; static fstring full_name; @@ -679,7 +649,8 @@ void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from) static fstring unknown_str; static fstring munged_dial; - if (from == NULL || to == NULL) return; + if (from == NULL || to == NULL) + return; to->logon_time = nt_time_to_unix(&from->logon_time); to->logoff_time = nt_time_to_unix(&from->logoff_time); @@ -699,14 +670,9 @@ void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from) select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str ); select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial ); - to->uid = (uid_t)-1; - to->gid = (gid_t)-1; to->user_rid = from->user_rid; to->group_rid = from->group_rid; - to->lm_pw = NULL; - to->nt_pw = NULL; - to->acct_ctrl = from->acb_info; to->unknown_3 = from->unknown_3; @@ -721,7 +687,7 @@ void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from) /************************************************************* copies a sam passwd. **************************************************************/ -void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from) +void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) { static fstring smb_name; static fstring full_name; @@ -734,7 +700,8 @@ void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from) static fstring unknown_str; static fstring munged_dial; - if (from == NULL || to == NULL) return; + if (from == NULL || to == NULL) + return; to->logon_time = nt_time_to_unix(&from->logon_time); to->logoff_time = nt_time_to_unix(&from->logoff_time); @@ -754,13 +721,11 @@ void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from) select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str ); select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial ); - to->uid = (uid_t)-1; - to->gid = (gid_t)-1; to->user_rid = from->user_rid; to->group_rid = from->group_rid; - - to->lm_pw = NULL; - to->nt_pw = NULL; + + /* FIXME!! Do we need to copy the passwords here as well? + I don't know. Need to figure this out --jerry */ to->acct_ctrl = from->acb_info; to->unknown_3 = from->unknown_3; @@ -776,13 +741,8 @@ void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from) /************************************************************* copies a sam passwd. - - FIXME! Do we need to use dynamically allocated strings - here instead of static strings? - - Why are password hashes not also copied? --jerry **************************************************************/ -void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from) +void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from) { static fstring smb_name=""; static fstring full_name=""; @@ -794,60 +754,90 @@ void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from) static fstring workstations=""; static fstring unknown_str=""; static fstring munged_dial=""; + static BYTE lm_pw[16], nt_pw[16]; - if (from == NULL || to == NULL) return; + if (from == NULL || to == NULL) + return; + /* we won't own this memory so set the flag. + This will also clear the strings from 'to' */ + pdb_set_mem_ownership (to, False); + memcpy(to, from, sizeof(*from)); - if (from->username != NULL) { - fstrcpy(smb_name , from->username); + if (from->username != NULL) + { + fstrcpy(smb_name , from->username); to->username = smb_name; } - if (from->full_name != NULL) { + if (from->full_name != NULL) + { fstrcpy(full_name, from->full_name); to->full_name = full_name; } - if (from->home_dir != NULL) { - fstrcpy(home_dir , from->home_dir); + if (from->home_dir != NULL) + { + fstrcpy(home_dir, from->home_dir); to->home_dir = home_dir; } - if (from->dir_drive != NULL) { + if (from->dir_drive != NULL) + { fstrcpy(dir_drive , from->dir_drive); to->dir_drive = dir_drive; } - if (from->logon_script != NULL) { + if (from->logon_script != NULL) + { fstrcpy(logon_script , from->logon_script); to->logon_script = logon_script; } - if (from->profile_path != NULL) { + if (from->profile_path != NULL) + { fstrcpy(profile_path , from->profile_path); to->profile_path = profile_path; } - if (from->acct_desc != NULL) { + if (from->acct_desc != NULL) + { fstrcpy(acct_desc , from->acct_desc); to->acct_desc = acct_desc; } - if (from->workstations != NULL) { + if (from->workstations != NULL) + { fstrcpy(workstations , from->workstations); to->workstations = workstations; } - if (from->unknown_str != NULL) { + if (from->unknown_str != NULL) + { fstrcpy(unknown_str , from->unknown_str); to->unknown_str = unknown_str; } - if (from->munged_dial != NULL) { + if (from->munged_dial != NULL) + { fstrcpy(munged_dial , from->munged_dial); to->munged_dial = munged_dial; } + + if (from->nt_pw != NULL) + { + memcpy (nt_pw, from->nt_pw, 16); + to->nt_pw = nt_pw; + } + + if (from->lm_pw != NULL) + { + memcpy (lm_pw, from->lm_pw, 16); + to->lm_pw = lm_pw; + } + + return; } /************************************************************* @@ -901,8 +891,11 @@ account without a valid local system user.\n", user_name); return False; } - /* create the SAM_ACCOUNT struct and call pdb_add_sam_account */ + /* create the SAM_ACCOUNT struct and call pdb_add_sam_account. + Because the new_sam_pwd only exists in the scope of this function + we will not allocate memory for members */ pdb_init_sam (&new_sam_acct); + pdb_set_mem_ownership (&new_sam_acct, False); pdb_set_username (&new_sam_acct, user_name); pdb_set_uid (&new_sam_acct, pwd->pw_uid); pdb_set_pass_last_set_time(&new_sam_acct, time(NULL)); @@ -1262,8 +1255,35 @@ uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass) /********************************************************************* collection of set...() functions for SAM_ACCOUNT_INFO ********************************************************************/ + +/******************************************************************** + The purpose of this flag is to determine whether or not we + should free the memory when we are done. This allows us to + use local static variables for string (reduce the number of + malloc() calls) while still allowing for flexibility of + dynamic objects. + + We always clear the structure even if setting the flag to the + same value. + *******************************************************************/ +void pdb_set_mem_ownership (SAM_ACCOUNT *sampass, BOOL flag) +{ + /* if we have no SAM_ACCOUNT struct or no change, then done */ + if (sampass == NULL) + return; + + /* clear the struct and set the ownership flag */ + pdb_clear_sam (sampass); + sampass->own_memory = flag; + + return; +} + BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags) { + if (!sampass) + return False; + if (sampass) { sampass->acct_ctrl = flags; @@ -1275,264 +1295,360 @@ BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags) BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime) { - if (sampass) - { - sampass->logon_time = mytime; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->logon_time = mytime; + return True; } BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime) { - if (sampass) - { - sampass->logoff_time = mytime; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->logoff_time = mytime; + return True; } BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime) { - if (sampass) - { - sampass->kickoff_time = mytime; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->kickoff_time = mytime; + return True; } BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime) { - if (sampass) - { - sampass->pass_can_change_time = mytime; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->pass_can_change_time = mytime; + return True; } BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime) { - if (sampass) - { - sampass->pass_must_change_time = mytime; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->pass_must_change_time = mytime; + return True; } BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime) { - if (sampass) - { - sampass->pass_last_set_time = mytime; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->pass_last_set_time = mytime; + return True; } BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len) { - if (sampass) - { - sampass->hours_len = len; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->hours_len = len; + return True; } BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours) { - if (sampass) - { - sampass->logon_divs = hours; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->logon_divs = hours; + return True; } BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid) { - if (sampass) - { - sampass->uid = uid; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->uid = uid; + return True; } BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid) { - if (sampass) - { - sampass->gid = gid; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->gid = gid; + return True; } BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid) { - if (sampass) - { - sampass->user_rid = rid; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->user_rid = rid; + return True; } BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid) { - if (sampass) - { - sampass->group_rid = grid; - return True; - } - - return False; + if (!sampass) + return False; + + sampass->group_rid = grid; + return True; } BOOL pdb_set_username (SAM_ACCOUNT *sampass, char *username) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->username = username; + else { - sampass->username = strdup(username); - return True; + if ( (sampass->username=strdup(username)) == NULL ) + { + DEBUG (0,("pdb_set_username: ERROR - Unable to malloc memory for [%s]\n", username)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_domain (SAM_ACCOUNT *sampass, char *domain) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->domain = domain; + else { - sampass->domain = strdup(domain); - return True; + if ( (sampass->domain=strdup(domain)) == NULL ) + { + DEBUG (0,("pdb_set_domain: ERROR - Unable to malloc memory for [%s]\n", domain)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_nt_username (SAM_ACCOUNT *sampass, char *nt_username) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->nt_username = nt_username; + else { - sampass->nt_username = strdup(nt_username); - return True; + if ( (sampass->nt_username=strdup(nt_username)) == NULL ) + { + DEBUG (0,("pdb_set_nt_username: ERROR - Unable to malloc memory for [%s]\n", nt_username)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_fullname (SAM_ACCOUNT *sampass, char *fullname) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->full_name = fullname; + else { - sampass->full_name = strdup(fullname); - return True; + if ( (sampass->full_name=strdup(fullname)) == NULL ) + { + DEBUG (0,("pdb_set_fullname: ERROR - Unable to malloc memory for [%s]\n", fullname)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_logon_script (SAM_ACCOUNT *sampass, char *logon_script) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->logon_script = logon_script; + else { - sampass->logon_script = strdup(logon_script); - return True; + if ( (sampass->logon_script=strdup(logon_script)) == NULL ) + { + DEBUG (0,("pdb_set_logon_script: ERROR - Unable to malloc memory for [%s]\n", logon_script)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->profile_path = profile_path; + else { - sampass->profile_path = strdup(profile_path); - return True; + if ( (sampass->profile_path=strdup(profile_path)) == NULL ) + { + DEBUG (0,("pdb_set_profile_path: ERROR - Unable to malloc memory for [%s]\n", profile_path)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->dir_drive = dir_drive; + else { - sampass->dir_drive = strdup(dir_drive); - return True; + if ( (sampass->dir_drive=strdup(dir_drive)) == NULL ) + { + DEBUG (0,("pdb_set_dir_drive: ERROR - Unable to malloc memory for [%s]\n", dir_drive)); + return False; + } } - - return False; + + return True; } BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir) { - if (sampass) + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->home_dir = homedir; + else { - sampass->home_dir = strdup(homedir); - return True; + if ( (sampass->home_dir=strdup(homedir)) == NULL ) + { + DEBUG (0,("pdb_set_home_dir: ERROR - Unable to malloc memory for [%s]\n", homedir)); + return False; + } } - - return False; + + return True; } +BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc) +{ + if (!sampass) + return False; -BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, BYTE *pwd) + if (!sampass->own_memory) + sampass->acct_desc = acct_desc; + else + { + if ( (sampass->acct_desc=strdup(acct_desc)) == NULL ) + { + DEBUG (0,("pdb_set_acct_desc: ERROR - Unable to malloc memory for [%s]\n", acct_desc)); + return False; + } + } + + return True; +} +BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations) +{ + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->workstations = workstations; + else + { + if ( (sampass->workstations=strdup(workstations)) == NULL ) + { + DEBUG (0,("pdb_set_workstations: ERROR - Unable to malloc memory for [%s]\n", workstations)); + return False; + } + } + + return True; +} + +BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial) { + if (!sampass) + return False; + + if (!sampass->own_memory) + sampass->munged_dial = munged_dial; + else + { + if ( (sampass->munged_dial=strdup(munged_dial)) == NULL ) + { + DEBUG (0,("pdb_set_munged_dial: ERROR - Unable to malloc memory for [%s]\n", munged_dial)); + return False; + } + } + + return True; +} - if (pwd == NULL) +BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, BYTE *pwd) +{ + if ( (!sampass) ||(pwd == NULL) ) return False; - - /* allocate space for the password and make a copy of it */ - if (sampass) + + if (!sampass->own_memory) + sampass->nt_pw = pwd; + else { if ((sampass->nt_pw=(BYTE*)malloc(sizeof(BYTE)*16)) == NULL) { DEBUG(0,("pdb_set_nt_passwd: ERROR - out of memory for nt_pw!\n")); return False; } - if (memcpy(sampass->nt_pw, pwd, 16)) - return True; + if (!memcpy(sampass->nt_pw, pwd, 16)) + return False; } - return False; + return True; } BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, BYTE *pwd) { - if (pwd == NULL) + if ( (!sampass) ||(pwd == NULL) ) return False; - - /* allocate space for the password and make a copy of it */ - if (sampass) + + if (!sampass->own_memory) + sampass->lm_pw = pwd; + else { if ((sampass->lm_pw=(BYTE*)malloc(sizeof(BYTE)*16)) == NULL) { DEBUG(0,("pdb_set_lanman_passwd: ERROR - out of memory for lm_pw!\n")); return False; } - if (memcpy(sampass->lm_pw, pwd, 16)) - return True; + if (!memcpy(sampass->lm_pw, pwd, 16)) + return False; } - return False; + return True; } diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 4473dd74c0..951c97ab3c 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -1222,6 +1222,13 @@ static BOOL build_sam_account (SAM_ACCOUNT *sam_pass, struct passwd *pwfile; + if (!sam_pass) + return (False); + + /* make sure that we own the memory here--also clears + any existing members as a side effect */ + pdb_set_mem_ownership(sam_pass, True); + /* is the user valid? Verify in system password file... FIXME!!! This is where we should look up an internal @@ -1347,10 +1354,8 @@ SAM_ACCOUNT* pdb_getsampwent (void) if (pw_buf == NULL) return NULL; - /* clear out any preexisting information from the last call */ - pdb_clear_sam (&global_sam_pass); - - /* build the SAM_ACCOUNT entry from the smb_passwd struct */ + /* build the SAM_ACCOUNT entry from the smb_passwd struct. + This will also clear out the previous SAM_ACCOUNT fields */ if (!build_sam_account (&global_sam_pass, pw_buf)) return NULL; @@ -1420,7 +1425,6 @@ SAM_ACCOUNT* pdb_getsampwnam (char *username) DEBUG(10, ("found by name: %s\n", smb_pw->smb_name)); /* now build the SAM_ACCOUNT */ - pdb_clear_sam (&global_sam_pass); if (!build_sam_account (&global_sam_pass, smb_pw)) return NULL; @@ -1460,7 +1464,6 @@ SAM_ACCOUNT* pdb_getsampwuid (uid_t uid) DEBUG(10, ("found by name: %s\n", smb_pw->smb_name)); /* now build the SAM_ACCOUNT */ - pdb_clear_sam (&global_sam_pass); if (!build_sam_account (&global_sam_pass, smb_pw)) return NULL; @@ -1499,7 +1502,6 @@ SAM_ACCOUNT* pdb_getsampwrid (uint32 rid) DEBUG(10, ("found by name: %s\n", smb_pw->smb_name)); /* now build the SAM_ACCOUNT */ - pdb_clear_sam (&global_sam_pass); if (!build_sam_account (&global_sam_pass, smb_pw)) return NULL; diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 29f1b119ae..e997d6c318 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -22,577 +22,586 @@ #ifdef WITH_TDBPWD -#define lp_tdb_passwd_file lp_smb_passwd_file -#define tdb_writelock(ptr) -#define tdb_writeunlock(ptr) +#define TDB_FORMAT_STRING "ddddddfffPPfPPPPffddBBwdwdBdd" +#define USERPREFIX "USER_" -extern int DEBUGLEVEL; -extern pstring samlogon_user; -extern BOOL sam_logon_in_ssb; +extern int DEBUGLEVEL; +extern pstring samlogon_user; +extern BOOL sam_logon_in_ssb; -#if 0 /* GWC */ -struct tdb_sam_entry + +struct tdb_enum_info { - time_t logon_time; /* logon time */ - time_t logoff_time; /* logoff time */ - time_t kickoff_time; /* kickoff time */ - time_t pass_last_set_time; /* password last set time */ - time_t pass_can_change_time; /* password can change time */ - time_t pass_must_change_time; /* password must change time */ - - uid_t smb_userid; /* this is actually the unix uid_t */ - gid_t smb_grpid; /* this is actually the unix gid_t */ - uint32 user_rid; /* Primary User ID */ - uint32 group_rid; /* Primary Group ID */ - - char smb_passwd[33]; /* Null if no password */ - char smb_nt_passwd[33]; /* Null if no password */ - - uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ - uint32 unknown_3; /* 0x00ff ffff */ - - uint16 logon_divs; /* 168 - number of hours in a week */ - uint32 hours_len; /* normally 21 bytes */ - uint8 hours[MAX_HOURS_LEN]; - - uint32 unknown_5; /* 0x0002 0000 */ - uint32 unknown_6; /* 0x0000 04ec */ - - /* relative pointers to dynamically allocated strings[] */ - int smb_name_offset; /* username string */ - int full_name_offset; /* user's full name string */ - int home_dir_offset; /* home directory string */ - int dir_drive_offset; /* home directory drive string */ - int logon_script_offset; /* logon script string */ - int profile_path_offset; /* profile path string */ - int acct_desc_offset; /* user description string */ - int workstations_offset; /* login from workstations string */ - int unknown_str_offset; /* don't know what this is, yet. */ - int munged_dial_offset; /* munged path name and dial-back tel number */ - - /* how to correctly declare this ?*/ - char strings[1]; + TDB_CONTEXT *passwd_tdb; + TDB_DATA key; }; -#endif +static struct tdb_enum_info global_tdb_ent; +static SAM_ACCOUNT global_sam_pass; -struct tdb_enum_info +/********************************************************************** + Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len + *********************************************************************/ +static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, BYTE *buf, + uint32 buflen) { - TDB_CONTEXT *passwd_tdb; - TDB_DATA key; -}; + static fstring username, + domain, + nt_username, + dir_drive, + unknown_str, + munged_dial; + static pstring full_name, + home_dir, + logon_script, + profile_path, + acct_desc, + workstations; + static BYTE *lm_pw_ptr, + *nt_pw_ptr, + lm_pw[16], + nt_pw[16]; + uint32 len = 0; + uint32 lmpwlen, ntpwlen, hourslen; + + /* unpack the buffer into variables */ + len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING, + &sampass->logon_time, + &sampass->logoff_time, + &sampass->kickoff_time, + &sampass->pass_last_set_time, + &sampass->pass_can_change_time, + &sampass->pass_must_change_time, + username, + domain, + nt_username, + full_name, + home_dir, + dir_drive, + logon_script, + profile_path, + acct_desc, + workstations, + unknown_str, + munged_dial, + &sampass->user_rid, + &sampass->group_rid, + &lmpwlen, &lm_pw_ptr, + &ntpwlen, &nt_pw_ptr, + &sampass->acct_ctrl, + &sampass->unknown_3, + &sampass->logon_divs, + &sampass->hours_len, + &hourslen, &sampass->hours, + &sampass->unknown_5, + &sampass->unknown_6); + + if (len == -1) + return False; + + /* + * We have to copy the password hashes into static memory + * and free the memory allocated by tdb_unpack. This is because + * the sampass->own_memory flag is for all pointer members. + * The remaining members are using static memory and so + * the password hashes must as well. --jerry + */ + if (lm_pw_ptr) + { + memcpy(lm_pw, lm_pw_ptr, 16); + free (lm_pw_ptr); + } + if (nt_pw_ptr) + { + memcpy(nt_pw, nt_pw_ptr, 16); + free (nt_pw_ptr); + } + + /* using static memory for strings */ + pdb_set_mem_ownership(sampass, False); + + pdb_set_username (sampass, username); + pdb_set_domain (sampass, domain); + pdb_set_nt_username (sampass, nt_username); + pdb_set_fullname (sampass, full_name); + pdb_set_homedir (sampass, home_dir); + pdb_set_dir_drive (sampass, dir_drive); + pdb_set_logon_script (sampass, logon_script); + pdb_set_profile_path (sampass, profile_path); + pdb_set_acct_desc (sampass, acct_desc); + pdb_set_workstations (sampass, workstations); + pdb_set_munged_dial (sampass, munged_dial); + pdb_set_lanman_passwd(sampass, lm_pw); + pdb_set_nt_passwd (sampass, nt_pw); + + return True; +} + +/********************************************************************** + Intialize a BYTE buffer from a SAM_ACCOUNT struct + *********************************************************************/ +static uint32 init_buffer_from_sam (BYTE **buf, SAM_ACCOUNT *sampass) +{ + size_t len, buflen; + + fstring username, + domain, + nt_username, + dir_drive, + unknown_str, + munged_dial; + pstring full_name, + home_dir, + logon_script, + profile_path, + acct_desc, + workstations; + BYTE lm_pw[16], + nt_pw[16]; + char null_pw[] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; + + /* do we have a valid SAM_ACCOUNT pointer? */ + if (sampass == NULL) + return -1; + + *buf = NULL; + buflen = 0; + + fstrcpy(username, sampass->username); + fstrcpy(domain, sampass->domain); + fstrcpy(nt_username, sampass->nt_username); + fstrcpy(dir_drive, sampass->dir_drive); + fstrcpy(unknown_str, sampass->unknown_str); + fstrcpy(munged_dial, sampass->munged_dial); + + pstrcpy(full_name, sampass->full_name); + pstrcpy(home_dir, sampass->home_dir); + pstrcpy(logon_script, sampass->logon_script); + pstrcpy(profile_path, sampass->profile_path); + pstrcpy(acct_desc, sampass->acct_desc); + pstrcpy(workstations, sampass->workstations); + + if (sampass->lm_pw) + memcpy(lm_pw, sampass->lm_pw, 16); + else + pdb_gethexpwd (null_pw, lm_pw); + + if (sampass->nt_pw) + memcpy(nt_pw, sampass->nt_pw, 16); + else + pdb_gethexpwd (null_pw, nt_pw); + + + /* one time to get the size needed */ + len = tdb_pack(NULL, 0, TDB_FORMAT_STRING, + sampass->logon_time, + sampass->logoff_time, + sampass->kickoff_time, + sampass->pass_last_set_time, + sampass->pass_can_change_time, + sampass->pass_must_change_time, + username, + domain, + nt_username, + full_name, + home_dir, + dir_drive, + logon_script, + profile_path, + acct_desc, + workstations, + unknown_str, + munged_dial, + sampass->user_rid, + sampass->group_rid, + 16, lm_pw, + 16, nt_pw, + sampass->acct_ctrl, + sampass->unknown_3, + sampass->logon_divs, + sampass->hours_len, + MAX_HOURS_LEN, sampass->hours, + sampass->unknown_5, + sampass->unknown_6); + + + /* malloc the space needed */ + if ( (*buf=(BYTE*)malloc(len)) == NULL) + { + DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n")); + return (-1); + } + + /* now for the real call to tdb_pack() */ + /* one time to get the size needed */ + buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING, + sampass->logon_time, + sampass->logoff_time, + sampass->kickoff_time, + sampass->pass_last_set_time, + sampass->pass_can_change_time, + sampass->pass_must_change_time, + username, + domain, + nt_username, + full_name, + home_dir, + dir_drive, + logon_script, + profile_path, + acct_desc, + workstations, + unknown_str, + munged_dial, + sampass->user_rid, + sampass->group_rid, + 16, lm_pw, + 16, nt_pw, + sampass->acct_ctrl, + sampass->unknown_3, + sampass->logon_divs, + sampass->hours_len, + MAX_HOURS_LEN, sampass->hours, + sampass->unknown_5, + sampass->unknown_6); + + + /* check to make sure we got it correct */ + if (buflen != len) + { + /* error */ + free (*buf); + return (-1); + } -static struct tdb_enum_info tdb_ent; + return (buflen); +} /*************************************************************** - Start to enumerate the TDB passwd list. Returns a void pointer - to ensure no modification outside this module. + Open the TDB account SAM fo renumeration. ****************************************************************/ - -static void *startsamtdbpwent(BOOL update) +BOOL pdb_setsampwent(BOOL update) { + pstring tdbfile; + + pstrcpy (tdbfile, lp_private_dir()); + pstrcat (tdbfile, "/passdb.tdb"); + /* Open tdb passwd */ - if (!(tdb_ent.passwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, update ? O_RDWR : O_RDONLY, 0600))) + if (!(global_tdb_ent.passwd_tdb = tdb_open(tdbfile, 0, 0, update ? O_RDWR : O_RDONLY, 0600))) { DEBUG(0, ("Unable to open TDB passwd, trying create new!\n")); - if (!(tdb_ent.passwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600))) + if (!(global_tdb_ent.passwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600))) { - DEBUG(0, ("Unable to creat TDB passwd (smbpasswd.tdb) !!!")); - return NULL; + DEBUG(0, ("Unable to create TDB passwd (smbpasswd.tdb) !!!")); + return False; } - return &tdb_ent; } - tdb_ent.key = tdb_firstkey(tdb_ent.passwd_tdb); - return &tdb_ent; + global_tdb_ent.key = tdb_firstkey(global_tdb_ent.passwd_tdb); + + return True; } /*************************************************************** End enumeration of the TDB passwd list. ****************************************************************/ - -static void endsamtdbpwent(void *vp) +void pdb_endsampwent(void) { - struct tdb_enum_info *p_ent = (struct tdb_enum_info *)vp; - - tdb_close(p_ent->passwd_tdb); - DEBUG(7, ("endtdbpwent: closed password file.\n")); + if (global_tdb_ent.passwd_tdb) + { + tdb_close(global_tdb_ent.passwd_tdb); + global_tdb_ent.passwd_tdb = NULL; + } + + DEBUG(7, ("endtdbpwent: closed password file.\n")); } -static struct sam_passwd *getsamtdb21pwent(void *vp) -{ - static struct sam_passwd sam_entry; - static struct tdb_sam_entry *tdb_entry; - struct tdb_enum_info *p_ent = (struct tdb_enum_info *)vp; - TDB_DATA data; - - if(p_ent == NULL) { - DEBUG(0,("gettdbpwent: Bad TDB Context pointer.\n")); - return NULL; - } - - data = tdb_fetch (p_ent->passwd_tdb, p_ent->key); - if (!data.dptr) - { - DEBUG(5,("gettdbpwent: database entry not found.\n")); - return NULL; - } - - tdb_entry = (struct tdb_sam_entry *)(data.dptr); - - sam_entry.logon_time = tdb_entry->logon_time; - sam_entry.logoff_time = tdb_entry->logoff_time; - sam_entry.kickoff_time = tdb_entry->kickoff_time; - sam_entry.pass_last_set_time = tdb_entry->pass_last_set_time; - sam_entry.pass_can_change_time = tdb_entry->pass_can_change_time; - sam_entry.pass_must_change_time = tdb_entry->pass_must_change_time; - sam_entry.smb_name = tdb_entry->strings + tdb_entry->smb_name_offset; - sam_entry.full_name = tdb_entry->strings + tdb_entry->full_name_offset; - sam_entry.home_dir = tdb_entry->strings + tdb_entry->home_dir_offset; - sam_entry.dir_drive = tdb_entry->strings + tdb_entry->dir_drive_offset; - sam_entry.logon_script = tdb_entry->strings + tdb_entry->logon_script_offset; - sam_entry.profile_path = tdb_entry->strings + tdb_entry->profile_path_offset; - sam_entry.acct_desc = tdb_entry->strings + tdb_entry->acct_desc_offset; - sam_entry.workstations = tdb_entry->strings + tdb_entry->workstations_offset; - sam_entry.unknown_str = tdb_entry->strings + tdb_entry->unknown_str_offset; - sam_entry.munged_dial = tdb_entry->strings + tdb_entry->munged_dial_offset; - sam_entry.smb_userid = tdb_entry->smb_userid; - sam_entry.smb_grpid = tdb_entry->smb_grpid; - sam_entry.user_rid = tdb_entry->user_rid; - sam_entry.group_rid = tdb_entry->group_rid; - sam_entry.smb_passwd = tdb_entry->smb_passwd; - sam_entry.smb_nt_passwd = tdb_entry->smb_nt_passwd; - sam_entry.acct_ctrl = tdb_entry->acct_ctrl; - sam_entry.unknown_3 = tdb_entry->unknown_3; - sam_entry.logon_divs = tdb_entry->logon_divs; - sam_entry.hours_len = tdb_entry->hours_len; - memcpy (sam_entry.hours, tdb_entry->hours, MAX_HOURS_LEN); - sam_entry.unknown_5 = tdb_entry->unknown_5; - sam_entry.unknown_6 = tdb_entry->unknown_6; - - p_ent->key = tdb_nextkey (p_ent->passwd_tdb, p_ent->key); - - return &sam_entry; -} -static BOOL del_samtdbpwd_entry(const char *name) +/***************************************************************** + Get one SAM_ACCOUNT from the TDB (next in line) +*****************************************************************/ +SAM_ACCOUNT* pdb_getsampwent(void) { - TDB_CONTEXT *pwd_tdb; - TDB_DATA key; - fstring keystr; - - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) - { - DEBUG(0, ("Unable to open TDB passwd!")); - return False; - } - - slprintf(keystr, sizeof(keystr), "USER_%s", name); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) - { - DEBUG(5, ("Error deleting entry from tdb database!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_error(pwd_tdb))); - tdb_close(pwd_tdb); - return False; - } - tdb_close(pwd_tdb); - return True; -} + TDB_DATA data; + struct passwd *pw; -static BOOL mod_samtdb21pwd_entry(struct sam_passwd* newpwd, BOOL override) -{ - TDB_CONTEXT *pwd_tdb; - TDB_DATA key; - TDB_DATA data; - struct tdb_sam_entry *tdb_entry; - fstring keystr; - - int smb_name_len = (newpwd->smb_name) ? (strlen (newpwd->smb_name) + 1) : 0; - int full_name_len = (newpwd->full_name) ? (strlen (newpwd->full_name) + 1) : 0; - int home_dir_len = (newpwd->home_dir) ? (strlen (newpwd->home_dir) + 1) : 0; - int dir_drive_len = (newpwd->dir_drive) ? (strlen (newpwd->dir_drive) + 1) : 0; - int logon_script_len = (newpwd->logon_script) ? (strlen (newpwd->logon_script) + 1) : 0; - int profile_path_len = (newpwd->profile_path) ? (strlen (newpwd->profile_path) + 1) : 0; - int acct_desc_len = (newpwd->acct_desc) ? (strlen (newpwd->acct_desc) + 1) : 0; - int workstations_len = (newpwd->workstations) ? (strlen (newpwd->workstations) + 1) : 0; - int unknown_str_len = (newpwd->unknown_str) ? (strlen (newpwd->unknown_str) + 1) : 0; - int munged_dial_len = (newpwd->munged_dial) ? (strlen (newpwd->munged_dial) + 1) : 0; - - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) - { - DEBUG(0, ("Unable to open TDB passwd!")); - return False; - } - - data.dsize = sizeof (struct tdb_sam_entry) + - smb_name_len + - full_name_len + - home_dir_len + - dir_drive_len + - logon_script_len + - profile_path_len + - acct_desc_len + - workstations_len + - unknown_str_len + - munged_dial_len; - - tdb_entry = malloc (data.dsize); - data.dptr = tdb_entry; - memset (data.dptr, 0, data.dsize); - - tdb_entry->logon_time = newpwd->logon_time; - tdb_entry->logoff_time = newpwd->logoff_time; - tdb_entry->kickoff_time = newpwd->kickoff_time; - tdb_entry->pass_last_set_time = newpwd->pass_last_set_time; - tdb_entry->pass_can_change_time = newpwd->pass_can_change_time; - tdb_entry->pass_must_change_time = newpwd->pass_must_change_time; - tdb_entry->smb_userid = newpwd->smb_userid; - tdb_entry->smb_grpid = newpwd->smb_grpid; - tdb_entry->user_rid = newpwd->user_rid; - tdb_entry->group_rid = newpwd->group_rid; - memcpy (tdb_entry->smb_passwd, newpwd->smb_passwd, strlen (newpwd->smb_passwd) + 1); - memcpy (tdb_entry->smb_nt_passwd, newpwd->smb_nt_passwd, strlen (newpwd->smb_nt_passwd) + 1); - tdb_entry->acct_ctrl = newpwd->acct_ctrl; - tdb_entry->unknown_3 = newpwd->unknown_3; - tdb_entry->logon_divs = newpwd->logon_divs; - tdb_entry->hours_len = newpwd->hours_len; - memcpy (tdb_entry->hours, newpwd->hours, MAX_HOURS_LEN); - tdb_entry->unknown_5 = newpwd->unknown_5; - tdb_entry->unknown_6 = newpwd->unknown_6; - tdb_entry->smb_name_offset = 0; - tdb_entry->full_name_offset = smb_name_len; - tdb_entry->home_dir_offset = tdb_entry->full_name_offset + full_name_len; - tdb_entry->dir_drive_offset = tdb_entry->home_dir_offset + home_dir_len; - tdb_entry->logon_script_offset = tdb_entry->dir_drive_offset + dir_drive_len; - tdb_entry->profile_path_offset = tdb_entry->logon_script_offset + logon_script_len; - tdb_entry->acct_desc_offset = tdb_entry->profile_path_offset + profile_path_len; - tdb_entry->workstations_offset = tdb_entry->acct_desc_offset + acct_desc_len; - tdb_entry->unknown_str_offset = tdb_entry->workstations_offset + workstations_len; - tdb_entry->munged_dial_offset = tdb_entry->unknown_str_offset + unknown_str_len; - if (newpwd->smb_name) - memcpy (tdb_entry->strings + tdb_entry->smb_name_offset, newpwd->smb_name, smb_name_len); - if (newpwd->full_name) - memcpy (tdb_entry->strings + tdb_entry->full_name_offset, newpwd->full_name, full_name_len); - if (newpwd->home_dir) - memcpy (tdb_entry->strings + tdb_entry->home_dir_offset, newpwd->home_dir, home_dir_len); - if (newpwd->dir_drive) - memcpy (tdb_entry->strings + tdb_entry->dir_drive_offset, newpwd->dir_drive, dir_drive_len); - if (newpwd->logon_script) - memcpy (tdb_entry->strings + tdb_entry->logon_script_offset, newpwd->logon_script, logon_script_len); - if (newpwd->profile_path) - memcpy (tdb_entry->strings + tdb_entry->profile_path_offset, newpwd->profile_path, profile_path_len); - if (newpwd->acct_desc) - memcpy (tdb_entry->strings + tdb_entry->acct_desc_offset, newpwd->acct_desc, acct_desc_len); - if (newpwd->workstations) - memcpy (tdb_entry->strings + tdb_entry->workstations_offset, newpwd->workstations, workstations_len); - if (newpwd->unknown_str) - memcpy (tdb_entry->strings + tdb_entry->unknown_str_offset, newpwd->unknown_str, unknown_str_len); - if (newpwd->munged_dial) - memcpy (tdb_entry->strings + tdb_entry->munged_dial_offset, newpwd->munged_dial, munged_dial_len); - - slprintf(keystr, sizeof(keystr), "USER_%s", newpwd->smb_name); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - tdb_writelock (pwd_tdb); - if (tdb_store (pwd_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) - { - DEBUG(0, ("Unable to modify TDB passwd!")); - DEBUGADD(0, (" Error: %s\n", tdb_error (pwd_tdb))); - tdb_writeunlock (pwd_tdb); - tdb_close (pwd_tdb); - return False; - } - - tdb_writeunlock (pwd_tdb); - tdb_close (pwd_tdb); - return True; -} + /* do we have an valid interation pointer? */ + if(global_tdb_ent.passwd_tdb == NULL) + { + DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n")); + return NULL; + } -static BOOL add_samtdb21pwd_entry(struct sam_passwd *newpwd) -{ - TDB_CONTEXT *pwd_tdb; - TDB_DATA key; - TDB_DATA data; - struct tdb_sam_entry *tdb_entry; - fstring keystr; - - int smb_name_len = (newpwd->smb_name) ? (strlen (newpwd->smb_name) + 1) : 1; - int full_name_len = (newpwd->full_name) ? (strlen (newpwd->full_name) + 1) : 1; - int home_dir_len = (newpwd->home_dir) ? (strlen (newpwd->home_dir) + 1) : 1; - int dir_drive_len = (newpwd->dir_drive) ? (strlen (newpwd->dir_drive) + 1) : 1; - int logon_script_len = (newpwd->logon_script) ? (strlen (newpwd->logon_script) + 1) : 1; - int profile_path_len = (newpwd->profile_path) ? (strlen (newpwd->profile_path) + 1) : 1; - int acct_desc_len = (newpwd->acct_desc) ? (strlen (newpwd->acct_desc) + 1) : 1; - int workstations_len = (newpwd->workstations) ? (strlen (newpwd->workstations) + 1) : 1; - int unknown_str_len = (newpwd->unknown_str) ? (strlen (newpwd->unknown_str) + 1) : 1; - int munged_dial_len = (newpwd->munged_dial) ? (strlen (newpwd->munged_dial) + 1) : 1; - - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDWR, 0600))) - { - DEBUG(0, ("Unable to open TDB passwd!")); - return False; - } - - data.dsize = sizeof (struct tdb_sam_entry) + - smb_name_len + - full_name_len + - home_dir_len + - dir_drive_len + - logon_script_len + - profile_path_len + - acct_desc_len + - workstations_len + - unknown_str_len + - munged_dial_len; - - tdb_entry = malloc (data.dsize); - data.dptr = tdb_entry; - memset (data.dptr, 0, data.dsize); - - tdb_entry->logon_time = newpwd->logon_time; - tdb_entry->logoff_time = newpwd->logoff_time; - tdb_entry->kickoff_time = newpwd->kickoff_time; - tdb_entry->pass_last_set_time = newpwd->pass_last_set_time; - tdb_entry->pass_can_change_time = newpwd->pass_can_change_time; - tdb_entry->pass_must_change_time = newpwd->pass_must_change_time; - tdb_entry->smb_userid = newpwd->smb_userid; - tdb_entry->smb_grpid = newpwd->smb_grpid; - tdb_entry->user_rid = newpwd->user_rid; - tdb_entry->group_rid = newpwd->group_rid; - memcpy (tdb_entry->smb_passwd, newpwd->smb_passwd, strlen (newpwd->smb_passwd) + 1); - memcpy (tdb_entry->smb_nt_passwd, newpwd->smb_nt_passwd, strlen (newpwd->smb_nt_passwd) + 1); - tdb_entry->acct_ctrl = newpwd->acct_ctrl; - tdb_entry->unknown_3 = newpwd->unknown_3; - tdb_entry->logon_divs = newpwd->logon_divs; - tdb_entry->hours_len = newpwd->hours_len; - memcpy (tdb_entry->hours, newpwd->hours, MAX_HOURS_LEN); - tdb_entry->unknown_5 = newpwd->unknown_5; - tdb_entry->unknown_6 = newpwd->unknown_6; - tdb_entry->smb_name_offset = 0; - tdb_entry->full_name_offset = smb_name_len; - tdb_entry->home_dir_offset = tdb_entry->full_name_offset + full_name_len; - tdb_entry->dir_drive_offset = tdb_entry->home_dir_offset + home_dir_len; - tdb_entry->logon_script_offset = tdb_entry->dir_drive_offset + dir_drive_len; - tdb_entry->profile_path_offset = tdb_entry->logon_script_offset + logon_script_len; - tdb_entry->acct_desc_offset = tdb_entry->profile_path_offset + profile_path_len; - tdb_entry->workstations_offset = tdb_entry->acct_desc_offset + acct_desc_len; - tdb_entry->unknown_str_offset = tdb_entry->workstations_offset + workstations_len; - tdb_entry->munged_dial_offset = tdb_entry->unknown_str_offset + unknown_str_len; - if (newpwd->smb_name) - memcpy (tdb_entry->strings + tdb_entry->smb_name_offset, newpwd->smb_name, smb_name_len); - if (newpwd->full_name) - memcpy (tdb_entry->strings + tdb_entry->full_name_offset, newpwd->full_name, full_name_len); - if (newpwd->home_dir) - memcpy (tdb_entry->strings + tdb_entry->home_dir_offset, newpwd->home_dir, home_dir_len); - if (newpwd->dir_drive) - memcpy (tdb_entry->strings + tdb_entry->dir_drive_offset, newpwd->dir_drive, dir_drive_len); - if (newpwd->logon_script) - memcpy (tdb_entry->strings + tdb_entry->logon_script_offset, newpwd->logon_script, logon_script_len); - if (newpwd->profile_path) - memcpy (tdb_entry->strings + tdb_entry->profile_path_offset, newpwd->profile_path, profile_path_len); - if (newpwd->acct_desc) - memcpy (tdb_entry->strings + tdb_entry->acct_desc_offset, newpwd->acct_desc, acct_desc_len); - if (newpwd->workstations) - memcpy (tdb_entry->strings + tdb_entry->workstations_offset, newpwd->workstations, workstations_len); - if (newpwd->unknown_str) - memcpy (tdb_entry->strings + tdb_entry->unknown_str_offset, newpwd->unknown_str, unknown_str_len); - if (newpwd->munged_dial) - memcpy (tdb_entry->strings + tdb_entry->munged_dial_offset, newpwd->munged_dial, munged_dial_len); - - slprintf(keystr, sizeof(keystr), "USER_%s", newpwd->smb_name); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; + data = tdb_fetch (global_tdb_ent.passwd_tdb, global_tdb_ent.key); + if (!data.dptr) + { + DEBUG(5,("pdb_getsampwent: database entry not found.\n")); + return NULL; + } - tdb_writelock (pwd_tdb); - if (tdb_store (pwd_tdb, key, data, TDB_INSERT) != TDB_SUCCESS) - { - DEBUG(0, ("Unable to modify TDB passwd!")); - DEBUGADD(0, (" Error: %s\n", tdb_error (pwd_tdb))); - tdb_writeunlock (pwd_tdb); - tdb_close (pwd_tdb); - return False; - } - - tdb_writeunlock (pwd_tdb); - tdb_close (pwd_tdb); - return True; + /* unpack the buffer */ + pdb_clear_sam (&global_sam_pass); + if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize)) + { + DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n")); + return NULL; + } + + /* validate the account and fill in UNIX uid and gid. sys_getpwnam() + is used instaed of Get_Pwnam() as we do not need to try case + permutations */ + if ((pw=sys_getpwnam(pdb_get_username(&global_sam_pass))) == NULL) + { + DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n", + pdb_get_username(&global_sam_pass))); + return NULL; + } + + pdb_set_uid (&global_sam_pass, pw->pw_uid); + pdb_set_gid (&global_sam_pass, pw->pw_gid); + + /* increment to next in line */ + global_tdb_ent.key = tdb_nextkey (global_tdb_ent.passwd_tdb, global_tdb_ent.key); + + return (&global_sam_pass); } -static struct sam_passwd *iterate_getsamtdb21pwrid(uint32 user_rid) +/****************************************************************** + Lookup a name in the SAM TDB +******************************************************************/ +SAM_ACCOUNT* pdb_getsampwnam (char *name) { - struct sam_passwd *pwd = NULL; - void *fp = NULL; - - DEBUG(10, ("search by smb_userid: %x\n", (int)user_rid)); + TDB_CONTEXT *pwd_tdb; + TDB_DATA data, key; + fstring keystr; + struct passwd *pw; + pstring tdbfile; + + pstrcpy (tdbfile, lp_private_dir()); + pstrcat (tdbfile, "/passdb.tdb"); + + /* set search key */ + slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name); + key.dptr = keystr; + key.dsize = strlen (keystr) + 1; - /* Open the smb password database - not for update. */ - fp = startsamtdbpwent(False); + /* open the accounts TDB */ + if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDONLY, 0600))) + { + DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n")); + return False; + } - if (fp == NULL) + /* get the record */ + data = tdb_fetch (pwd_tdb, key); + if (!data.dptr) { - DEBUG(0, ("unable to open smb password database.\n")); + DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n")); + DEBUGADD(5, (" Error: %s\n", tdb_error(pwd_tdb))); + tdb_close (pwd_tdb); return NULL; } - - while ((pwd = getsamtdb21pwent(fp)) != NULL && pwd->user_rid != user_rid); - - if (pwd != NULL) + + /* unpack the buffer */ + pdb_clear_sam (&global_sam_pass); + if (!init_sam_from_buffer (&global_sam_pass, data.dptr, data.dsize)) + { + DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n")); + return NULL; + } + + /* validate the account and fill in UNIX uid and gid. sys_getpwnam() + is used instaed of Get_Pwnam() as we do not need to try case + permutations */ + if ((pw=sys_getpwnam(pdb_get_username(&global_sam_pass))) == NULL) { - DEBUG(10, ("found by user_rid: %x\n", (int)user_rid)); + DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n", + pdb_get_username(&global_sam_pass))); + return NULL; } + + pdb_set_uid (&global_sam_pass, pw->pw_uid); + pdb_set_gid (&global_sam_pass, pw->pw_gid); + + /* cleanup */ + tdb_close (pwd_tdb); - endsamtdbpwent(fp); - return pwd; + return (&global_sam_pass); } -static struct sam_passwd *getsamtdb21pwnam(char *name) +/*************************************************************************** + Search by uid + + I now know what the 'T' stands for in TDB :-( This is an unacceptable + solution. We need multiple indexes and transactional support. I'm + including this implementation only as an example. + **************************************************************************/ +SAM_ACCOUNT* pdb_getsampwuid (uid_t uid) { - static struct sam_passwd sam_entry; - static struct tdb_sam_entry *tdb_entry; - TDB_CONTEXT *pwd_tdb; - TDB_DATA data; - TDB_DATA key; - fstring keystr; - - if (!(pwd_tdb = tdb_open(lp_tdb_passwd_file(), 0, 0, O_RDONLY, 0600))) - { - DEBUG(0, ("Unable to open TDB passwd!")); - return False; - } - - slprintf(keystr, sizeof(keystr), "USER_%s", name); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - data = tdb_fetch (pwd_tdb, key); - if (!data.dptr) - { - DEBUG(5,("getsamtdbpwent: error fetching database.\n")); - DEBUGADD(5, (" Error: %s\n", tdb_error(pwd_tdb))); - tdb_close (pwd_tdb); - return NULL; - } - - tdb_entry = (struct tdb_sam_entry *)(data.dptr); - - sam_entry.logon_time = tdb_entry->logon_time; - sam_entry.logoff_time = tdb_entry->logoff_time; - sam_entry.kickoff_time = tdb_entry->kickoff_time; - sam_entry.pass_last_set_time = tdb_entry->pass_last_set_time; - sam_entry.pass_can_change_time = tdb_entry->pass_can_change_time; - sam_entry.pass_must_change_time = tdb_entry->pass_must_change_time; - sam_entry.smb_name = tdb_entry->strings + tdb_entry->smb_name_offset; - sam_entry.full_name = tdb_entry->strings + tdb_entry->full_name_offset; - sam_entry.home_dir = tdb_entry->strings + tdb_entry->home_dir_offset; - sam_entry.dir_drive = tdb_entry->strings + tdb_entry->dir_drive_offset; - sam_entry.logon_script = tdb_entry->strings + tdb_entry->logon_script_offset; - sam_entry.profile_path = tdb_entry->strings + tdb_entry->profile_path_offset; - sam_entry.acct_desc = tdb_entry->strings + tdb_entry->acct_desc_offset; - sam_entry.workstations = tdb_entry->strings + tdb_entry->workstations_offset; - sam_entry.unknown_str = tdb_entry->strings + tdb_entry->unknown_str_offset; - sam_entry.munged_dial = tdb_entry->strings + tdb_entry->munged_dial_offset; - sam_entry.smb_userid = tdb_entry->smb_userid; - sam_entry.smb_grpid = tdb_entry->smb_grpid; - sam_entry.user_rid = tdb_entry->user_rid; - sam_entry.group_rid = tdb_entry->group_rid; - sam_entry.smb_passwd = tdb_entry->smb_passwd; - sam_entry.smb_nt_passwd = tdb_entry->smb_nt_passwd; - sam_entry.acct_ctrl = tdb_entry->acct_ctrl; - sam_entry.unknown_3 = tdb_entry->unknown_3; - sam_entry.logon_divs = tdb_entry->logon_divs; - sam_entry.hours_len = tdb_entry->hours_len; - memcpy (sam_entry.hours, tdb_entry->hours, MAX_HOURS_LEN); - sam_entry.unknown_5 = tdb_entry->unknown_5; - sam_entry.unknown_6 = tdb_entry->unknown_6; - - tdb_close (pwd_tdb); - return &sam_entry; -} + SAM_ACCOUNT *pw = NULL; -static SMB_BIG_UINT getsamtdbpwpos(void *vp) -{ - return (SMB_BIG_UINT)0; + if (!pdb_setsampwent(False)) + return NULL; + + while ( ((pw=pdb_getsampwent()) != NULL) && (pdb_get_uid(pw) != uid) ) + /* do nothing */ ; + + pdb_endsampwent(); + + return pw; } -static BOOL setsamtdbpwpos(void *vp, SMB_BIG_UINT tok) +/*************************************************************************** + Search by rid + **************************************************************************/ +SAM_ACCOUNT* pdb_getsampwrid (uint32 rid) { - return False; -} + SAM_ACCOUNT *pw = NULL; -static struct smb_passwd *getsamtdbpwent(void *vp) -{ - return pdb_sam_to_smb(getsamtdb21pwent(vp)); + if (!pdb_setsampwent(False)) + return NULL; + + while ( ((pw=pdb_getsampwent()) != NULL) && (pdb_get_user_rid(pw) != rid) ) + /* do nothing */ ; + + pdb_endsampwent(); + + return pw; } -static BOOL add_samtdbpwd_entry(struct smb_passwd *newpwd) -{ - return add_samtdb21pwd_entry(pdb_smb_to_sam(newpwd)); -} -static BOOL mod_samtdbpwd_entry(struct smb_passwd* pwd, BOOL override) +/*************************************************************************** + Delete a SAM_ACCOUNT +****************************************************************************/ +BOOL pdb_delete_sam_account(char *name) { - return mod_samtdb21pwd_entry(pdb_smb_to_sam(pwd), override); -} + TDB_CONTEXT *pwd_tdb; + TDB_DATA key; + fstring keystr; + pstring tdbfile; + + pstrcpy (tdbfile, lp_private_dir()); + pstrcat (tdbfile, "/passdb.tdb"); + -static struct sam_disp_info *getsamtdbdispnam(char *name) -{ - return pdb_sam_to_dispinfo(getsam21pwnam(name)); + /* open the TDB */ + if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600))) + { + DEBUG(0, ("Unable to open TDB passwd!")); + return False; + } + + /* set the search key */ + slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, name); + key.dptr = keystr; + key.dsize = strlen (keystr) + 1; + + /* it's outaa here! 8^) */ + if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) + { + DEBUG(5, ("Error deleting entry from tdb database!\n")); + DEBUGADD(5, (" Error: %s\n", tdb_error(pwd_tdb))); + tdb_close(pwd_tdb); + return False; + } + + tdb_close(pwd_tdb); + return True; } -static struct sam_disp_info *getsamtdbdisprid(uint32 rid) +/*************************************************************************** + Update the TDB SAM +****************************************************************************/ +static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag) { - return pdb_sam_to_dispinfo(getsam21pwrid(rid)); -} + TDB_CONTEXT *pwd_tdb; + TDB_DATA key, data; + BYTE *buf = NULL; + fstring keystr; + pstring tdbfile; + + pstrcpy (tdbfile, lp_private_dir()); + pstrcat (tdbfile, "/passdb.tdb"); + + if ( (!newpwd->uid) || (!newpwd->gid) ) + { + DEBUG (0,("tdb_update_sam: Attempting to store a SAM_ACCOUNT for [%s] with no uid/gid!\n", newpwd->username)); + return False; + } + + /* if we don't have a RID, then generate one */ + if (!newpwd->user_rid) + pdb_set_user_rid (pdb_uid_to_user_rid (newpwd->uid)); + if (!newpwd->group_rid) + pdb_set_user_rid (pdb_uid_to_group_rid (newpwd->gid)); + + /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */ + if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1) + { + DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n")); + return False; + } + data.dptr = buf; -static struct sam_disp_info *getsamtdbdispent(void *vp) -{ - return pdb_sam_to_dispinfo(getsam21pwent(vp)); + /* setup the index key */ + slprintf(keystr, sizeof(keystr), "%s%s", USERPREFIX, pdb_get_username(newpwd)); + key.dptr = keystr; + key.dsize = strlen (keystr) + 1; + + /* invalidate the existing TDB iterator if it is open */ + if (global_tdb_ent.passwd_tdb) + { + tdb_close(global_tdb_ent.passwd_tdb); + global_tdb_ent.passwd_tdb = NULL; + } + + /* open the account TDB */ + if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR, 0600))) + { + DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n")); + if (flag == TDB_INSERT) + { + DEBUG(0, ("Unable to open TDB passwd, trying create new!\n")); + if (!(pwd_tdb = tdb_open(tdbfile, 0, 0, O_RDWR | O_CREAT | O_EXCL, 0600))) + { + DEBUG(0, ("Unable to create TDB passwd (smbpasswd.tdb) !!!\n")); + return False; + } + } + } + + /* add the account */ + if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) + { + DEBUG(0, ("Unable to modify TDB passwd!")); + DEBUGADD(0, (" Error: %s\n", tdb_error (pwd_tdb))); + tdb_close (pwd_tdb); + return False; + } + + /* cleanup */ + tdb_close (pwd_tdb); + + return (True); } -static struct smb_passwd *iterate_getsamtdbpwrid(uint32 user_rid) +/*************************************************************************** + Modifies an existing SAM_ACCOUNT +****************************************************************************/ +BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override) { - return pdb_sam_to_smb(iterate_getsamtdb21pwrid(user_rid)); + return (tdb_update_sam(newpwd, override, TDB_MODIFY)); } -static struct smb_passwd *getsamtdbpwnam(char *name) +/*************************************************************************** + Adds an existing SAM_ACCOUNT +****************************************************************************/ +BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd) { - return pdb_sam_to_smb(getsamtdb21pwnam(name)); + return (tdb_update_sam(newpwd, True, TDB_INSERT)); } -static struct passdb_ops tdb_ops = { - startsamtdbpwent, - endsamtdbpwent, - getsamtdbpwpos, - setsamtdbpwpos, - getsamtdbpwnam, - iterate_getsmbpwuid, /* In passdb.c */ - iterate_getsamtdbpwrid, - getsamtdbpwent, - add_samtdbpwd_entry, - mod_samtdbpwd_entry, - del_samtdbpwd_entry, - getsamtdb21pwent, - getsamtdb21pwnam, - - /* TODO change get username from uid and then use - getsamtdb21pwnam */ - iterate_getsam21pwuid, - - iterate_getsamtdb21pwrid, - add_samtdb21pwd_entry, - mod_samtdb21pwd_entry, - getsamtdbdispnam, - getsamtdbdisprid, - getsamtdbdispent -}; - -struct passdb_ops *tdb_initialize_password_db(void) -{ - return &tdb_ops; -} #else /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */ diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 0e98d60f4a..93347e737f 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -34,11 +34,7 @@ BOOL secrets_init(void) if (tdb) return True; - pstrcpy(fname, lp_smb_passwd_file()); - p = strrchr(fname, '/'); - if(!p) return False; - - *p = 0; + pstrcpy(fname, lp_private_dir()); pstrcat(fname,"/secrets.tdb"); tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT, 0600); diff --git a/source3/passdb/smbpassfile.c b/source3/passdb/smbpassfile.c index 9087dcf0ea..72dcbea122 100644 --- a/source3/passdb/smbpassfile.c +++ b/source3/passdb/smbpassfile.c @@ -85,12 +85,10 @@ static BOOL pw_file_unlock(int fd, int *plock_depth) static void get_trust_account_file_name( char *domain, char *name, char *mac_file) { unsigned int mac_file_len; - char *p; - pstrcpy(mac_file, lp_smb_passwd_file()); - p = strrchr(mac_file, '/'); - if(p != NULL) - *++p = '\0'; + pstrcpy(mac_file, lp_private_dir()); + if (mac_file[strlen(mac_file)-1] != '/') + pstrcat (mac_file, "/"); mac_file_len = strlen(mac_file); |