[haiku-commits] BRANCH axeld-github.launch_daemon [2255428c123d] in src: servers/launch tests/servers/launch apps/login .

  • From: axeld-github.launch_daemon <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 26 Jun 2015 10:16:44 +0200 (CEST)

added 4 changesets to branch 'refs/remotes/axeld-github/launch_daemon'
old head: 196b0c640f67ce41705bd6b1491d6699800436ae
new head: 2255428c123d0aadefcb3339c48fe40c9063e2a2
overview: https://github.com/axeld/haiku/compare/196b0c640f67...2255428c123d

----------------------------------------------------------------------------

688b677af7b9: launch_daemon: Conditions now know if they are constant.

* This allows to remove a job in the init phase already, if its
condition is not only constant, but also failing.
* Also removed the special Job::LaunchInSafeMode() method; this is now
done using the conditions (the config option no_safemode remains,
though).

b3b1d19cf180: multiuser_utils: Fixed verifying empty password.

* verify_password() would accept all passwords if the there was
none set, instead of accepting only an empty password.

050a26bcaed4: launch_daemon: Don't verify passwords.

* Instead, the caller should have done this already. This is really
outside of the scope of the launch_daemon.
* Fixed Login with empty passwords; removed the (unused) test login
feature along the way.

2255428c123d: launch_daemon: We can now talk to the authentication manager.

* When creating the port of the registrar's authentication manager, we
now set it manually, so that the user/group functions work.
* This allows LaunchDaemon::_StartSession() to set up the user, and
groups as needed.

[ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

15 files changed, 223 insertions(+), 103 deletions(-)
headers/private/app/LaunchRoster.h | 3 +-
headers/private/libroot/user_group.h | 1 +
src/apps/login/LoginApp.cpp | 41 ++------
src/apps/login/LoginApp.h | 3 +-
src/bin/multiuser/multiuser_utils.cpp | 8 +-
src/kits/app/LaunchRoster.cpp | 6 +-
src/servers/launch/Conditions.cpp | 105 +++++++++++++++++++++
src/servers/launch/Conditions.h | 7 ++
src/servers/launch/Jamfile | 2 +-
src/servers/launch/Job.cpp | 23 ++---
src/servers/launch/Job.h | 4 -
src/servers/launch/LaunchDaemon.cpp | 72 +++++++-------
src/servers/launch/SettingsParser.cpp | 1 +
src/system/libroot/posix/user_group_common.cpp | 7 ++
src/tests/servers/launch/ConditionsTest.cpp | 43 +++++++++

############################################################################

Commit: 688b677af7b903410fbc359bc14e87c8eec19117
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Thu Jun 25 06:59:51 2015 UTC

launch_daemon: Conditions now know if they are constant.

* This allows to remove a job in the init phase already, if its
condition is not only constant, but also failing.
* Also removed the special Job::LaunchInSafeMode() method; this is now
done using the conditions (the config option no_safemode remains,
though).

----------------------------------------------------------------------------

diff --git a/src/servers/launch/Conditions.cpp
b/src/servers/launch/Conditions.cpp
index 8cf3d92..d577a25 100644
--- a/src/servers/launch/Conditions.cpp
+++ b/src/servers/launch/Conditions.cpp
@@ -21,9 +21,13 @@
class ConditionContainer : public Condition {
protected:

ConditionContainer(const BMessage& args);
+
ConditionContainer();

+public:
void AddCondition(Condition*
condition);

+ virtual bool IsConstant(ConditionContext&
context) const;
+
protected:
void ToString(BString&
string) const;

@@ -35,6 +39,7 @@ protected:
class AndCondition : public ConditionContainer {
public:

AndCondition(const BMessage& args);
+ AndCondition();

virtual bool Test(ConditionContext& context)
const;
virtual BString ToString() const;
@@ -46,6 +51,8 @@ public:

OrCondition(const BMessage& args);

virtual bool Test(ConditionContext& context)
const;
+ virtual bool IsConstant(ConditionContext&
context) const;
+
virtual BString ToString() const;
};

@@ -53,6 +60,7 @@ public:
class NotCondition : public ConditionContainer {
public:

NotCondition(const BMessage& args);
+ NotCondition();

virtual bool Test(ConditionContext& context)
const;
virtual BString ToString() const;
@@ -62,6 +70,8 @@ public:
class SafeModeCondition : public Condition {
public:
virtual bool Test(ConditionContext& context)
const;
+ virtual bool IsConstant(ConditionContext&
context) const;
+
virtual BString ToString() const;
};

@@ -71,6 +81,8 @@ public:

ReadOnlyCondition(const BMessage& args);

virtual bool Test(ConditionContext& context)
const;
+ virtual bool IsConstant(ConditionContext&
context) const;
+
virtual BString ToString() const;

private:
@@ -124,6 +136,13 @@ Condition::~Condition()
}


+bool
+Condition::IsConstant(ConditionContext& context) const
+{
+ return false;
+}
+
+
// #pragma mark -


@@ -145,6 +164,13 @@ ConditionContainer::ConditionContainer(const BMessage&
args)
}


+ConditionContainer::ConditionContainer()
+ :
+ fConditions(10, true)
+{
+}
+
+
void
ConditionContainer::AddCondition(Condition* condition)
{
@@ -153,6 +179,25 @@ ConditionContainer::AddCondition(Condition* condition)
}


+/*! A single constant failing condition makes this constant, too, otherwise,
+ a single non-constant condition makes this non-constant as well.
+*/
+bool
+ConditionContainer::IsConstant(ConditionContext& context) const
+{
+ bool fixed = true;
+ for (int32 index = 0; index < fConditions.CountItems(); index++) {
+ const Condition* condition = fConditions.ItemAt(index);
+ if (condition->IsConstant(context)) {
+ if (!condition->Test(context))
+ return true;
+ } else
+ fixed = false;
+ }
+ return fixed;
+}
+
+
void
ConditionContainer::ToString(BString& string) const
{
@@ -177,6 +222,11 @@ AndCondition::AndCondition(const BMessage& args)
}


+AndCondition::AndCondition()
+{
+}
+
+
bool
AndCondition::Test(ConditionContext& context) const
{
@@ -223,6 +273,25 @@ OrCondition::Test(ConditionContext& context) const
}


+/*! If there is a single succeeding constant condition, this is constant,
too.
+ Otherwise, it is non-constant if there is a single non-constant
condition.
+*/
+bool
+OrCondition::IsConstant(ConditionContext& context) const
+{
+ bool fixed = true;
+ for (int32 index = 0; index < fConditions.CountItems(); index++) {
+ const Condition* condition = fConditions.ItemAt(index);
+ if (condition->IsConstant(context)) {
+ if (condition->Test(context))
+ return true;
+ } else
+ fixed = false;
+ }
+ return fixed;
+}
+
+
BString
OrCondition::ToString() const
{
@@ -242,6 +311,11 @@ NotCondition::NotCondition(const BMessage& args)
}


+NotCondition::NotCondition()
+{
+}
+
+
bool
NotCondition::Test(ConditionContext& context) const
{
@@ -273,6 +347,13 @@ SafeModeCondition::Test(ConditionContext& context) const
}


+bool
+SafeModeCondition::IsConstant(ConditionContext& context) const
+{
+ return true;
+}
+
+
BString
SafeModeCondition::ToString() const
{
@@ -314,6 +395,13 @@ ReadOnlyCondition::Test(ConditionContext& context) const
}


+bool
+ReadOnlyCondition::IsConstant(ConditionContext& context) const
+{
+ return true;
+}
+
+
BString
ReadOnlyCondition::ToString() const
{
@@ -370,3 +458,20 @@ Conditions::FromMessage(const BMessage& message)
{
return create_condition("and", message);
}
+
+
+/*static*/ Condition*
+Conditions::AddNotSafeMode(Condition* condition)
+{
+ AndCondition* and = dynamic_cast<AndCondition*>(condition);
+ if (and == NULL)
+ and = new AndCondition();
+ if (and != condition && condition != NULL)
+ and->AddCondition(condition);
+
+ NotCondition* not = new NotCondition();
+ not->AddCondition(new SafeModeCondition());
+
+ and->AddCondition(not);
+ return and;
+}
diff --git a/src/servers/launch/Conditions.h b/src/servers/launch/Conditions.h
index 3f779ff..2414acc 100644
--- a/src/servers/launch/Conditions.h
+++ b/src/servers/launch/Conditions.h
@@ -24,6 +24,12 @@ public:
virtual ~Condition();

virtual bool Test(ConditionContext& context)
const = 0;
+
+ /*! Determines whether or not the result of this condition is fixed,
+ and will not change anymore.
+ */
+ virtual bool IsConstant(ConditionContext&
context) const;
+
virtual BString ToString() const = 0;
};

@@ -31,6 +37,7 @@ public:
class Conditions {
public:
static Condition* FromMessage(const BMessage&
message);
+ static Condition* AddNotSafeMode(Condition*
condition);
};


diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp
index 371e600..0932757 100644
--- a/src/servers/launch/Job.cpp
+++ b/src/servers/launch/Job.cpp
@@ -20,7 +20,6 @@ Job::Job(const char* name)
fEnabled(true),
fService(false),
fCreateDefaultPort(false),
- fLaunchInSafeMode(true),
fInitStatus(B_NO_INIT),
fTeam(-1),
fTarget(NULL)
@@ -34,7 +33,6 @@ Job::Job(const Job& other)
fEnabled(other.IsEnabled()),
fService(other.IsService()),
fCreateDefaultPort(other.CreateDefaultPort()),
- fLaunchInSafeMode(other.LaunchInSafeMode()),
fInitStatus(B_NO_INIT),
fTeam(-1),
fTarget(other.Target())
@@ -115,20 +113,6 @@ Job::AddPort(BMessage& data)
}


