# HG changeset patch # User Olaf Wintermann # Date 1371988309 -7200 # Node ID 6195c92262a2fa42d498dc61dc720aba6e5e06e8 # Parent 5bc6d078fb2c7199693219b0d42b634039717d0d# Parent 79fa26ecd1351af725e54fa89f11e0b2b76730c0 merge diff -r 5bc6d078fb2c -r 6195c92262a2 src/server/daemon/acl.c --- a/src/server/daemon/acl.c Sun Jun 23 13:49:17 2013 +0200 +++ b/src/server/daemon/acl.c Sun Jun 23 13:51:49 2013 +0200 @@ -28,10 +28,12 @@ #include #include +#include #include "../util/util.h" #include "../util/pool.h" #include "../safs/auth.h" +#include "log.h" #include "acl.h" void acllist_createhandle(Session *sn, Request *rq) { @@ -542,7 +544,9 @@ return check_access; } - +void fs_acl_finish() { + +} #endif @@ -556,4 +560,79 @@ return 1; } +void fs_acl_finish() { + +} + #endif + + +#ifdef LINUX + +#include + +int fs_acl_check(SysACL *acl, User *user, char *path, uint32_t access_mask) { + struct passwd *ws_pw = conf_getglobals()->Vuserpw; + if(!ws_pw) { + log_ereport(LOG_FAILURE, "fs_acl_check: unknown webserver uid/gid"); + return 1; + } + + // get uid/gid + struct passwd pw; + if(user) { + char *pwbuf = malloc(DEF_PWBUF); + if(pwbuf == NULL) { + return 0; + } + if(!util_getpwnam(user->name, &pw, pwbuf, DEF_PWBUF)) { + free(pwbuf); + return 0; + } + free(pwbuf); + acl->user_uid = pw.pw_uid; + acl->user_gid = pw.pw_gid; + } else { + acl->user_uid = 0; + acl->user_gid = 0; + } + + // set fs uid/gid + if(acl->user_uid != 0) { + if(setfsuid(pw.pw_uid)) { + log_ereport( + LOG_FAILURE, + "Cannot set fsuid to uid: %u", pw.pw_uid); + } + if(setfsgid(pw.pw_gid)) { + log_ereport( + LOG_FAILURE, + "Cannot set fsgid to gid: %u", pw.pw_gid); + } + } + + + return 1; +} + +void fs_acl_finish() { + struct passwd *pw = conf_getglobals()->Vuserpw; + if(!pw) { + log_ereport( + LOG_FAILURE, + "global configuration broken (Vuserpw is null)"); + return; + } + if(setfsuid(pw->pw_uid)) { + log_ereport( + LOG_FAILURE, + "Cannot set fsuid back to server uid: %u", pw->pw_uid); + } + if(setfsgid(pw->pw_gid)) { + log_ereport( + LOG_FAILURE, + "Cannot set fsgid back to server gid: %u", pw->pw_gid); + } +} + +#endif diff -r 5bc6d078fb2c -r 6195c92262a2 src/server/daemon/acl.h --- a/src/server/daemon/acl.h Sun Jun 23 13:49:17 2013 +0200 +++ b/src/server/daemon/acl.h Sun Jun 23 13:51:49 2013 +0200 @@ -49,6 +49,7 @@ // file system acl functions int fs_acl_check(SysACL *acl, User *user, char *path, uint32_t access_mask); +void fs_acl_finish(); #ifdef __cplusplus } diff -r 5bc6d078fb2c -r 6195c92262a2 src/server/daemon/config.c --- a/src/server/daemon/config.c Sun Jun 23 13:49:17 2013 +0200 +++ b/src/server/daemon/config.c Sun Jun 23 13:51:49 2013 +0200 @@ -64,6 +64,7 @@ InitConfig *cfg = load_init_config(file); UcxMempool *mp = cfg->parser.mp; if(cfg == NULL) { + fprintf(stderr, "Cannot load init.conf\n"); return 1; } @@ -149,34 +150,39 @@ * VirtualServer (dependencies: Listener) */ - /* init logfile first */ + // init logfile first UcxList *lfl = ucx_map_sstr_get(serverconf->objects, sstrn("LogFile", 7)); if(lfl != NULL) { ServerConfigObject *logobj = lfl->data; if(logobj == NULL) { - /* error */ + // error return NULL; } int ret = cfg_handle_logfile(serverconfig, logobj); if(ret != 0) { - /* cannot initialize log file */ + // cannot initialize log file return NULL; } } else { - /* horrible error */ + // horrible error return NULL; } UcxList *list = ucx_map_sstr_get(serverconf->objects, sstrn("Runtime", 7)); UCX_FOREACH(UcxList*, list, elm) { ServerConfigObject *scfgobj = elm->data; - cfg_handle_runtime(serverconfig, scfgobj); + if(cfg_handle_runtime(serverconfig, scfgobj)) { + // error + return NULL; + } } list = ucx_map_sstr_get(serverconf->objects, sstrn("Threadpool", 10)); UCX_FOREACH(UcxList*, list, elm) { - cfg_handle_threadpool(serverconfig, elm->data); + if(cfg_handle_threadpool(serverconfig, elm->data)) { + return NULL; + } } // check thread pool config if(check_thread_pool_cfg() != 0) { @@ -186,7 +192,11 @@ list = ucx_map_sstr_get(serverconf->objects, sstrn("EventHandler", 12)); UCX_FOREACH(UcxList*, list, elm) { - cfg_handle_eventhandler(serverconfig, (ServerConfigObject*)elm->data); + if(cfg_handle_eventhandler( + serverconfig, (ServerConfigObject*)elm->data)) { + // error + return NULL; + } } // check event handler config if(check_event_handler_cfg() != 0) { @@ -197,25 +207,33 @@ list = ucx_map_sstr_get(serverconf->objects, sstrn("AccessLog", 9)); UCX_FOREACH(UcxList*, list, elm) { ServerConfigObject *scfgobj = elm->data; - cfg_handle_accesslog(serverconfig, scfgobj); + if(cfg_handle_accesslog(serverconfig, scfgobj)) { + return NULL; + } } list = ucx_map_sstr_get(serverconf->objects, sstrn("AuthDB", 6)); UCX_FOREACH(UcxList*, list, elm) { ServerConfigObject *scfgobj = elm->data; - cfg_handle_authdb(serverconfig, scfgobj); + if(cfg_handle_authdb(serverconfig, scfgobj)) { + return NULL; + } } list = ucx_map_sstr_get(serverconf->objects, sstrn("Listener", 8)); UCX_FOREACH(UcxList*, list, elm) { ServerConfigObject *scfgobj = elm->data; - cfg_handle_listener(serverconfig, scfgobj); + if(cfg_handle_listener(serverconfig, scfgobj)) { + return NULL; + } } list = ucx_map_sstr_get(serverconf->objects, sstrn("VirtualServer", 13)); UCX_FOREACH(UcxList*, list, elm) { ServerConfigObject *scfgobj = elm->data; - cfg_handle_vs(serverconfig, scfgobj); + if(cfg_handle_vs(serverconfig, scfgobj)) { + return NULL; + } } @@ -261,12 +279,17 @@ } int cfg_handle_runtime(ServerConfiguration *cfg, ServerConfigObject *obj) { - cfg->user = sstrdup(cfg_directivelist_get_str( - obj->directives, - sstr("User"))); - cfg->tmp = sstrdup(cfg_directivelist_get_str( - obj->directives, - sstr("Temp"))); + sstr_t user = cfg_directivelist_get_str(obj->directives, sstr("User")); + if(user.ptr) { + cfg->user = sstrdup_pool(cfg->pool, user); + } + sstr_t tmp = cfg_directivelist_get_str(obj->directives, sstr("Temp")); + if(tmp.ptr) { + cfg->tmp = sstrdup_pool(cfg->pool, tmp); + } else { + log_ereport(LOG_MISCONFIG, "no temporary directory specified"); + return -1; + } // mime file sstr_t mf = cfg_directivelist_get_str(obj->directives, sstr("MimeFile")); @@ -400,9 +423,7 @@ evcfg.isdefault = util_getboolean(isdefault.ptr, 0); - int ret = create_event_handler(&evcfg); - - return ret; + return create_event_handler(&evcfg); } int cfg_handle_accesslog(ServerConfiguration *cfg, ServerConfigObject *obj) { diff -r 5bc6d078fb2c -r 6195c92262a2 src/server/daemon/vfs.c --- a/src/server/daemon/vfs.c Sun Jun 23 13:49:17 2013 +0200 +++ b/src/server/daemon/vfs.c Sun Jun 23 13:51:49 2013 +0200 @@ -292,8 +292,23 @@ } } - // open file + // open directory +#ifdef BSD DIR *sys_dir = opendir(path); + if(sys_dir) { + int dir_fd = dirfd(sys_dir); + } +#else + int dir_fd = open(path, O_RDONLY); + if(dir_fd == -1) { + if(ctx) { + ctx->vfs_errno = errno; + sys_set_error_status(ctx); + } + return NULL; + } + DIR *sys_dir = fdopendir(dir_fd); +#endif if(!sys_dir) { if(ctx) { ctx->vfs_errno = errno; @@ -310,7 +325,7 @@ } dir->ctx = ctx; dir->data = sys_dir; - dir->fd = dirfd(sys_dir); + dir->fd = dir_fd; dir->io = &sys_dir_io; return dir; } diff -r 5bc6d078fb2c -r 6195c92262a2 src/server/daemon/webserver.c --- a/src/server/daemon/webserver.c Sun Jun 23 13:49:17 2013 +0200 +++ b/src/server/daemon/webserver.c Sun Jun 23 13:51:49 2013 +0200 @@ -97,7 +97,31 @@ // set global vars conf_global_vars_s *vars = conf_getglobals(); + uid_t ws_uid = geteuid(); setpwent(); + char *pwbuf = malloc(DEF_PWBUF); + vars->Vuserpw = malloc(sizeof(struct passwd)); + if(cfg->user.ptr) { + if(!util_getpwnam(cfg->user.ptr, vars->Vuserpw, pwbuf, DEF_PWBUF)) { + log_ereport( + LOG_MISCONFIG, + "user %s does not exist!", + cfg->user.ptr); + free(vars->Vuserpw); + vars->Vuserpw = NULL; + } + } else { + if(!util_getpwuid(ws_uid, vars->Vuserpw, pwbuf, DEF_PWBUF)) { + log_ereport(LOG_FAILURE, "webserver_init: cannot get passwd data"); + free(vars->Vuserpw); + vars->Vuserpw = NULL; + } + } + free(pwbuf); + if(!vars->Vuserpw) { + log_ereport(LOG_WARN, "globalvars->Vuserpw is null"); + } + if(cfg->user.ptr) { char *pwbuf = malloc(DEF_PWBUF); vars->Vuserpw = malloc(sizeof(struct passwd)); @@ -116,7 +140,7 @@ } // change uid - if(vars->Vuserpw && geteuid() == 0) { + if(vars->Vuserpw && ws_uid == 0) { // a webserver user is set and we are root if(setgid(vars->Vuserpw->pw_gid) != 0) {