From 754d416ea54e1e520aa035a759ec8e3975ab5354 Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 5 Mar 2007 22:26:38 +0000 Subject: r21710: Add client support for the UNIX_INFO2 info level in the QueryFile, QueryPath and FindFirst calls. Add a new torture test to verify the server side. (This used to be commit 7f56da2d1fa0718e5282bb4aea7d9a63a62f0bc7) --- source4/libcli/raw/interfaces.h | 84 +++++++++++++++++++++++++++++++++++-- source4/libcli/raw/rawfileinfo.c | 21 ++++++++++ source4/libcli/raw/rawsearch.c | 67 ++++++++++++++++++++++------- source4/libcli/raw/rawsetfileinfo.c | 21 ++++++++++ source4/libcli/raw/trans2.h | 46 +++++++++++++++++--- 5 files changed, 214 insertions(+), 25 deletions(-) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 60cefe6931..e4efab3375 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -3,6 +3,7 @@ SMB request interface structures Copyright (C) Andrew Tridgell 2003 Copyright (C) James J Myers 2003 + Copyright (C) James Peach 2007 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 @@ -426,6 +427,7 @@ enum smb_fileinfo_level { RAW_FILEINFO_STREAM_INFO = SMB_QFILEINFO_STREAM_INFO, RAW_FILEINFO_COMPRESSION_INFO = SMB_QFILEINFO_COMPRESSION_INFO, RAW_FILEINFO_UNIX_BASIC = SMB_QFILEINFO_UNIX_BASIC, + RAW_FILEINFO_UNIX_INFO2 = SMB_QFILEINFO_UNIX_INFO2, RAW_FILEINFO_UNIX_LINK = SMB_QFILEINFO_UNIX_LINK, RAW_FILEINFO_BASIC_INFORMATION = SMB_QFILEINFO_BASIC_INFORMATION, RAW_FILEINFO_STANDARD_INFORMATION = SMB_QFILEINFO_STANDARD_INFORMATION, @@ -745,6 +747,32 @@ union smb_fileinfo { } out; } unix_basic_info; + /* RAW_FILEINFO_UNIX_INFO2 interface */ + struct { + enum smb_fileinfo_level level; + struct { + union smb_handle_or_path file; + } in; + struct { + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + NTTIME create_time; + uint32_t file_flags; + uint32_t flags_mask; + } out; + } unix_info2; + /* RAW_FILEINFO_UNIX_LINK interface */ struct { enum smb_fileinfo_level level; @@ -867,6 +895,7 @@ enum smb_setfileinfo_level { RAW_SFILEINFO_ALLOCATION_INFO = SMB_SFILEINFO_ALLOCATION_INFO, RAW_SFILEINFO_END_OF_FILE_INFO = SMB_SFILEINFO_END_OF_FILE_INFO, RAW_SFILEINFO_UNIX_BASIC = SMB_SFILEINFO_UNIX_BASIC, + RAW_SFILEINFO_UNIX_INFO2 = SMB_SFILEINFO_UNIX_INFO2, RAW_SFILEINFO_UNIX_LINK = SMB_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK = SMB_SFILEINFO_UNIX_HLINK, RAW_SFILEINFO_BASIC_INFORMATION = SMB_SFILEINFO_BASIC_INFORMATION, @@ -1003,8 +1032,6 @@ union smb_setfileinfo { } in; } mode_information; - - /* RAW_SFILEINFO_UNIX_BASIC interface */ struct { enum smb_setfileinfo_level level; @@ -1026,7 +1053,31 @@ union smb_setfileinfo { uint64_t nlink; } in; } unix_basic; - + + /* RAW_SFILEINFO_UNIX_INFO2 interface */ + struct { + enum smb_setfileinfo_level level; + struct { + union smb_handle_or_path file; + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + NTTIME create_time; + uint32_t file_flags; + uint32_t flags_mask; + } in; + } unix_info2; + /* RAW_SFILEINFO_UNIX_LINK, RAW_SFILEINFO_UNIX_HLINK interface */ struct { enum smb_setfileinfo_level level; @@ -2204,7 +2255,8 @@ enum smb_search_data_level { RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO = SMB_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO = SMB_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO = SMB_FIND_ID_BOTH_DIRECTORY_INFO, - RAW_SEARCH_DATA_UNIX_INFO = SMB_FIND_UNIX_INFO + RAW_SEARCH_DATA_UNIX_INFO = SMB_FIND_UNIX_INFO, + RAW_SEARCH_DATA_UNIX_INFO2 = SMB_FIND_UNIX_INFO2 }; /* union for file search */ @@ -2504,8 +2556,32 @@ union smb_search_data { uint64_t nlink; const char *name; } unix_info; + + /* RAW_SEARCH_DATA_UNIX_INFO2 interface */ + struct { + uint32_t file_index; + uint64_t end_of_file; + uint64_t num_bytes; + NTTIME status_change_time; + NTTIME access_time; + NTTIME change_time; + uint64_t uid; + uint64_t gid; + uint32_t file_type; + uint64_t dev_major; + uint64_t dev_minor; + uint64_t unique_id; + uint64_t permissions; + uint64_t nlink; + NTTIME create_time; + uint32_t file_flags; + uint32_t flags_mask; + const char *name; + } unix_info2; }; +/* Callback function passed to the raw search interface. */ +typedef BOOL (*smbcli_search_callback)(void *private, const union smb_search_data *file); enum smb_search_close_level {RAW_FINDCLOSE_GENERIC, RAW_FINDCLOSE_FCLOSE, RAW_FINDCLOSE_FINDCLOSE}; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 38f4d12369..7b15ce6fd6 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -3,6 +3,7 @@ client trans2 operations Copyright (C) James Myers 2003 Copyright (C) Andrew Tridgell 2003 + Copyright (C) James Peach 2007 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 @@ -403,6 +404,26 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, parms->unix_basic_info.out.nlink = BVAL(blob->data, 92); return NT_STATUS_OK; + case RAW_FILEINFO_UNIX_INFO2: + FINFO_CHECK_SIZE(116); + parms->unix_info2.out.end_of_file = BVAL(blob->data, 0); + parms->unix_info2.out.num_bytes = BVAL(blob->data, 8); + parms->unix_info2.out.status_change_time = smbcli_pull_nttime(blob->data, 16); + parms->unix_info2.out.access_time = smbcli_pull_nttime(blob->data, 24); + parms->unix_info2.out.change_time = smbcli_pull_nttime(blob->data, 32); + parms->unix_info2.out.uid = BVAL(blob->data, 40); + parms->unix_info2.out.gid = BVAL(blob->data, 48); + parms->unix_info2.out.file_type = IVAL(blob->data, 52); + parms->unix_info2.out.dev_major = BVAL(blob->data, 60); + parms->unix_info2.out.dev_minor = BVAL(blob->data, 68); + parms->unix_info2.out.unique_id = BVAL(blob->data, 76); + parms->unix_info2.out.permissions = BVAL(blob->data, 84); + parms->unix_info2.out.nlink = BVAL(blob->data, 92); + parms->unix_info2.out.create_time = smbcli_pull_nttime(blob->data, 100); + parms->unix_info2.out.file_flags = IVAL(blob->data, 108); + parms->unix_info2.out.flags_mask = IVAL(blob->data, 112); + return NT_STATUS_OK; + case RAW_FILEINFO_UNIX_LINK: smbcli_blob_pull_string(session, mem_ctx, blob, &parms->unix_link_info.out.link_dest, 0, 4, STR_UNICODE); diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 4836766a93..5abe19d50c 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client directory search routines Copyright (C) James Myers 2003 + Copyright (C) James Peach 2007 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 @@ -28,7 +29,7 @@ static void smb_raw_search_backend(struct smbcli_request *req, TALLOC_CTX *mem_ctx, uint16_t count, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { union smb_search_data search_data; @@ -69,7 +70,7 @@ static void smb_raw_search_backend(struct smbcli_request *req, static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { struct smbcli_request *req; @@ -110,7 +111,7 @@ static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { struct smbcli_request *req; @@ -605,17 +606,51 @@ static int parse_trans2_search(struct smbcli_tree *tree, } return ofs; - case RAW_SEARCH_DATA_DIRECTORY_INFO: - case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: - case RAW_SEARCH_DATA_NAME_INFO: - case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: - case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: - case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: { - uint_t str_flags = STR_UNICODE; - if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) { - str_flags = STR_ASCII; + case RAW_SEARCH_DATA_UNIX_INFO2: + if (blob->length < (116 + 8 + 1)) { + return -1; } - + + ofs = IVAL(blob->data, 0); + data->unix_info2.file_index = IVAL(blob->data, 4); + data->unix_info2.end_of_file = BVAL(blob->data, 8); + data->unix_info2.num_bytes = BVAL(blob->data, 16); + data->unix_info2.status_change_time = smbcli_pull_nttime(blob->data, 24); + data->unix_info2.access_time = smbcli_pull_nttime(blob->data, 32); + data->unix_info2.change_time = smbcli_pull_nttime(blob->data, 40); + data->unix_info2.uid = IVAL(blob->data, 48); + data->unix_info2.gid = IVAL(blob->data, 56); + data->unix_info2.file_type = IVAL(blob->data, 64); + data->unix_info2.dev_major = BVAL(blob->data, 68); + data->unix_info2.dev_minor = BVAL(blob->data, 76); + data->unix_info2.unique_id = BVAL(blob->data, 84); + data->unix_info2.permissions = IVAL(blob->data, 92); + data->unix_info2.nlink = IVAL(blob->data, 100); + data->unix_info2.create_time = smbcli_pull_nttime(blob->data, 108); + data->unix_info2.file_flags = IVAL(blob->data, 116); + data->unix_info2.flags_mask = IVAL(blob->data, 120); + + /* There is no length field for this name but we know it's null terminated. */ + len = smbcli_blob_pull_unix_string(tree->session, mem_ctx, blob, + &data->unix_info2.name, 116 + 8, 0); + + if (ofs != 0 && ofs < (116 + 8 + len)) { + return -1; + } + + return ofs; + + case RAW_SEARCH_DATA_DIRECTORY_INFO: + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_NAME_INFO: + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: { + uint_t str_flags = STR_UNICODE; + if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) { + str_flags = STR_ASCII; + } + status = smb_raw_search_common(mem_ctx, level, blob, data, &ofs, str_flags); if (!NT_STATUS_IS_OK(status)) { return -1; @@ -638,7 +673,7 @@ static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, int16_t count, DATA_BLOB *blob, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { int i; @@ -677,7 +712,7 @@ static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree, NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { DATA_BLOB p_blob, d_blob; NTSTATUS status; @@ -725,7 +760,7 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree, NTSTATUS smb_raw_search_next(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + smbcli_search_callback callback) { DATA_BLOB p_blob, d_blob; NTSTATUS status; diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 0daf14e0cc..794ba25480 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -3,6 +3,7 @@ RAW_SFILEINFO_* calls Copyright (C) James Myers 2003 Copyright (C) Andrew Tridgell 2003 + Copyright (C) James Peach 2007 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 @@ -166,6 +167,26 @@ static BOOL smb_raw_setinfo_backend(struct smbcli_tree *tree, SBVAL(blob->data, 92, parms->unix_basic.in.nlink); return True; + case RAW_SFILEINFO_UNIX_INFO2: + NEED_BLOB(116); + SBVAL(blob->data, 0, parms->unix_info2.in.end_of_file); + SBVAL(blob->data, 8, parms->unix_info2.in.num_bytes); + smbcli_push_nttime(blob->data, 16, parms->unix_info2.in.status_change_time); + smbcli_push_nttime(blob->data, 24, parms->unix_info2.in.access_time); + smbcli_push_nttime(blob->data, 32, parms->unix_info2.in.change_time); + SBVAL(blob->data, 40,parms->unix_info2.in.uid); + SBVAL(blob->data, 48,parms->unix_info2.in.gid); + SIVAL(blob->data, 52,parms->unix_info2.in.file_type); + SBVAL(blob->data, 60,parms->unix_info2.in.dev_major); + SBVAL(blob->data, 68,parms->unix_info2.in.dev_minor); + SBVAL(blob->data, 76,parms->unix_info2.in.unique_id); + SBVAL(blob->data, 84,parms->unix_info2.in.permissions); + SBVAL(blob->data, 92,parms->unix_info2.in.nlink); + smbcli_push_nttime(blob->data, 100, parms->unix_info2.in.create_time); + SIVAL(blob->data, 108, parms->unix_info2.in.file_flags); + SIVAL(blob->data, 112, parms->unix_info2.in.flags_mask); + return True; + case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: return smb_raw_setfileinfo_passthru(mem_ctx, RAW_SFILEINFO_DISPOSITION_INFORMATION, diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index bdc5bb2168..e4e85b58bc 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -3,6 +3,7 @@ SMB transaction2 handling Copyright (C) Jeremy Allison 1994-2002. Copyright (C) Andrew Tridgell 1995-2003. + Copyright (C) James Peach 2007 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 @@ -141,6 +142,7 @@ Found 8 aliased levels #define SMB_QFILEINFO_COMPRESSION_INFO 0x10b #define SMB_QFILEINFO_UNIX_BASIC 0x200 #define SMB_QFILEINFO_UNIX_LINK 0x201 +#define SMB_QFILEINFO_UNIX_INFO2 0x20b #define SMB_QFILEINFO_BASIC_INFORMATION 1004 #define SMB_QFILEINFO_STANDARD_INFORMATION 1005 #define SMB_QFILEINFO_INTERNAL_INFORMATION 1006 @@ -213,6 +215,7 @@ Found 13 valid levels #define SMB_SPATHINFO_POSIX_ACL 0x204 #define SMB_SPATHINFO_XATTR 0x205 #define SMB_SFILEINFO_ATTR_FLAGS 0x206 +#define SMB_SFILEINFO_UNIX_INFO2 0x20b #define SMB_SFILEINFO_BASIC_INFORMATION 1004 #define SMB_SFILEINFO_RENAME_INFORMATION 1010 #define SMB_SFILEINFO_DISPOSITION_INFORMATION 1013 @@ -267,6 +270,7 @@ Found 0 aliased levels #define SMB_FIND_ID_FULL_DIRECTORY_INFO 0x105 #define SMB_FIND_ID_BOTH_DIRECTORY_INFO 0x106 #define SMB_FIND_UNIX_INFO 0x202 +#define SMB_FIND_UNIX_INFO2 0x20b /* flags on trans2 findfirst/findnext that control search */ #define FLAG_TRANS2_FIND_CLOSE 0x1 @@ -321,9 +325,6 @@ Found 0 aliased levels #define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL)) -#define SMB_QFILEINFO_UNIX_BASIC 0x200 /* UNIX File Info*/ -#define SMB_SFILEINFO_UNIX_BASIC 0x200 - #define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */ /* means "don't change it" */ #define SMB_UID_NO_CHANGE 0xFFFFFFFF @@ -336,6 +337,8 @@ Found 0 aliased levels #define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF /* +UNIX_BASIC info level: + Offset Size Name 0 LARGE_INTEGER EndOfFile File size 8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks). @@ -365,6 +368,31 @@ Offset Size Name 100 - end. */ +/* +SMB_QUERY_FILE_UNIX_INFO2 is SMB_QUERY_FILE_UNIX_BASIC with create +time and file flags appended. The corresponding info level for +findfirst/findnext is SMB_FIND_FILE_UNIX_UNIX2. + +Size Offset Value +--------------------- +0 LARGE_INTEGER EndOfFile File size +8 LARGE_INTEGER Blocks Number of blocks used on disk +16 LARGE_INTEGER ChangeTime Attribute change time +24 LARGE_INTEGER LastAccessTime Last access time +32 LARGE_INTEGER LastModificationTime Last modification time +40 LARGE_INTEGER Uid Numeric user id for the owner +48 LARGE_INTEGER Gid Numeric group id of owner +56 ULONG Type Enumeration specifying the file type +60 LARGE_INTEGER devmajor Major device number if type is device +68 LARGE_INTEGER devminor Minor device number if type is device +76 LARGE_INTEGER uniqueid This is a server-assigned unique id +84 LARGE_INTEGER permissions Standard UNIX permissions +92 LARGE_INTEGER nlinks Number of hard link) +100 LARGE_INTEGER CreationTime Create/birth time +108 ULONG FileFlags File flags enumeration +112 ULONG FileFlagsMask Mask of valid flags +*/ + /* UNIX filetype mappings. */ #define UNIX_TYPE_FILE 0 @@ -404,12 +432,20 @@ Offset Size Name #define UNIX_EXTRA_MASK 0007000 #define UNIX_ALL_MASK 0007777 +/* Flags for the file_flags field in UNIX_INFO2: */ +#define EXT_SECURE_DELETE 0x00000001 +#define EXT_ENABLE_UNDELETE 0x00000002 +#define EXT_SYNCHRONOUS 0x00000004 +#define EXT_IMMUTABLE 0x00000008 +#define EXT_OPEN_APPEND_ONLY 0x00000010 +#define EXT_DO_NOT_BACKUP 0x00000020 +#define EXT_NO_UPDATE_ATIME 0x00000040 +#define EXT_HIDDEN 0x00000080 + #define SMB_QFILEINFO_UNIX_LINK 0x201 #define SMB_SFILEINFO_UNIX_LINK 0x201 #define SMB_SFILEINFO_UNIX_HLINK 0x203 -#define SMB_FIND_FILE_UNIX 0x202 - /* Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus 64-bits worth of capability fun :-). -- cgit