-bool
-Job::LaunchInSafeMode() const
-{
- return fLaunchInSafeMode;
-}
-
-
-void
-Job::SetLaunchInSafeMode(bool launch)
-{
- fLaunchInSafeMode = launch;
-}
-
-
const BStringList&
Job::Arguments() const
{
diff --git a/src/servers/launch/Job.h b/src/servers/launch/Job.h
index efea7fe..3b868b4 100644
--- a/src/servers/launch/Job.h
+++ b/src/servers/launch/Job.h
@@ -42,9 +42,6 @@ public:

void AddPort(BMessage& data);

- bool LaunchInSafeMode()
const;
- void
SetLaunchInSafeMode(bool launch);
-
const BStringList& Arguments() const;
BStringList& Arguments();
void AddArgument(const char*
argument);
@@ -82,7 +79,6 @@ private:
bool fEnabled;
bool fService;
bool fCreateDefaultPort;
- bool fLaunchInSafeMode;
PortMap fPortMap;
status_t fInitStatus;
team_id fTeam;
diff --git a/src/servers/launch/LaunchDaemon.cpp
b/src/servers/launch/LaunchDaemon.cpp
index fb2d9be..63b2ebb 100644
--- a/src/servers/launch/LaunchDaemon.cpp
+++ b/src/servers/launch/LaunchDaemon.cpp
@@ -102,7 +102,8 @@ private:
void _LaunchJobs(Target*
target);
void _AddLaunchJob(Job* job);
void _AddTarget(Target*
target);
- void _SetCondition(BaseJob*
job, BMessage& message);
+ void _SetCondition(BaseJob*
job,
+ const
BMessage& message);

status_t _StartSession(const
char* login,
const
char* password);
@@ -589,8 +590,6 @@ LaunchDaemon::_AddJob(Target* target, bool service,
BMessage& message)
job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled()));
job->SetService(service);
job->SetCreateDefaultPort(!message.GetBool("legacy", !service));
- job->SetLaunchInSafeMode(
- !message.GetBool("no_safemode", !job->LaunchInSafeMode()));
job->SetTarget(target);

_SetCondition(job, message);
@@ -628,9 +627,13 @@ LaunchDaemon::_InitJobs()
JobMap::iterator remove = iterator++;

