2004-09-20 07:28:43 +00:00
/*
Unix SMB / CIFS implementation .
POSIX NTVFS backend - read
Copyright ( C ) Andrew Tridgell 2004
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
2004-11-05 07:24:25 +00:00
# include "includes.h"
2004-09-20 07:28:43 +00:00
# include "vfs_posix.h"
2004-11-05 11:31:35 +00:00
# include "librpc/gen_ndr/ndr_xattr.h"
2004-09-20 07:28:43 +00:00
2004-12-17 22:47:49 +00:00
/*
reply to a RAW_FILEINFO_EA_LIST call
*/
static NTSTATUS pvfs_query_ea_list ( struct pvfs_state * pvfs , TALLOC_CTX * mem_ctx ,
struct pvfs_filename * name , int fd ,
uint_t num_names ,
struct ea_name * names ,
struct smb_ea_list * eas )
{
NTSTATUS status ;
int i ;
struct xattr_DosEAs * ealist = talloc_p ( mem_ctx , struct xattr_DosEAs ) ;
ZERO_STRUCTP ( eas ) ;
status = pvfs_doseas_load ( pvfs , name , fd , ealist ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
eas - > eas = talloc_array_p ( mem_ctx , struct ea_struct , num_names ) ;
if ( eas - > eas = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
eas - > num_eas = num_names ;
for ( i = 0 ; i < num_names ; i + + ) {
int j ;
eas - > eas [ i ] . flags = 0 ;
eas - > eas [ i ] . name . s = names [ i ] . name . s ;
eas - > eas [ i ] . value = data_blob ( NULL , 0 ) ;
for ( j = 0 ; j < ealist - > num_eas ; j + + ) {
if ( StrCaseCmp ( eas - > eas [ i ] . name . s ,
ealist - > eas [ j ] . name ) = = 0 ) {
eas - > eas [ i ] . value = ealist - > eas [ j ] . value ;
break ;
}
}
}
return NT_STATUS_OK ;
}
2004-11-05 11:31:35 +00:00
/*
reply to a RAW_FILEINFO_ALL_EAS call
*/
static NTSTATUS pvfs_query_all_eas ( struct pvfs_state * pvfs , TALLOC_CTX * mem_ctx ,
2004-11-17 12:36:14 +00:00
struct pvfs_filename * name , int fd ,
struct smb_ea_list * eas )
2004-11-05 11:31:35 +00:00
{
NTSTATUS status ;
int i ;
struct xattr_DosEAs * ealist = talloc_p ( mem_ctx , struct xattr_DosEAs ) ;
ZERO_STRUCTP ( eas ) ;
status = pvfs_doseas_load ( pvfs , name , fd , ealist ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2004-12-17 22:47:49 +00:00
eas - > eas = talloc_array_p ( mem_ctx , struct ea_struct , ealist - > num_eas ) ;
2004-11-05 11:31:35 +00:00
if ( eas - > eas = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-12-17 22:47:49 +00:00
eas - > num_eas = 0 ;
for ( i = 0 ; i < ealist - > num_eas ; i + + ) {
eas - > eas [ eas - > num_eas ] . flags = 0 ;
eas - > eas [ eas - > num_eas ] . name . s = ealist - > eas [ i ] . name ;
eas - > eas [ eas - > num_eas ] . value = ealist - > eas [ i ] . value ;
eas - > num_eas + + ;
2004-11-05 11:31:35 +00:00
}
return NT_STATUS_OK ;
}
2004-09-20 07:28:43 +00:00
/*
approximately map a struct pvfs_filename to a generic fileinfo struct
*/
2004-11-18 03:31:35 +00:00
static NTSTATUS pvfs_map_fileinfo ( struct pvfs_state * pvfs ,
struct smbsrv_request * req ,
2004-11-05 11:31:35 +00:00
struct pvfs_filename * name , union smb_fileinfo * info ,
int fd )
2004-09-20 07:28:43 +00:00
{
2004-10-25 01:16:04 +00:00
switch ( info - > generic . level ) {
2004-10-28 13:19:39 +00:00
case RAW_FILEINFO_GENERIC :
return NT_STATUS_INVALID_LEVEL ;
2004-10-25 01:16:04 +00:00
case RAW_FILEINFO_GETATTR :
info - > getattr . out . attrib = name - > dos . attrib ;
info - > getattr . out . size = name - > st . st_size ;
info - > getattr . out . write_time = nt_time_to_unix ( name - > dos . write_time ) ;
return NT_STATUS_OK ;
case RAW_FILEINFO_GETATTRE :
case RAW_FILEINFO_STANDARD :
info - > standard . out . create_time = nt_time_to_unix ( name - > dos . create_time ) ;
info - > standard . out . access_time = nt_time_to_unix ( name - > dos . access_time ) ;
info - > standard . out . write_time = nt_time_to_unix ( name - > dos . write_time ) ;
info - > standard . out . size = name - > st . st_size ;
info - > standard . out . alloc_size = name - > dos . alloc_size ;
info - > standard . out . attrib = name - > dos . attrib ;
return NT_STATUS_OK ;
case RAW_FILEINFO_EA_SIZE :
info - > ea_size . out . create_time = nt_time_to_unix ( name - > dos . create_time ) ;
info - > ea_size . out . access_time = nt_time_to_unix ( name - > dos . access_time ) ;
info - > ea_size . out . write_time = nt_time_to_unix ( name - > dos . write_time ) ;
info - > ea_size . out . size = name - > st . st_size ;
info - > ea_size . out . alloc_size = name - > dos . alloc_size ;
info - > ea_size . out . attrib = name - > dos . attrib ;
info - > ea_size . out . ea_size = name - > dos . ea_size ;
return NT_STATUS_OK ;
2004-12-17 22:47:49 +00:00
case RAW_FILEINFO_EA_LIST :
return pvfs_query_ea_list ( pvfs , req , name , fd ,
info - > ea_list . in . num_names ,
info - > ea_list . in . ea_names ,
& info - > ea_list . out ) ;
2004-10-25 01:16:04 +00:00
case RAW_FILEINFO_ALL_EAS :
2004-11-18 03:31:35 +00:00
return pvfs_query_all_eas ( pvfs , req , name , fd , & info - > all_eas . out ) ;
2004-10-25 01:16:04 +00:00
case RAW_FILEINFO_IS_NAME_VALID :
return NT_STATUS_OK ;
case RAW_FILEINFO_BASIC_INFO :
case RAW_FILEINFO_BASIC_INFORMATION :
info - > basic_info . out . create_time = name - > dos . create_time ;
info - > basic_info . out . access_time = name - > dos . access_time ;
info - > basic_info . out . write_time = name - > dos . write_time ;
info - > basic_info . out . change_time = name - > dos . change_time ;
info - > basic_info . out . attrib = name - > dos . attrib ;
return NT_STATUS_OK ;
case RAW_FILEINFO_STANDARD_INFO :
case RAW_FILEINFO_STANDARD_INFORMATION :
info - > standard_info . out . alloc_size = name - > dos . alloc_size ;
info - > standard_info . out . size = name - > st . st_size ;
info - > standard_info . out . nlink = name - > st . st_nlink ;
info - > standard_info . out . delete_pending = 0 ;
info - > standard_info . out . directory =
( name - > dos . attrib & FILE_ATTRIBUTE_DIRECTORY ) ? 1 : 0 ;
return NT_STATUS_OK ;
case RAW_FILEINFO_EA_INFO :
case RAW_FILEINFO_EA_INFORMATION :
info - > ea_info . out . ea_size = name - > dos . ea_size ;
return NT_STATUS_OK ;
case RAW_FILEINFO_NAME_INFO :
case RAW_FILEINFO_NAME_INFORMATION :
info - > name_info . out . fname . s = name - > original_name ;
return NT_STATUS_OK ;
case RAW_FILEINFO_ALL_INFO :
case RAW_FILEINFO_ALL_INFORMATION :
info - > all_info . out . create_time = name - > dos . create_time ;
info - > all_info . out . access_time = name - > dos . access_time ;
info - > all_info . out . write_time = name - > dos . write_time ;
info - > all_info . out . change_time = name - > dos . change_time ;
info - > all_info . out . attrib = name - > dos . attrib ;
info - > all_info . out . alloc_size = name - > dos . alloc_size ;
info - > all_info . out . size = name - > st . st_size ;
info - > all_info . out . nlink = name - > st . st_nlink ;
info - > all_info . out . delete_pending = 0 ;
info - > all_info . out . directory =
( name - > dos . attrib & FILE_ATTRIBUTE_DIRECTORY ) ? 1 : 0 ;
info - > all_info . out . ea_size = name - > dos . ea_size ;
info - > all_info . out . fname . s = name - > original_name ;
return NT_STATUS_OK ;
case RAW_FILEINFO_ALT_NAME_INFO :
case RAW_FILEINFO_ALT_NAME_INFORMATION :
info - > name_info . out . fname . s = pvfs_short_name ( pvfs , name , name ) ;
return NT_STATUS_OK ;
case RAW_FILEINFO_STREAM_INFO :
case RAW_FILEINFO_STREAM_INFORMATION :
2004-11-18 03:31:35 +00:00
return pvfs_stream_information ( pvfs , req , name , fd , & info - > stream_info . out ) ;
2004-10-25 01:16:04 +00:00
case RAW_FILEINFO_COMPRESSION_INFO :
case RAW_FILEINFO_COMPRESSION_INFORMATION :
info - > compression_info . out . compressed_size = name - > st . st_size ;
info - > compression_info . out . format = 0 ;
info - > compression_info . out . unit_shift = 0 ;
info - > compression_info . out . chunk_shift = 0 ;
info - > compression_info . out . cluster_shift = 0 ;
return NT_STATUS_OK ;
case RAW_FILEINFO_INTERNAL_INFORMATION :
info - > internal_information . out . file_id = name - > dos . file_id ;
return NT_STATUS_OK ;
case RAW_FILEINFO_ACCESS_INFORMATION :
info - > access_information . out . access_flags = 0 ;
return NT_STATUS_OK ;
case RAW_FILEINFO_POSITION_INFORMATION :
info - > position_information . out . position = 0 ;
return NT_STATUS_OK ;
case RAW_FILEINFO_MODE_INFORMATION :
2004-11-07 10:09:50 +00:00
info - > mode_information . out . mode = 0 ;
2004-10-25 01:16:04 +00:00
return NT_STATUS_OK ;
case RAW_FILEINFO_ALIGNMENT_INFORMATION :
info - > alignment_information . out . alignment_requirement = 0 ;
return NT_STATUS_OK ;
case RAW_FILEINFO_NETWORK_OPEN_INFORMATION :
info - > network_open_information . out . create_time = name - > dos . create_time ;
info - > network_open_information . out . access_time = name - > dos . access_time ;
info - > network_open_information . out . write_time = name - > dos . write_time ;
info - > network_open_information . out . change_time = name - > dos . change_time ;
info - > network_open_information . out . alloc_size = name - > dos . alloc_size ;
info - > network_open_information . out . size = name - > st . st_size ;
info - > network_open_information . out . attrib = name - > dos . attrib ;
return NT_STATUS_OK ;
case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION :
info - > attribute_tag_information . out . attrib = name - > dos . attrib ;
info - > attribute_tag_information . out . reparse_tag = 0 ;
return NT_STATUS_OK ;
2004-11-18 03:31:35 +00:00
case RAW_FILEINFO_SEC_DESC :
return pvfs_acl_query ( pvfs , req , name , fd , info ) ;
2004-09-20 07:28:43 +00:00
}
2004-10-25 01:16:04 +00:00
return NT_STATUS_INVALID_LEVEL ;
2004-09-20 07:28:43 +00:00
}
/*
return info on a pathname
*/
2004-09-29 13:17:09 +00:00
NTSTATUS pvfs_qpathinfo ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , union smb_fileinfo * info )
2004-09-20 07:28:43 +00:00
{
2004-09-29 13:17:09 +00:00
struct pvfs_state * pvfs = ntvfs - > private_data ;
2004-09-20 07:28:43 +00:00
struct pvfs_filename * name ;
NTSTATUS status ;
/* resolve the cifs name to a posix name */
2004-11-17 05:58:04 +00:00
status = pvfs_resolve_name ( pvfs , req , info - > generic . in . fname , PVFS_RESOLVE_STREAMS , & name ) ;
2004-09-20 07:28:43 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2004-11-17 05:58:04 +00:00
if ( ! name - > stream_exists ) {
2004-09-20 07:28:43 +00:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2004-11-05 11:31:35 +00:00
status = pvfs_map_fileinfo ( pvfs , req , name , info , - 1 ) ;
2004-10-25 01:16:04 +00:00
return status ;
2004-09-20 07:28:43 +00:00
}
/*
query info on a open file
*/
2004-09-29 13:17:09 +00:00
NTSTATUS pvfs_qfileinfo ( struct ntvfs_module_context * ntvfs ,
struct smbsrv_request * req , union smb_fileinfo * info )
2004-09-20 07:28:43 +00:00
{
2004-09-29 13:17:09 +00:00
struct pvfs_state * pvfs = ntvfs - > private_data ;
2004-09-20 07:28:43 +00:00
struct pvfs_file * f ;
2004-11-08 03:54:12 +00:00
struct pvfs_file_handle * h ;
2004-09-20 07:28:43 +00:00
NTSTATUS status ;
2004-09-29 13:17:09 +00:00
f = pvfs_find_fd ( pvfs , req , info - > generic . in . fnum ) ;
2004-09-20 07:28:43 +00:00
if ( ! f ) {
return NT_STATUS_INVALID_HANDLE ;
}
2004-11-08 03:54:12 +00:00
h = f - > handle ;
2004-09-20 07:28:43 +00:00
/* update the file information */
2004-11-08 03:54:12 +00:00
status = pvfs_resolve_name_fd ( pvfs , h - > fd , h - > name ) ;
2004-09-20 07:28:43 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2004-11-08 03:54:12 +00:00
status = pvfs_map_fileinfo ( pvfs , req , h - > name , info , h - > fd ) ;
2004-10-24 14:18:03 +00:00
2004-10-25 01:16:04 +00:00
/* a qfileinfo can fill in a bit more info than a qpathinfo -
now modify the levels that need to be fixed up */
switch ( info - > generic . level ) {
case RAW_FILEINFO_STANDARD_INFO :
case RAW_FILEINFO_STANDARD_INFORMATION :
2004-11-08 03:54:12 +00:00
if ( h - > create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE ) {
2004-10-25 01:16:04 +00:00
info - > standard_info . out . delete_pending = 1 ;
info - > standard_info . out . nlink - - ;
}
break ;
case RAW_FILEINFO_ALL_INFO :
case RAW_FILEINFO_ALL_INFORMATION :
2004-11-08 03:54:12 +00:00
if ( h - > create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE ) {
2004-10-25 01:16:04 +00:00
info - > all_info . out . delete_pending = 1 ;
info - > all_info . out . nlink - - ;
}
break ;
case RAW_FILEINFO_POSITION_INFORMATION :
2004-11-08 03:54:12 +00:00
info - > position_information . out . position = h - > position ;
2004-10-25 01:16:04 +00:00
break ;
case RAW_FILEINFO_ACCESS_INFORMATION :
2004-11-08 11:35:49 +00:00
info - > access_information . out . access_flags = f - > access_mask ;
2004-10-25 01:16:04 +00:00
break ;
2004-11-07 10:09:50 +00:00
case RAW_FILEINFO_MODE_INFORMATION :
2004-11-08 03:54:12 +00:00
info - > mode_information . out . mode = h - > mode ;
2004-11-07 10:09:50 +00:00
break ;
2004-10-25 01:16:04 +00:00
default :
break ;
}
2004-10-24 14:18:03 +00:00
return status ;
2004-09-20 07:28:43 +00:00
}