Merge branch 'for-linus' of git://git.infradead.org/ubi-2.6
[firefly-linux-kernel-4.4.55.git] / fs / cifs / link.c
1 /*
2  *   fs/cifs/link.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2008
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   This library is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU Lesser General Public License as published
9  *   by the Free Software Foundation; either version 2.1 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This library is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15  *   the GNU Lesser General Public License for more details.
16  *
17  *   You should have received a copy of the GNU Lesser General Public License
18  *   along with this library; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 #include <linux/fs.h>
22 #include <linux/stat.h>
23 #include <linux/slab.h>
24 #include <linux/namei.h>
25 #include "cifsfs.h"
26 #include "cifspdu.h"
27 #include "cifsglob.h"
28 #include "cifsproto.h"
29 #include "cifs_debug.h"
30 #include "cifs_fs_sb.h"
31
32 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
33 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
34 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
35 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
36 #define CIFS_MF_SYMLINK_FILE_SIZE \
37         (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
38
39 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
40 #define CIFS_MF_SYMLINK_MD5_FORMAT \
41         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
42 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
43         md5_hash[0],  md5_hash[1],  md5_hash[2],  md5_hash[3], \
44         md5_hash[4],  md5_hash[5],  md5_hash[6],  md5_hash[7], \
45         md5_hash[8],  md5_hash[9],  md5_hash[10], md5_hash[11],\
46         md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
47
48 static int
49 symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
50 {
51         int rc;
52         unsigned int size;
53         struct crypto_shash *md5;
54         struct sdesc *sdescmd5;
55
56         md5 = crypto_alloc_shash("md5", 0, 0);
57         if (IS_ERR(md5)) {
58                 cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
59                 return PTR_ERR(md5);
60         }
61         size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
62         sdescmd5 = kmalloc(size, GFP_KERNEL);
63         if (!sdescmd5) {
64                 rc = -ENOMEM;
65                 cERROR(1, "%s: Memory allocation failure\n", __func__);
66                 goto symlink_hash_err;
67         }
68         sdescmd5->shash.tfm = md5;
69         sdescmd5->shash.flags = 0x0;
70
71         rc = crypto_shash_init(&sdescmd5->shash);
72         if (rc) {
73                 cERROR(1, "%s: Could not init md5 shash\n", __func__);
74                 goto symlink_hash_err;
75         }
76         crypto_shash_update(&sdescmd5->shash, link_str, link_len);
77         rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
78
79 symlink_hash_err:
80         crypto_free_shash(md5);
81         kfree(sdescmd5);
82
83         return rc;
84 }
85
86 static int
87 CIFSParseMFSymlink(const u8 *buf,
88                    unsigned int buf_len,
89                    unsigned int *_link_len,
90                    char **_link_str)
91 {
92         int rc;
93         unsigned int link_len;
94         const char *md5_str1;
95         const char *link_str;
96         u8 md5_hash[16];
97         char md5_str2[34];
98
99         if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
100                 return -EINVAL;
101
102         md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
103         link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
104
105         rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
106         if (rc != 1)
107                 return -EINVAL;
108
109         rc = symlink_hash(link_len, link_str, md5_hash);
110         if (rc) {
111                 cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
112                 return rc;
113         }
114
115         snprintf(md5_str2, sizeof(md5_str2),
116                  CIFS_MF_SYMLINK_MD5_FORMAT,
117                  CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
118
119         if (strncmp(md5_str1, md5_str2, 17) != 0)
120                 return -EINVAL;
121
122         if (_link_str) {
123                 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
124                 if (!*_link_str)
125                         return -ENOMEM;
126         }
127
128         *_link_len = link_len;
129         return 0;
130 }
131
132 static int
133 CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
134 {
135         int rc;
136         unsigned int link_len;
137         unsigned int ofs;
138         u8 md5_hash[16];
139
140         if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
141                 return -EINVAL;
142
143         link_len = strlen(link_str);
144
145         if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
146                 return -ENAMETOOLONG;
147
148         rc = symlink_hash(link_len, link_str, md5_hash);
149         if (rc) {
150                 cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
151                 return rc;
152         }
153
154         snprintf(buf, buf_len,
155                  CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
156                  link_len,
157                  CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
158
159         ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
160         memcpy(buf + ofs, link_str, link_len);
161
162         ofs += link_len;
163         if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
164                 buf[ofs] = '\n';
165                 ofs++;
166         }
167
168         while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
169                 buf[ofs] = ' ';
170                 ofs++;
171         }
172
173         return 0;
174 }
175
176 static int
177 CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
178                     const char *fromName, const char *toName,
179                     const struct nls_table *nls_codepage, int remap)
180 {
181         int rc;
182         int oplock = 0;
183         __u16 netfid = 0;
184         u8 *buf;
185         unsigned int bytes_written = 0;
186
187         buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
188         if (!buf)
189                 return -ENOMEM;
190
191         rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
192         if (rc != 0) {
193                 kfree(buf);
194                 return rc;
195         }
196
197         rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
198                          CREATE_NOT_DIR, &netfid, &oplock, NULL,
199                          nls_codepage, remap);
200         if (rc != 0) {
201                 kfree(buf);
202                 return rc;
203         }
204
205         rc = CIFSSMBWrite(xid, tcon, netfid,
206                           CIFS_MF_SYMLINK_FILE_SIZE /* length */,
207                           0 /* offset */,
208                           &bytes_written, buf, NULL, 0);
209         CIFSSMBClose(xid, tcon, netfid);
210         kfree(buf);
211         if (rc != 0)
212                 return rc;
213
214         if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
215                 return -EIO;
216
217         return 0;
218 }
219
220 static int
221 CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
222                    const unsigned char *searchName, char **symlinkinfo,
223                    const struct nls_table *nls_codepage, int remap)
224 {
225         int rc;
226         int oplock = 0;
227         __u16 netfid = 0;
228         u8 *buf;
229         char *pbuf;
230         unsigned int bytes_read = 0;
231         int buf_type = CIFS_NO_BUFFER;
232         unsigned int link_len = 0;
233         FILE_ALL_INFO file_info;
234
235         rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
236                          CREATE_NOT_DIR, &netfid, &oplock, &file_info,
237                          nls_codepage, remap);
238         if (rc != 0)
239                 return rc;
240
241         if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
242                 CIFSSMBClose(xid, tcon, netfid);
243                 /* it's not a symlink */
244                 return -EINVAL;
245         }
246
247         buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
248         if (!buf)
249                 return -ENOMEM;
250         pbuf = buf;
251
252         rc = CIFSSMBRead(xid, tcon, netfid,
253                          CIFS_MF_SYMLINK_FILE_SIZE /* length */,
254                          0 /* offset */,
255                          &bytes_read, &pbuf, &buf_type);
256         CIFSSMBClose(xid, tcon, netfid);
257         if (rc != 0) {
258                 kfree(buf);
259                 return rc;
260         }
261
262         rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
263         kfree(buf);
264         if (rc != 0)
265                 return rc;
266
267         return 0;
268 }
269
270 bool
271 CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr)
272 {
273         if (!(fattr->cf_mode & S_IFREG))
274                 /* it's not a symlink */
275                 return false;
276
277         if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
278                 /* it's not a symlink */
279                 return false;
280
281         return true;
282 }
283
284 int
285 CIFSCheckMFSymlink(struct cifs_fattr *fattr,
286                    const unsigned char *path,
287                    struct cifs_sb_info *cifs_sb, int xid)
288 {
289         int rc;
290         int oplock = 0;
291         __u16 netfid = 0;
292         struct tcon_link *tlink;
293         struct cifsTconInfo *pTcon;
294         u8 *buf;
295         char *pbuf;
296         unsigned int bytes_read = 0;
297         int buf_type = CIFS_NO_BUFFER;
298         unsigned int link_len = 0;
299         FILE_ALL_INFO file_info;
300
301         if (!CIFSCouldBeMFSymlink(fattr))
302                 /* it's not a symlink */
303                 return 0;
304
305         tlink = cifs_sb_tlink(cifs_sb);
306         if (IS_ERR(tlink))
307                 return PTR_ERR(tlink);
308         pTcon = tlink_tcon(tlink);
309
310         rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
311                          CREATE_NOT_DIR, &netfid, &oplock, &file_info,
312                          cifs_sb->local_nls,
313                          cifs_sb->mnt_cifs_flags &
314                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
315         if (rc != 0)
316                 goto out;
317
318         if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
319                 CIFSSMBClose(xid, pTcon, netfid);
320                 /* it's not a symlink */
321                 goto out;
322         }
323
324         buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
325         if (!buf) {
326                 rc = -ENOMEM;
327                 goto out;
328         }
329         pbuf = buf;
330
331         rc = CIFSSMBRead(xid, pTcon, netfid,
332                          CIFS_MF_SYMLINK_FILE_SIZE /* length */,
333                          0 /* offset */,
334                          &bytes_read, &pbuf, &buf_type);
335         CIFSSMBClose(xid, pTcon, netfid);
336         if (rc != 0) {
337                 kfree(buf);
338                 goto out;
339         }
340
341         rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
342         kfree(buf);
343         if (rc == -EINVAL) {
344                 /* it's not a symlink */
345                 rc = 0;
346                 goto out;
347         }
348
349         if (rc != 0)
350                 goto out;
351
352         /* it is a symlink */
353         fattr->cf_eof = link_len;
354         fattr->cf_mode &= ~S_IFMT;
355         fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
356         fattr->cf_dtype = DT_LNK;
357 out:
358         cifs_put_tlink(tlink);
359         return rc;
360 }
361
362 int
363 cifs_hardlink(struct dentry *old_file, struct inode *inode,
364               struct dentry *direntry)
365 {
366         int rc = -EACCES;
367         int xid;
368         char *fromName = NULL;
369         char *toName = NULL;
370         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
371         struct tcon_link *tlink;
372         struct cifsTconInfo *pTcon;
373         struct cifsInodeInfo *cifsInode;
374
375         tlink = cifs_sb_tlink(cifs_sb);
376         if (IS_ERR(tlink))
377                 return PTR_ERR(tlink);
378         pTcon = tlink_tcon(tlink);
379
380         xid = GetXid();
381
382         fromName = build_path_from_dentry(old_file);
383         toName = build_path_from_dentry(direntry);
384         if ((fromName == NULL) || (toName == NULL)) {
385                 rc = -ENOMEM;
386                 goto cifs_hl_exit;
387         }
388
389         if (pTcon->unix_ext)
390                 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
391                                             cifs_sb->local_nls,
392                                             cifs_sb->mnt_cifs_flags &
393                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
394         else {
395                 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
396                                         cifs_sb->local_nls,
397                                         cifs_sb->mnt_cifs_flags &
398                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
399                 if ((rc == -EIO) || (rc == -EINVAL))
400                         rc = -EOPNOTSUPP;
401         }
402
403         d_drop(direntry);       /* force new lookup from server of target */
404
405         /* if source file is cached (oplocked) revalidate will not go to server
406            until the file is closed or oplock broken so update nlinks locally */
407         if (old_file->d_inode) {
408                 cifsInode = CIFS_I(old_file->d_inode);
409                 if (rc == 0) {
410                         old_file->d_inode->i_nlink++;
411 /* BB should we make this contingent on superblock flag NOATIME? */
412 /*                      old_file->d_inode->i_ctime = CURRENT_TIME;*/
413                         /* parent dir timestamps will update from srv
414                         within a second, would it really be worth it
415                         to set the parent dir cifs inode time to zero
416                         to force revalidate (faster) for it too? */
417                 }
418                 /* if not oplocked will force revalidate to get info
419                    on source file from srv */
420                 cifsInode->time = 0;
421
422                 /* Will update parent dir timestamps from srv within a second.
423                    Would it really be worth it to set the parent dir (cifs
424                    inode) time field to zero to force revalidate on parent
425                    directory faster ie
426                         CIFS_I(inode)->time = 0;  */
427         }
428
429 cifs_hl_exit:
430         kfree(fromName);
431         kfree(toName);
432         FreeXid(xid);
433         cifs_put_tlink(tlink);
434         return rc;
435 }
436
437 void *
438 cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
439 {
440         struct inode *inode = direntry->d_inode;
441         int rc = -ENOMEM;
442         int xid;
443         char *full_path = NULL;
444         char *target_path = NULL;
445         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
446         struct tcon_link *tlink = NULL;
447         struct cifsTconInfo *tcon;
448
449         xid = GetXid();
450
451         tlink = cifs_sb_tlink(cifs_sb);
452         if (IS_ERR(tlink)) {
453                 rc = PTR_ERR(tlink);
454                 tlink = NULL;
455                 goto out;
456         }
457         tcon = tlink_tcon(tlink);
458
459         /*
460          * For now, we just handle symlinks with unix extensions enabled.
461          * Eventually we should handle NTFS reparse points, and MacOS
462          * symlink support. For instance...
463          *
464          * rc = CIFSSMBQueryReparseLinkInfo(...)
465          *
466          * For now, just return -EACCES when the server doesn't support posix
467          * extensions. Note that we still allow querying symlinks when posix
468          * extensions are manually disabled. We could disable these as well
469          * but there doesn't seem to be any harm in allowing the client to
470          * read them.
471          */
472         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
473             && !(tcon->ses->capabilities & CAP_UNIX)) {
474                 rc = -EACCES;
475                 goto out;
476         }
477
478         full_path = build_path_from_dentry(direntry);
479         if (!full_path)
480                 goto out;
481
482         cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
483
484         rc = -EACCES;
485         /*
486          * First try Minshall+French Symlinks, if configured
487          * and fallback to UNIX Extensions Symlinks.
488          */
489         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
490                 rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
491                                         cifs_sb->local_nls,
492                                         cifs_sb->mnt_cifs_flags &
493                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
494
495         if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
496                 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
497                                              cifs_sb->local_nls);
498
499         kfree(full_path);
500 out:
501         if (rc != 0) {
502                 kfree(target_path);
503                 target_path = ERR_PTR(rc);
504         }
505
506         FreeXid(xid);
507         if (tlink)
508                 cifs_put_tlink(tlink);
509         nd_set_link(nd, target_path);
510         return NULL;
511 }
512
513 int
514 cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
515 {
516         int rc = -EOPNOTSUPP;
517         int xid;
518         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
519         struct tcon_link *tlink;
520         struct cifsTconInfo *pTcon;
521         char *full_path = NULL;
522         struct inode *newinode = NULL;
523
524         xid = GetXid();
525
526         tlink = cifs_sb_tlink(cifs_sb);
527         if (IS_ERR(tlink)) {
528                 rc = PTR_ERR(tlink);
529                 goto symlink_exit;
530         }
531         pTcon = tlink_tcon(tlink);
532
533         full_path = build_path_from_dentry(direntry);
534         if (full_path == NULL) {
535                 rc = -ENOMEM;
536                 goto symlink_exit;
537         }
538
539         cFYI(1, "Full path: %s", full_path);
540         cFYI(1, "symname is %s", symname);
541
542         /* BB what if DFS and this volume is on different share? BB */
543         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
544                 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
545                                          cifs_sb->local_nls,
546                                          cifs_sb->mnt_cifs_flags &
547                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
548         else if (pTcon->unix_ext)
549                 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
550                                            cifs_sb->local_nls);
551         /* else
552            rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
553                                         cifs_sb_target->local_nls); */
554
555         if (rc == 0) {
556                 if (pTcon->unix_ext)
557                         rc = cifs_get_inode_info_unix(&newinode, full_path,
558                                                       inode->i_sb, xid);
559                 else
560                         rc = cifs_get_inode_info(&newinode, full_path, NULL,
561                                                  inode->i_sb, xid, NULL);
562
563                 if (rc != 0) {
564                         cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
565                               rc);
566                 } else {
567                         d_instantiate(direntry, newinode);
568                 }
569         }
570 symlink_exit:
571         kfree(full_path);
572         cifs_put_tlink(tlink);
573         FreeXid(xid);
574         return rc;
575 }
576
577 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
578 {
579         char *p = nd_get_link(nd);
580         if (!IS_ERR(p))
581                 kfree(p);
582 }