/*
 * Minimal handling of Linux kernel capabilities
 *
 * Copyright 2000-2023 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

/* Depending on distros, some have capset(), others use the more complicated
 * libcap. Let's stick to what we need and the kernel documents (capset).
 * Note that prctl is needed here.
 */
#include <linux/capability.h>
#include <sys/prctl.h>
#include <errno.h>
#include <unistd.h>
#include <syscall.h>

#include <haproxy/api.h>
#include <haproxy/cfgparse.h>
#include <haproxy/errors.h>
#include <haproxy/tools.h>

/* supported names, zero-terminated */
static const struct {
	int cap;
	const char *name;
} known_caps[] = {
#ifdef CAP_NET_RAW
	{ CAP_NET_RAW, "cap_net_raw" },
#endif
#ifdef CAP_NET_ADMIN
	{ CAP_NET_ADMIN, "cap_net_admin" },
#endif
#ifdef CAP_NET_BIND_SERVICE
	{ CAP_NET_BIND_SERVICE, "cap_net_bind_service" },
#endif
	/* must be last */
	{ 0, 0 }
};

/* provided by sys/capability.h on some distros */
static inline int capset(cap_user_header_t hdrp, const cap_user_data_t datap)
{
	return syscall(SYS_capset, hdrp, datap);
}

/* defaults to zero, i.e. we don't keep any cap after setuid() */
static uint32_t caplist;

/* try to apply capabilities before switching UID from <from_uid> to <to_uid>.
 * In practice we need to do this in 4 steps:
 *   - set PR_SET_KEEPCAPS to preserve caps across the final setuid()
 *   - set the effective and permitted caps ;
 *   - switch euid to non-zero
 *   - set the effective and permitted caps again
 *   - then the caller can safely call setuid()
 * We don't do this if the current euid is not zero or if the target uid
 * is zero. Returns >=0 on success, negative on failure. Alerts or warnings
 * may be emitted.
 */
int prepare_caps_for_setuid(int from_uid, int to_uid)
{
	struct __user_cap_data_struct cap_data = { };
	struct __user_cap_header_struct cap_hdr = {
		.pid = 0, /* current process */
		.version = _LINUX_CAPABILITY_VERSION_1,
	};

	if (from_uid != 0)
		return 0;

	if (!to_uid)
		return 0;

	if (!caplist)
		return 0;

	if (prctl(PR_SET_KEEPCAPS, 1) == -1) {
		ha_alert("Failed to preserve capabilities using prctl(): %s\n", strerror(errno));
		return -1;
	}

	cap_data.effective = cap_data.permitted = caplist | (1 << CAP_SETUID);
	if (capset(&cap_hdr, &cap_data) == -1) {
		ha_alert("Failed to preset the capabilities to preserve using capset(): %s\n", strerror(errno));
		return -1;
	}

	if (seteuid(to_uid) == -1) {
		ha_alert("Failed to set effective uid to %d: %s\n", to_uid, strerror(errno));
		return -1;
	}

	cap_data.effective = cap_data.permitted = caplist | (1 << CAP_SETUID);
	if (capset(&cap_hdr, &cap_data) == -1) {
		ha_alert("Failed to set the final capabilities using capset(): %s\n", strerror(errno));
		return -1;
	}
	/* all's good */
	return 0;
}

/* finalize the capabilities after setuid(). The most important is to drop the
 * CAP_SET_SETUID capability, which would otherwise allow to switch back to any
 * UID and recover everything.
 */
int finalize_caps_after_setuid(int from_uid, int to_uid)
{
	struct __user_cap_data_struct cap_data = { };
	struct __user_cap_header_struct cap_hdr = {
		.pid = 0, /* current process */
		.version = _LINUX_CAPABILITY_VERSION_1,
	};

	if (from_uid != 0)
		return 0;

	if (!to_uid)
		return 0;

	if (!caplist)
		return 0;

	cap_data.effective = cap_data.permitted = caplist;
	if (capset(&cap_hdr, &cap_data) == -1) {
		ha_alert("Failed to drop the setuid capability using capset(): %s\n", strerror(errno));
		return -1;
	}
	/* all's good */
	return 0;
}

/* parse the "setcap" global keyword. Returns -1 on failure, 0 on success. */
static int cfg_parse_global_setcap(char **args, int section_type,
                                   struct proxy *curpx, const struct proxy *defpx,
                                   const char *file, int line, char **err)
{
	char *name = args[1];
	char *next;
	uint32_t caps = 0;
	int id;

	if (!*name) {
		memprintf(err, "'%s' : missing capability name(s). ", args[0]);
		goto dump_caps;
	}

	while (name && *name) {
		next = strchr(name, ',');
		if (next)
			*(next++) = '\0';

		for (id = 0; known_caps[id].cap; id++) {
			if (strcmp(name, known_caps[id].name) == 0) {
				caps |= 1U << known_caps[id].cap;
				break;
			}
		}

		if (!known_caps[id].cap) {
			memprintf(err, "'%s' : unsupported capability '%s'. ", args[0], args[1]);
			goto dump_caps;
		}
		name = next;
	}

	caplist |= caps;
	return 0;


 dump_caps:
	memprintf(err, "%s Supported ones are: ", *err);

	for (id = 0; known_caps[id].cap; id++)
		memprintf(err, "%s%s%s%s", *err,
			  id ? known_caps[id+1].cap ? ", " : " and " : "",
			  known_caps[id].name, known_caps[id+1].cap ? "" : ".");
	return -1;
}

static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_GLOBAL, "setcap", cfg_parse_global_setcap },
        { 0, NULL, NULL }
}};

INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
