The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

[Apache] Патч для suexec - rlimits и root-owned скрипты (patch apache limit)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: patch, apache, limit,  (найти похожие документы)
From: Dmitry Morozovsky <marck@rinet.ru> Subject: [Apache] Патч для suexec - rlimits и root-owned скрипты --- suexec.c.orig Sun Oct 28 17:48:52 2001 +++ suexec.c Wed Dec 12 19:50:18 2001 @@ -69,6 +69,12 @@ * *********************************************************************** * + * Minor modifications for setting rlimits and allow root-owned scripts + * to be executed have been done by Oleg Bulyzhin <oleg@rinet.ru> and + * Dmitry Morozovsky <marck@rinet.ru> + * + *********************************************************************** + * * * Error messages in the suexec logfile are prefixed with severity values * similar to those used by the main server: @@ -93,6 +99,14 @@ #include "suexec.h" +/* +OB: we need it later */ +#include <sys/time.h> +#include <sys/resource.h> +#include <login_cap.h> +#include <grp.h> +/* -OB */ + + /* *********************************************************************** * There is no initgroups() in QNX, so I believe this is safe :-) @@ -280,6 +294,30 @@ struct stat dir_info; /* directory info holder */ struct stat prg_info; /* program info holder */ + /* +OB: we need it later */ + login_cap_t *lc = NULL; + char capnam[128]; + rlim_t capval; + struct rlimit limit[RLIM_NLIMITS]; + int i, rc; + struct { + const char *cap; + rlim_t (*func)(login_cap_t *, const char *, rlim_t, rlim_t); + } resources[] = { + { "cputime", login_getcaptime }, + { "filesize", login_getcapsize }, + { "datasize", login_getcapsize }, + { "stacksize", login_getcapsize }, + { "coredumpsize", login_getcapsize }, + { "memoryuse", login_getcapsize }, + { "memorylocked", login_getcapsize }, + { "maxproc", login_getcapnum }, + { "openfiles", login_getcapnum }, + /* DM: we need it since 4.x, also make finish entry */ + { "sbsize", login_getcapnum }, + { NULL, NULL } + }; + prog = argv[0]; /* * Check existence/validity of the UID of the user @@ -444,14 +482,48 @@ actual_uname = strdup(pw->pw_name); target_homedir = strdup(pw->pw_dir); + /* +OB: get login class name */ + if ((lc = login_getpwclass(pw)) == NULL) { + log_err("emerg: cant get login class (%ld: %s)\n", uid, cmd); + exit(127); + } + /* if user has no class in passwd entry + * trying to get "group" class - class + * with name identical to group name + */ + if (strncmp(lc->lc_class, "default", 7) == 0) { + if ((gr = getgrgid(pw->pw_gid)) == NULL) { /* getting group */ + log_err("emerg: getgrgid failed (%ld: %s)\n", uid, cmd); + exit(127); + } + /* looking for class for this group */ + if ((lc = login_getclass(gr->gr_name)) == NULL) { + log_err("emerg: cant get login class (%ld: %s)\n", uid, cmd); + exit(127); + } + } + /* -OB */ + /* * Log the transaction here to be sure we have an open log * before we setuid(). */ + + /* +OB */ + /* Original log_err call log_err("info: (target/actual) uid: (%s/%s) gid: (%s/%s) cmd: %s\n", target_uname, actual_uname, target_gname, actual_gname, cmd); + */ + + /* My log_err call */ + log_err("info: (target/actual) class: (%s) uid: (%s/%s) gid: (%s/%s) cmd: %s\n", + lc->lc_class, + target_uname, actual_uname, + target_gname, actual_gname, + cmd); + /* -OB */ /* * Error out if attempt is made to execute as root or as @@ -482,6 +554,39 @@ exit(109); } + /* +OB: * set up limits */ + for (rc = 0, i = 0; i < RLIM_NLIMITS; i++) { /* init with current values */ + if (getrlimit(i, &limit[i]) == -1) { + rc = 1; + log_err("emerg: getrlimit i = %u (%ld: %s)\n", i, uid, cmd); + } + } + if (rc) exit(127); + + for (i = 0; i < RLIM_NLIMITS && resources[i].cap; i++) { + + sprintf(capnam, "%s-cur", resources[i].cap); + capval = resources[i].func(lc, resources[i].cap, limit[i].rlim_cur, + limit[i].rlim_cur); + limit[i].rlim_cur = resources[i].func(lc, capnam, capval, capval); + + sprintf(capnam, "%s-max", resources[i].cap); + capval = resources[i].func(lc, resources[i].cap, limit[i].rlim_max, + limit[i].rlim_max); + limit[i].rlim_max = resources[i].func(lc, capnam, capval, capval); + + } + /* set up calculated limits */ + for (rc = 0, i = 0; i < RLIM_NLIMITS && resources[i].cap; i++) { + if (setrlimit(i, &limit[i]) == -1) { + rc = 1; + log_err("emerg: setrlimit i = %u (%ld: %s)\n", i, uid, cmd); + } + } + if (rc) exit(127); + login_close(lc); + /* -OB */ + /* * setuid() to the target user. Error out on fail. */ @@ -571,10 +676,14 @@ * Error out if the target name/group is different from * the name/group of the cwd or the program. */ + /* +DM: allow also well-formed root-owned scripts to run + (for hardlinked common scripts) + */ + if ((uid != dir_info.st_uid) || (gid != dir_info.st_gid) || - (uid != prg_info.st_uid) || - (gid != prg_info.st_gid)) { + (uid != prg_info.st_uid && prg_info.st_uid != 0) || + (gid != prg_info.st_gid && prg_info.st_gid != 0)) { log_err("error: target uid/gid (%ld/%ld) mismatch " "with directory (%ld/%ld) or program (%ld/%ld)\n", uid, gid, @@ -582,6 +691,13 @@ prg_info.st_uid, prg_info.st_gid); exit(120); } + if (prg_info.st_uid == 0) + log_err("notice: [%u] running script is root-owned (%s/%s)\n", + getpid(), cwd, cmd); + else if (prg_info.st_gid == 0) + log_err("notice: [%u] running script is wheel-owned (%s/%s)\n", + getpid(), cwd, cmd); + /* * Error out if the program is not executable for the user. * Otherwise, she won't find any error in the logs except for

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий
Имя:
E-Mail:
Заголовок:
Текст:




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру