Ticket #254: droproot.diff

File droproot.diff, 3.0 KB (added by Simo Leone <simo@…>, at 2007-02-22T01:53:21Z)

A quick and dirty patch to drop root privs. Needs some polish to make it shinier.

  • bitlbee.conf

    === modified file 'bitlbee.conf'
    old new  
    1919##
    2020# RunMode = Inetd
    2121
     22## User:
     23##
     24## If BitlBee is run as root as a Daemon or ForkDaemon, it can drop root
     25## privileges, and change to specified user.
     26##
     27# User = bitlbee
     28
    2229## DaemonPort/DaemonInterface:
    2330##
    2431## For daemon mode, you can specify on what interface and port the daemon
  • conf.c

    === modified file 'conf.c'
    old new  
    6666        conf->motdfile = g_strdup( ETCDIR "/motd.txt" );
    6767        conf->ping_interval = 180;
    6868        conf->ping_timeout = 300;
     69        conf->user = "";
    6970        proxytype = 0;
    7071       
    7172        i = conf_loadini( conf, CONF_FILE );
     
    7980                fprintf( stderr, "Warning: Unable to read configuration file `%s'.\n", CONF_FILE );
    8081        }
    8182       
    82         while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:" ) ) >= 0 )
     83        while( argc > 0 && ( opt = getopt( argc, argv, "i:p:P:nvIDFc:d:hR:u:" ) ) >= 0 )
    8384        /*     ^^^^ Just to make sure we skip this step from the REHASH handler. */
    8485        {
    8586                if( opt == 'i' )
     
    139140                                "  -I  Classic/InetD mode. (Default)\n"
    140141                                "  -D  Daemon mode. (Still EXPERIMENTAL!)\n"
    141142                                "  -F  Forking daemon. (one process per client)\n"
     143                                "  -u  Run daemon as specified user.\n"
    142144                                "  -P  Specify PID-file (not for inetd mode)\n"
    143145                                "  -i  Specify the interface (by IP address) to listen on.\n"
    144146                                "      (Default: 0.0.0.0 (any interface))\n"
     
    158160                           mode anyway!) */
    159161                        ipc_master_set_statefile( optarg );
    160162                }
     163                else if(opt == 'u' )
     164                {
     165                        conf->user = g_strdup( optarg );
     166                }
    161167        }
    162168       
    163169        if( conf->configdir[strlen(conf->configdir)-1] != '/' )
     
    293299                               
    294300                                g_free( url );
    295301                        }
     302                        else if( g_strcasecmp( ini->key, "user" ) == 0 )
     303                        {
     304                                conf->user = g_strdup( ini->value );
     305                        }
    296306                        else
    297307                        {
    298308                                fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
  • conf.h

    === modified file 'conf.h'
    old new  
    4848        char **migrate_storage;
    4949        int ping_interval;
    5050        int ping_timeout;
     51        char *user;
    5152} conf_t;
    5253
    5354conf_t *conf_load( int argc, char *argv[] );
  • unix.c

    === modified file 'unix.c'
    old new  
    3333#include <unistd.h>
    3434#include <sys/time.h>
    3535#include <sys/wait.h>
     36#include <pwd.h>
    3637
    3738global_t global;        /* Against global namespace pollution */
    3839
     
    5960        if( global.conf == NULL )
    6061                return( 1 );
    6162       
     63        if( ( global.conf->runmode == RUNMODE_DAEMON ||
     64                global.conf->runmode == RUNMODE_FORKDAEMON )
     65                && ( !getuid() || !geteuid() ) )
     66        {
     67                struct passwd *pw = NULL;
     68                pw = getpwnam(global.conf->user);
     69                if (pw)
     70                {
     71                        setgid(pw->pw_gid);
     72                        setuid(pw->pw_uid);
     73                }
     74        }
     75
    6276        if( global.conf->runmode == RUNMODE_INETD )
    6377        {
    6478                i = bitlbee_inetd_init();