Index: bitlbee.conf
===================================================================
--- bitlbee.conf	(revision 80e9db97776bfd6c6192135d65027abd8f50887c)
+++ bitlbee.conf	(revision aaf92a9eb64327892e39fdbd7113d797d1d68cec)
@@ -19,4 +19,11 @@
 ##
 # RunMode = Inetd
+
+## User:
+## 
+## If BitlBee is started by root as a daemon, it can drop root privileges,
+## and change to the specified user.
+##
+# User = bitlbee
 
 ## DaemonPort/DaemonInterface:
Index: conf.c
===================================================================
--- conf.c	(revision 80e9db97776bfd6c6192135d65027abd8f50887c)
+++ conf.c	(revision aaf92a9eb64327892e39fdbd7113d797d1d68cec)
@@ -63,4 +63,5 @@
 	conf->ping_interval = 180;
 	conf->ping_timeout = 300;
+	conf->user = NULL;
 	proxytype = 0;
 	
@@ -76,5 +77,5 @@
 	}
 	
-	while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:" ) ) >= 0 )
+	while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
 	/*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
 	{
@@ -132,4 +133,5 @@
 			        "  -D  Daemon mode. (Still EXPERIMENTAL!)\n"
 			        "  -F  Forking daemon. (one process per client)\n"
+				"  -u  Run daemon as specified user.\n"
 			        "  -P  Specify PID-file (not for inetd mode)\n"
 			        "  -i  Specify the interface (by IP address) to listen on.\n"
@@ -151,4 +153,9 @@
 			ipc_master_set_statefile( optarg );
 		}
+		else if( opt == 'u' )
+		{
+			g_free( conf->user );
+			conf->user = g_strdup( optarg );
+		}
 	}
 	
@@ -192,8 +199,10 @@
 			else if( g_strcasecmp( ini->key, "daemoninterface" ) == 0 )
 			{
+				g_free( conf->iface );
 				conf->iface = g_strdup( ini->value );
 			}
 			else if( g_strcasecmp( ini->key, "daemonport" ) == 0 )
 			{
+				g_free( conf->port );
 				conf->port = g_strdup( ini->value );
 			}
@@ -209,12 +218,15 @@
 			else if( g_strcasecmp( ini->key, "authpassword" ) == 0 )
 			{
+				g_free( conf->auth_pass );
 				conf->auth_pass = g_strdup( ini->value );
 			}
 			else if( g_strcasecmp( ini->key, "operpassword" ) == 0 )
 			{
+				g_free( conf->oper_pass );
 				conf->oper_pass = g_strdup( ini->value );
 			}
 			else if( g_strcasecmp( ini->key, "hostname" ) == 0 )
 			{
+				g_free( conf->hostname );
 				conf->hostname = g_strdup( ini->value );
 			}
@@ -281,4 +293,9 @@
 				g_free( url );
 			}
+			else if( g_strcasecmp( ini->key, "user" ) == 0 )
+			{
+				g_free( conf->user );
+				conf->user = g_strdup( ini->value );
+			}
 			else
 			{
Index: conf.h
===================================================================
--- conf.h	(revision 80e9db97776bfd6c6192135d65027abd8f50887c)
+++ conf.h	(revision aaf92a9eb64327892e39fdbd7113d797d1d68cec)
@@ -49,4 +49,5 @@
 	int ping_interval;
 	int ping_timeout;
+	char *user;
 } conf_t;
 
Index: unix.c
===================================================================
--- unix.c	(revision 80e9db97776bfd6c6192135d65027abd8f50887c)
+++ unix.c	(revision aaf92a9eb64327892e39fdbd7113d797d1d68cec)
@@ -34,4 +34,5 @@
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <pwd.h>
 
 global_t global;	/* Against global namespace pollution */
@@ -45,6 +46,4 @@
 	struct sigaction sig, old;
 	
-	memset( &global, 0, sizeof( global_t ) );
-	
 	log_init();
 	CONF_FILE = g_strdup( CONF_FILE_DEF );
@@ -87,10 +86,24 @@
 		return( i );
 	
+	if( ( global.conf->user && *global.conf->user ) &&
+	    ( global.conf->runmode == RUNMODE_DAEMON || 
+	      global.conf->runmode == RUNMODE_FORKDAEMON ) &&
+	    ( !getuid() || !geteuid() ) )
+	{
+		struct passwd *pw = NULL;
+		pw = getpwnam( global.conf->user );
+		if( pw )
+		{
+			setgid( pw->pw_gid );
+			setuid( pw->pw_uid );
+		}
+	}
+
 	global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );
-	if ( global.storage == NULL) {
+	if( global.storage == NULL )
+	{
 		log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage );
 		return( 1 );
 	}
-	
  	
 	/* Catch some signals to tell the user what's happening before quitting */
