/*
 * Copyright (C) 2017 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "privs.h"
#include "privs.c"

#include <glib.h>

// Test that dropping permissions really works
static void test_sc_privs_drop(void)
{
	if (geteuid() != 0 || getuid() == 0) {
		g_test_skip("run this test after chown root.root; chmod u+s");
		return;
	}
	if (getegid() != 0 || getgid() == 0) {
		g_test_skip("run this test after chown root.root; chmod g+s");
		return;
	}
	if (g_test_subprocess()) {
		// We start as a regular user with effective-root identity.
		g_assert_cmpint(getuid(), !=, 0);
		g_assert_cmpint(getgid(), !=, 0);

		g_assert_cmpint(geteuid(), ==, 0);
		g_assert_cmpint(getegid(), ==, 0);

		// We drop the privileges.
		sc_privs_drop();

		// The we are no longer root.
		g_assert_cmpint(getuid(), !=, 0);
		g_assert_cmpint(geteuid(), !=, 0);
		g_assert_cmpint(getgid(), !=, 0);
		g_assert_cmpint(getegid(), !=, 0);

		// We don't have any supplementary groups.
		gid_t groups[2];
		int num_groups = getgroups(1, groups);
		g_assert_cmpint(num_groups, ==, 1);
		g_assert_cmpint(groups[0], ==, getgid());

		// All done.
		return;
	}
	g_test_trap_subprocess(NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR);
	g_test_trap_assert_passed();
}

static void __attribute__((constructor)) init(void)
{
	g_test_add_func("/privs/sc_privs_drop", test_sc_privs_drop);
}
