diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 87 | ||||
-rw-r--r-- | source3/smbd/close.c | 11 | ||||
-rw-r--r-- | source3/smbd/dir.c | 8 | ||||
-rw-r--r-- | source3/smbd/file_access.c | 11 | ||||
-rw-r--r-- | source3/smbd/globals.c | 1 | ||||
-rw-r--r-- | source3/smbd/globals.h | 1 | ||||
-rw-r--r-- | source3/smbd/lanman.c | 6 | ||||
-rw-r--r-- | source3/smbd/password.c | 2 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 4 | ||||
-rw-r--r-- | source3/smbd/reply.c | 8 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 12 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 21 |
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, ¤t_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, ¤t_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); } /******************************************************************* |