diff mbox series

[2/2] ksmbd-tools: casefold utf-8 share names

Message ID 20220911205729.299358-2-atteh.mailbox@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/2] ksmbd: casefold utf-8 share names and fix ascii lowercase conversion | expand

Commit Message

Atte Heikkilä Sept. 11, 2022, 8:57 p.m. UTC
Match kernel space behavior regarding case-insensitivity of UTF-8 share
names by first NFD(I) normalizing and then casefolding them. Fallback
to ASCII lowercase conversion on failure.

Signed-off-by: Atte Heikkilä <atteh.mailbox@gmail.com>
---
 addshare/addshare.c        |  6 +++---
 include/management/share.h |  1 +
 lib/config_parser.c        |  2 +-
 lib/management/share.c     | 19 +++++++++++++++++++
 mountd/rpc_srvsvc.c        |  2 +-
 5 files changed, 25 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/addshare/addshare.c b/addshare/addshare.c
index f5894c9..be4c67d 100644
--- a/addshare/addshare.c
+++ b/addshare/addshare.c
@@ -123,17 +123,17 @@  int main(int argc, char *argv[])
 		switch (c) {
 		case 'a':
 			g_free(share);
-			share = g_ascii_strdown(optarg, strlen(optarg));
+			share = shm_casefold_share_name(optarg, strlen(optarg));
 			command = command_add_share;
 			break;
 		case 'd':
 			g_free(share);
-			share = g_ascii_strdown(optarg, strlen(optarg));
+			share = shm_casefold_share_name(optarg, strlen(optarg));
 			command = command_del_share;
 			break;
 		case 'u':
 			g_free(share);
-			share = g_ascii_strdown(optarg, strlen(optarg));
+			share = shm_casefold_share_name(optarg, strlen(optarg));
 			command = command_update_share;
 			break;
 		case 'o':
diff --git a/include/management/share.h b/include/management/share.h
index 306cca5..bb3952c 100644
--- a/include/management/share.h
+++ b/include/management/share.h
@@ -141,6 +141,7 @@  static inline int test_share_flag(struct ksmbd_share *share, int flag)
 
 struct ksmbd_share *get_ksmbd_share(struct ksmbd_share *share);
 void put_ksmbd_share(struct ksmbd_share *share);
+char *shm_casefold_share_name(char *name, size_t len);
 struct ksmbd_share *shm_lookup_share(char *name);
 
 struct smbconf_group;
diff --git a/lib/config_parser.c b/lib/config_parser.c
index 2dbc0c7..a1dc85c 100644
--- a/lib/config_parser.c
+++ b/lib/config_parser.c
@@ -93,7 +93,7 @@  static int add_new_group(char *line)
 	while (*end && *end != ']')
 		end = g_utf8_find_next_char(end, NULL);
 
-	name = g_ascii_strdown(begin + 1, end - begin - 1);
+	name = shm_casefold_share_name(begin + 1, end - begin - 1);
 	if (!name)
 		goto out_free;
 
diff --git a/lib/management/share.c b/lib/management/share.c
index 22e6a83..fc09ea8 100644
--- a/lib/management/share.c
+++ b/lib/management/share.c
@@ -236,6 +236,25 @@  int shm_init(void)
 	return 0;
 }
 
+char *shm_casefold_share_name(char *name, size_t len)
+{
+	char *nfdi_name, *nfdicf_name;
+
+	nfdi_name = g_utf8_normalize(name, len, G_NORMALIZE_NFD);
+	if (!nfdi_name)
+		goto out_ascii;
+
+	nfdicf_name = g_utf8_casefold(nfdi_name, strlen(nfdi_name));
+	if (!nfdicf_name)
+		goto out_ascii;
+
+	g_free(nfdi_name);
+	return nfdicf_name;
+out_ascii:
+	g_free(nfdi_name);
+	return g_ascii_strdown(name, len);
+}
+
 static struct ksmbd_share *__shm_lookup_share(char *name)
 {
 	return g_hash_table_lookup(shares_table, name);
diff --git a/mountd/rpc_srvsvc.c b/mountd/rpc_srvsvc.c
index 38b984b..8716c34 100644
--- a/mountd/rpc_srvsvc.c
+++ b/mountd/rpc_srvsvc.c
@@ -171,7 +171,7 @@  static int srvsvc_share_get_info_invoke(struct ksmbd_rpc_pipe *pipe,
 	int ret;
 	gchar *share_name;
 
-	share_name = g_ascii_strdown(STR_VAL(hdr->share_name),
+	share_name = shm_casefold_share_name(STR_VAL(hdr->share_name),
 			strlen(STR_VAL(hdr->share_name)));
 	share = shm_lookup_share(share_name);
 	if (!share)