summaryrefslogtreecommitdiffstats
path: root/source/smbd
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-08-04 05:42:36 +0000
committerGerald Carter <jerry@samba.org>2004-08-04 05:42:36 +0000
commitfecd5ea163ffcd1bbee5b06e05112dbff9aa71b1 (patch)
tree917402d02525c39dd42d3aed01609ac02be104b4 /source/smbd
parent7cc5217c98cab4d0d970a2eb7f378319bedb6a46 (diff)
downloadsamba-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.c85
-rw-r--r--source/smbd/filename.c4
-rw-r--r--source/smbd/mangle.c4
-rw-r--r--source/smbd/mangle_hash.c10
-rw-r--r--source/smbd/mangle_hash2.c8
-rw-r--r--source/smbd/password.c26
-rw-r--r--source/smbd/reply.c6
-rw-r--r--source/smbd/server.c11
-rw-r--r--source/smbd/service.c8
-rw-r--r--source/smbd/trans2.c39
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 */
-
}
/*