diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/msdfs.c | 52 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 74 |
2 files changed, 81 insertions, 45 deletions
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 3641e8d4cc..f4376d49ce 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -525,7 +525,6 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, char *q = NULL; NTSTATUS status; struct smb_filename *smb_fname = NULL; - char *localpath = NULL; char *canon_dfspath = NULL; /* Canonicalized dfs path. (only '/' components). */ @@ -547,26 +546,29 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, status = unix_convert(ctx, conn, pdp->reqpath, &smb_fname, search_flag ? UCF_ALLOW_WCARD_LCOMP : 0); - if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, - NT_STATUS_OBJECT_PATH_NOT_FOUND)) { - return status; - } - - status = get_full_smb_filename(ctx, smb_fname, &localpath); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(smb_fname); - return status; - } + if (!NT_STATUS_EQUAL(status, + NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + return status; + } - TALLOC_FREE(smb_fname); + /* Create an smb_fname to use below. */ + status = create_synthetic_smb_fname(ctx, pdp->reqpath, NULL, + NULL, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } /* Optimization - check if we can redirect the whole path. */ - if (is_msdfs_link_internal(ctx, conn, localpath, pp_targetpath, NULL)) { + if (is_msdfs_link_internal(ctx, conn, smb_fname->base_name, + pp_targetpath, NULL)) { if (search_flag) { DEBUG(6,("dfs_path_lookup (FindFirst) No redirection " "for dfs link %s.\n", dfspath)); - return NT_STATUS_OK; + status = NT_STATUS_OK; + goto out; } DEBUG(6,("dfs_path_lookup: %s resolves to a " @@ -576,7 +578,8 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, if (consumedcntp) { *consumedcntp = strlen(dfspath); } - return NT_STATUS_PATH_NOT_COVERED; + status = NT_STATUS_PATH_NOT_COVERED; + goto out; } /* Prepare to test only for '/' components in the given path, @@ -585,7 +588,8 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, canon_dfspath = talloc_strdup(ctx, dfspath); if (!canon_dfspath) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } if (!pdp->posix_path) { string_replace(canon_dfspath, '\\', '/'); @@ -607,7 +611,7 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, * DFS path. If we hit a DFS link then we're done. */ - p = strrchr_m(localpath, '/'); + p = strrchr_m(smb_fname->base_name, '/'); if (consumedcntp) { q = strrchr_m(canon_dfspath, '/'); } @@ -619,9 +623,11 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, } if (is_msdfs_link_internal(ctx, conn, - localpath, pp_targetpath, NULL)) { + smb_fname->base_name, pp_targetpath, + NULL)) { DEBUG(4, ("dfs_path_lookup: Redirecting %s because " - "parent %s is dfs link\n", dfspath, localpath)); + "parent %s is dfs link\n", dfspath, + smb_fname_str_dbg(smb_fname))); if (consumedcntp) { *consumedcntp = strlen(canon_dfspath); @@ -631,11 +637,12 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, *consumedcntp)); } - return NT_STATUS_PATH_NOT_COVERED; + status = NT_STATUS_PATH_NOT_COVERED; + goto out; } /* Step back on the filesystem. */ - p = strrchr_m(localpath, '/'); + p = strrchr_m(smb_fname->base_name, '/'); if (consumedcntp) { /* And in the canonicalized dfs path. */ @@ -643,7 +650,10 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx, } } - return NT_STATUS_OK; + status = NT_STATUS_OK; + out: + TALLOC_FREE(smb_fname); + return status; } /***************************************************************** diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6fde8d240c..50edf466c3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3982,7 +3982,6 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, time_t create_time, mtime, atime; SMB_STRUCT_STAT sbuf; char *p; - char *fname; char *base_name; char *dos_fname; int mode; @@ -4000,11 +3999,6 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, return NT_STATUS_INVALID_LEVEL; } - status = get_full_smb_filename(mem_ctx, smb_fname, &fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n", smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1, info_level, max_data_bytes)); @@ -4070,10 +4064,18 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, } else { dos_fname = talloc_asprintf(mem_ctx, "\\%s", - fname); + smb_fname->base_name); if (!dos_fname) { return NT_STATUS_NO_MEMORY; } + if (is_ntfs_stream_smb_fname(smb_fname)) { + dos_fname = talloc_asprintf(dos_fname, "%s", + smb_fname->stream_name); + if (!dos_fname) { + return NT_STATUS_NO_MEMORY; + } + } + string_replace(dos_fname, '/', '\\'); } @@ -4126,7 +4128,9 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, case SMB_INFO_QUERY_EA_SIZE: { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + unsigned int ea_size = + estimate_ea_size(conn, fsp, + smb_fname->base_name); DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); data_size = 26; srv_put_dos_date2(pdata,0,create_time); @@ -4156,7 +4160,10 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); - ea_file_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); + ea_file_list = + get_ea_list_from_file(mem_ctx, conn, fsp, + smb_fname->base_name, + &total_ea_len); ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len); if (!ea_list || (total_ea_len > data_size)) { @@ -4176,7 +4183,9 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); - ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); + ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, + smb_fname->base_name, + &total_ea_len); if (!ea_list || (total_ea_len > data_size)) { data_size = 4; SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ @@ -4197,10 +4206,10 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, /*TODO: add filtering and index handling */ - ea_file_list = get_ea_list_from_file(mem_ctx, - conn, fsp, - fname, - &total_ea_len); + ea_file_list = + get_ea_list_from_file(mem_ctx, conn, fsp, + smb_fname->base_name, + &total_ea_len); if (!ea_file_list) { return NT_STATUS_NO_EAS_ON_FILE; } @@ -4257,7 +4266,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, case SMB_FILE_EA_INFORMATION: case SMB_QUERY_FILE_EA_INFO: { - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + unsigned int ea_size = + estimate_ea_size(conn, fsp, smb_fname->base_name); DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); data_size = 4; SIVAL(pdata,0,ea_size); @@ -4318,7 +4328,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, case SMB_FILE_ALL_INFORMATION: { int len; - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + unsigned int ea_size = + estimate_ea_size(conn, fsp, smb_fname->base_name); DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); put_long_date_timespec(pdata,create_time_ts); put_long_date_timespec(pdata+8,atime_ts); @@ -4349,7 +4360,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/ { int len; - unsigned int ea_size = estimate_ea_size(conn, fsp, fname); + unsigned int ea_size = + estimate_ea_size(conn, fsp, smb_fname->base_name); DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n")); put_long_date_timespec(pdata+0x00,create_time_ts); put_long_date_timespec(pdata+0x08,atime_ts); @@ -4445,8 +4457,12 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: " "SMB_FILE_STREAM_INFORMATION\n")); + if (is_ntfs_stream_smb_fname(smb_fname)) { + return NT_STATUS_INVALID_PARAMETER; + } + status = SMB_VFS_STREAMINFO( - conn, fsp, fname, talloc_tos(), + conn, fsp, smb_fname->base_name, talloc_tos(), &num_streams, &streams); if (!NT_STATUS_IS_OK(status)) { @@ -4551,8 +4567,9 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, #else return NT_STATUS_DOS(ERRDOS, ERRbadlink); #endif - len = SMB_VFS_READLINK(conn,fname, - buffer, PATH_MAX); + len = SMB_VFS_READLINK(conn, + smb_fname->base_name, + buffer, PATH_MAX); if (len == -1) { return map_nt_error_from_unix(errno); } @@ -4578,12 +4595,17 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); } else { - file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); + file_acl = + SMB_VFS_SYS_ACL_GET_FILE(conn, + smb_fname->base_name, + SMB_ACL_TYPE_ACCESS); } if (file_acl == NULL && no_acl_syscall_error(errno)) { - DEBUG(5,("smbd_do_qfilepathinfo: ACLs not implemented on filesystem containing %s\n", - fname )); + DEBUG(5,("smbd_do_qfilepathinfo: ACLs " + "not implemented on " + "filesystem containing %s\n", + smb_fname->base_name)); return NT_STATUS_NOT_IMPLEMENTED; } @@ -4595,7 +4617,11 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, fsp->fsp_name->base_name, SMB_ACL_TYPE_DEFAULT); } else { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); + def_acl = + SMB_VFS_SYS_ACL_GET_FILE( + conn, + smb_fname->base_name, + SMB_ACL_TYPE_DEFAULT); } def_acl = free_empty_sys_acl(conn, def_acl); } |