status_t status = B_NO_INIT;
- if (job->IsEnabled() && (!IsSafeMode() ||
job->LaunchInSafeMode())) {
- std::set<BString> dependencies;
- status = job->Init(*this, dependencies);
+ if (job->IsEnabled()) {
+ // Filter out jobs that have a constant and failing
condition
+ if (job->Condition() == NULL ||
!job->Condition()->IsConstant(*this)
+ || job->Condition()->Test(*this)) {
+ std::set<BString> dependencies;
+ status = job->Init(*this, dependencies);
+ }
}

if (status != B_OK) {
@@ -679,14 +682,19 @@ LaunchDaemon::_AddTarget(Target* target)


void
-LaunchDaemon::_SetCondition(BaseJob* job, BMessage& message)
+LaunchDaemon::_SetCondition(BaseJob* job, const BMessage& message)
{
+ Condition* condition = NULL;
+
BMessage conditions;
- if (message.FindMessage("if", &conditions) == B_OK) {
- Condition* condition = Conditions::FromMessage(conditions);
- if (condition != NULL)
- job->SetCondition(condition);
- }
+ if (message.FindMessage("if", &conditions) == B_OK)
+ condition = Conditions::FromMessage(conditions);
+
+ if (message.GetBool("no_safemode"))
+ condition = Conditions::AddNotSafeMode(condition);
+
+ if (condition != NULL)
+ job->SetCondition(condition);
}


diff --git a/src/servers/launch/SettingsParser.cpp
b/src/servers/launch/SettingsParser.cpp
index 083993d..3606de0 100644
--- a/src/servers/launch/SettingsParser.cpp
+++ b/src/servers/launch/SettingsParser.cpp
@@ -126,6 +126,7 @@ const static settings_template kTargetTemplate[] = {
{B_STRING_TYPE, "name", NULL, true},
{B_BOOL_TYPE, "reset", NULL},
{B_MESSAGE_TYPE, "if", kConditionTemplate},
+ {B_BOOL_TYPE, "no_safemode", NULL},
{B_MESSAGE_TYPE, "job", kJobTemplate},
{B_MESSAGE_TYPE, "service", kJobTemplate},
{0, NULL, NULL}
diff --git a/src/tests/servers/launch/ConditionsTest.cpp
b/src/tests/servers/launch/ConditionsTest.cpp
index 0f48382..d6ff329 100644
--- a/src/tests/servers/launch/ConditionsTest.cpp
+++ b/src/tests/servers/launch/ConditionsTest.cpp
@@ -43,6 +43,7 @@ ConditionsTest::TestSafemode()
{
Condition* condition = _Condition("safemode");
CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));

class SafemodeConditionContext : public ConditionContext {
public:
@@ -52,6 +53,7 @@ ConditionsTest::TestSafemode()
}
} safemodeContext;
CPPUNIT_ASSERT(condition->Test(safemodeContext));
+ CPPUNIT_ASSERT(condition->IsConstant(safemodeContext));
}


@@ -60,6 +62,7 @@ ConditionsTest::TestFileExists()
{
Condition* condition = _Condition("file_exists /boot");
CPPUNIT_ASSERT(condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));

condition = _Condition("file_exists /boot/don't fool me!");
CPPUNIT_ASSERT(!condition->Test(sConditionContext));
@@ -73,17 +76,34 @@ ConditionsTest::TestOr()
"file_exists /boot\n"
"}\n");
CPPUNIT_ASSERT(condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));

condition = _Condition("or {\n"
"file_exists /nowhere\n"
"}\n");
CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));

condition = _Condition("or {\n"
"file_exists /boot\n"
"file_exists /nowhere\n"
"}\n");
CPPUNIT_ASSERT(condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
+
+ condition = _Condition("or {\n"
+ "not safemode\n"
+ "file_exists /boot\n"
+ "}\n");
+ CPPUNIT_ASSERT(condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
+
+ condition = _Condition("or {\n"
+ "safemode\n"
+ "file_exists /boot\n"
+ "}\n");
+ CPPUNIT_ASSERT(condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
}


@@ -94,17 +114,40 @@ ConditionsTest::TestAnd()
"file_exists /boot\n"
"}\n");
CPPUNIT_ASSERT(condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));

condition = _Condition("and {\n"
"file_exists /nowhere\n"
"}\n");
CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));

condition = _Condition("and {\n"
"file_exists /boot\n"
"file_exists /nowhere\n"
"}\n");
CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
+
+ condition = _Condition("and {\n"
+ "safemode\n"
+ "file_exists /nowhere\n"
+ "}\n");
+ CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
+
+ condition = _Condition("and {\n"
+ "not safemode\n"
+ "file_exists /nowhere\n"
+ "}\n");
+ CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
+
+ condition = _Condition("and {\n"
+ "safemode\n"
+ "}\n");
+ CPPUNIT_ASSERT(!condition->Test(sConditionContext));
+ CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
}



