The OpenNET Project / Index page

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

Возможность запускать скрипты принадлежащие руту из suexec (limit apache patch suexec)


<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: limit, apache, patch, suexec,  (найти похожие документы)
Date: Wed, 8 Nov 2000 22:54:26 +0300 (MSK) From: Dmitry Morozovsky <marck@rinet.ru> Subject: Возможность запускать скрипты принадлежащие руту из suexec Приветствую, коллеги. Мы вот тут заимплементили странного, а именно фиксацию лимитов для суэкзеченных скриптов (плюс добывание класса пользователя, или взятие его их группы, если у него нет explicit класса) Кроме того, после тяжкого раздумья была-таки сделана модификация, позволяющая пускать скрипты, принадлежащие руту (благо проверка на правильные права все равно делается) Все крайне непортабельно, у нас работает под FreeBSD 3.x и 4.x :) Портинг категорически приветствуется. Если вы что-нибудь с этим сделаете, напишите об этом мне и Олегу (стоит в CC:) Конструктивная ругань тоже приветствуется, разумеется ;) Sincerely, D.Marck [DM5020, DM268-RIPE, DM3-RIPN] ------------------------------------------------------------------------ *** Dmitry Morozovsky --- D.Marck --- Wild Woozle --- marck@rinet.ru *** ------------------------------------------------------------------------ --- suexec.c.ru Wed Nov 8 22:45:34 2000 +++ suexec.c.new Wed Nov 8 22:47:50 2000 @@ -68,6 +68,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: @@ -88,6 +94,13 @@ #include <sys/stat.h> #include <sys/types.h> +/* +OB: we need it later */ +#include <sys/time.h> +#include <sys/resource.h> +#include <login_cap.h> +#include <grp.h> +/* -OB */ + #include <stdarg.h> #include "suexec.h" @@ -279,6 +292,32 @@ 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 } + }; + + /* -OB */ + /* * If there are a proper number of arguments, set * all of them to variables. Otherwise, error out. @@ -404,14 +443,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 @@ -443,6 +516,44 @@ } /* + * +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); + + } + + for (rc = 0, i = 0; i < RLIM_NLIMITS && resources[i].cap; i++) { /* set up calculated limits */ + 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. */ if ((setuid(uid)) != 0) { @@ -450,6 +561,7 @@ exit(110); } + /* * Get the current working directory, as well as the proper * document root (dependant upon whether or not it is a @@ -531,9 +643,12 @@ * 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) || + (uid != prg_info.st_uid && prg_info.st_uid != 0) || (gid != prg_info.st_gid)) { log_err("error: target uid/gid (%ld/%ld) mismatch " "with directory (%ld/%ld) or program (%ld/%ld)\n", @@ -542,6 +657,9 @@ 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); /* * Error out if the program is not executable for the user. * Otherwise, she won't find any error in the logs except for
= Apache-Talk@lists.lexa.ru mailing list = Mail "unsubscribe apache-talk" to majordomo@lists.lexa.ru if you want to quit. = Archive avaliable at http://www.lexa.ru/apache-talk =

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

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




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

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