[pkg-fso-commits] [SCM] Automatic Display Manager branch, bug540201, updated. debian/0.6-1-32-g6c296c1
Enrico Zini
enrico at enricozini.org
Tue Jul 5 17:42:07 UTC 2011
The following commit has been merged in the bug540201 branch:
commit 6c296c1998eec142dfa0f23c54e2d761cda183be
Author: Enrico Zini <enrico at enricozini.org>
Date: Tue Jul 5 19:42:03 2011 +0200
Move session setup code to child process
diff --git a/xsession-child.c b/xsession-child.c
index 2a152d9..f5ef518 100644
--- a/xsession-child.c
+++ b/xsession-child.c
@@ -19,12 +19,15 @@
*/
#include "xsession-child.h"
+#include "xserver.h"
#include "common.h"
#include "log.h"
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/wait.h>
+#include <fcntl.h>
#include <grp.h>
#include <signal.h>
#include <errno.h>
@@ -38,6 +41,56 @@
#endif
/*
+ * Truncate ~/.xsession-errors if it is longer than \a maxsize.
+ *
+ * The function looks for .xsession-errors in the current directory, so when it
+ * is called the current directory must be the user's homedir.
+ *
+ * The function also assumes that we are running as the user. As a consequence
+ * it does not worry about symlink attacks, because they would only be possible
+ * if the user's home directory is group or world writable.
+ *
+ * curdirname is the name of the current directory, and it is only used when
+ * logging error messages.
+ *
+ * The function returns true on success, false on failure.
+ */
+static int cleanup_xse(off_t maxsize, const char* curdirname)
+{
+ int ret = E_OS_ERROR;
+ int xse_fd = -1;
+ struct stat xse_st;
+
+ xse_fd = open(".xsession-errors", O_WRONLY | O_CREAT, 0600);
+ if (xse_fd < 0)
+ {
+ log_err("cannot open `%s/%s': %m", curdirname, ".xsession-errors");
+ goto cleanup;
+ }
+ if (fstat(xse_fd, &xse_st) < 0)
+ {
+ log_err("cannot stat `%s/%s': %m", curdirname, ".xsession-errors");
+ goto cleanup;
+ }
+ if (xse_st.st_size > maxsize)
+ {
+ if (ftruncate(xse_fd, 0) < 0)
+ {
+ log_err("cannot truncate `%s/%s': %m", curdirname, ".xsession-errors");
+ goto cleanup;
+ }
+ }
+
+ /* If we made it so far, we succeeded */
+ ret = E_SUCCESS;
+
+cleanup:
+ if (xse_fd >= 0)
+ close(xse_fd);
+ return ret;
+}
+
+/*
* setup_uid_gid() split in two functions for PAM support -
* pam_setcred() needs to be called after initgroups(), but
* before setuid().
@@ -198,8 +251,43 @@ static void shutdown_pam(struct nodm_xsession_child* s)
s->pamh = 0;
}
+int nodm_xsession_child_common_env(struct nodm_xsession_child* s)
+{
+ // Setup environment
+ setenv("HOME", s->pwent.pw_dir, 1);
+ setenv("USER", s->pwent.pw_name, 1);
+ setenv("USERNAME", s->pwent.pw_name, 1);
+ setenv("LOGNAME", s->pwent.pw_name, 1);
+ setenv("PWD", s->pwent.pw_dir, 1);
+ setenv("SHELL", s->pwent.pw_shell, 1);
+ setenv("DISPLAY", s->srv->name, 1);
+ setenv("WINDOWPATH", s->srv->windowpath, 1);
+
+
+ // Clear the NODM_* environment variables
+ unsetenv("NODM_USER");
+ unsetenv("NODM_XINIT");
+ unsetenv("NODM_XSESSION");
+ unsetenv("NODM_X_OPTIONS");
+ unsetenv("NODM_MIN_SESSION_TIME");
+ unsetenv("NODM_RUN_SESSION");
+
+ // Move to home directory
+ if (chdir(s->pwent.pw_dir) == 0)
+ {
+ // Truncate ~/.xsession-errors
+ if (s->conf_cleanup_xse)
+ cleanup_xse(0, s->pwent.pw_dir);
+ }
+
+ return E_SUCCESS;
+}
+
int nodm_xsession_child(struct nodm_xsession_child* s)
{
+ int res = nodm_xsession_child_common_env(s);
+ if (res != E_SUCCESS) return res;
+
/*
* This is a workaround for Linux libc bug/feature (?) - the
* /dev/log file descriptor is open without the close-on-exec flag
@@ -242,6 +330,9 @@ int nodm_xsession_child_pam(struct nodm_xsession_child* s)
child = fork ();
if (child == 0) { /* child shell */
+ int res = nodm_xsession_child_common_env(s);
+ if (res != E_SUCCESS) return res;
+
/*
* This is a workaround for Linux libc bug/feature (?) - the
* /dev/log file descriptor is open without the close-on-exec flag
diff --git a/xsession-child.h b/xsession-child.h
index 8a453d6..2a232af 100644
--- a/xsession-child.h
+++ b/xsession-child.h
@@ -21,11 +21,20 @@
#ifndef NODM_XSESSION_CHILD_H
#define NODM_XSESSION_CHILD_H
+#include <stdbool.h>
#include <pwd.h>
#include <security/pam_appl.h>
+struct nodm_xserver;
+
struct nodm_xsession_child
{
+ /// X server we connect to
+ struct nodm_xserver* srv;
+
+ /// If set to true, perform ~/.xsession-errors cleanup
+ bool conf_cleanup_xse;
+
/// Information about the user we run the session for
struct passwd pwent;
@@ -42,6 +51,9 @@ struct nodm_xsession_child
int exit_status;
};
+/// Setup common environment bits in the child process
+int nodm_xsession_child_common_env(struct nodm_xsession_child* s);
+
/// Just exec the session
int nodm_xsession_child(struct nodm_xsession_child* s);
diff --git a/xsession.c b/xsession.c
index 35515a3..316f81c 100644
--- a/xsession.c
+++ b/xsession.c
@@ -27,62 +27,11 @@
#include <signal.h>
#include <pwd.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-/*
- * Truncate ~/.xsession-errors if it is longer than \a maxsize.
- *
- * The function looks for .xsession-errors in the current directory, so when it
- * is called the current directory must be the user's homedir.
- *
- * The function also assumes that we are running as the user. As a consequence
- * it does not worry about symlink attacks, because they would only be possible
- * if the user's home directory is group or world writable.
- *
- * curdirname is the name of the current directory, and it is only used when
- * logging error messages.
- *
- * The function returns true on success, false on failure.
- */
-static int cleanup_xse(off_t maxsize, const char* curdirname)
-{
- int ret = E_OS_ERROR;
- int xse_fd = -1;
- struct stat xse_st;
-
- xse_fd = open(".xsession-errors", O_WRONLY | O_CREAT, 0600);
- if (xse_fd < 0)
- {
- log_err("cannot open `%s/%s': %m", curdirname, ".xsession-errors");
- goto cleanup;
- }
- if (fstat(xse_fd, &xse_st) < 0)
- {
- log_err("cannot stat `%s/%s': %m", curdirname, ".xsession-errors");
- goto cleanup;
- }
- if (xse_st.st_size > maxsize)
- {
- if (ftruncate(xse_fd, 0) < 0)
- {
- log_err("cannot truncate `%s/%s': %m", curdirname, ".xsession-errors");
- goto cleanup;
- }
- }
-
- /* If we made it so far, we succeeded */
- ret = E_SUCCESS;
-
-cleanup:
- if (xse_fd >= 0)
- close(xse_fd);
- return ret;
-}
-
int nodm_xsession_init(struct nodm_xsession* s)
{
s->conf_use_pam = true;
@@ -92,6 +41,7 @@ int nodm_xsession_init(struct nodm_xsession* s)
if (!bounded_strcpy(s->conf_run_as, getenv_with_default("NODM_USER", "root")))
log_warn("username has been truncated");
+ // Get the X session command
if (!bounded_strcpy(s->conf_session_command, getenv_with_default("NODM_XSESSION", "/etc/X11/Xsession")))
log_warn("session command has been truncated");
@@ -103,6 +53,8 @@ int nodm_xsession_init(struct nodm_xsession* s)
int nodm_xsession_start(struct nodm_xsession* s, struct nodm_xserver* srv)
{
struct nodm_xsession_child child;
+ child.srv = srv;
+ child.conf_cleanup_xse = s->conf_cleanup_xse;
// Validate the user using the normal system user database
struct passwd *pw = 0;
@@ -152,33 +104,6 @@ int nodm_xsession_start(struct nodm_xsession* s, struct nodm_xserver* srv)
s->pid = fork();
if (s->pid == 0)
{
- // Setup environment
- setenv("HOME", pw->pw_dir, 1);
- setenv("USER", pw->pw_name, 1);
- setenv("USERNAME", pw->pw_name, 1);
- setenv("LOGNAME", pw->pw_name, 1);
- setenv("PWD", pw->pw_dir, 1);
- setenv("SHELL", pw->pw_shell, 1);
- setenv("DISPLAY", srv->name, 1);
- setenv("WINDOWPATH", srv->windowpath, 1);
-
-
- // Clear the NODM_* environment variables
- unsetenv("NODM_USER");
- unsetenv("NODM_XINIT");
- unsetenv("NODM_XSESSION");
- unsetenv("NODM_X_OPTIONS");
- unsetenv("NODM_MIN_SESSION_TIME");
- unsetenv("NODM_RUN_SESSION");
-
- // Move to home directory
- if (chdir(pw->pw_dir) == 0)
- {
- // Truncate ~/.xsession-errors
- if (s->conf_cleanup_xse)
- cleanup_xse(0, pw->pw_dir);
- }
-
// child shell */
if (s->conf_use_pam)
exit(nodm_xsession_child_pam(&child));
--
Automatic Display Manager
More information about the pkg-fso-commits
mailing list