Реклама:

info.krc.karelia.ru

win -:|:- koi -:|:- iso -:|:- dos -:|:- mac

Start -:|:- Проекты -:|:- О нас

Wrapper - первые шаги.

Что мы подразумеваем под словом wrapper? Под эти словом подразумевается программа, которая из себя вызывает другую или несколько. Для чего это нужно? Представьте себе ситуацию, с которой мне пришлось сталкнуться в моей организации. Начнем с того, что орга низация занимается разработкой программных продуктов и дизайном веб серверов. В нашей сети есть машины и под Linux и под Windows 95/NT и даже Mac. Многим (в связи со спецификой работы) нужен терминальный доступ к серверу. Было два варианта: поставить SSH или открыть 23 порт с нормальным шелом. Первый вариант не подходит - все сказали зачем нам дополнительный софт ставить, когда есть нормальный телнет. Мне же не подходил второй вариант, но 20 человек против одного, сами понимаете. Всех пользователей надо б ыло ограничить в доступе к определенным директориям, запретить просмотр системных файлв и т.д.
Как выйти из такой ситуации? Поставить последний bash с возможностью работать в restricted режиме? Тоже не подходит. Я давно слышал, что многие запускали NCSA HTTP Daemon из под этого самого wrapper-a. Тем самым, демон работал в своей собственной файловой системе. Это мне как раз и нужно. Работа началсь. Первым делом, надо создать свою собственную файловую систему. Я ее создал в /usr/ и назвал env. Далее, создал в этой директории такие же поддиректории, как и в корневой файловой системе:

 
$ ls -la /usr/env

total 10

drwxr-xr-x  10 root  wheel  512 Apr 18 17:49 .

drwxr-xr-x  19 root  wheel  512 Apr 18 16:08 ..

drwxr-xr-x   2 root  wheel  512 Apr 18 16:05 bin

drwxr-xr-x   2 root  wheel  512 Apr 17 19:47 dev

drwxr-xr-x   2 root  wheel  512 Apr 28 12:09 etc

drwxr-xr-x   4 root  wheel  512 Apr 18 16:08 home

drwxr-xr-x   2 root  wheel  512 Apr 18 16:05 sbin

drwxr-xr-x   2 root  wheel  512 Apr 17 19:48 tmp

drwxr-xr-x   6 root  wheel  512 Apr 18 16:05 usr

drwxr-xr-x   4 root  wheel  512 Apr 19 16:07 var

$

После чего в директорию /usr/env/usr/lib скопировал нужные библиотеки: 
$ ls -la /usr/env/usr/lib

total 6640

drwxr-xr-x  2 root  wheel     1024 Apr 19 16:10 .

drwxr-xr-x  6 root  wheel      512 Apr 18 16:05 ..

-r--r--r--  1 root  wheel  1040382 Apr 17 19:50 libc.a

-r--r--r--  1 root  wheel   512558 Apr 17 19:50 libc.so

-r--r--r--  1 root  wheel   512558 Apr 17 19:50 libc.so.3

-r--r--r--  1 root  wheel  1263628 Apr 17 19:50 libc_pic.a

-r--r--r--  1 root  wheel  1189452 Apr 17 19:50 libc_r.a

-r--r--r--  1 root  wheel   565215 Apr 17 19:50 libc_r.so

-r--r--r--  1 root  wheel   565215 Apr 17 19:50 libc_r.so.3

-r--r--r--  1 root  wheel     4004 Apr 17 19:50 libcalendar.a

-r--r--r--  1 root  wheel     4948 Apr 17 19:50 libcalendar.so

-r--r--r--  1 root  wheel     4948 Apr 17 19:50 libcalendar.so.2

-r--r--r--  1 root  wheel    51750 Apr 17 19:50 libcam.a

-r--r--r--  1 root  wheel    50156 Apr 17 19:50 libcam.so

-r--r--r--  1 root  wheel    50156 Apr 17 19:50 libcam.so.2

-r--r--r--  1 root  wheel     6358 Apr 17 19:50 libcom_err.a

