// SPDX-License-Identifier: GPL-2.0
/*
 * Functions corresponding to password object type attributes under BIOS Password Object GUID for
 * use with dell-wmi-sysman
 *
 *  Copyright (c) 2020 Dell Inc.
 */

#include "dell-wmi-sysman.h"

enum po_properties {IS_PASS_SET = 1, MIN_PASS_LEN, MAX_PASS_LEN};

get_instance_id(po);

static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr,
					  char *buf)
{
	int instance_id = get_po_instance_id(kobj);
	union acpi_object *obj;
	ssize_t ret;

	if (instance_id < 0)
		return instance_id;

	/* need to use specific instance_id and guid combination to get right data */
	obj = get_wmiobj_pointer(instance_id, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID);
	if (!obj)
		return -EIO;
	if (obj->package.elements[IS_PASS_SET].type != ACPI_TYPE_INTEGER) {
		kfree(obj);
		return -EINVAL;
	}
	ret = snprintf(buf, PAGE_SIZE, "%lld\n", obj->package.elements[IS_PASS_SET].integer.value);
	kfree(obj);
	return ret;
}

static struct kobj_attribute po_is_pass_set = __ATTR_RO(is_enabled);

static ssize_t current_password_store(struct kobject *kobj,
				      struct kobj_attribute *attr,
				      const char *buf, size_t count)
{
	char *target = NULL;
	int length;

	length = strlen(buf);
	if (buf[length-1] == '\n')
		length--;

	/* firmware does verifiation of min/max password length,
	 * hence only check for not exceeding MAX_BUFF here.
	 */
	if (length >= MAX_BUFF)
		return -EINVAL;

	if (strcmp(kobj->name, "Admin") == 0)
		target = wmi_priv.current_admin_password;
	else if (strcmp(kobj->name, "System") == 0)
		target = wmi_priv.current_system_password;
	if (!target)
		return -EIO;
	memcpy(target, buf, length);
	target[length] = '\0';

	return count;
}

static struct kobj_attribute po_current_password = __ATTR_WO(current_password);

static ssize_t new_password_store(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  const char *buf, size_t count)
{
	char *p, *buf_cp;
	int ret;

	buf_cp = kstrdup(buf, GFP_KERNEL);
	if (!buf_cp)
		return -ENOMEM;
	p = memchr(buf_cp, '\n', count);

	if (p != NULL)
		*p = '\0';
	if (strlen(buf_cp) > MAX_BUFF) {
		ret = -EINVAL;
		goto out;
	}

	ret = set_new_password(kobj->name, buf_cp);

out:
	kfree(buf_cp);
	return ret ? ret : count;
}

static struct kobj_attribute po_new_password = __ATTR_WO(new_password);

attribute_n_property_show(min_password_length, po);
static struct kobj_attribute po_min_pass_length = __ATTR_RO(min_password_length);

attribute_n_property_show(max_password_length, po);
static struct kobj_attribute po_max_pass_length = __ATTR_RO(max_password_length);

static ssize_t mechanism_show(struct kobject *kobj, struct kobj_attribute *attr,
			 char *buf)
{
	return sprintf(buf, "password\n");
}

static struct kobj_attribute po_mechanism = __ATTR_RO(mechanism);

static ssize_t role_show(struct kobject *kobj, struct kobj_attribute *attr,
			 char *buf)
{
	if (strcmp(kobj->name, "Admin") == 0)
		return sprintf(buf, "bios-admin\n");
	else if (strcmp(kobj->name, "System") == 0)
		return sprintf(buf, "power-on\n");
	return -EIO;
}

static struct kobj_attribute po_role = __ATTR_RO(role);

static struct attribute *po_attrs[] = {
	&po_is_pass_set.attr,
	&po_min_pass_length.attr,
	&po_max_pass_length.attr,
	&po_current_password.attr,
	&po_new_password.attr,
	&po_role.attr,
	&po_mechanism.attr,
	NULL,
};

static const struct attribute_group po_attr_group = {
	.attrs = po_attrs,
};

int alloc_po_data(void)
{
	int ret = 0;

	wmi_priv.po_instances_count = get_instance_count(DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID);
	wmi_priv.po_data = kcalloc(wmi_priv.po_instances_count, sizeof(struct po_data), GFP_KERNEL);
	if (!wmi_priv.po_data) {
		wmi_priv.po_instances_count = 0;
		ret = -ENOMEM;
	}
	return ret;
}

/**
 * populate_po_data() - Populate all properties of an instance under password object attribute
 * @po_obj: ACPI object with password object data
 * @instance_id: The instance to enumerate
 * @attr_name_kobj: The parent kernel object
 */
int populate_po_data(union acpi_object *po_obj, int instance_id, struct kobject *attr_name_kobj)
{
	wmi_priv.po_data[instance_id].attr_name_kobj = attr_name_kobj;
	strlcpy_attr(wmi_priv.po_data[instance_id].attribute_name,
		     po_obj[ATTR_NAME].string.pointer);
	wmi_priv.po_data[instance_id].min_password_length =
		(uintptr_t)po_obj[MIN_PASS_LEN].string.pointer;
	wmi_priv.po_data[instance_id].max_password_length =
		(uintptr_t) po_obj[MAX_PASS_LEN].string.pointer;

	return sysfs_create_group(attr_name_kobj, &po_attr_group);
}

/**
 * exit_po_attributes() - Clear all attribute data
 *
 * Clears all data allocated for this group of attributes
 */
void exit_po_attributes(void)
{
	int instance_id;

	for (instance_id = 0; instance_id < wmi_priv.po_instances_count; instance_id++) {
		if (wmi_priv.po_data[instance_id].attr_name_kobj)
			sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj,
								&po_attr_group);
	}
	kfree(wmi_priv.po_data);
}
