/*
 * Copyright 2011 Google Inc. All Rights Reserved
 * Author: mikew@google.com (Mike Waychison)
 */

/*
 * We have to include the klibc types.h here to keep the kernel's
 * types.h from being used.
 */
#include <sys/types.h>

#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/utsname.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "kinit.h"

#define ARRAY_SIZE(x)  (sizeof(x) / sizeof(x[0]))

#define MAKE_CAP(cap) [cap] = { .cap_name = #cap }

struct capability {
	const char *cap_name;
} capabilities[] = {
	MAKE_CAP(CAP_CHOWN),
	MAKE_CAP(CAP_DAC_OVERRIDE),
	MAKE_CAP(CAP_DAC_READ_SEARCH),
	MAKE_CAP(CAP_FOWNER),
	MAKE_CAP(CAP_FSETID),
	MAKE_CAP(CAP_KILL),
	MAKE_CAP(CAP_SETGID),
	MAKE_CAP(CAP_SETUID),
	MAKE_CAP(CAP_SETPCAP),
	MAKE_CAP(CAP_LINUX_IMMUTABLE),
	MAKE_CAP(CAP_NET_BIND_SERVICE),
	MAKE_CAP(CAP_NET_BROADCAST),
	MAKE_CAP(CAP_NET_ADMIN),
	MAKE_CAP(CAP_NET_RAW),
	MAKE_CAP(CAP_IPC_LOCK),
	MAKE_CAP(CAP_IPC_OWNER),
	MAKE_CAP(CAP_SYS_MODULE),
	MAKE_CAP(CAP_SYS_RAWIO),
	MAKE_CAP(CAP_SYS_CHROOT),
	MAKE_CAP(CAP_SYS_PTRACE),
	MAKE_CAP(CAP_SYS_PACCT),
	MAKE_CAP(CAP_SYS_ADMIN),
	MAKE_CAP(CAP_SYS_BOOT),
	MAKE_CAP(CAP_SYS_NICE),
	MAKE_CAP(CAP_SYS_RESOURCE),
	MAKE_CAP(CAP_SYS_TIME),
	MAKE_CAP(CAP_SYS_TTY_CONFIG),
	MAKE_CAP(CAP_MKNOD),
	MAKE_CAP(CAP_LEASE),
	MAKE_CAP(CAP_AUDIT_WRITE),
	MAKE_CAP(CAP_AUDIT_CONTROL),
	MAKE_CAP(CAP_SETFCAP),
	MAKE_CAP(CAP_MAC_OVERRIDE),
	MAKE_CAP(CAP_MAC_ADMIN),
	MAKE_CAP(CAP_SYSLOG),
};

static void fail(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
static void fail(const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	exit(1);
}

/*
 * Find the capability ordinal by name, and return its ordinal.
 * Returns -1 on failure.
 */
static int find_capability(const char *s)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
		if (capabilities[i].cap_name
		 && strcasecmp(s, capabilities[i].cap_name) == 0) {
			return i;
		}
	}
	return -1;
}

static void do_capset(int cap_ordinal)
{
	struct __user_cap_header_struct hdr;
	struct __user_cap_data_struct caps[2];

	/* Get the current capability mask */
	hdr.version = _LINUX_CAPABILITY_VERSION_3;
	hdr.pid = getpid();
	if (capget(&hdr, caps)) {
		perror("capget()");
		exit(1);
	}

	/* Drop the bits */
	if (cap_ordinal < 32)
		caps[0].inheritable &= ~(1U << cap_ordinal);
	else
		caps[1].inheritable &= ~(1U << (cap_ordinal - 32));

	/* And drop the capability. */
	hdr.version = _LINUX_CAPABILITY_VERSION_3;
	hdr.pid = getpid();
	if (capset(&hdr, caps))
		fail("Couldn't drop the capability \"%s\"\n",
		     capabilities[cap_ordinal].cap_name);
}

static void do_bset(int cap_ordinal)
{
	int ret;

	ret = prctl(PR_CAPBSET_READ, cap_ordinal);
	if (ret == 1) {
		ret = prctl(PR_CAPBSET_DROP, cap_ordinal);
		if (ret != 0)
			fail("Error dropping capability %s from bset\n",
			     capabilities[cap_ordinal].cap_name);
	} else if (ret < 0)
		fail("Kernel doesn't recognize capability %d\n", cap_ordinal);
}

static void do_usermodehelper_file(const char *filename, int cap_ordinal)
{
	uint32_t lo32, hi32;
	FILE *file;
	static const size_t buf_size = 80;
	char buf[buf_size];
	char tail;
	size_t bytes_read;
	int ret;

	/* Try and open the file */
	file = fopen(filename, "r+");
	if (!file && errno == ENOENT)
		fail("Could not disable usermode helpers capabilities as "
		     "%s is not available\n", filename);
	if (!file)
		fail("Failed to access file %s errno %d\n", filename, errno);

	/* Read and process the current bits */
	bytes_read = fread(buf, 1, buf_size - 1, file);
	if (bytes_read == 0)
		fail("Trouble reading %s\n", filename);
	buf[bytes_read] = '\0';
	ret = sscanf(buf, "%u %u %c", &lo32, &hi32, &tail);
	if (ret != 2)
		fail("Failed to understand %s \"%s\"\n", filename, buf);

	/* Clear the bits in the local copy */
	if (cap_ordinal < 32)
		lo32 &= ~(1 << cap_ordinal);
	else
		hi32 &= ~(1 << (cap_ordinal - 32));

	/* Commit the new bit masks to the kernel */
	sprintf(buf, "%u %u", lo32, hi32);
	ret = fwrite(buf, 1, strlen(buf) + 1, file);
	if (ret != 0)
		fail("Failed to commit usermode helper bitmasks: %d\n", ret);

	/* Cleanup */
	fclose(file);
}

static void do_usermodehelper(int cap_ordinal)
{
	static const char * const files[] = {
		"/proc/sys/kernel/usermodehelper/bset",
		"/proc/sys/kernel/usermodehelper/inheritable",
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(files); i++)
		do_usermodehelper_file(files[i], cap_ordinal);
}

static void drop_capability(int cap_ordinal)
{
	do_usermodehelper(cap_ordinal);
	do_bset(cap_ordinal);
	do_capset(cap_ordinal);

	printf("Dropped capability: %s\n", capabilities[cap_ordinal].cap_name);
}

int drop_capabilities(const char *caps)
{
	char *s, *saveptr = NULL;
	char *token;

	if (!caps)
		return 0;

	/* Create a duplicate string that can be modified. */
	s = strdup(caps);
	if (!s)
		fail("Failed to drop caps as requested.  Exiting\n");

	token = strtok_r(s, ",", &saveptr);
	while (token) {
		int cap_ordinal = find_capability(token);

		if (cap_ordinal < 0)
			fail("Could not understand capability name \"%s\" "
			     "on command line, failing init\n", token);

		drop_capability(cap_ordinal);

		token = strtok_r(NULL, ",", &saveptr);
	}

	free(s);
	return 0;
}
