cifs: handle cases where a channel is closed
[platform/kernel/linux-rpi.git] / fs / smb / client / unc.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2020, Microsoft Corporation.
4  *
5  *   Author(s): Steve French <stfrench@microsoft.com>
6  *              Suresh Jayaraman <sjayaraman@suse.de>
7  *              Jeff Layton <jlayton@kernel.org>
8  */
9
10 #include <linux/fs.h>
11 #include <linux/slab.h>
12 #include <linux/inet.h>
13 #include <linux/ctype.h>
14 #include "cifsglob.h"
15 #include "cifsproto.h"
16
17 /* extract the host portion of the UNC string */
18 char *extract_hostname(const char *unc)
19 {
20         const char *src;
21         char *dst, *delim;
22         unsigned int len;
23
24         /* skip double chars at beginning of string */
25         /* BB: check validity of these bytes? */
26         if (strlen(unc) < 3)
27                 return ERR_PTR(-EINVAL);
28         for (src = unc; *src && *src == '\\'; src++)
29                 ;
30         if (!*src)
31                 return ERR_PTR(-EINVAL);
32
33         /* delimiter between hostname and sharename is always '\\' now */
34         delim = strchr(src, '\\');
35         if (!delim)
36                 return ERR_PTR(-EINVAL);
37
38         len = delim - src;
39         dst = kmalloc((len + 1), GFP_KERNEL);
40         if (dst == NULL)
41                 return ERR_PTR(-ENOMEM);
42
43         memcpy(dst, src, len);
44         dst[len] = '\0';
45
46         return dst;
47 }
48
49 char *extract_sharename(const char *unc)
50 {
51         const char *src;
52         char *delim, *dst;
53
54         /* skip double chars at the beginning */
55         src = unc + 2;
56
57         /* share name is always preceded by '\\' now */
58         delim = strchr(src, '\\');
59         if (!delim)
60                 return ERR_PTR(-EINVAL);
61         delim++;
62
63         /* caller has to free the memory */
64         dst = kstrdup(delim, GFP_KERNEL);
65         if (!dst)
66                 return ERR_PTR(-ENOMEM);
67
68         return dst;
69 }