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