Add userdel
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 ;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user