Add userdel

This commit is contained in:
Ingo Weinhold
2013-09-18 16:33:17 +02:00
parent 0e9e586cac
commit e9d9ac713f
7 changed files with 188 additions and 9 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
tac tail tcpdump tcptester tee telnet telnetd test timeout top touch tac tail tcpdump tcptester tee telnet telnetd test timeout top touch
tr traceroute translate trash true truncate tsort tty tr traceroute translate trash true truncate tsort tty
uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx
<bin>updatedb uptime urlwrapper useradd uudecode uuencode <bin>updatedb uptime urlwrapper useradd userdel uudecode uuencode
vdir version vmstat vdir version vmstat
waitfor watch wc wget whoami writembr@x86 xargs xres waitfor watch wc wget whoami writembr@x86 xargs xres
yes yes
+1 -1
View File
@@ -37,7 +37,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
tac tail tcpdump tcptester tee telnet telnetd test timeout top touch tac tail tcpdump tcptester tee telnet telnetd test timeout top touch
tr traceroute trash true truncate tsort tty tr traceroute trash true truncate tsort tty
uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx uname unchop unexpand unmount uniq unlink unshar unzip unzipsfx
<bin>updatedb uptime urlwrapper useradd uudecode uuencode <bin>updatedb uptime urlwrapper useradd userdel uudecode uuencode
vdir version vmstat vdir version vmstat
waitfor watch wc wget whoami writembr@x86 xargs xres waitfor watch wc wget whoami writembr@x86 xargs xres
yes yes
+2
View File
@@ -121,7 +121,9 @@ enum {
B_REG_GET_GROUP = 'rggr', B_REG_GET_GROUP = 'rggr',
B_REG_GET_USER_GROUPS = 'rgug', B_REG_GET_USER_GROUPS = 'rgug',
B_REG_UPDATE_USER = 'ruus', B_REG_UPDATE_USER = 'ruus',
B_REG_DELETE_USER = 'rdus',
B_REG_UPDATE_GROUP = 'rugr', B_REG_UPDATE_GROUP = 'rugr',
B_REG_DELETE_GROUP = 'rdgr',
}; };
// B_REG_MIME_SET_PARAM "which" constants // B_REG_MIME_SET_PARAM "which" constants
+2
View File
@@ -15,5 +15,7 @@ BinCommand passwd : passwd.cpp : libmultiuser_utils.a ;
BinCommand useradd : useradd.cpp : libmultiuser_utils.a ; BinCommand useradd : useradd.cpp : libmultiuser_utils.a ;
BinCommand userdel : userdel.cpp ;
# set set-uid bit on passwd # set set-uid bit on passwd
MODE on passwd = 04755 ; MODE on passwd = 04755 ;
+98
View File
@@ -0,0 +1,98 @@
/*
* Copyright 2013, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <getopt.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <OS.h>
#include <RegistrarDefs.h>
#include <user_group.h>
#include <util/KMessage.h>
#include "multiuser_utils.h"
extern const char *__progname;
static const char* kUsage =
"Usage: %s [ <options> ] <user name>\n"
"Deletes the specified user.\n"
"\n"
"Options:\n"
" -h, --help\n"
" Print usage info.\n"
;
static void
print_usage_and_exit(bool error)
{
fprintf(error ? stderr : stdout, kUsage, __progname);
exit(error ? 1 : 0);
}
int
main(int argc, const char* const* argv)
{
while (true) {
static struct option sLongOptions[] = {
{ "help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
};
opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "h", sLongOptions, NULL);
if (c == -1)
break;
switch (c) {
case 'h':
print_usage_and_exit(false);
break;
default:
print_usage_and_exit(true);
break;
}
}
if (optind != argc - 1)
print_usage_and_exit(true);
const char* user = argv[optind];
if (geteuid() != 0) {
fprintf(stderr, "Error: Only root may delete users.\n");
exit(1);
}
if (getpwnam(user) == NULL) {
fprintf(stderr, "Error: User \"%s\" doesn't exists.\n", user);
exit(1);
}
// prepare request for the registrar
KMessage message(BPrivate::B_REG_DELETE_USER);
if (message.AddString("name", user) != B_OK) {
fprintf(stderr, "Error: Out of memory!\n");
exit(1);
}
// send the request
KMessage reply;
status_t error = send_authentication_request_to_registrar(message, reply);
if (error != B_OK) {
fprintf(stderr, "Error: Failed to delete user: %s\n", strerror(error));
exit(1);
}
return 0;
}
@@ -435,6 +435,12 @@ public:
return B_OK; return B_OK;
} }
void RemoveUser(User* user)
{
fUsersByID.erase(fUsersByID.find(user->UID()));
fUsersByName.erase(fUsersByName.find(user->Name()));
}
User* UserByID(uid_t uid) const User* UserByID(uid_t uid) const
{ {
map<uid_t, User*>::const_iterator it = fUsersByID.find(uid); map<uid_t, User*>::const_iterator it = fUsersByID.find(uid);
@@ -721,7 +727,7 @@ AuthenticationManager::_RequestThread()
if (error == B_OK) { if (error == B_OK) {
message.SendReply(fPasswdDBReply, -1, -1, 0, registrarTeam); message.SendReply(fPasswdDBReply, -1, -1, 0, registrarTeam);
} else { } else {
fPasswdDBReply->SetTo(1); _InvalidatePasswdDBReply();
KMessage reply(error); KMessage reply(error);
message.SendReply(&reply, -1, -1, 0, registrarTeam); message.SendReply(&reply, -1, -1, 0, registrarTeam);
} }
@@ -752,7 +758,7 @@ AuthenticationManager::_RequestThread()
if (error == B_OK) { if (error == B_OK) {
message.SendReply(fGroupDBReply, -1, -1, 0, registrarTeam); message.SendReply(fGroupDBReply, -1, -1, 0, registrarTeam);
} else { } else {
fGroupDBReply->SetTo(1); _InvalidateGroupDBReply();
KMessage reply(error); KMessage reply(error);
message.SendReply(&reply, -1, -1, 0, registrarTeam); message.SendReply(&reply, -1, -1, 0, registrarTeam);
} }
@@ -789,7 +795,7 @@ AuthenticationManager::_RequestThread()
message.SendReply(fShadowPwdDBReply, -1, -1, 0, message.SendReply(fShadowPwdDBReply, -1, -1, 0,
registrarTeam); registrarTeam);
} else { } else {
fShadowPwdDBReply->SetTo(1); _InvalidateShadowPwdDBReply();
KMessage reply(error); KMessage reply(error);
message.SendReply(&reply, -1, -1, 0, registrarTeam); message.SendReply(&reply, -1, -1, 0, registrarTeam);
} }
@@ -915,7 +921,7 @@ AuthenticationManager::_RequestThread()
error = B_BAD_VALUE; error = B_BAD_VALUE;
} }
// only can change anything // only root can change anything
if (error == B_OK && !isRoot) if (error == B_OK && !isRoot)
error = EPERM; error = EPERM;
@@ -951,8 +957,8 @@ AuthenticationManager::_RequestThread()
if (error == B_OK) { if (error == B_OK) {
fUserDB->AddUser(user); fUserDB->AddUser(user);
fUserDB->WriteToDisk(); fUserDB->WriteToDisk();
fPasswdDBReply->SetTo(1); _InvalidatePasswdDBReply();
fShadowPwdDBReply->SetTo(1); _InvalidateShadowPwdDBReply();
} }
} catch (...) { } catch (...) {
error = B_NO_MEMORY; error = B_NO_MEMORY;
@@ -971,13 +977,59 @@ AuthenticationManager::_RequestThread()
break; break;
} }
case B_REG_DELETE_USER:
{
// find user
User* user = NULL;
int32 uid;
const char* name;
if (message.FindInt32("uid", &uid) == B_OK) {
user = fUserDB->UserByID(uid);
} else if (message.FindString("name", &name) == B_OK) {
user = fUserDB->UserByName(name);
} else {
error = B_BAD_VALUE;
}
if (error == B_OK && user == NULL)
error = ENOENT;
// only root can change anything
if (error == B_OK && !isRoot)
error = EPERM;
// apply the change
if (error == B_OK) {
fUserDB->RemoveUser(user);
fUserDB->WriteToDisk();
_InvalidatePasswdDBReply();
_InvalidateShadowPwdDBReply();
}
// send reply
KMessage reply;
reply.SetWhat(error);
message.SendReply(&reply, -1, -1, 0, registrarTeam);
break;
}
case B_REG_UPDATE_GROUP: case B_REG_UPDATE_GROUP:
debug_printf("B_REG_UPDATE_GROUP done: currently unsupported!\n"); debug_printf("B_REG_UPDATE_GROUP done: currently unsupported!\n");
break; break;
case B_REG_DELETE_GROUP:
{
debug_printf(
"B_REG_DELETE_GROUP done: currently unsupported!\n");
break;
}
default: default:
debug_printf("REG: invalid message: %" B_PRIu32 "\n", debug_printf("REG: invalid message: %" B_PRIu32 "\n",
message.What()); message.What());
} }
} }
} }
@@ -1132,3 +1184,24 @@ AuthenticationManager::_InitShadowPwdDB()
return B_OK; return B_OK;
} }
void
AuthenticationManager::_InvalidatePasswdDBReply()
{
fPasswdDBReply->SetTo(1);
}
void
AuthenticationManager::_InvalidateGroupDBReply()
{
fGroupDBReply->SetTo(1);
}
void
AuthenticationManager::_InvalidateShadowPwdDBReply()
{
fShadowPwdDBReply->SetTo(1);
}
@@ -35,6 +35,10 @@ private:
status_t _InitGroupDB(); status_t _InitGroupDB();
status_t _InitShadowPwdDB(); status_t _InitShadowPwdDB();
void _InvalidatePasswdDBReply();
void _InvalidateGroupDBReply();
void _InvalidateShadowPwdDBReply();
private: private:
port_id fRequestPort; port_id fRequestPort;
thread_id fRequestThread; thread_id fRequestThread;