add: drop privileges
This commit is contained in:
		
							parent
							
								
									486b45c680
								
							
						
					
					
						commit
						1d8408581a
					
				
					 6 changed files with 118 additions and 7 deletions
				
			
		| 
						 | 
					@ -26,6 +26,8 @@ typedef struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *file;
 | 
					    char *file;
 | 
				
			||||||
    char database[256];
 | 
					    char database[256];
 | 
				
			||||||
 | 
					    char user[256];
 | 
				
			||||||
 | 
					    char group[256];
 | 
				
			||||||
    log_level_t log_level;
 | 
					    log_level_t log_level;
 | 
				
			||||||
    run_type_t run_type;
 | 
					    run_type_t run_type;
 | 
				
			||||||
    char server_port[6];
 | 
					    char server_port[6];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,4 +14,7 @@ helper_parse_cli(int argc, const char **argv, config_t *config);
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
helper_get_weekday(const struct tm *time_struct);
 | 
					helper_get_weekday(const struct tm *time_struct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					helper_drop_privileges();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CORE_HELPERS_H */
 | 
					#endif /* CORE_HELPERS_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/config.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/config.c
									
										
									
									
									
								
							| 
						 | 
					@ -64,6 +64,16 @@ config_load(IniDispatch *disp, void *config_void)
 | 
				
			||||||
            strcpy(config->database, disp->value);
 | 
					            strcpy(config->database, disp->value);
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if(CONFINI_IS_KEY("core", "user"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            strcpy(config->user, disp->value);
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if(CONFINI_IS_KEY("core", "group"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            strcpy(config->group, disp->value);
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if(CONFINI_IS_KEY("core", "not-found-file"))
 | 
					        if(CONFINI_IS_KEY("core", "not-found-file"))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            strcpy(config->not_found_file, disp->value);
 | 
					            strcpy(config->not_found_file, disp->value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ database_migrate()
 | 
				
			||||||
    rc = sqlite3_step(stmt);
 | 
					    rc = sqlite3_step(stmt);
 | 
				
			||||||
    if (rc != SQLITE_DONE)
 | 
					    if (rc != SQLITE_DONE)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        LOG_FATAL("couldn't write new schema version");
 | 
					        LOG_FATAL("couldn't write new schema version\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sqlite3_finalize(stmt);
 | 
					    sqlite3_finalize(stmt);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										81
									
								
								src/helpers/drop_privileges.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/helpers/drop_privileges.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,81 @@
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <pwd.h>
 | 
				
			||||||
 | 
					#include <grp.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <config.h>
 | 
				
			||||||
 | 
					#include <logger.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uid_t
 | 
				
			||||||
 | 
					get_uid_for_user(char *user)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(user == NULL || user[0] == '\0')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return getuid();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    struct passwd *pwd = calloc(1, sizeof(struct passwd));
 | 
				
			||||||
 | 
					    size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char);
 | 
				
			||||||
 | 
					    char *buffer = malloc(buffer_len);
 | 
				
			||||||
 | 
					    getpwnam_r(user, pwd, buffer, buffer_len, &pwd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pwd == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG_FATAL("couldn't find user to drop privileges\n");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uid_t result = pwd->pw_uid;
 | 
				
			||||||
 | 
					    free(buffer);
 | 
				
			||||||
 | 
					    free(pwd);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gid_t
 | 
				
			||||||
 | 
					get_gid_for_group(char *group)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(group == NULL || group[0] == '\0')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return getgid();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    struct group *grp = calloc(1, sizeof(struct group));
 | 
				
			||||||
 | 
					    size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char);
 | 
				
			||||||
 | 
					    char *buffer = malloc(buffer_len);
 | 
				
			||||||
 | 
					    getgrnam_r(group, grp, buffer, buffer_len, &grp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(grp == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG_FATAL("couldn't find group to drop privileges\n");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gid_t result = grp->gr_gid;
 | 
				
			||||||
 | 
					    free(buffer);
 | 
				
			||||||
 | 
					    free(grp);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					helper_drop_privileges()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uid_t uid = get_uid_for_user(global_config.user);
 | 
				
			||||||
 | 
					    gid_t gid = get_gid_for_group(global_config.group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LOG_DEBUG("drop privileges to %lu:%lu\n", uid, gid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (setgid(gid) == -1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG_FATAL("failed to drop group privileges\n");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (setuid(uid) == -1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG_FATAL("failed to drop user privileges\n");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										27
									
								
								src/main.c
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								src/main.c
									
										
									
									
									
								
							| 
						 | 
					@ -49,6 +49,9 @@ main(int argc, const char** argv)
 | 
				
			||||||
    /******************** LOAD CONFIG ********************/
 | 
					    /******************** LOAD CONFIG ********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    global_config.file = "core.ini";
 | 
					    global_config.file = "core.ini";
 | 
				
			||||||
 | 
					    strcpy(global_config.user, "");
 | 
				
			||||||
 | 
					    strcpy(global_config.group, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    strcpy(global_config.not_found_file, "404.html");
 | 
					    strcpy(global_config.not_found_file, "404.html");
 | 
				
			||||||
    strcpy(global_config.not_found_file_type, "text/html");
 | 
					    strcpy(global_config.not_found_file_type, "text/html");
 | 
				
			||||||
    strcpy(global_config.not_found_content, "404 - NOT FOUND");
 | 
					    strcpy(global_config.not_found_content, "404 - NOT FOUND");
 | 
				
			||||||
| 
						 | 
					@ -77,6 +80,24 @@ main(int argc, const char** argv)
 | 
				
			||||||
    global_config.http_server_opts.extra_headers = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Methods: *";
 | 
					    global_config.http_server_opts.extra_headers = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Methods: *";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /******************** SETUP CONNECTION ********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct mg_connection *c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mg_mgr_init(&mgr, NULL);
 | 
				
			||||||
 | 
					    c = mg_bind(&mgr, global_config.server_port, handler_connection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(c == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LOG_FATAL("failed to bind to port %s\n", global_config.server_port);
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mg_set_protocol_http_websocket(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    helper_drop_privileges();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /******************** SETUP DATABASE ********************/
 | 
					    /******************** SETUP DATABASE ********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int rc = sqlite3_open(global_config.database, &global_database);
 | 
					    int rc = sqlite3_open(global_config.database, &global_database);
 | 
				
			||||||
| 
						 | 
					@ -102,12 +123,6 @@ main(int argc, const char** argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /******************** START MAIN LOOP ********************/
 | 
					    /******************** START MAIN LOOP ********************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct mg_connection *c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mg_mgr_init(&mgr, NULL);
 | 
					 | 
				
			||||||
    c = mg_bind(&mgr, global_config.server_port, handler_connection);
 | 
					 | 
				
			||||||
    mg_set_protocol_http_websocket(c);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (;;)
 | 
					    for (;;)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        mg_mgr_poll(&mgr, 1000);
 | 
					        mg_mgr_poll(&mgr, 1000);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue