Commit 95316d81 authored by JINMEI Tatuya's avatar JINMEI Tatuya

a simple implementation of the "-u" option with mostly trivial tests.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac268@2525 e5f2f494-b856-4b98-b285-d166d9295462
parent 6145807d
......@@ -46,6 +46,7 @@ libasio_link_a_CPPFLAGS = $(AM_CPPFLAGS)
BUILT_SOURCES = spec_config.h
pkglibexec_PROGRAMS = b10-auth
b10_auth_SOURCES = auth_srv.cc auth_srv.h
b10_auth_SOURCES += change_user.cc change_user.h
b10_auth_SOURCES += common.h
b10_auth_SOURCES += main.cc
b10_auth_LDADD = $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
......
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <errno.h>
#include <string.h>
#include <pwd.h>
#include <unistd.h>
#include <boost/lexical_cast.hpp>
#include <exceptions/exceptions.h>
#include <auth/common.h>
using namespace boost;
void
changeUser(const char* const username) {
const struct passwd *runas_pw = NULL;
runas_pw = getpwnam(username);
if (runas_pw == NULL) {
try {
runas_pw = getpwuid(lexical_cast<uid_t>(username));
} catch (const bad_lexical_cast& err) {
isc_throw(FatalError,
"Failed to parse user name or UID:" << username);
}
}
if (runas_pw == NULL) {
isc_throw(FatalError, "Unknown user name or UID:" << username);
}
if (setgid(runas_pw->pw_gid) < 0) {
isc_throw(FatalError, "setgid() failed: " << strerror(errno));
}
if (setuid(runas_pw->pw_uid) < 0) {
isc_throw(FatalError, "setuid() failed: " << strerror(errno));
}
}
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#ifndef __CHANGE_USER_H
#define __CHANGE_USER_H 1
/// \brief Change the run time user.
///
/// This function changes the effective user of the authoritative server
/// process.
/// \c username can be either a textual user name or its numeric ID.
/// If the specified user name (or ID) doesn't specify a local user ID
/// or the user originally starting the process doesn't have a permission
/// of changing the user to \c username, this function throws an exception
/// of class \c FatalError.
///
/// \param username User name or ID of the new effective user.
void changeUser(const char* const username);
#endif // __CHANGE_USER_H
// Local Variables:
// mode: c++
// End:
......@@ -96,9 +96,10 @@ main(int argc, char* argv[]) {
int ch;
const char* port = DNSPORT;
const char* address = NULL;
const char* uid = NULL;
bool use_ipv4 = true, use_ipv6 = true, cache = true;
while ((ch = getopt(argc, argv, "46a:np:v")) != -1) {
while ((ch = getopt(argc, argv, "46a:np:u:v")) != -1) {
switch (ch) {
case '4':
// Note that -4 means "ipv4 only", we need to set "use_ipv6" here,
......@@ -120,6 +121,9 @@ main(int argc, char* argv[]) {
case 'p':
port = optarg;
break;
case 'u':
uid = optarg;
break;
case 'v':
verbose_mode = true;
break;
......@@ -165,6 +169,10 @@ main(int argc, char* argv[]) {
my_command_handler);
cout << "[b10-auth] Configuration channel established." << endl;
if (uid != NULL) {
changeUser(uid);
}
auth_server->setConfigSession(cs);
auth_server->updateConfig(ElementPtr());
......
......@@ -13,7 +13,9 @@ TESTS += run_unittests
run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
run_unittests_SOURCES += ../change_user.h ../change_user.cc
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += change_user_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
......
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <stdlib.h>
#include <string>
#include <gtest/gtest.h>
#include <auth/common.h>
#include <auth/change_user.h>
using namespace std;
namespace {
class ChangeUserTest : public ::testing::Test {
protected:
// normally the USER environment variable should be set to the name
// of the local user running this test. If we encounter a case where
// this doesn't hold, we'll need to add a prerequisite check in each
// test. For now we assume this is valid for simplicity.
ChangeUserTest() : my_username(getenv("USER")) {}
const string my_username;
};
TEST_F(ChangeUserTest, changeToTheSameUser) {
// changing to the run time user should succeed.
EXPECT_NO_THROW(changeUser(my_username.c_str()));
}
TEST_F(ChangeUserTest, badUID) {
// -1 should be an invalid numeric UID, and (hopefully) shouldn't be
// a valid textual username.
EXPECT_THROW(changeUser("-1"), FatalError);
}
TEST_F(ChangeUserTest, promotionAttempt) {
// change to root should fail unless the running user is a super user.
if (my_username == "root") {
cerr << "Already a super user, skipping the test" << endl;
return;
}
EXPECT_THROW(changeUser("root"), FatalError);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment