109 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 12struct 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);29out:30 kvfree(resp);31 return user;32}33 34struct 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(sizeof(struct ksmbd_user), GFP_KERNEL);40 if (!user)41 return NULL;42 43 user->name = kstrdup(resp->account, GFP_KERNEL);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, GFP_KERNEL);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 if (resp_ext->ngroups > NGROUPS_MAX) {60 pr_err("ngroups(%u) from login response exceeds max groups(%d)\n",61 resp_ext->ngroups, NGROUPS_MAX);62 goto err_free;63 }64 65 user->sgid = kmemdup(resp_ext->____payload,66 resp_ext->ngroups * sizeof(gid_t),67 GFP_KERNEL);68 if (!user->sgid)69 goto err_free;70 71 user->ngroups = resp_ext->ngroups;72 ksmbd_debug(SMB, "supplementary groups : %d\n", user->ngroups);73 }74 75 return user;76 77err_free:78 kfree(user->name);79 kfree(user->passkey);80 kfree(user);81 return NULL;82}83 84void ksmbd_free_user(struct ksmbd_user *user)85{86 ksmbd_ipc_logout_request(user->name, user->flags);87 kfree(user->sgid);88 kfree(user->name);89 kfree(user->passkey);90 kfree(user);91}92 93int ksmbd_anonymous_user(struct ksmbd_user *user)94{95 if (user->name[0] == '\0')96 return 1;97 return 0;98}99 100bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2)101{102 if (strcmp(u1->name, u2->name))103 return false;104 if (memcmp(u1->passkey, u2->passkey, u1->passkey_sz))105 return false;106 107 return true;108}109