summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/chgpasswd.c87
-rw-r--r--source3/smbd/close.c11
-rw-r--r--source3/smbd/dir.c8
-rw-r--r--source3/smbd/file_access.c11
-rw-r--r--source3/smbd/globals.c1
-rw-r--r--source3/smbd/globals.h1
-rw-r--r--source3/smbd/lanman.c6
-rw-r--r--source3/smbd/password.c2
-rw-r--r--source3/smbd/posix_acls.c4
-rw-r--r--source3/smbd/reply.c8
-rw-r--r--source3/smbd/sesssetup.c12
-rw-r--r--source3/smbd/vfs.c21
12 files changed, 102 insertions, 70 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 2da36b2fe6..dcefc82bba 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -1008,6 +1008,59 @@ static NTSTATUS check_oem_password(const char *user,
return NT_STATUS_WRONG_PASSWORD;
}
+bool password_in_history(uint8_t nt_pw[NT_HASH_LEN],
+ uint32_t pw_history_len,
+ const uint8_t *pw_history)
+{
+ static const uint8_t zero_md5_nt_pw[SALTED_MD5_HASH_LEN] = { 0, };
+ int i;
+
+ dump_data(100, nt_pw, NT_HASH_LEN);
+ dump_data(100, pw_history, PW_HISTORY_ENTRY_LEN * pw_history_len);
+
+ for (i=0; i<pw_history_len; i++) {
+ uint8_t new_nt_pw_salted_md5_hash[SALTED_MD5_HASH_LEN];
+ const uint8_t *current_salt;
+ const uint8_t *old_nt_pw_salted_md5_hash;
+
+ current_salt = &pw_history[i*PW_HISTORY_ENTRY_LEN];
+ old_nt_pw_salted_md5_hash = current_salt + PW_HISTORY_SALT_LEN;
+
+ if (memcmp(zero_md5_nt_pw, old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0) {
+ /* Ignore zero valued entries. */
+ continue;
+ }
+
+ if (memcmp(zero_md5_nt_pw, current_salt,
+ PW_HISTORY_SALT_LEN) == 0)
+ {
+ /*
+ * New format: zero salt and then plain nt hash.
+ * Directly compare the hashes.
+ */
+ if (memcmp(nt_pw, old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0)
+ {
+ return true;
+ }
+ } else {
+ /*
+ * Old format: md5sum of salted nt hash.
+ * Create salted version of new pw to compare.
+ */
+ E_md5hash(current_salt, nt_pw, new_nt_pw_salted_md5_hash);
+
+ if (memcmp(new_nt_pw_salted_md5_hash,
+ old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/***********************************************************
This routine takes the given password and checks it against
the password history. Returns True if this password has been
@@ -1017,11 +1070,8 @@ static NTSTATUS check_oem_password(const char *user,
static bool check_passwd_history(struct samu *sampass, const char *plaintext)
{
uchar new_nt_p16[NT_HASH_LEN];
- uchar zero_md5_nt_pw[SALTED_MD5_HASH_LEN];
const uint8 *nt_pw;
const uint8 *pwhistory;
- bool found = False;
- int i;
uint32 pwHisLen, curr_pwHisLen;
pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen);
@@ -1048,30 +1098,13 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext)
return True;
}
- dump_data(100, new_nt_p16, NT_HASH_LEN);
- dump_data(100, pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen);
-
- memset(zero_md5_nt_pw, '\0', SALTED_MD5_HASH_LEN);
- for (i=0; i<pwHisLen; i++) {
- uchar new_nt_pw_salted_md5_hash[SALTED_MD5_HASH_LEN];
- const uchar *current_salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN];
- const uchar *old_nt_pw_salted_md5_hash = &pwhistory[(i*PW_HISTORY_ENTRY_LEN)+
- PW_HISTORY_SALT_LEN];
- if (!memcmp(zero_md5_nt_pw, old_nt_pw_salted_md5_hash, SALTED_MD5_HASH_LEN)) {
- /* Ignore zero valued entries. */
- continue;
- }
- /* Create salted versions of new to compare. */
- E_md5hash(current_salt, new_nt_p16, new_nt_pw_salted_md5_hash);
-
- if (!memcmp(new_nt_pw_salted_md5_hash, old_nt_pw_salted_md5_hash, SALTED_MD5_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;
- }
+ if (password_in_history(new_nt_p16, pwHisLen, pwhistory)) {
+ DEBUG(1,("check_passwd_history: proposed new password for "
+ "user %s found in history list !\n",
+ pdb_get_username(sampass) ));
+ return true;
}
- return found;
+ return false;
}
/***********************************************************
@@ -1156,7 +1189,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
}
}
- /* removed calculation here, becuase passdb now calculates
+ /* removed calculation here, because passdb now calculates
based on policy. jmcd */
if ((can_change_time != 0) && (time(NULL) < can_change_time)) {
DEBUG(1, ("user %s cannot change password now, must "
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 05c3c709a1..ca1ac47fa0 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -336,6 +336,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
become_user(conn, fsp->vuid);
became_user = True;
}
+ fsp->delete_on_close = true;
set_delete_on_close_lck(lck, True, &current_user.ut);
if (became_user) {
unbecome_user();
@@ -481,6 +482,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
* the delete on close flag. JRA.
*/
+ fsp->delete_on_close = false;
set_delete_on_close_lck(lck, False, NULL);
done:
@@ -924,6 +926,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
struct share_mode_lock *lck = NULL;
bool delete_dir = False;
NTSTATUS status = NT_STATUS_OK;
+ NTSTATUS status1 = NT_STATUS_OK;
/*
* NT can set delete_on_close of the last open
@@ -958,6 +961,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
}
send_stat_cache_delete_message(fsp->fsp_name->base_name);
set_delete_on_close_lck(lck, True, &current_user.ut);
+ fsp->delete_on_close = true;
if (became_user) {
unbecome_user();
}
@@ -1022,9 +1026,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
fsp, NT_STATUS_OK);
}
- status = fd_close(fsp);
+ status1 = fd_close(fsp);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status1)) {
DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
fsp_str_dbg(fsp), fsp->fh->fd, errno,
strerror(errno)));
@@ -1042,6 +1046,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
out:
TALLOC_FREE(lck);
+ if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
+ status = status1;
+ }
return status;
}
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 5ce4a7b099..3fe3218762 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -1227,14 +1227,6 @@ bool is_visible_file(connection_struct *conn, const char *dir_path,
goto out;
}
- /* If it's a dfs symlink, ignore _hide xxxx_ options */
- if (lp_host_msdfs() &&
- lp_msdfs_root(SNUM(conn)) &&
- is_msdfs_link(conn, entry, NULL)) {
- ret = true;
- goto out;
- }
-
/* Create an smb_filename with stream_name == NULL. */
status = create_synthetic_smb_fname(talloc_tos(), entry, NULL,
pst, &smb_fname_base);
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index 7d0a552956..631efce677 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -54,6 +54,17 @@ bool can_access_file_acl(struct connection_struct *conn,
status = se_access_check(secdesc, conn->server_info->ptok,
access_mask, &access_granted);
ret = NT_STATUS_IS_OK(status);
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("can_access_file_acl for file %s "
+ "access_mask 0x%x, access_granted 0x%x "
+ "access %s\n",
+ smb_fname_str_dbg(smb_fname),
+ (unsigned int)access_mask,
+ (unsigned int)access_granted,
+ ret ? "ALLOWED" : "DENIED" ));
+ NDR_PRINT_DEBUG(security_descriptor, secdesc);
+ }
out:
TALLOC_FREE(secdesc);
return ret;
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 68fa795ba2..e6db5ec414 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -122,7 +122,6 @@ int conn_ctx_stack_ndx = 0;
struct vfs_init_function_entry *backends = NULL;
char *sparse_buf = NULL;
-char *LastDir = NULL;
/* Current number of oplocks we have outstanding. */
int32_t exclusive_oplocks_open = 0;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 0db61f87a3..3cc967f4fd 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -131,7 +131,6 @@ extern int conn_ctx_stack_ndx;
struct vfs_init_function_entry;
extern struct vfs_init_function_entry *backends;
extern char *sparse_buf;
-extern char *LastDir;
/* Current number of oplocks we have outstanding. */
extern int32_t exclusive_oplocks_open;
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 7ee6c9b59c..27115021bf 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -1569,7 +1569,9 @@ static bool check_share_info(int uLevel, char* id)
}
break;
case 1:
- if (strcmp(id,"B13BWz") != 0) {
+ /* Level-2 descriptor is allowed (and ignored) */
+ if (strcmp(id,"B13BWz") != 0 &&
+ strcmp(id,"B13BWzWWWzB9B") != 0) {
return False;
}
break;
@@ -2616,7 +2618,7 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
*/
{
- auth_serversupplied_info *server_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 755ff5d6cd..2e63f7a395 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -248,7 +248,7 @@ static int register_homes_share(const char *username)
int register_existing_vuid(struct smbd_server_connection *sconn,
uint16 vuid,
- auth_serversupplied_info *server_info,
+ struct auth_serversupplied_info *server_info,
DATA_BLOB response_blob,
const char *smb_name)
{
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 828053811b..7342420a89 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1109,6 +1109,10 @@ uint32_t map_canon_ace_perms(int snum,
}
}
+ if ((perms & S_IWUSR) && lp_dos_filemode(snum)) {
+ nt_mask |= (SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|DELETE_ACCESS);
+ }
+
DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n",
(unsigned int)perms, (unsigned int)nt_mask ));
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index b2d98bfbc0..b6316aac46 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -5368,8 +5368,12 @@ void reply_rmdir(struct smb_request *req)
goto out;
}
- close_file(req, fsp, NORMAL_CLOSE);
- reply_outbuf(req, 0, 0);
+ status = close_file(req, fsp, NORMAL_CLOSE);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ } else {
+ reply_outbuf(req, 0, 0);
+ }
dptr_closepath(sconn, smb_dname->base_name, req->smbpid);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 612cf2231a..ae99127db2 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -41,7 +41,7 @@ struct pending_auth_data {
is set approriately
*/
static NTSTATUS do_map_to_guest(NTSTATUS status,
- auth_serversupplied_info **server_info,
+ struct auth_serversupplied_info **server_info,
const char *user, const char *domain)
{
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
@@ -128,10 +128,10 @@ static void reply_sesssetup_blob(struct smb_request *req,
Do a 'guest' logon, getting back the
****************************************************************************/
-static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
+static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
{
struct auth_context *auth_context;
- auth_usersupplied_info *user_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
NTSTATUS nt_status;
unsigned char chal[8];
@@ -244,7 +244,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
NTSTATUS ret = NT_STATUS_OK;
struct PAC_DATA *pac_data = NULL;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
- auth_serversupplied_info *server_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
DATA_BLOB session_key = data_blob_null;
uint8 tok_id[2];
DATA_BLOB nullblob = data_blob_null;
@@ -1388,8 +1388,8 @@ void reply_sesssetup_and_X(struct smb_request *req)
const char *native_os;
const char *native_lanman;
const char *primary_domain;
- auth_usersupplied_info *user_info = NULL;
- auth_serversupplied_info *server_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
uint16 smb_flag2 = req->flags2;
NTSTATUS nt_status;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 2ce61eed30..5acec70f54 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -706,26 +706,7 @@ const char *vfs_readdirname(connection_struct *conn, void *p,
int vfs_ChDir(connection_struct *conn, const char *path)
{
- int res;
-
- if (!LastDir) {
- LastDir = SMB_STRDUP("");
- }
-
- if (strcsequal(path,"."))
- return(0);
-
- if (*path == '/' && strcsequal(LastDir,path))
- return(0);
-
- DEBUG(4,("vfs_ChDir to %s\n",path));
-
- res = SMB_VFS_CHDIR(conn,path);
- if (!res) {
- SAFE_FREE(LastDir);
- LastDir = SMB_STRDUP(path);
- }
- return(res);
+ return SMB_VFS_CHDIR(conn,path);
}
/*******************************************************************