xref: /linux/fs/smb/server/mgmt/user_config.c (revision 87e801e1678342fc23b1eb92c0eecedf5dca79cb)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
4  */
5 
6 #include <linux/slab.h>
7 #include <linux/mm.h>
8 
9 #include "user_config.h"
10 #include "../transport_ipc.h"
11 
12 struct ksmbd_user *ksmbd_login_user(const char *account)
13 {
14 	struct ksmbd_login_response *resp;
15 	struct ksmbd_login_response_ext *resp_ext = NULL;
16 	struct ksmbd_user *user = NULL;
17 
18 	resp = ksmbd_ipc_login_request(account);
19 	if (!resp)
20 		return NULL;
21 
22 	if (!(resp->status & KSMBD_USER_FLAG_OK))
23 		goto out;
24 
25 	if (resp->status & KSMBD_USER_FLAG_EXTENSION)
26 		resp_ext = ksmbd_ipc_login_request_ext(account);
27 
28 	user = ksmbd_alloc_user(resp, resp_ext);
29 out:
30 	kvfree(resp);
31 	return user;
32 }
33 
34 struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
35 		struct ksmbd_login_response_ext *resp_ext)
36 {
37 	struct ksmbd_user *user;
38 
39 	user = kmalloc_obj(struct ksmbd_user, KSMBD_DEFAULT_GFP);
40 	if (!user)
41 		return NULL;
42 
43 	user->name = kstrdup(resp->account, KSMBD_DEFAULT_GFP);
44 	user->flags = resp->status;
45 	user->gid = resp->gid;
46 	user->uid = resp->uid;
47 	user->passkey_sz = resp->hash_sz;
48 	user->passkey = kmalloc(resp->hash_sz, KSMBD_DEFAULT_GFP);
49 	if (user->passkey)
50 		memcpy(user->passkey, resp->hash, resp->hash_sz);
51 
52 	user->ngroups = 0;
53 	user->sgid = NULL;
54 
55 	if (!user->name || !user->passkey)
56 		goto err_free;
57 
58 	if (resp_ext) {
59 		user->sgid = kmemdup(resp_ext->____payload,
60 				     resp_ext->ngroups * sizeof(gid_t),
61 				     KSMBD_DEFAULT_GFP);
62 		if (!user->sgid)
63 			goto err_free;
64 
65 		user->ngroups = resp_ext->ngroups;
66 		ksmbd_debug(SMB, "supplementary groups : %d\n", user->ngroups);
67 	}
68 
69 	return user;
70 
71 err_free:
72 	kfree(user->name);
73 	kfree(user->passkey);
74 	kfree(user);
75 	return NULL;
76 }
77 
78 void ksmbd_free_user(struct ksmbd_user *user)
79 {
80 	ksmbd_ipc_logout_request(user->name, user->flags);
81 	kfree(user->sgid);
82 	kfree(user->name);
83 	kfree(user->passkey);
84 	kfree(user);
85 }
86 
87 bool ksmbd_anonymous_user(struct ksmbd_user *user)
88 {
89 	return user->name[0] == '\0';
90 }
91 
92 bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2)
93 {
94 	if (strcmp(u1->name, u2->name))
95 		return false;
96 	if (memcmp(u1->passkey, u2->passkey, u1->passkey_sz))
97 		return false;
98 
99 	return true;
100 }
101