diff options
-rw-r--r-- | source3/modules/vfs_default.c | 58 | ||||
-rw-r--r-- | source3/smbd/close.c | 5 | ||||
-rw-r--r-- | source3/smbd/file_access.c | 10 | ||||
-rw-r--r-- | source3/smbd/reply.c | 86 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 81 |
5 files changed, 81 insertions, 159 deletions
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index d6a66b01de5..cdfd28c5711 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -218,27 +218,17 @@ static int vfswrap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_open); - /* - * XXX: Should an error be returned if there is a stream rather than - * trying to open a filename with a ':'? - */ - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_open(fname, flags, mode); - - TALLOC_FREE(fname); - + result = sys_open(smb_fname->base_name, flags, mode); + out: END_PROFILE(syscall_open); return result; } @@ -562,23 +552,17 @@ static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp) static int vfswrap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_stat); - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_stat(fname, &smb_fname->st); - - TALLOC_FREE(fname); - + result = sys_stat(smb_fname->base_name, &smb_fname->st); + out: END_PROFILE(syscall_stat); return result; } @@ -596,23 +580,17 @@ static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUC static int vfswrap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int result; - NTSTATUS status; - char *fname = NULL; + int result = -1; START_PROFILE(syscall_lstat); - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - return -1; + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; } - result = sys_lstat(fname, &smb_fname->st); - - TALLOC_FREE(fname); - + result = sys_lstat(smb_fname->base_name, &smb_fname->st); + out: END_PROFILE(syscall_lstat); return result; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index f878aaa0568..788b0a7ceca 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -47,10 +47,7 @@ static NTSTATUS check_magic(struct files_struct *fsp) ctx = talloc_stackframe(); - status = get_full_smb_filename(ctx, fsp->fsp_name, &fname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } + fname = fsp->fsp_name->base_name; if (!(p = strrchr_m(fname,'/'))) { p = fname; diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index d8fee1db06f..7d0a552956e 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -33,7 +33,6 @@ bool can_access_file_acl(struct connection_struct *conn, NTSTATUS status; uint32_t access_granted; struct security_descriptor *secdesc = NULL; - char *fname = NULL; bool ret; if (conn->server_info->utok.uid == 0 || conn->admin_user) { @@ -41,13 +40,7 @@ bool can_access_file_acl(struct connection_struct *conn, return true; } - status = get_full_smb_filename(talloc_tos(), smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - ret = false; - goto out; - } - - status = SMB_VFS_GET_NT_ACL(conn, fname, + status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION), @@ -62,7 +55,6 @@ bool can_access_file_acl(struct connection_struct *conn, access_mask, &access_granted); ret = NT_STATUS_IS_OK(status); out: - TALLOC_FREE(fname); TALLOC_FREE(secdesc); return ret; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 72595aeda7e..76d32a2f98e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1340,6 +1340,7 @@ void reply_search(struct smb_request *req) char *path = NULL; const char *mask = NULL; char *directory = NULL; + struct smb_filename *smb_fname = NULL; char *fname = NULL; SMB_OFF_T size; uint32 mode; @@ -1364,14 +1365,12 @@ void reply_search(struct smb_request *req) if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - END_PROFILE(SMBsearch); - return; + goto out; } if (lp_posix_pathnames()) { reply_unknown_new(req, req->cmd); - END_PROFILE(SMBsearch); - return; + goto out; } /* If we were called as SMBffirst then we must expect close. */ @@ -1387,8 +1386,7 @@ void reply_search(struct smb_request *req) &nt_status, &mask_contains_wcard); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } p++; @@ -1398,8 +1396,6 @@ void reply_search(struct smb_request *req) /* dirtype &= ~aDIR; */ if (status_len == 0) { - struct smb_filename *smb_fname = NULL; - nt_status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, path, @@ -1409,35 +1405,25 @@ void reply_search(struct smb_request *req) if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - END_PROFILE(SMBsearch); - return; + goto out; } reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } nt_status = unix_convert(ctx, conn, path, &smb_fname, UCF_ALLOW_WCARD_LCOMP); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } - nt_status = get_full_smb_filename(ctx, smb_fname, &directory); - TALLOC_FREE(smb_fname); - if (!NT_STATUS_IS_OK(nt_status)) { - reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; - } + directory = smb_fname->base_name; nt_status = check_name(conn, directory); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } p = strrchr_m(directory,'/'); @@ -1452,8 +1438,7 @@ void reply_search(struct smb_request *req) if (!directory) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } memset((char *)status,'\0',21); @@ -1470,8 +1455,7 @@ void reply_search(struct smb_request *req) &conn->dirptr); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); - END_PROFILE(SMBsearch); - return; + goto out; } dptr_num = dptr_dnum(conn->dirptr); } else { @@ -1511,8 +1495,7 @@ void reply_search(struct smb_request *req) if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)), 0,aVOLID,0,!allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } dptr_fill(buf+12,dptr_num); if (dptr_zero(buf+12) && (status_len==0)) { @@ -1524,8 +1507,7 @@ void reply_search(struct smb_request *req) data_blob_const(buf, sizeof(buf))) == -1) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } } else { unsigned int i; @@ -1564,8 +1546,7 @@ void reply_search(struct smb_request *req) convert_timespec_to_time_t(date), !allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } if (!dptr_fill(buf+12,dptr_num)) { break; @@ -1574,8 +1555,7 @@ void reply_search(struct smb_request *req) data_blob_const(buf, sizeof(buf))) == -1) { reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; + goto out; } numentries++; } @@ -1602,8 +1582,7 @@ void reply_search(struct smb_request *req) if ((numentries == 0) && !mask_contains_wcard) { reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles); - END_PROFILE(SMBsearch); - return; + goto out; } SSVAL(req->outbuf,smb_vwv0,numentries); @@ -1635,7 +1614,8 @@ void reply_search(struct smb_request *req) dirtype, numentries, maxentries )); - + out: + TALLOC_FREE(smb_fname); END_PROFILE(SMBsearch); return; } @@ -5811,9 +5791,6 @@ static void notify_rename(connection_struct *conn, bool is_dir, { char *parent_dir_src = NULL; char *parent_dir_dst = NULL; - char *fname_src = NULL; - char *fname_dst = NULL; - NTSTATUS status; uint32 mask; mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME @@ -5826,24 +5803,17 @@ static void notify_rename(connection_struct *conn, bool is_dir, goto out; } - status = get_full_smb_filename(talloc_tos(), smb_fname_src, - &fname_src); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = get_full_smb_filename(talloc_tos(), smb_fname_dst, - &fname_dst); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - if (strcmp(parent_dir_src, parent_dir_dst) == 0) { - notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src); - notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst); + notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, + smb_fname_src->base_name); + notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, + smb_fname_dst->base_name); } else { - notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src); - notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst); + notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, + smb_fname_src->base_name); + notify_fname(conn, NOTIFY_ACTION_ADDED, mask, + smb_fname_dst->base_name); } /* this is a strange one. w2k3 gives an additional event for @@ -5853,13 +5823,11 @@ static void notify_rename(connection_struct *conn, bool is_dir, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES |FILE_NOTIFY_CHANGE_CREATION, - fname_dst); + smb_fname_dst->base_name); } out: TALLOC_FREE(parent_dir_src); TALLOC_FREE(parent_dir_dst); - TALLOC_FREE(fname_src); - TALLOC_FREE(fname_dst); } /**************************************************************************** diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 8637d1bda1e..daaf97c18d8 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -471,17 +471,13 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname, struct ea_list *ea_list) { char *fname = NULL; - NTSTATUS status; if (!lp_ea_support(SNUM(conn))) { return NT_STATUS_EAS_NOT_SUPPORTED; } - status = get_full_smb_filename(talloc_tos(), smb_fname, - &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + /* For now setting EAs on streams isn't supported. */ + fname = smb_fname->base_name; for (;ea_list; ea_list = ea_list->next) { int ret; @@ -2039,7 +2035,7 @@ static void call_trans2findfirst(connection_struct *conn, if (total_params < 13) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } dirtype = SVAL(params,0); @@ -2077,12 +2073,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", ask_sharemode = false; if (!lp_unix_extensions()) { reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + goto out; } break; default: reply_nterror(req, NT_STATUS_INVALID_LEVEL); - return; + goto out; } srvstr_get_path_wcard(ctx, params, req->flags2, &directory, @@ -2090,7 +2086,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", STR_TERMINATE, &ntstatus, &mask_contains_wcard); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } ntstatus = resolve_dfspath_wcard(ctx, conn, @@ -2102,32 +2098,27 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); - return; + goto out; } reply_nterror(req, ntstatus); - return; + goto out; } ntstatus = unix_convert(ctx, conn, directory, &smb_dname, (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP)); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } mask = smb_dname->original_lcomp; - ntstatus = get_full_smb_filename(ctx, smb_dname, &directory); - TALLOC_FREE(smb_dname); - if (!NT_STATUS_IS_OK(ntstatus)) { - reply_nterror(req, ntstatus); - return; - } + directory = smb_dname->base_name; ntstatus = check_name(conn, directory); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } p = strrchr_m(directory,'/'); @@ -2137,14 +2128,14 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", mask = talloc_strdup(ctx,"*"); if (!mask) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } mask_contains_wcard = True; } directory = talloc_strdup(talloc_tos(), "./"); if (!directory) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } } else { *p = 0; @@ -2157,7 +2148,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", if (total_data < 4) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } ea_size = IVAL(pdata,0); @@ -2165,19 +2156,19 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } if (!lp_ea_support(SNUM(conn))) { reply_doserror(req, ERRDOS, ERReasnotsupported); - return; + goto out; } /* Pull out the list of names. */ ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4); if (!ea_list) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); - return; + goto out; } } @@ -2185,7 +2176,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); if(*ppdata == NULL ) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } pdata = *ppdata; data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; @@ -2194,7 +2185,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd *pparams = (char *)SMB_REALLOC(*pparams, 10); if (*pparams == NULL) { reply_nterror(req, NT_STATUS_NO_MEMORY); - return; + goto out; } params = *pparams; @@ -2213,7 +2204,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); - return; + goto out; } dptr_num = dptr_dnum(conn->dirptr); @@ -2296,11 +2287,11 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dptr_close(&dptr_num); if (Protocol < PROTOCOL_NT1) { reply_doserror(req, ERRDOS, ERRnofiles); - return; + goto out; } else { reply_botherror(req, NT_STATUS_NO_SUCH_FILE, ERRDOS, ERRbadfile); - return; + goto out; } } @@ -2339,7 +2330,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd char mangled_name[13]; name_to_8_3(mask, mangled_name, True, conn->params); } - + out: + TALLOC_FREE(smb_dname); return; } @@ -5122,8 +5114,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, const struct smb_filename *smb_fname_old, const struct smb_filename *smb_fname_new) { - char *oldname = NULL; - char *newname = NULL; NTSTATUS status = NT_STATUS_OK; /* source must already exist. */ @@ -5141,25 +5131,22 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, return NT_STATUS_FILE_IS_A_DIRECTORY; } - status = get_full_smb_filename(ctx, smb_fname_new, &newname); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - status = get_full_smb_filename(ctx, smb_fname_old, &oldname); - if (!NT_STATUS_IS_OK(status)) { - goto out; + /* Setting a hardlink to/from a stream isn't currently supported. */ + if (is_ntfs_stream_smb_fname(smb_fname_old) || + is_ntfs_stream_smb_fname(smb_fname_new)) { + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname )); + DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", + smb_fname_old->base_name, smb_fname_new->base_name)); - if (SMB_VFS_LINK(conn,oldname,newname) != 0) { + if (SMB_VFS_LINK(conn, smb_fname_old->base_name, + smb_fname_new->base_name) != 0) { status = map_nt_error_from_unix(errno); DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n", - nt_errstr(status), newname, oldname)); + nt_errstr(status), smb_fname_old->base_name, + smb_fname_new->base_name)); } - out: - TALLOC_FREE(newname); - TALLOC_FREE(oldname); return status; } |