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 Frenchchar *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 Frenchchar *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