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…
Reference in a new issue