[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tpop3d-discuss] Option to chroot() for virtual servers
From: |
Travis Miller |
Subject: |
[tpop3d-discuss] Option to chroot() for virtual servers |
Date: |
Sun, 15 Dec 2002 18:48:54 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020605 |
Chris (and everyone else):
A little history: We currently use tpop3d for hosting email for
"virtual" users (ie, they do not exist in /etc/passwd). To do this, all
of the mail boxes are owned by the same user "mailspool" in group
"mailspool" and the pop3 user is authenticated via mysql.
And the idea: So to improve a little on security I thought I would try
patching tpop3d to chroot() to the mail spool and setgid()/setuid() to a
non-privledeged user right before net_loop() in main.c. I have
attached a patch that seems to work for this as long as you have a copy
of /etc/passwd and /etc/group in /path/to/spools/etc. When you do not
have copies in the there, auth_mysql fails at parse_uid(),parse_gid and
all the other passwd/group system calls (of course). Of course, it
breaks other things such as kill -HUP also....
My Question:
Does this seem like a worth while advantage to add?
It does mean leaving open file descriptors after the chroot(),
setuid()... is that fact not worth worrying with with chroot'ing in the
first place?
Would it be worth the effort to code in a work around for all the
uid/gid calls when chroot() is enabled?
And lastly, I am no code wizard, so comments/ideas on methods of
implementing this? (mine is very basic!)
(The attached patch is against 1.4.2, chroot is enabled via configure
with --enable-chroot)
Travis
address@hidden
diff -u tpop3d-1.4.2/configure.in tpop3d-1.4.2-chroot/configure.in
--- tpop3d-1.4.2/configure.in 2002-06-27 15:08:46.000000000 -0500
+++ tpop3d-1.4.2-chroot/configure.in 2002-12-15 17:53:25.000000000 -0600
@@ -198,6 +198,13 @@
[enable_drac=$enableval],
[enable_drac=no])
+dnl Enable chroot()ed server
+AC_ARG_ENABLE(chroot,
+ [ --enable-choot Enable support for chroot()'d
server.
+ [default=no]],
+ [enable_chroot=$enableval],
+ [enable_chroot=no])
+
dnl Some options mainly useful for development/debugging.
dnl Note the ugliness I've used to put a note in the output of
@@ -331,6 +338,11 @@
AC_DEFINE(USE_DRAC,1,[Enables notification of a DRAC daemon.])
fi
+if test x"$enable_chroot" = x"yes"
+then
+ AC_DEFINE(WITH_CHROOT,1,[Enables ablilty to chroot() server.])
+fi
+
if test x"$enable_backtrace" = x"yes"
then
AC_DEFINE(APPALLING_BACKTRACE_HACK,1,[Produce a backtrace if the program
crashes.])
Common subdirectories: tpop3d-1.4.2/darwin and tpop3d-1.4.2-chroot/darwin
Common subdirectories: tpop3d-1.4.2/init.d and tpop3d-1.4.2-chroot/init.d
diff -u tpop3d-1.4.2/main.c tpop3d-1.4.2-chroot/main.c
--- tpop3d-1.4.2/main.c 2002-06-25 15:28:00.000000000 -0500
+++ tpop3d-1.4.2-chroot/main.c 2002-12-15 17:41:31.000000000 -0600
@@ -32,6 +32,11 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#if defined(WITH_CHROOT)
+#include <pwd.h>
+#include <grp.h>
+#endif
+
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -453,6 +458,77 @@
#define EXIT_REMOVING_PIDFILE(n) do { if (pidfile) remove_pid_file(pidfile);
exit((n)); } while (0)
+#if defined(WITH_CHROOT)
+/* do_chroot:
+ * Jail the server to a particular section of the file system. This, of
course, is not
+ * useful if we are still root; so we drop root priviledges also... This has a
*large*
+ * effect on how the rest of the server works, it may currently break things.
Returns 0
+ * on failure and 1 on success.
+ */
+int do_chroot(void) {
+ struct passwd *pw;
+ struct group *gr;
+ int new_uid;
+ int new_gid;
+ char *path;
+ char *tmp;
+
+ /* Get the path to chroot() to */
+ if ((path = config_get_string("chroot-path")) == NULL) {
+ log_print(LOG_INFO, _("do_chroot: could not determine
chroot-path"),path);
+ return(0);
+ }
+
+ /* We need to know what user to setuid() to after chroot(), first attemt
to get
+ * the username from the config, if that fails try to get the uid. */
+ if ((tmp = config_get_string("chroot-user")) != NULL) {
+ if ((pw = getpwnam(tmp)) != NULL) {
+ new_uid = pw->pw_uid;
+ } else {
+ log_print(LOG_INFO, _("do_chroot: could not determine chroot-user
(chroot-user: %s)"),tmp);
+ return(0);
+ }
+ } else if (config_get_int("chroot-uid",&new_uid) != 1) {
+ log_print(LOG_INFO, _("do_chroot: could not determine
chroot-user"),new_uid);
+ return(0);
+ }
+
+ /* Now we do the exact same thing for the setgid() call */
+ if ((tmp = config_get_string("chroot-group")) != NULL) {
+ if ((gr = getgrnam(tmp)) != NULL) {
+ new_gid = gr->gr_gid;
+ } else {
+ log_print(LOG_INFO, _("do_chroot: could not determine chroot-group
(chroot-group: %s)"),tmp);
+ return(0);
+ }
+ } else if (config_get_int("chroot-gid",&new_gid) != 1) {
+ log_print(LOG_INFO, _("do_chroot: could not determine chroot-group"));
+ return(0);
+ }
+
+ /* chroot and chdir */
+ if (chroot(path) == -1) {
+ log_print(LOG_INFO, _("do_chroot: chroot(%s) failed!"),path);
+ return(0);
+ } else if (chdir("/") == -1) {
+ log_print(LOG_INFO, _("do_chroot: chdir(/) failed!"));
+ return(0);
+ }
+
+ /* become a non-root user, too easy to break chroot() as root */
+ if (setgid((gid_t)new_gid) == -1) {
+ log_print(LOG_ERR, "do_chroot: setgid(%d)",new_gid);
+ return(0);
+ } else if (setuid((uid_t)new_uid) == -1) {
+ log_print(LOG_ERR, "do_chroot: setuid(%d)",new_uid);
+ return(0);
+ }
+
+ /* Success! */
+ return(1);
+}
+#endif
+
/* usage:
* Print usage information.
*/
@@ -747,6 +823,19 @@
EXIT_REMOVING_PIDFILE(1);
} else log_print(LOG_INFO, _("%d authentication drivers successfully
loaded"), na);
+#if defined(WITH_CHROOT)
+ /* Now that we have all the open file descriptors and everything else that
we should
+ * need, we can chroot(). */
+ if (config_get_bool("chroot")) {
+ int cr = do_chroot();
+ if (!cr) {
+ log_print(LOG_ERR, _("Unable to successfully chroot();
aborting."));
+ log_print(LOG_ERR, _("you may wish to check your config file %s"),
configfile);
+ EXIT_REMOVING_PIDFILE(1);
+ } else log_print(LOG_INFO, _("Successfully chroot()'d"));
+ }
+#endif
+
net_loop();
if (!post_fork)
- [tpop3d-discuss] Option to chroot() for virtual servers,
Travis Miller <=