// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2007 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
#ident "$XORP: xorp/rtrmgr/userdb.cc,v 1.21 2007/02/16 22:47:27 pavlin Exp $"
#include "rtrmgr_module.h"
#include "libxorp/xorp.h"
#include "libxorp/xlog.h"
#include "libxorp/debug.h"
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include "userdb.hh"
User::User(uid_t user_id, const string& username)
: _user_id(user_id),
_username(username)
{
}
bool
User::has_acl_capability(const string& capname) const
{
set<string>::const_iterator iter;
iter = _capabilities.find(capname);
if (iter == _capabilities.end()) {
return false;
} else {
return true;
}
}
void
User::add_acl_capability(const string& capname)
{
set<string>::iterator iter;
iter = _capabilities.find(capname);
if (iter == _capabilities.end()) {
_capabilities.insert(capname);
}
}
UserInstance::UserInstance(uid_t user_id, const string& username)
: User(user_id, username), _authenticated(false), _config_mode(false),
_is_a_zombie(false)
{
}
UserDB::UserDB(bool verbose)
: _verbose(verbose)
{
}
UserDB::~UserDB()
{
map<uid_t, User*>::iterator iter;
for (iter = _users.begin(); iter != _users.end(); ++iter) {
delete iter->second;
}
}
void
UserDB::load_password_file()
{
#ifdef HOST_OS_WINDOWS
string username("Administrator");
uid_t userid = 0;
add_user(userid, username, userid);
#else // ! HOST_OS_WINDOWS
struct passwd* pwent;
pwent = getpwent();
while (pwent != NULL) {
debug_msg("User: %s UID: %u\n", pwent->pw_name,
XORP_UINT_CAST(pwent->pw_uid));
add_user(pwent->pw_uid, pwent->pw_name, pwent->pw_gid);
pwent = getpwent();
}
endpwent();
#endif // ! HOST_OS_WINDOWS
}
User*
UserDB::add_user(uid_t user_id, const string& username, gid_t pw_gid)
{
if (_users.find(user_id) == _users.end()) {
User* newuser = new User(user_id, username);
#ifndef HOST_OS_WINDOWS
struct group* grp = getgrnam("xorp");
if (grp != NULL) {
debug_msg("group xorp exists, id=%u\n",
XORP_UINT_CAST(grp->gr_gid));
if (pw_gid == (gid_t)grp->gr_gid) {
/* is the user's default group is the "xorp" group */
debug_msg("user's default groyp is xorp\n");
newuser->add_acl_capability("config");
} else {
/* if not, then check if they're listed in /etc/group as
being in the xorp group */
char **gr_mem = grp->gr_mem;
while (*gr_mem != NULL) {
debug_msg("found user %s in group xorp\n", *gr_mem);
if (*gr_mem == username) {
newuser->add_acl_capability("config");
break;
}
gr_mem++;
}
}
} else {
XLOG_ERROR("Group \"xorp\" does not exist on this system.");
}
#else // ! HOST_OS_WINDOWS
UNUSED(pw_gid);
newuser->add_acl_capability("config");
#endif // ! HOST_OS_WINDOWS
_users[user_id] = newuser;
return newuser;
} else {
// This user_id already exists
return NULL;
}
}
const User*
UserDB::find_user_by_user_id(uid_t user_id)
{
//
// XXX: we always reloads the cache on each access to the
// find_user_by_user_id(). This is not optimal, but guarantees that
// the user accounts in the system and the rtrmgr are in-sync.
//
load_password_file();
map<uid_t, User*>::const_iterator iter = _users.find(user_id);
if (iter == _users.end())
return NULL;
else
return iter->second;
}
void
UserDB::remove_user(uid_t user_id)
{
map<uid_t, User*>::iterator iter = _users.find(user_id);
User* user = iter->second;
_users.erase(iter);
delete user;
}
bool
UserDB::has_capability(uid_t user_id, const string& capability)
{
const User* user = find_user_by_user_id(user_id);
if (user == NULL)
return false;
return (user->has_acl_capability(capability));
}
syntax highlighted by Code2HTML, v. 0.9.1