diff options
Diffstat (limited to 'fs/ksmbd/misc.c')
| -rw-r--r-- | fs/ksmbd/misc.c | 46 | 
1 files changed, 37 insertions, 9 deletions
diff --git a/fs/ksmbd/misc.c b/fs/ksmbd/misc.c index df991107ad2c..9e8afaa686e3 100644 --- a/fs/ksmbd/misc.c +++ b/fs/ksmbd/misc.c @@ -7,6 +7,7 @@  #include <linux/kernel.h>  #include <linux/xattr.h>  #include <linux/fs.h> +#include <linux/unicode.h>  #include "misc.h"  #include "smb_common.h" @@ -159,7 +160,7 @@ out:   */  char *convert_to_nt_pathname(struct ksmbd_share_config *share, -			     struct path *path) +			     const struct path *path)  {  	char *pathname, *ab_pathname, *nt_pathname;  	int share_path_len = share->path_sz; @@ -226,26 +227,53 @@ void ksmbd_conv_path_to_windows(char *path)  	strreplace(path, '/', '\\');  } +char *ksmbd_casefold_sharename(struct unicode_map *um, const char *name) +{ +	char *cf_name; +	int cf_len; + +	cf_name = kzalloc(KSMBD_REQ_MAX_SHARE_NAME, GFP_KERNEL); +	if (!cf_name) +		return ERR_PTR(-ENOMEM); + +	if (IS_ENABLED(CONFIG_UNICODE) && um) { +		const struct qstr q_name = {.name = name, .len = strlen(name)}; + +		cf_len = utf8_casefold(um, &q_name, cf_name, +				       KSMBD_REQ_MAX_SHARE_NAME); +		if (cf_len < 0) +			goto out_ascii; + +		return cf_name; +	} + +out_ascii: +	cf_len = strscpy(cf_name, name, KSMBD_REQ_MAX_SHARE_NAME); +	if (cf_len < 0) { +		kfree(cf_name); +		return ERR_PTR(-E2BIG); +	} + +	for (; *cf_name; ++cf_name) +		*cf_name = isascii(*cf_name) ? tolower(*cf_name) : *cf_name; +	return cf_name - cf_len; +} +  /**   * ksmbd_extract_sharename() - get share name from tree connect request   * @treename:	buffer containing tree name and share name   *   * Return:      share name on success, otherwise error   */ -char *ksmbd_extract_sharename(char *treename) +char *ksmbd_extract_sharename(struct unicode_map *um, const char *treename)  { -	char *name = treename; -	char *dst; -	char *pos = strrchr(name, '\\'); +	const char *name = treename, *pos = strrchr(name, '\\');  	if (pos)  		name = (pos + 1);  	/* caller has to free the memory */ -	dst = kstrdup(name, GFP_KERNEL); -	if (!dst) -		return ERR_PTR(-ENOMEM); -	return dst; +	return ksmbd_casefold_sharename(um, name);  }  /**  |