-r--r--r--  1 root  wheel     5828 Apr 17 19:50 libcom_err.so

-r--r--r--  1 root  wheel     5828 Apr 17 19:50 libcom_err.so.2

-r--r--r--  1 root  wheel    30064 Apr 17 19:50 libcompat.a

-r--r--r--  1 root  wheel     6198 Apr 17 19:50 libcrypt.a

-r--r--r--  1 root  wheel     7607 Apr 17 19:50 libcrypt.so

-r--r--r--  1 root  wheel     7607 Apr 17 19:50 libcrypt.so.2

-r--r--r--  1 root  wheel    80084 Apr 17 19:50 libcurses.a

-r--r--r--  1 root  wheel    45964 Apr 17 19:50 libcurses.so

-r--r--r--  1 root  wheel    45964 Apr 17 19:50 libcurses.so.2

-r--r--r--  1 root  wheel   106908 Apr 19 16:10 libmytinfo.a

-r--r--r--  1 root  wheel    84057 Apr 19 16:10 libmytinfo.so

-r--r--r--  1 root  wheel    84057 Apr 19 16:10 libmytinfo.so.2

-r--r--r--  1 root  wheel   108778 Apr 19 16:10 libncurses.a

-r--r--r--  1 root  wheel    70059 Apr 19 16:10 libncurses.so

-r--r--r--  1 root  wheel    70059 Apr 19 16:10 libncurses.so.3

-r--r--r--  1 root  wheel    38852 Apr 17 20:08 libutil.a

-r--r--r--  1 root  wheel    30107 Apr 17 20:08 libutil.so

-r--r--r--  1 root  wheel    30107 Apr 17 20:08 libutil.so.2

$

Понятно, что можно скомпелировать нужные программы без того, чтобы   
они нуждались в этих библиотеках, но времени было мало и пришлось их
просто   скопировать. Далее, стоит подумать о том, какие программы 
стоит отдать   пользователям. Стандартный набор выглядит у меня примерно 
так: 
$ ls -la /usr/env/bin

total 1140

drwxr-xr-x   2 root  wheel     512 Apr 18 16:05 .

drwxr-xr-x  10 root  wheel     512 Apr 18 17:49 ..

-r-xr-xr-x   1 root  wheel   55296 Apr 18 15:00 cat

-r-xr-xr-x   1 root  wheel   58184 Apr 18 15:00 chmod

-r-xr-xr-x   1 root  wheel   60904 Apr 18 15:01 cp

-r-xr-xr-x   1 root  wheel  258328 Apr 18 14:55 csh

-r-xr-xr-x   1 root  wheel   43792 Apr 18 15:02 ln

-r-xr-xr-x   1 root  wheel  173432 Apr 18 14:57 ls

-r-xr-xr-x   1 root  wheel   46156 Apr 18 15:02 mkdir

-r-xr-xr-x   1 root  wheel  155768 Apr 18 15:03 mv

-r-xr-xr-x   1 root  wheel   51820 Apr 18 15:06 pwd

-r-xr-xr-x   1 root  wheel  158552 Apr 18 15:03 rm

-r-xr-xr-x   1 root  wheel   43208 Apr 18 15:04 rmdir

$

Можно еще что то положить и в sbin, но это уже не столь важно.   
Далее поговорим о содержимом etc. Что стоит туда класть? Если у Вас 
Linux, то   достаточно положить Файл паролей, где все пароли заменены 
звездочкой, делается   для того, чтобы ls показывал имя пользователя. 
И файл групп group и файл   termcap. Далее по вашему усмотрению. 
Отлично, файловая система создана,   приступаем к написанию wrapper-a. 
Вот код моего: 
#include 

#include 

#include 

#include 



void main( int argc, char *argv[] )

