Merge pull request #20 from bket/drop_priv - fiche - A pastebin adjusted for gopher use
 (HTM) git clone git://vernunftzentrum.de/fiche.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 4c3f5908e36d6037c26400fc6bbfe7c6fc343b4f
 (DIR) parent a284706e78fc19568e8954376b0cb8e04a24221c
 (HTM) Author: solusipse <solus1ps3@gmail.com>
       Date:   Tue, 22 Sep 2015 04:33:34 +0200
       
       Merge pull request #20 from bket/drop_priv
       
       Drop privileges when running as root
       Diffstat:
         README.md                           |      10 ++++++----
         fiche.c                             |      33 +++++++++++++++++++------------
         fiche.h                             |       3 +--
       
       3 files changed, 27 insertions(+), 19 deletions(-)
       ---
 (DIR) diff --git a/README.md b/README.md
       @@ -115,13 +115,15 @@ http://domain.com/abcdef/
        
        #### User name ####
        
       -If you use fiche as service (see details below) you may want to save files as other user, to do that use `-u` option,
       -there's example:
       +Set the user that fiche runs as using the `-u` option, example:
        
        ```
       -fiche -u http
       +fiche -u _fiche
        ```
        
       +This option has effect only if fiche was started by root, otherwise it is ignored and fiche runs under the
       +current user id.
       +
        -----------------
        
        #### Buffersize ####
       @@ -221,7 +223,7 @@ You can run fiche as service, there is simple systemd example:
        Description=FICHE-SERVER
        
        [Service]
       -ExecStart=/usr/local/bin/fiche -d code.solusipse.net -o /home/www/code/ -l /home/www/log.txt
       +ExecStart=/usr/local/bin/fiche -d code.solusipse.net -o /home/www/code/ -l /home/www/log.txt -u _fiche
        
        [Install]
        WantedBy=multi-user.target
 (DIR) diff --git a/fiche.c b/fiche.c
       @@ -36,6 +36,17 @@ int main(int argc, char **argv)
            time_seed = time(0);
        
            parse_parameters(argc, argv);
       +
       +    if (getuid() == 0)
       +    {
       +        if (UID == -1)
       +            error("ERROR: user not set");
       +        if (setgid(GID) != 0)
       +            error("ERROR: Unable to drop group privileges");
       +        if (setuid(UID) != 0)
       +            error("ERROR: Unable to drop user privileges");
       +    }
       +
            if (BASEDIR == NULL)
                set_basedir();
        
       @@ -255,12 +266,11 @@ void load_list(char *file_path, int type)
        int create_socket()
        {
            int lsocket = socket(AF_INET, SOCK_STREAM, 0);
       +
            if (lsocket < 0)
       -    {
                error("ERROR: Couldn't open socket");
       -        return 0;
       -    }
       -    else return lsocket;
       +
       +    return lsocket;
        }
        
        struct sockaddr_in set_address(struct sockaddr_in server_address)
       @@ -317,8 +327,6 @@ int create_directory(char *slug)
            mkdir(BASEDIR, S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP);
            int result = mkdir(directory, S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH | S_IXGRP);
        
       -    change_owner(directory);
       -
            free(directory);
        
            return result;
       @@ -335,18 +343,11 @@ void save_to_file(char *slug, char *buffer, struct client_data data)
            fprintf(fp, "%s", buffer);
            fclose(fp);
        
       -    change_owner(directory);
            display_info(data, directory, "");
        
            free(directory);
        }
        
       -void change_owner(char *directory)
       -{
       -    if (UID != -1 && GID != -1)
       -        chown(directory, UID, GID);
       -}
       -
        void set_uid_gid(char *username)
        {
            struct passwd *userdata = getpwnam(username);
       @@ -388,6 +389,12 @@ void startup_message()
            printf("====================================\n");
        }
        
       +void error(char *buffer)
       +{
       +    printf("%s\n", buffer);
       +    exit(1);
       +}
       +
        void parse_parameters(int argc, char **argv)
        {
            int c;
 (DIR) diff --git a/fiche.h b/fiche.h
       @@ -80,7 +80,7 @@ int create_directory(char *slug);
        int check_protocol(char *buffer);
        
        void bind_to_port(int listen_socket, struct sockaddr_in serveraddr);
       -void error(char *error_code){perror(error_code); exit(1);}
       +void error(char *buffer);
        void perform_connection(int listen_socket);
        void generate_url(char *buffer, char *slug, size_t slug_length, struct client_data data);
        void save_to_file(char *buffer, char *slug, struct client_data data);
       @@ -90,7 +90,6 @@ void set_basedir();
        void load_list(char *file_path, int type);
        void parse_parameters(int argc, char **argv);
        void save_log(char *slug, char *hostaddrp, char *h_name);
       -void change_owner(char *directory);
        void set_uid_gid();
        
        char *check_banlist(char *ip_address);