The following patch will add two command line options to svnserve,
allowing users who run svnserve as a stand alone daemon to drop
privileges to a user specified uid and gid. (-u uid -g gid)
As I'm not very familiar with the subversion codebase and standards,
so my patch may not be the optimal way of doing this. I am, however,
sending this patch to the list in hope that somebody can pick this
up and make a decent feature out of it.
The patch is included below, but can also be found at;
http://forkbomb.org/svn-1.2.0-rc2-svnserve-uid-gid-option.patch
- Tom.
diff -ruN subversion-1.2.0-rc2/subversion/svnserve/main.c subversion-1.2.0-rc2-hack/subversion/svnserve/main.c
--- subversion-1.2.0-rc2/subversion/svnserve/main.c 2005-04-16 21:23:41.000000000 +0100
+++ subversion-1.2.0-rc2-hack/subversion/svnserve/main.c 2005-04-26 05:21:20.000000000 +0100
@@ -119,6 +119,8 @@
{"threads", 'T', 0, N_("use threads instead of fork")},
#endif
{"listen-once", 'X', 0, N_("listen once (useful for debugging)")},
+ {"uid", 'u', 1, N_("drop privileges to uid (daemon mode)")},
+ {"gid", 'g', 1, N_("drop privileges to gid (daemon mode)")},
{0, 0, 0, 0}
};
@@ -286,11 +288,13 @@
}
apr_getopt_init(&os, pool, argc, argv);
-
+
params.root = "/";
params.tunnel = FALSE;
params.tunnel_user = NULL;
params.read_only = FALSE;
+ params.uid = getuid();
+ params.gid = getgid();
while (1)
{
status = apr_getopt_long(os, svnserve__options, &opt, &arg);
@@ -314,6 +318,14 @@
mode_opt_count++;
break;
+ case 'u':
+ params.uid = atoi(arg);
+ break;
+
+ case 'g':
+ params.gid = atoi(arg);
+ break;
+
case SVNSERVE_OPT_FOREGROUND:
foreground = TRUE;
break;
@@ -465,8 +477,26 @@
apr_socket_listen(sock, 7);
#if APR_HAS_FORK
- if (run_mode != run_mode_listen_once && !foreground)
+ if (run_mode != run_mode_listen_once && !foreground) {
+
+ if ((params.gid != getgid()) && setregid(params.gid, params.gid) == -1) {
+ svn_error_clear
+ (svn_cmdline_fprintf
+ (stderr, pool,
+ _("Failed to set GID\n")));
+ exit(1);
+ }
+
+ if ((params.uid != getuid()) && setreuid(params.uid, params.uid) == -1) {
+ svn_error_clear
+ (svn_cmdline_fprintf
+ (stderr, pool,
+ _("Failed to set UID\n")));
+ exit(1);
+ }
+
apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);
+ }
apr_signal(SIGCHLD, sigchld_handler);
#endif
diff -ruN subversion-1.2.0-rc2/subversion/svnserve/server.h subversion-1.2.0-rc2-hack/subversion/svnserve/server.h
--- subversion-1.2.0-rc2/subversion/svnserve/server.h 2004-02-19 19:25:41.000000000 +0000
+++ subversion-1.2.0-rc2-hack/subversion/svnserve/server.h 2005-04-26 05:06:17.000000000 +0100
@@ -45,6 +45,12 @@
/* True if the deprecated read-only flag was specified on the
command-line, which forces all connections to be read-only. */
svn_boolean_t read_only;
+
+ /* Run server as the specified UID and GID. Useful for dropping
+ privileges when started by root. */
+ uid_t uid;
+ gid_t gid;
+
} serve_params_t;
/* Serve the connection CONN according to the parameters PARAMS. */
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Apr 26 06:45:45 2005