Sat, 22 Jun 2013 13:54:41 +0200
added file system ACLs for linux
--- a/src/server/daemon/acl.c Sat Jun 22 13:08:36 2013 +0200 +++ b/src/server/daemon/acl.c Sat Jun 22 13:54:41 2013 +0200 @@ -28,10 +28,12 @@ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #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 <sys/fsuid.h> + +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
--- a/src/server/daemon/acl.h Sat Jun 22 13:08:36 2013 +0200 +++ b/src/server/daemon/acl.h Sat Jun 22 13:54:41 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 }
--- a/src/server/daemon/webserver.c Sat Jun 22 13:08:36 2013 +0200 +++ b/src/server/daemon/webserver.c Sat Jun 22 13:54:41 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) {