############################################################################

Commit: b3b1d19cf18029fe3cf1ab816dec61298ada04de
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Thu Jun 25 15:47:27 2015 UTC

multiuser_utils: Fixed verifying empty password.

* verify_password() would accept all passwords if the there was
none set, instead of accepting only an empty password.

----------------------------------------------------------------------------

diff --git a/src/bin/multiuser/multiuser_utils.cpp
b/src/bin/multiuser/multiuser_utils.cpp
index 97551f4..dbf2c49 100644
--- a/src/bin/multiuser/multiuser_utils.cpp
+++ b/src/bin/multiuser/multiuser_utils.cpp
@@ -103,8 +103,12 @@ verify_password(passwd* passwd, spwd* spwd, const char*
plainPassword)
}

// If no password is required, we're done.
- if (requiredPassword == NULL || strlen(requiredPassword) == 0)
- return true;
+ if (requiredPassword == NULL || requiredPassword[0] == '\0') {
+ if (plainPassword == NULL || plainPassword[0] == '\0')
+ return true;
+
+ return false;
+ }

// crypt and check it
char* encryptedPassword = crypt(plainPassword, requiredPassword);

############################################################################

Commit: 050a26bcaed453362e622edbabf9f8a6b5a34a75
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Thu Jun 25 15:51:20 2015 UTC

launch_daemon: Don't verify passwords.

* Instead, the caller should have done this already. This is really
outside of the scope of the launch_daemon.
* Fixed Login with empty passwords; removed the (unused) test login
feature along the way.

----------------------------------------------------------------------------

diff --git a/headers/private/app/LaunchRoster.h
b/headers/private/app/LaunchRoster.h
index 5a85161..aaf7196 100644
--- a/headers/private/app/LaunchRoster.h
+++ b/headers/private/app/LaunchRoster.h
@@ -25,8 +25,7 @@ public:
status_t Target(const char*
name, BMessage& data,
const
char* baseName = NULL);

- status_t StartSession(const
char* login,
- const
char* password);
+ status_t StartSession(const
char* login);

class Private;

diff --git a/src/apps/login/LoginApp.cpp b/src/apps/login/LoginApp.cpp
index 30c5d77..abf2d90 100644
--- a/src/apps/login/LoginApp.cpp
+++ b/src/apps/login/LoginApp.cpp
@@ -144,21 +144,19 @@ LoginApp::ArgvReceived(int32 argc, char **argv)
void
LoginApp::TryLogin(BMessage *message)
{
+ BMessage reply(kLoginBad);
status_t status = B_BAD_VALUE;

- const char *login;
- const char *password;
- BMessage reply(kLoginBad);
+ const char* login;
if (message->FindString("login", &login) == B_OK) {
- if (message->FindString("password", &password) < B_OK)
- password = NULL;
+ const char* password = message->GetString("password");

- if (password != NULL) {
- status = StartUserSession(login, password);
+ status = ValidateLogin(login, password);
+ if (status == B_OK) {
+ status = BLaunchRoster().StartSession(login);
if (status == B_OK)
Quit();
- } else
- status = ValidateLogin(login, password);
+ }

fprintf(stderr, "ValidateLogin: %s\n", strerror(status));
}
@@ -179,39 +177,18 @@ LoginApp::ValidateLogin(const char *login, const char
*password)
struct passwd *pwd;

pwd = getpwnam(login);
- if (!pwd)
+ if (pwd == NULL)
return ENOENT;
- if (strcmp(pwd->pw_name, login))
+ if (strcmp(pwd->pw_name, login) != 0)
return ENOENT;

- if (password == NULL) {
- // we only want to check is login exists.
- return B_OK;
- }
-
-#ifdef __HAIKU__
if (verify_password(pwd, getspnam(login), password))
return B_OK;
-#else
- // for testing
- if (strcmp(crypt(password, pwd->pw_passwd), pwd->pw_passwd) == 0)
- return B_OK;
-#endif

return B_PERMISSION_DENIED;
}


