// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Copyright (C) 2021 Samsung Electronics Co., Ltd.
 *   Author(s): Namjae Jeon <linkinjeon@kernel.org>
 */

#include <linux/fs.h>

#include "glob.h"
#include "ndr.h"

static inline char *ndr_get_field(struct ndr *n)
{
	return n->data + n->offset;
}

static int try_to_realloc_ndr_blob(struct ndr *n, size_t sz)
{
	char *data;

	data = krealloc(n->data, n->offset + sz + 1024, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	n->data = data;
	n->length += 1024;
	memset(n->data + n->offset, 0, 1024);
	return 0;
}

static int ndr_write_int16(struct ndr *n, __u16 value)
{
	if (n->length <= n->offset + sizeof(value)) {
		int ret;

		ret = try_to_realloc_ndr_blob(n, sizeof(value));
		if (ret)
			return ret;
	}

	*(__le16 *)ndr_get_field(n) = cpu_to_le16(value);
	n->offset += sizeof(value);
	return 0;
}

static int ndr_write_int32(struct ndr *n, __u32 value)
{
	if (n->length <= n->offset + sizeof(value)) {
		int ret;

		ret = try_to_realloc_ndr_blob(n, sizeof(value));
		if (ret)
			return ret;
	}

	*(__le32 *)ndr_get_field(n) = cpu_to_le32(value);
	n->offset += sizeof(value);
	return 0;
}

static int ndr_write_int64(struct ndr *n, __u64 value)
{
	if (n->length <= n->offset + sizeof(value)) {
		int ret;

		ret = try_to_realloc_ndr_blob(n, sizeof(value));
		if (ret)
			return ret;
	}

	*(__le64 *)ndr_get_field(n) = cpu_to_le64(value);
	n->offset += sizeof(value);
	return 0;
}

static int ndr_write_bytes(struct ndr *n, void *value, size_t sz)
{
	if (n->length <= n->offset + sz) {
		int ret;

		ret = try_to_realloc_ndr_blob(n, sz);
		if (ret)
			return ret;
	}

	memcpy(ndr_get_field(n), value, sz);
	n->offset += sz;
	return 0;
}

static int ndr_write_string(struct ndr *n, char *value)
{
	size_t sz;

	sz = strlen(value) + 1;
	if (n->length <= n->offset + sz) {
		int ret;

		ret = try_to_realloc_ndr_blob(n, sz);
		if (ret)
			return ret;
	}

	memcpy(ndr_get_field(n), value, sz);
	n->offset += sz;
	n->offset = ALIGN(n->offset, 2);
	return 0;
}

static int ndr_read_string(struct ndr *n, void *value, size_t sz)
{
	int len;

	if (n->offset + sz > n->length)
		return -EINVAL;

	len = strnlen(ndr_get_field(n), sz);
	if (value)
		memcpy(value, ndr_get_field(n), len);
	len++;
	n->offset += len;
	n->offset = ALIGN(n->offset, 2);
	return 0;
}

static int ndr_read_bytes(struct ndr *n, void *value, size_t sz)
{
	if (n->offset + sz > n->length)
		return -EINVAL;

	if (value)
		memcpy(value, ndr_get_field(n), sz);
	n->offset += sz;
	return 0;
}

static int ndr_read_int16(struct ndr *n, __u16 *value)
{
	if (n->offset + sizeof(__u16) > n->length)
		return -EINVAL;

	if (value)
		*value = le16_to_cpu(*(__le16 *)ndr_get_field(n));
	n->offset += sizeof(__u16);
	return 0;
}

static int ndr_read_int32(struct ndr *n, __u32 *value)
{
	if (n->offset + sizeof(__u32) > n->length)
		return -EINVAL;

	if (value)
		*value = le32_to_cpu(*(__le32 *)ndr_get_field(n));
	n->offset += sizeof(__u32);
	return 0;
}

static int ndr_read_int64(struct ndr *n, __u64 *value)
{
	if (n->offset + sizeof(__u64) > n->length)
		return -EINVAL;

	if (value)
		*value = le64_to_cpu(*(__le64 *)ndr_get_field(n));
	n->offset += sizeof(__u64);
	return 0;
}

int ndr_encode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
{
	char hex_attr[12] = {0};
	int ret;

	n->offset = 0;
	n->length = 1024;
	n->data = kzalloc(n->length, GFP_KERNEL);
	if (!n->data)
		return -ENOMEM;

	if (da->version == 3) {
		snprintf(hex_attr, 10, "0x%x", da->attr);
		ret = ndr_write_string(n, hex_attr);
	} else {
		ret = ndr_write_string(n, "");
	}
	if (ret)
		return ret;

	ret = ndr_write_int16(n, da->version);
	if (ret)
		return ret;

	ret = ndr_write_int32(n, da->version);
	if (ret)
		return ret;

	ret = ndr_write_int32(n, da->flags);
	if (ret)
		return ret;

	ret = ndr_write_int32(n, da->attr);
	if (ret)
		return ret;

	if (da->version == 3) {
		ret = ndr_write_int32(n, da->ea_size);
		if (ret)
			return ret;
		ret = ndr_write_int64(n, da->size);
		if (ret)
			return ret;
		ret = ndr_write_int64(n, da->alloc_size);
	} else {
		ret = ndr_write_int64(n, da->itime);
	}
	if (ret)
		return ret;

	ret = ndr_write_int64(n, da->create_time);
	if (ret)
		return ret;

	if (da->version == 3)
		ret = ndr_write_int64(n, da->change_time);
	return ret;
}

int ndr_decode_dos_attr(struct ndr *n, struct xattr_dos_attrib *da)
{
	char hex_attr[12];
	unsigned int version2;
	int ret;

	n->offset = 0;
	ret = ndr_read_string(n, hex_attr, sizeof(hex_attr));
	if (ret)
		return ret;

	ret = ndr_read_int16(n, &da->version);
	if (ret)
		return ret;

	if (da->version != 3 && da->version != 4) {
		ksmbd_debug(VFS, "v%d version is not supported\n", da->version);
		return -EINVAL;
	}

	ret = ndr_read_int32(n, &version2);
	if (ret)
		return ret;

	if (da->version != version2) {
		ksmbd_debug(VFS, "ndr version mismatched(version: %d, version2: %d)\n",
		       da->version, version2);
		return -EINVAL;
	}

	ret = ndr_read_int32(n, NULL);
	if (ret)
		return ret;

	ret = ndr_read_int32(n, &da->attr);
	if (ret)
		return ret;

	if (da->version == 4) {
		ret = ndr_read_int64(n, &da->itime);
		if (ret)
			return ret;

		ret = ndr_read_int64(n, &da->create_time);
	} else {
		ret = ndr_read_int32(n, NULL);
		if (ret)
			return ret;

		ret = ndr_read_int64(n, NULL);
		if (ret)
			return ret;

		ret = ndr_read_int64(n, NULL);
		if (ret)
			return ret;

		ret = ndr_read_int64(n, &da->create_time);
		if (ret)
			return ret;

		ret = ndr_read_int64(n, NULL);
	}

	return ret;
}

static int ndr_encode_posix_acl_entry(struct ndr *n, struct xattr_smb_acl *acl)
{
	int i, ret;

	ret = ndr_write_int32(n, acl->count);
	if (ret)
		return ret;

	n->offset = ALIGN(n->offset, 8);
	ret = ndr_write_int32(n, acl->count);
	if (ret)
		return ret;

	ret = ndr_write_int32(n, 0);
	if (ret)
		return ret;

	for (i = 0; i < acl->count; i++) {
		n->offset = ALIGN(n->offset, 8);
		ret = ndr_write_int16(n, acl->entries[i].type);
		if (ret)
			return ret;

		ret = ndr_write_int16(n, acl->entries[i].type);
		if (ret)
			return ret;

		if (acl->entries[i].type == SMB_ACL_USER) {
			n->offset = ALIGN(n->offset, 8);
			ret = ndr_write_int64(n, acl->entries[i].uid);
		} else if (acl->entries[i].type == SMB_ACL_GROUP) {
			n->offset = ALIGN(n->offset, 8);
			ret = ndr_write_int64(n, acl->entries[i].gid);
		}
		if (ret)
			return ret;

		/* push permission */
		ret = ndr_write_int32(n, acl->entries[i].perm);
	}

	return ret;
}

int ndr_encode_posix_acl(struct ndr *n,
			 struct mnt_idmap *idmap,
			 struct inode *inode,
			 struct xattr_smb_acl *acl,
			 struct xattr_smb_acl *def_acl)
{
	unsigned int ref_id = 0x00020000;
	int ret;
	vfsuid_t vfsuid;
	vfsgid_t vfsgid;

	n->offset = 0;
	n->length = 1024;
	n->data = kzalloc(n->length, GFP_KERNEL);
	if (!n->data)
		return -ENOMEM;

	if (acl) {
		/* ACL ACCESS */
		ret = ndr_write_int32(n, ref_id);
		ref_id += 4;
	} else {
		ret = ndr_write_int32(n, 0);
	}
	if (ret)
		return ret;

	if (def_acl) {
		/* DEFAULT ACL ACCESS */
		ret = ndr_write_int32(n, ref_id);
		ref_id += 4;
	} else {
		ret = ndr_write_int32(n, 0);
	}
	if (ret)
		return ret;

	vfsuid = i_uid_into_vfsuid(idmap, inode);
	ret = ndr_write_int64(n, from_kuid(&init_user_ns, vfsuid_into_kuid(vfsuid)));
	if (ret)
		return ret;
	vfsgid = i_gid_into_vfsgid(idmap, inode);
	ret = ndr_write_int64(n, from_kgid(&init_user_ns, vfsgid_into_kgid(vfsgid)));
	if (ret)
		return ret;
	ret = ndr_write_int32(n, inode->i_mode);
	if (ret)
		return ret;

	if (acl) {
		ret = ndr_encode_posix_acl_entry(n, acl);
		if (def_acl && !ret)
			ret = ndr_encode_posix_acl_entry(n, def_acl);
	}
	return ret;
}

int ndr_encode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
{
	unsigned int ref_id = 0x00020004;
	int ret;

	n->offset = 0;
	n->length = 2048;
	n->data = kzalloc(n->length, GFP_KERNEL);
	if (!n->data)
		return -ENOMEM;

	ret = ndr_write_int16(n, acl->version);
	if (ret)
		return ret;

	ret = ndr_write_int32(n, acl->version);
	if (ret)
		return ret;

	ret = ndr_write_int16(n, 2);
	if (ret)
		return ret;

	ret = ndr_write_int32(n, ref_id);
	if (ret)
		return ret;

	/* push hash type and hash 64bytes */
	ret = ndr_write_int16(n, acl->hash_type);
	if (ret)
		return ret;

	ret = ndr_write_bytes(n, acl->hash, XATTR_SD_HASH_SIZE);
	if (ret)
		return ret;

	ret = ndr_write_bytes(n, acl->desc, acl->desc_len);
	if (ret)
		return ret;

	ret = ndr_write_int64(n, acl->current_time);
	if (ret)
		return ret;

	ret = ndr_write_bytes(n, acl->posix_acl_hash, XATTR_SD_HASH_SIZE);
	if (ret)
		return ret;

	/* push ndr for security descriptor */
	ret = ndr_write_bytes(n, acl->sd_buf, acl->sd_size);
	return ret;
}

int ndr_decode_v4_ntacl(struct ndr *n, struct xattr_ntacl *acl)
{
	unsigned int version2;
	int ret;

	n->offset = 0;
	ret = ndr_read_int16(n, &acl->version);
	if (ret)
		return ret;
	if (acl->version != 4) {
		ksmbd_debug(VFS, "v%d version is not supported\n", acl->version);
		return -EINVAL;
	}

	ret = ndr_read_int32(n, &version2);
	if (ret)
		return ret;
	if (acl->version != version2) {
		ksmbd_debug(VFS, "ndr version mismatched(version: %d, version2: %d)\n",
		       acl->version, version2);
		return -EINVAL;
	}

	/* Read Level */
	ret = ndr_read_int16(n, NULL);
	if (ret)
		return ret;

	/* Read Ref Id */
	ret = ndr_read_int32(n, NULL);
	if (ret)
		return ret;

	ret = ndr_read_int16(n, &acl->hash_type);
	if (ret)
		return ret;

	ret = ndr_read_bytes(n, acl->hash, XATTR_SD_HASH_SIZE);
	if (ret)
		return ret;

	ndr_read_bytes(n, acl->desc, 10);
	if (strncmp(acl->desc, "posix_acl", 9)) {
		pr_err("Invalid acl description : %s\n", acl->desc);
		return -EINVAL;
	}

	/* Read Time */
	ret = ndr_read_int64(n, NULL);
	if (ret)
		return ret;

	/* Read Posix ACL hash */
	ret = ndr_read_bytes(n, acl->posix_acl_hash, XATTR_SD_HASH_SIZE);
	if (ret)
		return ret;

	acl->sd_size = n->length - n->offset;
	acl->sd_buf = kzalloc(acl->sd_size, GFP_KERNEL);
	if (!acl->sd_buf)
		return -ENOMEM;

	ret = ndr_read_bytes(n, acl->sd_buf, acl->sd_size);
	return ret;
}
