* Moved private passwd/group/shadow passwd limit constants from

<libroot_private.h> to <user_group.h>.
* Added support in the registrar for adding and modifying users.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25040 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-04-19 00:10:51 +00:00
parent 80d0ab493a
commit f694f63e2b
5 changed files with 262 additions and 36 deletions
-32
View File
@@ -10,38 +10,6 @@
#include <image.h>
#define MAX_PASSWD_NAME_LEN (32)
#define MAX_PASSWD_PASSWORD_LEN (32)
#define MAX_PASSWD_REAL_NAME_LEN (128)
#define MAX_PASSWD_HOME_DIR_LEN (B_PATH_NAME_LENGTH)
#define MAX_PASSWD_SHELL_LEN (B_PATH_NAME_LENGTH)
#define MAX_PASSWD_BUFFER_SIZE ( \
MAX_PASSWD_NAME_LEN \
+ MAX_PASSWD_PASSWORD_LEN \
+ MAX_PASSWD_REAL_NAME_LEN \
+ MAX_PASSWD_HOME_DIR_LEN \
+ MAX_PASSWD_SHELL_LEN)
#define MAX_GROUP_NAME_LEN (32)
#define MAX_GROUP_PASSWORD_LEN (32)
#define MAX_GROUP_MEMBER_COUNT (32)
#define MAX_GROUP_BUFFER_SIZE ( \
MAX_GROUP_NAME_LEN \
+ MAX_GROUP_PASSWORD_LEN \
+ ((MAX_GROUP_MEMBER_COUNT + 1) * sizeof(char*)))
// MAX_GROUP_NAME_LEN and MAX_GROUP_PASSWORD_LEN are char* aligned
#define MAX_SHADOW_PWD_NAME_LEN (32)
#define MAX_SHADOW_PWD_PASSWORD_LEN (128)
#define MAX_SHADOW_PWD_BUFFER_SIZE ( \
MAX_SHADOW_PWD_NAME_LEN \
+ MAX_SHADOW_PWD_PASSWORD_LEN)
struct user_space_program_args;
struct real_time_data;
+37
View File
@@ -11,6 +11,41 @@
#include <OS.h>
#define MAX_PASSWD_NAME_LEN (32)
#define MAX_PASSWD_PASSWORD_LEN (32)
#define MAX_PASSWD_REAL_NAME_LEN (128)
#define MAX_PASSWD_HOME_DIR_LEN (B_PATH_NAME_LENGTH)
#define MAX_PASSWD_SHELL_LEN (B_PATH_NAME_LENGTH)
#define MAX_PASSWD_BUFFER_SIZE ( \
MAX_PASSWD_NAME_LEN \
+ MAX_PASSWD_PASSWORD_LEN \
+ MAX_PASSWD_REAL_NAME_LEN \
+ MAX_PASSWD_HOME_DIR_LEN \
+ MAX_PASSWD_SHELL_LEN)
#define MAX_GROUP_NAME_LEN (32)
#define MAX_GROUP_PASSWORD_LEN (32)
#define MAX_GROUP_MEMBER_COUNT (32)
#define MAX_GROUP_BUFFER_SIZE ( \
MAX_GROUP_NAME_LEN \
+ MAX_GROUP_PASSWORD_LEN \
+ ((MAX_GROUP_MEMBER_COUNT + 1) * sizeof(char*)))
// MAX_GROUP_NAME_LEN and MAX_GROUP_PASSWORD_LEN are char* aligned
#define MAX_SHADOW_PWD_NAME_LEN (32)
#define MAX_SHADOW_PWD_PASSWORD_LEN (128)
#define MAX_SHADOW_PWD_BUFFER_SIZE ( \
MAX_SHADOW_PWD_NAME_LEN \
+ MAX_SHADOW_PWD_PASSWORD_LEN)
#ifdef __cplusplus
#include <AutoLocker.h>
@@ -106,4 +141,6 @@ status_t parse_shadow_pwd_line(char* line, char*& name, char*& password,
} // namespace BPrivate
#endif // __cplusplus
#endif // _LIBROOT_USER_GROUP_COMMON_H
+223 -3
View File
@@ -103,6 +103,20 @@ private:
class AuthenticationManager::User {
public:
User()
:
fUID(0),
fGID(0),
fLastChanged(0),
fMin(-1),
fMax(-1),
fWarn(-1),
fInactive(-1),
fExpiration(-1),
fFlags(0)
{
}
User(const char* name, const char* password, uid_t uid, gid_t gid,
const char* home, const char* shell, const char* realName)
:
@@ -123,6 +137,26 @@ public:
{
}
User(const User& other)
:
fUID(other.fUID),
fGID(other.fGID),
fName(other.fName),
fPassword(other.fPassword),
fHome(other.fHome),
fShell(other.fShell),
fRealName(other.fRealName),
fShadowPassword(other.fShadowPassword),
fLastChanged(other.fLastChanged),
fMin(other.fMin),
fMax(other.fMax),
fWarn(other.fWarn),
fInactive(other.fInactive),
fExpiration(other.fExpiration),
fFlags(other.fFlags)
{
}
const string& Name() const { return fName; }
const uid_t UID() const { return fUID; }
@@ -139,6 +173,56 @@ public:
fFlags = flags;
}
void UpdateFromMessage(const KMessage& message)
{
int32 intValue;
const char* stringValue;
if (message.FindInt32("uid", &intValue) == B_OK)
fUID = intValue;
if (message.FindInt32("gid", &intValue) == B_OK)
fGID = intValue;
if (message.FindString("name", &stringValue) == B_OK)
fName = stringValue;
if (message.FindString("password", &stringValue) == B_OK)
fPassword = stringValue;
if (message.FindString("home", &stringValue) == B_OK)
fHome = stringValue;
if (message.FindString("shell", &stringValue) == B_OK)
fShell = stringValue;
if (message.FindString("real name", &stringValue) == B_OK)
fRealName = stringValue;
if (message.FindString("shadow password", &stringValue) == B_OK) {
fShadowPassword = stringValue;
// TODO:
// fLastChanged = now;
}
if (message.FindInt32("min", &intValue) == B_OK)
fMin = intValue;
if (message.FindInt32("max", &intValue) == B_OK)
fMax = intValue;
if (message.FindInt32("warn", &intValue) == B_OK)
fWarn = intValue;
if (message.FindInt32("inactive", &intValue) == B_OK)
fInactive = intValue;
if (message.FindInt32("expiration", &intValue) == B_OK)
fExpiration = intValue;
if (message.FindInt32("flags", &intValue) == B_OK)
fFlags = intValue;
}
passwd* WriteFlatPasswd(FlatStore& store) const
{
@@ -204,6 +288,30 @@ public:
return B_OK;
}
void WritePasswdLine(FILE* file)
{
fprintf(file, "%s:%s:%d:%d:%s:%s:%s\n",
fName.c_str(), fPassword.c_str(), (int)fUID, (int)fGID,
fRealName.c_str(), fHome.c_str(), fShell.c_str());
}
void WriteShadowPwdLine(FILE* file)
{
fprintf(file, "%s:%s:%d:", fName.c_str(), fShadowPassword.c_str(),
fLastChanged);
// The following values are supposed to be printed as empty strings,
// if negative.
int values[5] = { fMin, fMax, fWarn, fInactive, fExpiration };
for (int i = 0; i < 5; i++) {
if (values[i] >= 0)
fprintf(file, "%d", values[i]);
fprintf(file, ":");
}
fprintf(file, "%d\n", fFlags);
}
private:
uid_t fUID;
gid_t fGID;
@@ -375,6 +483,42 @@ public:
return count;
}
void WriteToDisk()
{
// rename the old files
string passwdBackup(kPasswdFile);
string shadowBackup(kShadowPwdFile);
passwdBackup += ".old";
shadowBackup += ".old";
rename(kPasswdFile, passwdBackup.c_str());
rename(kShadowPwdFile, shadowBackup.c_str());
// Don't check errors. We can't do anything anyway.
// open files
FILE* passwdFile = fopen(kPasswdFile, "w");
if (passwdFile == NULL) {
debug_printf("REG: Failed to open passwd file \"%s\" for "
"writing: %s\n", kPasswdFile, strerror(errno));
}
CObjectDeleter<FILE, int> _1(passwdFile, fclose);
FILE* shadowFile = fopen(kShadowPwdFile, "w");
if (shadowFile == NULL) {
debug_printf("REG: Failed to open shadow passwd file \"%s\" for "
"writing: %s\n", kShadowPwdFile, strerror(errno));
}
CObjectDeleter<FILE, int> _2(shadowFile, fclose);
// write users
for (map<uid_t, User*>::const_iterator it = fUsersByID.begin();
it != fUsersByID.end(); ++it) {
User* user = it->second;
user->WritePasswdLine(passwdFile);
user->WriteShadowPwdLine(shadowFile);
}
}
private:
map<uid_t, User*> fUsersByID;
map<string, User*> fUsersByName;
@@ -547,6 +691,8 @@ AuthenticationManager::_RequestThread()
if (error != B_OK)
return B_OK;
bool isRoot = (messageInfo.sender == 0);
switch (message.What()) {
case B_REG_GET_PASSWD_DB:
{
@@ -614,7 +760,7 @@ AuthenticationManager::_RequestThread()
case B_REG_GET_SHADOW_PASSWD_DB:
{
// only root may see the shadow passwd
if (messageInfo.sender != 0)
if (!isRoot)
error = EPERM;
// lazily build the reply
@@ -668,7 +814,7 @@ AuthenticationManager::_RequestThread()
bool getShadowPwd = message.GetBool("shadow", false);
// only root may see the shadow passwd
if (error == B_OK && getShadowPwd && messageInfo.sender != 0)
if (error == B_OK && getShadowPwd && !isRoot)
error = EPERM;
// add user to message
@@ -751,8 +897,82 @@ AuthenticationManager::_RequestThread()
}
case B_REG_UPDATE_USER:
case B_REG_UPDATE_GROUP:
{
// 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;
}
// only can change anything
if (error == B_OK && !isRoot)
error = EPERM;
// check addUser vs. existing user
bool addUser = message.GetBool("add user", false);
if (error == B_OK) {
if (addUser) {
if (user != NULL)
error = EEXIST;
} else if (user == NULL)
error = ENOENT;
}
// apply all changes
if (error == B_OK) {
// clone the user object and update it from the message
User* oldUser = user;
user = NULL;
try {
user = (oldUser != NULL ? new User(*oldUser)
: new User);
user->UpdateFromMessage(message);
// uid and name should remain the same
if (oldUser != NULL) {
if (oldUser->UID() != user->UID()
|| oldUser->Name() != user->Name()) {
error = B_BAD_VALUE;
}
}
// replace the old user and write DBs to disk
if (error == B_OK) {
fUserDB->AddUser(user);
fUserDB->WriteToDisk();
fPasswdDBReply->SetTo(1);
fShadowPwdDBReply->SetTo(1);
}
} catch (...) {
error = B_NO_MEMORY;
}
if (error == B_OK)
delete oldUser;
else
delete user;
}
// send reply
KMessage reply;
reply.SetWhat(error);
message.SendReply(&reply, -1, -1, 0, registrarTeam);
break;
}
case B_REG_UPDATE_GROUP:
debug_printf("B_REG_UPDATE_GROUP done: currently unsupported!\n");
break;
default:
debug_printf("REG: invalid message: %lu\n", message.What());
}
}
}
+1 -1
View File
@@ -22,7 +22,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <libroot_private.h>
#include <user_group.h>
/* use pwents to find home */
#define USE_PWENTS
+1
View File
@@ -15,6 +15,7 @@
#include <SupportDefs.h>
#include <libroot_private.h>
#include <user_group.h>
int