-status_t
-LoginApp::StartUserSession(const char* login, const char* password)
-{
- if (login == NULL || password == NULL)
- return B_BAD_VALUE;
-
- return BLaunchRoster().StartSession(login, password);
-}
-
-
int
LoginApp::getpty(char *pty, char *tty)
{
diff --git a/src/apps/login/LoginApp.h b/src/apps/login/LoginApp.h
index 588af96..f3ddde2 100644
--- a/src/apps/login/LoginApp.h
+++ b/src/apps/login/LoginApp.h
@@ -29,9 +29,8 @@ public:
private:
void TryLogin(BMessage *message);
status_t ValidateLogin(const char *login, const char
*password);
- status_t StartUserSession(const char *login, const char
*password);
int getpty(char *pty, char *tty);
-
+
DesktopWindow* fDesktopWindow;
LoginWindow* fLoginWindow;
bool fEditShelfMode;
diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp
index 5d4ea84..4a94fc1 100644
--- a/src/kits/app/LaunchRoster.cpp
+++ b/src/kits/app/LaunchRoster.cpp
@@ -175,17 +175,15 @@ BLaunchRoster::Target(const char* name, BMessage& data,
const char* baseName)


status_t
-BLaunchRoster::StartSession(const char* login, const char* password)
+BLaunchRoster::StartSession(const char* login)
{
- if (login == NULL || password == NULL)
+ if (login == NULL)
return B_BAD_VALUE;

BMessage request(B_LAUNCH_SESSION);
status_t status = request.AddInt32("user", getuid());
if (status == B_OK)
status = request.AddString("login", login);
- if (status == B_OK)
- status = request.AddString("password", password);
if (status != B_OK)
return status;

diff --git a/src/servers/launch/LaunchDaemon.cpp
b/src/servers/launch/LaunchDaemon.cpp
index 63b2ebb..0b3c95c 100644
--- a/src/servers/launch/LaunchDaemon.cpp
+++ b/src/servers/launch/LaunchDaemon.cpp
@@ -105,8 +105,7 @@ private:
void _SetCondition(BaseJob*
job,
const
BMessage& message);

- status_t _StartSession(const
char* login,
- const
char* password);
+ status_t _StartSession(const
char* login);

void
_RetrieveKernelOptions();
void _SetupEnvironment();
@@ -361,15 +360,15 @@ LaunchDaemon::MessageReceived(BMessage* message)

status_t status = B_OK;
const char* login = message->GetString("login");
- const char* password = message->GetString("password");
- if (login == NULL || password == NULL)
+ if (login == NULL)
status = B_BAD_VALUE;
if (status == B_OK && user != 0) {
// Only the root user can start sessions
+ // TODO: we'd actually need to know the uid of
the sender
status = B_PERMISSION_DENIED;
}
if (status == B_OK)
- status = _StartSession(login, password);
+ status = _StartSession(login);

BMessage reply((uint32)status);
message->SendReply(&reply);
@@ -699,11 +698,9 @@ LaunchDaemon::_SetCondition(BaseJob* job, const BMessage&
message)


status_t
-LaunchDaemon::_StartSession(const char* login, const char* password)
+LaunchDaemon::_StartSession(const char* login)
{
- Unlock();
-
- // TODO: enable user/group code and password authentication
+ // TODO: enable user/group code
// The launch_daemon currently cannot talk to the registrar, though
/*
struct passwd* passwd = getpwnam(login);
@@ -712,15 +709,13 @@ LaunchDaemon::_StartSession(const char* login, const
char* password)
if (strcmp(passwd->pw_name, login) != 0)
return B_NAME_NOT_FOUND;

- // TODO: check for auto-login, and ignore password then
- if (!verify_password(passwd, getspnam(login), password))
- return B_PERMISSION_DENIED;
-
// Check if there is a user session running already
uid_t user = passwd->pw_uid;
gid_t group = passwd->pw_gid;
*/

+ Unlock();
+
if (fork() == 0) {
if (setsid() < 0)
exit(EXIT_FAILURE);

############################################################################

Commit: 2255428c123d0aadefcb3339c48fe40c9063e2a2
Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date: Fri Jun 26 08:00:26 2015 UTC

launch_daemon: We can now talk to the authentication manager.

* When creating the port of the registrar's authentication manager, we
now set it manually, so that the user/group functions work.
* This allows LaunchDaemon::_StartSession() to set up the user, and
groups as needed.

----------------------------------------------------------------------------

diff --git a/headers/private/libroot/user_group.h
b/headers/private/libroot/user_group.h
index a6c1631..945415e 100644
--- a/headers/private/libroot/user_group.h
+++ b/headers/private/libroot/user_group.h
@@ -89,6 +89,7 @@ public:


port_id get_registrar_authentication_port();
+void set_registrar_authentication_port(port_id port);
status_t send_authentication_request_to_registrar(KMessage& request,
KMessage& reply);

diff --git a/src/servers/launch/Jamfile b/src/servers/launch/Jamfile
index 93c9271..09d2ec7 100644
--- a/src/servers/launch/Jamfile
+++ b/src/servers/launch/Jamfile
@@ -1,6 +1,6 @@
SubDir HAIKU_TOP src servers launch ;

-UsePrivateHeaders app package shared storage support ;
+UsePrivateHeaders app libroot shared storage support ;
UsePrivateSystemHeaders ;

UseHeaders [ FDirName $(HAIKU_TOP) src bin multiuser ] ;
diff --git a/src/servers/launch/Job.cpp b/src/servers/launch/Job.cpp
index 0932757..449ae0c 100644
--- a/src/servers/launch/Job.cpp
+++ b/src/servers/launch/Job.cpp
@@ -11,6 +11,8 @@
#include <Message.h>
#include <Roster.h>

+#include <user_group.h>
+
#include "Target.h"


@@ -241,6 +243,11 @@ Job::Init(const Finder& finder, std::set<BString>&
dependencies)
break;
}
iterator->second.SetInt32("port", port);
+
+ if (name == "x-vnd.haiku-registrar:auth") {
+ // Allow the launch_daemon to access the registrar
authentication
+ BPrivate::set_registrar_authentication_port(port);
+ }
}

if (fInitStatus == B_OK && fCreateDefaultPort && !defaultPort) {
diff --git a/src/servers/launch/LaunchDaemon.cpp
b/src/servers/launch/LaunchDaemon.cpp
index 0b3c95c..1b792ab 100644
--- a/src/servers/launch/LaunchDaemon.cpp
+++ b/src/servers/launch/LaunchDaemon.cpp
@@ -702,7 +702,7 @@ LaunchDaemon::_StartSession(const char* login)
{
// TODO: enable user/group code
// The launch_daemon currently cannot talk to the registrar, though
-/*
+
struct passwd* passwd = getpwnam(login);
if (passwd == NULL)
return B_NAME_NOT_FOUND;
@@ -712,7 +712,6 @@ LaunchDaemon::_StartSession(const char* login)
// Check if there is a user session running already
uid_t user = passwd->pw_uid;
gid_t group = passwd->pw_gid;
-*/

Unlock();

@@ -720,22 +719,12 @@ LaunchDaemon::_StartSession(const char* login)
if (setsid() < 0)
exit(EXIT_FAILURE);

-/*
-debug_printf("session leader...\n");
- if (initgroups(login, group) == -1) {
-debug_printf("1.ouch: %s\n", strerror(errno));
+ if (initgroups(login, group) == -1)
exit(EXIT_FAILURE);
- }
- //endgrent();
- if (setgid(group) != 0) {
-debug_printf("2.ouch: %s\n", strerror(errno));
+ if (setgid(group) != 0)
exit(EXIT_FAILURE);
- }
- if (setuid(user) != 0) {
-debug_printf("3.ouch: %s\n", strerror(errno));
+ if (setuid(user) != 0)
exit(EXIT_FAILURE);
- }
-*/

// TODO: This leaks the parent application
be_app = NULL;
diff --git a/src/system/libroot/posix/user_group_common.cpp
b/src/system/libroot/posix/user_group_common.cpp
index 5c234bf..eb5911b 100644
--- a/src/system/libroot/posix/user_group_common.cpp
+++ b/src/system/libroot/posix/user_group_common.cpp
@@ -67,6 +67,13 @@ BPrivate::get_registrar_authentication_port()
}


+void
+BPrivate::set_registrar_authentication_port(port_id port)
+{
+ sRegistrarPort = port;
+}
+
+
status_t
BPrivate::send_authentication_request_to_registrar(KMessage& request,
KMessage& reply)


Other related posts:

  • » [haiku-commits] BRANCH axeld-github.launch_daemon [2255428c123d] in src: servers/launch tests/servers/launch apps/login . - axeld-github . launch_daemon