Данный код запускается на 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