diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-12-26 13:58:46 -0500 |
---|---|---|
committer | Pavel Shilovsky <pshilovsky@samba.org> | 2012-07-24 13:55:05 -0400 |
commit | 2503a0dba989486c59523a947a1dcb50ad90fee9 (patch) | |
tree | 1e79a740d744cee1a1981e4d0a355303ffc9a4d2 /fs/cifs | |
parent | 68889f269b16a11866f4ec71e8177bdd0c184a3f (diff) |
CIFS: Add SMB2 support for is_path_accessible
that needs for a successful mount through SMB2 protocol.
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifs_unicode.c | 61 | ||||
-rw-r--r-- | fs/cifs/cifs_unicode.h | 5 | ||||
-rw-r--r-- | fs/cifs/smb2misc.c | 25 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 25 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 132 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 167 | ||||
-rw-r--r-- | fs/cifs/smb2proto.h | 8 |
7 files changed, 423 insertions, 0 deletions
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 97c1d4210869..7dab9c04ad52 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
@@ -330,3 +330,64 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, | |||
330 | ctoUTF16_out: | 330 | ctoUTF16_out: |
331 | return i; | 331 | return i; |
332 | } | 332 | } |
333 | |||
334 | #ifdef CONFIG_CIFS_SMB2 | ||
335 | /* | ||
336 | * cifs_local_to_utf16_bytes - how long will a string be after conversion? | ||
337 | * @from - pointer to input string | ||
338 | * @maxbytes - don't go past this many bytes of input string | ||
339 | * @codepage - source codepage | ||
340 | * | ||
341 | * Walk a string and return the number of bytes that the string will | ||
342 | * be after being converted to the given charset, not including any null | ||
343 | * termination required. Don't walk past maxbytes in the source buffer. | ||
344 | */ | ||
345 | |||
346 | static int | ||
347 | cifs_local_to_utf16_bytes(const char *from, int len, | ||
348 | const struct nls_table *codepage) | ||
349 | { | ||
350 | int charlen; | ||
351 | int i; | ||
352 | wchar_t wchar_to; | ||
353 | |||
354 | for (i = 0; len && *from; i++, from += charlen, len -= charlen) { | ||
355 | charlen = codepage->char2uni(from, len, &wchar_to); | ||
356 | /* Failed conversion defaults to a question mark */ | ||
357 | if (charlen < 1) | ||
358 | charlen = 1; | ||
359 | } | ||
360 | return 2 * i; /* UTF16 characters are two bytes */ | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | * cifs_strndup_to_utf16 - copy a string to wire format from the local codepage | ||
365 | * @src - source string | ||
366 | * @maxlen - don't walk past this many bytes in the source string | ||
367 | * @utf16_len - the length of the allocated string in bytes (including null) | ||
368 | * @cp - source codepage | ||
369 | * @remap - map special chars | ||
370 | * | ||
371 | * Take a string convert it from the local codepage to UTF16 and | ||
372 | * put it in a new buffer. Returns a pointer to the new string or NULL on | ||
373 | * error. | ||
374 | */ | ||
375 | __le16 * | ||
376 | cifs_strndup_to_utf16(const char *src, const int maxlen, int *utf16_len, | ||
377 | const struct nls_table *cp, int remap) | ||
378 | { | ||
379 | int len; | ||
380 | __le16 *dst; | ||
381 | |||
382 | len = cifs_local_to_utf16_bytes(src, maxlen, cp); | ||
383 | len += 2; /* NULL */ | ||
384 | dst = kmalloc(len, GFP_KERNEL); | ||
385 | if (!dst) { | ||
386 | *utf16_len = 0; | ||
387 | return NULL; | ||
388 | } | ||
389 | cifsConvertToUTF16(dst, src, strlen(src), cp, remap); | ||
390 | *utf16_len = len; | ||
391 | return dst; | ||
392 | } | ||
393 | #endif /* CONFIG_CIFS_SMB2 */ | ||
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index a44c6eb8a4d7..4fb097468e21 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h | |||
@@ -84,6 +84,11 @@ char *cifs_strndup_from_utf16(const char *src, const int maxlen, | |||
84 | const struct nls_table *codepage); | 84 | const struct nls_table *codepage); |
85 | extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen, | 85 | extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen, |
86 | const struct nls_table *cp, int mapChars); | 86 | const struct nls_table *cp, int mapChars); |
87 | #ifdef CONFIG_CIFS_SMB2 | ||
88 | extern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen, | ||
89 | int *utf16_len, const struct nls_table *cp, | ||
90 | int remap); | ||
91 | #endif /* CONFIG_CIFS_SMB2 */ | ||
87 | #endif | 92 | #endif |
88 | 93 | ||
89 | /* | 94 | /* |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index 10729a74da27..eb73a136641c 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -230,6 +230,11 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr) | |||
230 | ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferLength); | 230 | ((struct smb2_sess_setup_rsp *)hdr)->SecurityBufferLength); |
231 | break; | 231 | break; |
232 | case SMB2_CREATE: | 232 | case SMB2_CREATE: |
233 | *off = le32_to_cpu( | ||
234 | ((struct smb2_create_rsp *)hdr)->CreateContextsOffset); | ||
235 | *len = le32_to_cpu( | ||
236 | ((struct smb2_create_rsp *)hdr)->CreateContextsLength); | ||
237 | break; | ||
233 | case SMB2_READ: | 238 | case SMB2_READ: |
234 | case SMB2_QUERY_INFO: | 239 | case SMB2_QUERY_INFO: |
235 | case SMB2_QUERY_DIRECTORY: | 240 | case SMB2_QUERY_DIRECTORY: |
@@ -315,3 +320,23 @@ calc_size_exit: | |||
315 | cFYI(1, "SMB2 len %d", len); | 320 | cFYI(1, "SMB2 len %d", len); |
316 | return len; | 321 | return len; |
317 | } | 322 | } |
323 | |||
324 | /* Note: caller must free return buffer */ | ||
325 | __le16 * | ||
326 | cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) | ||
327 | { | ||
328 | int len; | ||
329 | const char *start_of_path; | ||
330 | __le16 *to; | ||
331 | |||
332 | /* Windows doesn't allow paths beginning with \ */ | ||
333 | if (from[0] == '\\') | ||
334 | start_of_path = from + 1; | ||
335 | else | ||
336 | start_of_path = from; | ||
337 | to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, | ||
338 | cifs_sb->local_nls, | ||
339 | cifs_sb->mnt_cifs_flags & | ||
340 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
341 | return to; | ||
342 | } | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 0e33ca32abf9..1266137406fa 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -157,6 +157,30 @@ smb2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
157 | return rc; | 157 | return rc; |
158 | } | 158 | } |
159 | 159 | ||
160 | static int | ||
161 | smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, | ||
162 | struct cifs_sb_info *cifs_sb, const char *full_path) | ||
163 | { | ||
164 | int rc; | ||
165 | __u64 persistent_fid, volatile_fid; | ||
166 | __le16 *utf16_path; | ||
167 | |||
168 | utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); | ||
169 | if (!utf16_path) | ||
170 | return -ENOMEM; | ||
171 | |||
172 | rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid, | ||
173 | FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0); | ||
174 | if (rc) { | ||
175 | kfree(utf16_path); | ||
176 | return rc; | ||
177 | } | ||
178 | |||
179 | rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid); | ||
180 | kfree(utf16_path); | ||
181 | return rc; | ||
182 | } | ||
183 | |||
160 | struct smb_version_operations smb21_operations = { | 184 | struct smb_version_operations smb21_operations = { |
161 | .setup_request = smb2_setup_request, | 185 | .setup_request = smb2_setup_request, |
162 | .check_receive = smb2_check_receive, | 186 | .check_receive = smb2_check_receive, |
@@ -174,6 +198,7 @@ struct smb_version_operations smb21_operations = { | |||
174 | .logoff = SMB2_logoff, | 198 | .logoff = SMB2_logoff, |
175 | .tree_connect = SMB2_tcon, | 199 | .tree_connect = SMB2_tcon, |
176 | .tree_disconnect = SMB2_tdis, | 200 | .tree_disconnect = SMB2_tdis, |
201 | .is_path_accessible = smb2_is_path_accessible, | ||
177 | }; | 202 | }; |
178 | 203 | ||
179 | struct smb_version_values smb21_values = { | 204 | struct smb_version_values smb21_values = { |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 48c04b2832e2..ef0769c398a5 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -829,3 +829,135 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) | |||
829 | 829 | ||
830 | return rc; | 830 | return rc; |
831 | } | 831 | } |
832 | |||
833 | int | ||
834 | SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path, | ||
835 | u64 *persistent_fid, u64 *volatile_fid, __u32 desired_access, | ||
836 | __u32 create_disposition, __u32 file_attributes, __u32 create_options) | ||
837 | { | ||
838 | struct smb2_create_req *req; | ||
839 | struct smb2_create_rsp *rsp; | ||
840 | struct TCP_Server_Info *server; | ||
841 | struct cifs_ses *ses = tcon->ses; | ||
842 | struct kvec iov[2]; | ||
843 | int resp_buftype; | ||
844 | int uni_path_len; | ||
845 | int rc = 0; | ||
846 | int num_iovecs = 2; | ||
847 | |||
848 | cFYI(1, "create/open"); | ||
849 | |||
850 | if (ses && (ses->server)) | ||
851 | server = ses->server; | ||
852 | else | ||
853 | return -EIO; | ||
854 | |||
855 | rc = small_smb2_init(SMB2_CREATE, tcon, (void **) &req); | ||
856 | if (rc) | ||
857 | return rc; | ||
858 | |||
859 | if (enable_oplocks) | ||
860 | req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_BATCH; | ||
861 | else | ||
862 | req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE; | ||
863 | req->ImpersonationLevel = IL_IMPERSONATION; | ||
864 | req->DesiredAccess = cpu_to_le32(desired_access); | ||
865 | /* File attributes ignored on open (used in create though) */ | ||
866 | req->FileAttributes = cpu_to_le32(file_attributes); | ||
867 | req->ShareAccess = FILE_SHARE_ALL_LE; | ||
868 | req->CreateDisposition = cpu_to_le32(create_disposition); | ||
869 | req->CreateOptions = cpu_to_le32(create_options); | ||
870 | uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2; | ||
871 | req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) | ||
872 | - 1 /* pad */ - 4 /* do not count rfc1001 len field */); | ||
873 | |||
874 | iov[0].iov_base = (char *)req; | ||
875 | /* 4 for rfc1002 length field */ | ||
876 | iov[0].iov_len = get_rfc1002_length(req) + 4; | ||
877 | |||
878 | /* MUST set path len (NameLength) to 0 opening root of share */ | ||
879 | if (uni_path_len >= 4) { | ||
880 | req->NameLength = cpu_to_le16(uni_path_len - 2); | ||
881 | /* -1 since last byte is buf[0] which is sent below (path) */ | ||
882 | iov[0].iov_len--; | ||
883 | iov[1].iov_len = uni_path_len; | ||
884 | iov[1].iov_base = path; | ||
885 | /* | ||
886 | * -1 since last byte is buf[0] which was counted in | ||
887 | * smb2_buf_len. | ||
888 | */ | ||
889 | inc_rfc1001_len(req, uni_path_len - 1); | ||
890 | } else { | ||
891 | num_iovecs = 1; | ||
892 | req->NameLength = 0; | ||
893 | } | ||
894 | |||
895 | rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buftype, 0); | ||
896 | rsp = (struct smb2_create_rsp *)iov[0].iov_base; | ||
897 | |||
898 | if (rc != 0) { | ||
899 | cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); | ||
900 | goto creat_exit; | ||
901 | } | ||
902 | |||
903 | if (rsp == NULL) { | ||
904 | rc = -EIO; | ||
905 | goto creat_exit; | ||
906 | } | ||
907 | *persistent_fid = rsp->PersistentFileId; | ||
908 | *volatile_fid = rsp->VolatileFileId; | ||
909 | creat_exit: | ||
910 | free_rsp_buf(resp_buftype, rsp); | ||
911 | return rc; | ||
912 | } | ||
913 | |||
914 | int | ||
915 | SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, | ||
916 | u64 persistent_fid, u64 volatile_fid) | ||
917 | { | ||
918 | struct smb2_close_req *req; | ||
919 | struct smb2_close_rsp *rsp; | ||
920 | struct TCP_Server_Info *server; | ||
921 | struct cifs_ses *ses = tcon->ses; | ||
922 | struct kvec iov[1]; | ||
923 | int resp_buftype; | ||
924 | int rc = 0; | ||
925 | |||
926 | cFYI(1, "Close"); | ||
927 | |||
928 | if (ses && (ses->server)) | ||
929 | server = ses->server; | ||
930 | else | ||
931 | return -EIO; | ||
932 | |||
933 | rc = small_smb2_init(SMB2_CLOSE, tcon, (void **) &req); | ||
934 | if (rc) | ||
935 | return rc; | ||
936 | |||
937 | req->PersistentFileId = persistent_fid; | ||
938 | req->VolatileFileId = volatile_fid; | ||
939 | |||
940 | iov[0].iov_base = (char *)req; | ||
941 | /* 4 for rfc1002 length field */ | ||
942 | iov[0].iov_len = get_rfc1002_length(req) + 4; | ||
943 | |||
944 | rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0); | ||
945 | rsp = (struct smb2_close_rsp *)iov[0].iov_base; | ||
946 | |||
947 | if (rc != 0) { | ||
948 | if (tcon) | ||
949 | cifs_stats_fail_inc(tcon, SMB2_CLOSE_HE); | ||
950 | goto close_exit; | ||
951 | } | ||
952 | |||
953 | if (rsp == NULL) { | ||
954 | rc = -EIO; | ||
955 | goto close_exit; | ||
956 | } | ||
957 | |||
958 | /* BB FIXME - decode close response, update inode for caching */ | ||
959 | |||
960 | close_exit: | ||
961 | free_rsp_buf(resp_buftype, rsp); | ||
962 | return rc; | ||
963 | } | ||
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index aa77bf3a7a69..5cd358ef312e 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -281,4 +281,171 @@ struct smb2_tree_disconnect_rsp { | |||
281 | __le16 Reserved; | 281 | __le16 Reserved; |
282 | } __packed; | 282 | } __packed; |
283 | 283 | ||
284 | /* File Attrubutes */ | ||
285 | #define FILE_ATTRIBUTE_READONLY 0x00000001 | ||
286 | #define FILE_ATTRIBUTE_HIDDEN 0x00000002 | ||
287 | #define FILE_ATTRIBUTE_SYSTEM 0x00000004 | ||
288 | #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 | ||
289 | #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 | ||
290 | #define FILE_ATTRIBUTE_NORMAL 0x00000080 | ||
291 | #define FILE_ATTRIBUTE_TEMPORARY 0x00000100 | ||
292 | #define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 | ||
293 | #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 | ||
294 | #define FILE_ATTRIBUTE_COMPRESSED 0x00000800 | ||
295 | #define FILE_ATTRIBUTE_OFFLINE 0x00001000 | ||
296 | #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 | ||
297 | #define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 | ||
298 | |||
299 | /* Oplock levels */ | ||
300 | #define SMB2_OPLOCK_LEVEL_NONE 0x00 | ||
301 | #define SMB2_OPLOCK_LEVEL_II 0x01 | ||
302 | #define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08 | ||
303 | #define SMB2_OPLOCK_LEVEL_BATCH 0x09 | ||
304 | #define SMB2_OPLOCK_LEVEL_LEASE 0xFF | ||
305 | |||
306 | /* Desired Access Flags */ | ||
307 | #define FILE_READ_DATA_LE cpu_to_le32(0x00000001) | ||
308 | #define FILE_WRITE_DATA_LE cpu_to_le32(0x00000002) | ||
309 | #define FILE_APPEND_DATA_LE cpu_to_le32(0x00000004) | ||
310 | #define FILE_READ_EA_LE cpu_to_le32(0x00000008) | ||
311 | #define FILE_WRITE_EA_LE cpu_to_le32(0x00000010) | ||
312 | #define FILE_EXECUTE_LE cpu_to_le32(0x00000020) | ||
313 | #define FILE_READ_ATTRIBUTES_LE cpu_to_le32(0x00000080) | ||
314 | #define FILE_WRITE_ATTRIBUTES_LE cpu_to_le32(0x00000100) | ||
315 | #define FILE_DELETE_LE cpu_to_le32(0x00010000) | ||
316 | #define FILE_READ_CONTROL_LE cpu_to_le32(0x00020000) | ||
317 | #define FILE_WRITE_DAC_LE cpu_to_le32(0x00040000) | ||
318 | #define FILE_WRITE_OWNER_LE cpu_to_le32(0x00080000) | ||
319 | #define FILE_SYNCHRONIZE_LE cpu_to_le32(0x00100000) | ||
320 | #define FILE_ACCESS_SYSTEM_SECURITY_LE cpu_to_le32(0x01000000) | ||
321 | #define FILE_MAXIMAL_ACCESS_LE cpu_to_le32(0x02000000) | ||
322 | #define FILE_GENERIC_ALL_LE cpu_to_le32(0x10000000) | ||
323 | #define FILE_GENERIC_EXECUTE_LE cpu_to_le32(0x20000000) | ||
324 | #define FILE_GENERIC_WRITE_LE cpu_to_le32(0x40000000) | ||
325 | #define FILE_GENERIC_READ_LE cpu_to_le32(0x80000000) | ||
326 | |||
327 | /* ShareAccess Flags */ | ||
328 | #define FILE_SHARE_READ_LE cpu_to_le32(0x00000001) | ||
329 | #define FILE_SHARE_WRITE_LE cpu_to_le32(0x00000002) | ||
330 | #define FILE_SHARE_DELETE_LE cpu_to_le32(0x00000004) | ||
331 | #define FILE_SHARE_ALL_LE cpu_to_le32(0x00000007) | ||
332 | |||
333 | /* CreateDisposition Flags */ | ||
334 | #define FILE_SUPERSEDE_LE cpu_to_le32(0x00000000) | ||
335 | #define FILE_OPEN_LE cpu_to_le32(0x00000001) | ||
336 | #define FILE_CREATE_LE cpu_to_le32(0x00000002) | ||
337 | #define FILE_OPEN_IF_LE cpu_to_le32(0x00000003) | ||
338 | #define FILE_OVERWRITE_LE cpu_to_le32(0x00000004) | ||
339 | #define FILE_OVERWRITE_IF_LE cpu_to_le32(0x00000005) | ||
340 | |||
341 | /* CreateOptions Flags */ | ||
342 | #define FILE_DIRECTORY_FILE_LE cpu_to_le32(0x00000001) | ||
343 | /* same as #define CREATE_NOT_FILE_LE cpu_to_le32(0x00000001) */ | ||
344 | #define FILE_WRITE_THROUGH_LE cpu_to_le32(0x00000002) | ||
345 | #define FILE_SEQUENTIAL_ONLY_LE cpu_to_le32(0x00000004) | ||
346 | #define FILE_NO_INTERMEDIATE_BUFFERRING_LE cpu_to_le32(0x00000008) | ||
347 | #define FILE_SYNCHRONOUS_IO_ALERT_LE cpu_to_le32(0x00000010) | ||
348 | #define FILE_SYNCHRONOUS_IO_NON_ALERT_LE cpu_to_le32(0x00000020) | ||
349 | #define FILE_NON_DIRECTORY_FILE_LE cpu_to_le32(0x00000040) | ||
350 | #define FILE_COMPLETE_IF_OPLOCKED_LE cpu_to_le32(0x00000100) | ||
351 | #define FILE_NO_EA_KNOWLEDGE_LE cpu_to_le32(0x00000200) | ||
352 | #define FILE_RANDOM_ACCESS_LE cpu_to_le32(0x00000800) | ||
353 | #define FILE_DELETE_ON_CLOSE_LE cpu_to_le32(0x00001000) | ||
354 | #define FILE_OPEN_BY_FILE_ID_LE cpu_to_le32(0x00002000) | ||
355 | #define FILE_OPEN_FOR_BACKUP_INTENT_LE cpu_to_le32(0x00004000) | ||
356 | #define FILE_NO_COMPRESSION_LE cpu_to_le32(0x00008000) | ||
357 | #define FILE_RESERVE_OPFILTER_LE cpu_to_le32(0x00100000) | ||
358 | #define FILE_OPEN_REPARSE_POINT_LE cpu_to_le32(0x00200000) | ||
359 | #define FILE_OPEN_NO_RECALL_LE cpu_to_le32(0x00400000) | ||
360 | #define FILE_OPEN_FOR_FREE_SPACE_QUERY_LE cpu_to_le32(0x00800000) | ||
361 | |||
362 | #define FILE_READ_RIGHTS_LE (FILE_READ_DATA_LE | FILE_READ_EA_LE \ | ||
363 | | FILE_READ_ATTRIBUTES_LE) | ||
364 | #define FILE_WRITE_RIGHTS_LE (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE \ | ||
365 | | FILE_WRITE_EA_LE | FILE_WRITE_ATTRIBUTES_LE) | ||
366 | #define FILE_EXEC_RIGHTS_LE (FILE_EXECUTE_LE) | ||
367 | |||
368 | /* Impersonation Levels */ | ||
369 | #define IL_ANONYMOUS cpu_to_le32(0x00000000) | ||
370 | #define IL_IDENTIFICATION cpu_to_le32(0x00000001) | ||
371 | #define IL_IMPERSONATION cpu_to_le32(0x00000002) | ||
372 | #define IL_DELEGATE cpu_to_le32(0x00000003) | ||
373 | |||
374 | /* Create Context Values */ | ||
375 | #define SMB2_CREATE_EA_BUFFER "ExtA" /* extended attributes */ | ||
376 | #define SMB2_CREATE_SD_BUFFER "SecD" /* security descriptor */ | ||
377 | #define SMB2_CREATE_DURABLE_HANDLE_REQUEST "DHnQ" | ||
378 | #define SMB2_CREATE_DURABLE_HANDLE_RECONNECT "DHnC" | ||
379 | #define SMB2_CREATE_ALLOCATION_SIZE "AlSi" | ||
380 | #define SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST "MxAc" | ||
381 | #define SMB2_CREATE_TIMEWARP_REQUEST "TWrp" | ||
382 | #define SMB2_CREATE_QUERY_ON_DISK_ID "QFid" | ||
383 | #define SMB2_CREATE_REQUEST_LEASE "RqLs" | ||
384 | |||
385 | struct smb2_create_req { | ||
386 | struct smb2_hdr hdr; | ||
387 | __le16 StructureSize; /* Must be 57 */ | ||
388 | __u8 SecurityFlags; | ||
389 | __u8 RequestedOplockLevel; | ||
390 | __le32 ImpersonationLevel; | ||
391 | __le64 SmbCreateFlags; | ||
392 | __le64 Reserved; | ||
393 | __le32 DesiredAccess; | ||
394 | __le32 FileAttributes; | ||
395 | __le32 ShareAccess; | ||
396 | __le32 CreateDisposition; | ||
397 | __le32 CreateOptions; | ||
398 | __le16 NameOffset; | ||
399 | __le16 NameLength; | ||
400 | __le32 CreateContextsOffset; | ||
401 | __le32 CreateContextsLength; | ||
402 | __u8 Buffer[1]; | ||
403 | } __packed; | ||
404 | |||
405 | struct smb2_create_rsp { | ||
406 | struct smb2_hdr hdr; | ||
407 | __le16 StructureSize; /* Must be 89 */ | ||
408 | __u8 OplockLevel; | ||
409 | __u8 Reserved; | ||
410 | __le32 CreateAction; | ||
411 | __le64 CreationTime; | ||
412 | __le64 LastAccessTime; | ||
413 | __le64 LastWriteTime; | ||
414 | __le64 ChangeTime; | ||
415 | __le64 AllocationSize; | ||
416 | __le64 EndofFile; | ||
417 | __le32 FileAttributes; | ||
418 | __le32 Reserved2; | ||
419 | __u64 PersistentFileId; /* opaque endianness */ | ||
420 | __u64 VolatileFileId; /* opaque endianness */ | ||
421 | __le32 CreateContextsOffset; | ||
422 | __le32 CreateContextsLength; | ||
423 | __u8 Buffer[1]; | ||
424 | } __packed; | ||
425 | |||
426 | /* Currently defined values for close flags */ | ||
427 | #define SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB cpu_to_le16(0x0001) | ||
428 | struct smb2_close_req { | ||
429 | struct smb2_hdr hdr; | ||
430 | __le16 StructureSize; /* Must be 24 */ | ||
431 | __le16 Flags; | ||
432 | __le32 Reserved; | ||
433 | __u64 PersistentFileId; /* opaque endianness */ | ||
434 | __u64 VolatileFileId; /* opaque endianness */ | ||
435 | } __packed; | ||
436 | |||
437 | struct smb2_close_rsp { | ||
438 | struct smb2_hdr hdr; | ||
439 | __le16 StructureSize; /* 60 */ | ||
440 | __le16 Flags; | ||
441 | __le32 Reserved; | ||
442 | __le64 CreationTime; | ||
443 | __le64 LastAccessTime; | ||
444 | __le64 LastWriteTime; | ||
445 | __le64 ChangeTime; | ||
446 | __le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */ | ||
447 | __le64 EndOfFile; | ||
448 | __le32 Attributes; | ||
449 | } __packed; | ||
450 | |||
284 | #endif /* _SMB2PDU_H */ | 451 | #endif /* _SMB2PDU_H */ |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index bc7299349dbf..85aa8d5ea41a 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -36,6 +36,8 @@ extern int map_smb2_to_linux_error(char *buf, bool log_err); | |||
36 | extern int smb2_check_message(char *buf, unsigned int length); | 36 | extern int smb2_check_message(char *buf, unsigned int length); |
37 | extern unsigned int smb2_calc_size(struct smb2_hdr *hdr); | 37 | extern unsigned int smb2_calc_size(struct smb2_hdr *hdr); |
38 | extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr); | 38 | extern char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr); |
39 | extern __le16 *cifs_convert_path_to_utf16(const char *from, | ||
40 | struct cifs_sb_info *cifs_sb); | ||
39 | 41 | ||
40 | extern int smb2_check_receive(struct mid_q_entry *mid, | 42 | extern int smb2_check_receive(struct mid_q_entry *mid, |
41 | struct TCP_Server_Info *server, bool log_error); | 43 | struct TCP_Server_Info *server, bool log_error); |
@@ -54,5 +56,11 @@ extern int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, | |||
54 | const char *tree, struct cifs_tcon *tcon, | 56 | const char *tree, struct cifs_tcon *tcon, |
55 | const struct nls_table *); | 57 | const struct nls_table *); |
56 | extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon); | 58 | extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon); |
59 | extern int SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, | ||
60 | __le16 *path, u64 *persistent_fid, u64 *volatile_fid, | ||
61 | __u32 desired_access, __u32 create_disposition, | ||
62 | __u32 file_attributes, __u32 create_options); | ||
63 | extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, | ||
64 | u64 persistent_file_id, u64 volatile_file_id); | ||
57 | 65 | ||
58 | #endif /* _SMB2PROTO_H */ | 66 | #endif /* _SMB2PROTO_H */ |