diff options
author | Gerald Carter <jerry@samba.org> | 2004-08-04 05:42:36 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-08-04 05:42:36 +0000 |
commit | fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1 (patch) | |
tree | 917402d02525c39dd42d3aed01609ac02be104b4 /source/smbd | |
parent | 7cc5217c98cab4d0d970a2eb7f378319bedb6a46 (diff) | |
download | samba-fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1.tar.gz samba-fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1.tar.xz samba-fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1.zip |
r1643: syncing all changes from 3.0 and hopefully get 3.0.6rc2 out tomorrow
Diffstat (limited to 'source/smbd')
-rw-r--r-- | source/smbd/chgpasswd.c | 85 | ||||
-rw-r--r-- | source/smbd/filename.c | 4 | ||||
-rw-r--r-- | source/smbd/mangle.c | 4 | ||||
-rw-r--r-- | source/smbd/mangle_hash.c | 10 | ||||
-rw-r--r-- | source/smbd/mangle_hash2.c | 8 | ||||
-rw-r--r-- | source/smbd/password.c | 26 | ||||
-rw-r--r-- | source/smbd/reply.c | 6 | ||||
-rw-r--r-- | source/smbd/server.c | 11 | ||||
-rw-r--r-- | source/smbd/service.c | 8 | ||||
-rw-r--r-- | source/smbd/trans2.c | 39 |
10 files changed, 146 insertions, 55 deletions
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index ca13a167fb0..a1b90c8fed4 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -933,6 +933,65 @@ static NTSTATUS check_oem_password(const char *user, } /*********************************************************** + This routine takes the given password and checks it against + the password history. Returns True if this password has been + found in the history list. +************************************************************/ + +static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext) +{ + uchar new_nt_p16[NT_HASH_LEN]; + uchar zero_nt_pw[NT_HASH_LEN]; + const uint8 *nt_pw; + const uint8 *pwhistory; + BOOL found = False; + int i, pwHisLen, curr_pwHisLen; + + account_policy_get(AP_PASSWORD_HISTORY, &pwHisLen); + if (pwHisLen == 0) { + return False; + } + + pwhistory = pdb_get_pw_history(sampass, &curr_pwHisLen); + if (!pwhistory || curr_pwHisLen == 0) { + return False; + } + + /* Only examine the minimum of the current history len and + the stored history len. Avoids race conditions. */ + pwHisLen = MIN(pwHisLen,curr_pwHisLen); + + nt_pw = pdb_get_nt_passwd(sampass); + + E_md4hash(plaintext, new_nt_p16); + + if (!memcmp(nt_pw, new_nt_p16, NT_HASH_LEN)) { + DEBUG(10,("check_passwd_history: proposed new password for user %s is the same as the current password !\n", + pdb_get_username(sampass) )); + return True; + } + + dump_data(100, new_nt_p16, NT_HASH_LEN); + dump_data(100, pwhistory, NT_HASH_LEN*pwHisLen); + + memset(zero_nt_pw, '\0', NT_HASH_LEN); + for (i=0; i<pwHisLen; i++) { + if (!memcmp(&pwhistory[i*NT_HASH_LEN], zero_nt_pw, NT_HASH_LEN)) { + /* Ignore zero entries. */ + continue; + } + if (!memcmp(&pwhistory[i*NT_HASH_LEN], new_nt_p16, NT_HASH_LEN)) { + DEBUG(1,("check_passwd_history: proposed new password for user %s found in history list !\n", + pdb_get_username(sampass) )); + found = True; + break; + } + } + + return found; +} + +/*********************************************************** Code to change the oem password. Changes both the lanman and NT hashes. Old_passwd is almost always NULL. NOTE this function is designed to be called as root. Check the old password @@ -941,20 +1000,21 @@ static NTSTATUS check_oem_password(const char *user, NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root) { - struct passwd *pass; - BOOL ret; uint32 min_len; + struct passwd *pass = NULL; + const char *username = pdb_get_username(hnd); + time_t can_change_time = pdb_get_pass_can_change_time(hnd); - if (time(NULL) < pdb_get_pass_can_change_time(hnd)) { + if ((can_change_time != 0) && (time(NULL) < can_change_time)) { DEBUG(1, ("user %s cannot change password now, must wait until %s\n", - pdb_get_username(hnd), http_timestring(pdb_get_pass_can_change_time(hnd)))); - return NT_STATUS_PASSWORD_RESTRICTION; + username, http_timestring(can_change_time))); + return NT_STATUS_ACCOUNT_RESTRICTION; } if (account_policy_get(AP_MIN_PASSWORD_LEN, &min_len) && (strlen(new_passwd) < min_len)) { DEBUG(1, ("user %s cannot change password - password too short\n", - pdb_get_username(hnd))); + username)); DEBUGADD(1, (" account policy min password len = %d\n", min_len)); return NT_STATUS_PASSWORD_RESTRICTION; /* return NT_STATUS_PWD_TOO_SHORT; */ @@ -965,14 +1025,19 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw if (strlen(new_passwd) < lp_min_passwd_length()) { /* too short, must be at least MINPASSWDLENGTH */ DEBUG(1, ("Password Change: user %s, New password is shorter than minimum password length = %d\n", - pdb_get_username(hnd), lp_min_passwd_length())); + username, lp_min_passwd_length())); return NT_STATUS_PASSWORD_RESTRICTION; /* return NT_STATUS_PWD_TOO_SHORT; */ } - pass = Get_Pwnam(pdb_get_username(hnd)); + if (check_passwd_history(hnd,new_passwd)) { + return NT_STATUS_PASSWORD_RESTRICTION; + } + + pass = Get_Pwnam(username); if (!pass) { - DEBUG(1, ("check_oem_password: Username does not exist in system !?!\n")); + DEBUG(1, ("check_oem_password: Username %s does not exist in system !?!\n", username)); + return NT_STATUS_ACCESS_DENIED; } /* @@ -988,7 +1053,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw */ if(lp_unix_password_sync() && - !chgpasswd(pdb_get_username(hnd), pass, old_passwd, new_passwd, as_root)) { + !chgpasswd(username, pass, old_passwd, new_passwd, as_root)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source/smbd/filename.c b/source/smbd/filename.c index ab75d9c06ae..cc1c0a40b66 100644 --- a/source/smbd/filename.c +++ b/source/smbd/filename.c @@ -326,7 +326,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen */ if (mangle_is_mangled(start)) { - mangle_check_cache( start ); + mangle_check_cache( start, sizeof(pstring) - 1 - (start - name) ); } DEBUG(5,("New file %s\n",start)); @@ -476,7 +476,7 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength, * (JRA). */ if (mangled) - mangled = !mangle_check_cache( name ); + mangled = !mangle_check_cache( name, maxlength ); /* open the directory */ if (!(cur_dir = OpenDir(conn, path, True))) { diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c index b77fe601b69..43becff69db 100644 --- a/source/smbd/mangle.c +++ b/source/smbd/mangle.c @@ -98,9 +98,9 @@ BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case) looking for a matching name if it doesn't. It should succeed most of the time or there will be a huge performance penalty */ -BOOL mangle_check_cache(char *s) +BOOL mangle_check_cache(char *s, size_t maxlen) { - return mangle_fns->check_cache(s); + return mangle_fns->check_cache(s, maxlen); } /* diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c index d7239b82a79..13ec99a917f 100644 --- a/source/smbd/mangle_hash.c +++ b/source/smbd/mangle_hash.c @@ -557,7 +557,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name ) * Check for a name on the mangled name stack * * Input: s - Input *and* output string buffer. - * + * maxlen - space in i/o string buffer. * Output: True if the name was found in the cache, else False. * * Notes: If a reverse map is found, the function will overwrite the string @@ -568,7 +568,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name ) * ************************************************************************** ** */ -static BOOL check_cache( char *s ) +static BOOL check_cache( char *s, size_t maxlen ) { ubi_cacheEntryPtr FoundPtr; char *ext_start = NULL; @@ -602,7 +602,7 @@ static BOOL check_cache( char *s ) if( !FoundPtr ) { if(saved_ext) { /* Replace the saved_ext as it was truncated. */ - (void)pstrcat( s, saved_ext ); + (void)safe_strcat( s, saved_ext, maxlen ); SAFE_FREE(saved_ext); } return( False ); @@ -612,10 +612,10 @@ static BOOL check_cache( char *s ) found_name = (char *)(FoundPtr + 1); found_name += (strlen( found_name ) + 1); - (void)pstrcpy( s, found_name ); + (void)safe_strcpy( s, found_name, maxlen ); if( saved_ext ) { /* Replace the saved_ext as it was truncated. */ - (void)pstrcat( s, saved_ext ); + (void)safe_strcat( s, saved_ext, maxlen ); SAFE_FREE(saved_ext); } diff --git a/source/smbd/mangle_hash2.c b/source/smbd/mangle_hash2.c index dcfd7663ba3..f68873687bd 100644 --- a/source/smbd/mangle_hash2.c +++ b/source/smbd/mangle_hash2.c @@ -362,10 +362,8 @@ static void mangle_reset(void) /* try to find a 8.3 name in the cache, and if found then replace the string with the original long name. - - The filename must be able to hold at least sizeof(fstring) */ -static BOOL check_cache(char *name) +static BOOL check_cache(char *name, size_t maxlen) { u32 hash, multiplier; unsigned int i; @@ -403,10 +401,10 @@ static BOOL check_cache(char *name) if (extension[0]) { M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension)); - slprintf(name, sizeof(fstring), "%s.%s", prefix, extension); + slprintf(name, maxlen, "%s.%s", prefix, extension); } else { M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix)); - fstrcpy(name, prefix); + safe_strcpy(name, prefix, maxlen); } return True; diff --git a/source/smbd/password.c b/source/smbd/password.c index b2dbde151d0..3be1516cf04 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -253,19 +253,23 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, /* Register a home dir service for this user iff (a) This is not a guest connection, - (b) we have a home directory defined, and - (c) there s not an existing static share by that name */ - - if ( (!vuser->guest) - && vuser->unix_homedir - && *(vuser->unix_homedir) - && (lp_servicenumber(vuser->user.unix_name) == -1) ) - { - DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", + (b) we have a home directory defined + If a share exists by this name (autoloaded or not) reuse it so + long as the home directory is the same as the share directory. */ + + if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { + int servicenumber = lp_servicenumber(vuser->user.unix_name); + if ( servicenumber == -1 ) { + DEBUG(3, ("Adding homes service for user '%s' using home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); - vuser->homes_snum = add_home_service(vuser->user.unix_name, - vuser->user.unix_name, vuser->unix_homedir); + vuser->user.unix_name, vuser->unix_homedir); + } else if (strcmp(lp_pathname(servicenumber),vuser->unix_homedir) == 0) { + DEBUG(3, ("Reusing homes service for user '%s' using home directory: '%s'\n", + vuser->user.unix_name, vuser->unix_homedir)); + + vuser->homes_snum = servicenumber; + } } else { vuser->homes_snum = -1; } diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 71efb793af0..f3ab709df48 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -1583,7 +1583,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name) */ if (!rc && mangle_is_mangled(mask)) - mangle_check_cache( mask ); + mangle_check_cache( mask, sizeof(pstring)-1 ); if (!has_wild) { pstrcat(directory,"/"); @@ -3738,7 +3738,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui */ if (!rc && mangle_is_mangled(mask)) - mangle_check_cache( mask ); + mangle_check_cache( mask, sizeof(pstring)-1 ); has_wild = ms_has_wild(mask); @@ -4216,7 +4216,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, */ if (!rc && mangle_is_mangled(mask)) - mangle_check_cache( mask ); + mangle_check_cache( mask, sizeof(pstring)-1 ); has_wild = ms_has_wild(mask); diff --git a/source/smbd/server.c b/source/smbd/server.c index c3e0da542e2..16281dd86cb 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -409,11 +409,12 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ in smbstatus for port 445 connects */ set_remote_machine_name(get_peer_addr(smbd_server_fd()), False); - /* Reset global variables in util.c so - that client substitutions will be - done correctly in the process. */ - reset_globals_after_fork(); + /* Reset the state of the random + * number generation system, so + * children do not get the same random + * numbers as each other */ + set_need_random_reseed(); /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */ if (tdb_reopen_all() == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); @@ -717,7 +718,7 @@ void build_options(BOOL screen); /* we want to re-seed early to prevent time delays causing client problems at a later date. (tridge) */ - generate_random_buffer(NULL, 0, False); + generate_random_buffer(NULL, 0); /* make absolutely sure we run as root - to handle cases where people are crazy enough to have it setuid */ diff --git a/source/smbd/service.c b/source/smbd/service.c index 3b499d5cc1d..794b5332ac5 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -823,8 +823,12 @@ void close_cnum(connection_struct *conn, uint16 vuid) { DirCacheFlush(SNUM(conn)); - file_close_conn(conn); - dptr_closecnum(conn); + if (IS_IPC(conn)) { + pipe_close_conn(conn); + } else { + file_close_conn(conn); + dptr_closecnum(conn); + } change_to_root_user(); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index a7db9daf7d6..f3176940c2f 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -3358,16 +3358,15 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", * a new info level should be used for mknod. JRA. */ -#if !defined(HAVE_MAKEDEV_FN) - return(ERROR_DOS(ERRDOS,ERRnoaccess)); -#else /* HAVE_MAKEDEV_FN */ uint32 file_type = IVAL(pdata,0); +#if defined(HAVE_MAKEDEV) uint32 dev_major = IVAL(pdata,4); uint32 dev_minor = IVAL(pdata,12); +#endif uid_t myuid = geteuid(); gid_t mygid = getegid(); - SMB_DEV_T dev; + SMB_DEV_T dev = (SMB_DEV_T)0; if (tran_call == TRANSACT2_SETFILEINFO) return(ERROR_DOS(ERRDOS,ERRnoaccess)); @@ -3375,7 +3374,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (raw_unixmode == SMB_MODE_NO_CHANGE) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); +#if defined(HAVE_MAKEDEV) dev = makedev(dev_major, dev_minor); +#endif /* We can only create as the owner/group we are. */ @@ -3384,10 +3385,30 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE)) return(ERROR_DOS(ERRDOS,ERRnoaccess)); - if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV && - file_type != UNIX_TYPE_FIFO && - file_type != UNIX_TYPE_SOCKET) - return(ERROR_DOS(ERRDOS,ERRnoaccess)); + switch (file_type) { +#if defined(S_IFIFO) + case UNIX_TYPE_FIFO: + unixmode |= S_IFIFO; + break; +#endif +#if defined(S_IFSOCK) + case UNIX_TYPE_SOCKET: + unixmode |= S_IFSOCK; + break; +#endif +#if defined(S_IFCHR) + case UNIX_TYPE_CHARDEV: + unixmode |= S_IFCHR; + break; +#endif +#if defined(S_IFBLK) + case UNIX_TYPE_BLKDEV: + unixmode |= S_IFBLK; + break; +#endif + default: + return(ERROR_DOS(ERRDOS,ERRnoaccess)); + } DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \ 0%o for file %s\n", (double)dev, unixmode, fname )); @@ -3401,8 +3422,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", SSVAL(params,0,0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); return(-1); -#endif /* HAVE_MAKEDEV_FN */ - } /* |