{

  uid_t uid;

  gid_t gid;

  char  *p, *home;

  struct passwd *wpass;



    p = "/usr/env";

    uid = getuid();

    gid = getgid();

    wpass = getpwuid(uid);

    home = wpass->pw_dir;



    if( chdir(p) )

    {

       fprintf(stderr, "chdir to %s failed\n", p );

    }

    else if( chroot(p) )

    {

       fprintf(stderr, "chroot to %s failed\n", p );

    }

    else if( setuid(uid) != 0 )

    {

       fprintf(stderr, "setuid failed\n" );

    }

    else if( setgid(gid) != 0 )

    {

       fprintf(stderr, "setuid failed\n" );

    }

    else if ( chdir(home) )

    {

       fprintf(stderr, "chdir to %s failed\n", home);

    }

    else

    {

      execl( "/bin/csh","csh",(char *)0 );

      fprintf(stderr, "execl failed for shell.\n");

    }

    exit(0);

}

Далее делаем: # gcc -o wrapper wrapper.c 
А потом копируем его в   /bin и делаем его chmod u+s /bin/wrapper После 
чего, чтобы никто другой не   ругался делаем:
echo /bin/wrapper >> /etc/shells 
Создадим пробного   пользователя с шелом /bin/wrapper. И попробуем войти 
телнетом на машину:   
FreeBSD/i386 (joshua) (ttyp1)



login: user120

Password: *****



Last login: Thu Apr 29 13:25:36 from invalid hostname

Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994

        The Regents of the University of California.  All rights reserved.



FreeBSD 3.0-RELEASE (GENERIC)



% ls -la



-rw-------   1 user120  users    518 Apr 16 14:22 mbox

lrwxr-xr-x   1 root    wheel     21 Apr 16 16:01 pub -> /var/ftp/users/user120

drwxr-xr-x   2 user120  users    512 Apr 16 16:00 www



% cd /

% ls -la



drwxr-xr-x  10 root  wheel  512 Apr 18 13:49 .

drwxr-xr-x  10 root  wheel  512 Apr 18 13:49 ..

drwxr-xr-x   2 root  wheel  512 Apr 18 12:05 bin

drwxr-xr-x   2 root  wheel  512 Apr 17 15:47 dev

drwxr-xr-x   2 root  wheel  512 Apr 28 08:09 etc

drwxr-xr-x   4 root  wheel  512 Apr 18 12:08 home

drwxr-xr-x   2 root  wheel  512 Apr 18 12:05 sbin

drwxr-xr-x   2 root  wheel  512 Apr 17 15:48 tmp

drwxr-xr-x   6 root  wheel  512 Apr 18 12:05 usr

drwxr-xr-x   4 root  wheel  512 Apr 19 12:07 var



%

Вот, теперь пользователь ничего не видит кроме того, что Вы ему   
разрешили видеть и использовать. 
А если хотите запустить демон в своей   файловой системе? Вот небольшая 
программа, которая сделает это: 
#include 

#include 



main(argc, argv)

int     argc;

char  **argv;

{

    char *path, *user, *cmd;

    struct passwd *pwd;



#ifdef LOG_DAEMON

    (void) openlog(argv[0], LOG_PID, LOG_DAEMON);

#else

    (void) openlog(argv[0], LOG_PID);

#endif



    path = "/usr/env";

    user = "root";

    cmd  = "/usr/local/sbin/proftpd";



    if (chdir(path)) {

	syslog(LOG_ERR, "chdir(%s): %m", path);

	return (0);

    }

    if ((pwd = getpwnam(user)) == 0) {

	syslog(LOG_ERR, "%s: user unknown", user);

	return (0);

    }

    /* Do the chroot() before giving away root privileges. */



    if (chroot(path)) {

	syslog(LOG_ERR, "chroot(%s): %m", argv[1]);

	return (0);

    }

    /* Switch group id then user id. */



    if (setgid(pwd->pw_gid)) {

	syslog(LOG_ERR, "setgid(%d): %m", pwd->pw_gid);

	return (0);

    }

    if (setuid(pwd->pw_uid)) {

	syslog(LOG_ERR, "setuid(%d): %m", pwd->pw_uid);

	return (0);

    }

    endpwent();

    (void) execvp(cmd, argv);

    syslog(LOG_ERR, "%s: %m", argv[1]);

    return (0);

}

(c) Алексей Александров12.05.1999.

 

Rambler's Top100 Service Яндекс цитирования