LINUX.ORG.RU

setuid() и членство в дополнительных группах


0

1

Данный код запускается на ubuntu 10.04 под рутом. Цель - открыть файл на чтение, притом, что владелец - другой пользователь www-data. Все это нужно для того, чтобы демон работал с данными, загружаемыми в Апач, под пользователем croco c uid 1000. Одного setuid( 1000 ) оказывается недостаточно. Список доп. групп после вызова setuid( 1000 ) содержит gid 0. Если пробовать установить доп. группы до вызова setuid(), файл открывается, но непонятно почему. Прошу объяснить, как установить доп. группы, и почему список групп не включает id 33, хотя неявно применяется.

int main(int argc, char **argv)
{
	gid_t grps[1024];
	grps[0] = 33; // gid of www-data
	if( !setgroups( 1, grps ) ) { puts( strerror( errno ) ); putchar( '\n'); }

	int gi = getgroups( 1024, grps );
	for( int i = 0; i < gi; ++i ) printf( "%d ", grps[gi] ); printf( "\n");

	setuid( 1000 ); // uid of croco

	gi = getgroups( 1024, grps );
	for( int i = 0; i < gi; ++i ) printf( "%d ", grps[gi] ); printf( "\n");

	FILE* f = fopen( "/home/croco/aab", "rb" );
	if( f ) { printf( "aab: OK\n" ); fclose( f ); } else { printf( "aab: failed\n" ); }

	return 0;
}

Кусочек /etc/group:

www-data:x:33:croco

root@uvis:~# stat /home/croco/aab
  File: `/home/croco/aab'
  Size: 8               Blocks: 8          IO Block: 4096   regular file
Device: 821h/2081d      Inode: 1311581     Links: 1
Access: (0660/-rw-rw----)  Uid: (   33/www-data)   Gid: (   33/www-data)
Access: 2011-10-13 13:02:15.654923606 +0400
Modify: 2011-10-13 13:02:12.854834259 +0400
Change: 2011-10-13 13:02:12.854834259 +0400
root@uvis:~# ./right_checker
Success

0
0
aab: OK

Заметим, что список дополнительных групп, возвращаемый getgroups, всегда содержит только группу 0.

Если закомментировать вызов setgroups(), то getgroups возвращает то же 0, но доступ к файлу aab невозможен.

root@uvis:~# ./right_checker
0
0
aab: failed

Будет информативнее, если эту строку заменить на нижнюю

for( int i = 0; i < gi; ++i ) printf( "%d ", grps[gi] ); printf( "\n");
for( int i = 0; i < gi; i++ ) printf( "%d ", grps[i] ); printf( "\n");

oleg_2
()
Ответ на: комментарий от oleg_2

Большое спасибо, слона как грится не приметил. :)

anymouse
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.