zeerd's blog         Search     Categories     Tags     Feed

闲来生雅趣,无事乐逍遥。对窗相望雪,一盏茶香飘。

Linux系统,在不真正添加用户的情况下进行文件系统权限管理

#FileSystem @Linux


Contents:
下面的程序在测试时需要以root权限运行:

首先,程序会以root权限创建一个目录和一个文件,并在文件中写入“Hello,world!”。

然后,用chmod函数对目录和文件进行权限设定(注意:系统中并不存在一个id为1010的账户),同时将目录和文件权限设置为仅有所有者可以读写。并尝试使用root权限进行读取。可以看到读取能够成功。

接下来,调用setegid/seteuid将可执行程序本身用户和组设置为不存在的1010,并验证可以正常读写。

再继续,将执行程序本身用户和组设置为另一个不存在的1011。因为之前设置过文件只有1010可以读写,所以这里的读写会失败。

最后,将执行程序本身用户和组设置为不存在的1011,但是通过setgroups函数将可执行文件加入到1010组中。同时设置目录和文件为同组可读写。结果是读写都可以成功。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
char* folder = argv[1];mkdir(folder, 0755);
char* file = NULL;asprintf(&file, "%s/test", folder);

/* create a single file with root right */
FILE *fp = fopen(file, "w");
if(fp != NULL) {
fprintf(fp, "Hello,world!\\n");
fclose(fp);
}

/* set the owner of those to a non-exist user-id and group-id */
chown(folder, 1010, 1010);
chown(file, 1010, 1010);
/* and set the owner could read and write it only */
chmod(folder, 0700);
chmod(file, 0600);

/* testing for the root user, root could read and write it as wish. */
fp = fopen(file, "r");
if(fp != NULL) {
char word[100] = "";
fscanf(fp, "%s", word);
printf("root read %s\\n", word);
fclose(fp);
} else {
perror("root read");
}

/* change the user-id and group-id of the executable-program-self to the
non-exist user-id and group-id */
/* maybe setuid()/setgid() were more safer here.
but we want to change the user-id and group-id again later, so use
seteuid()/setegid() here for this testing. */
setegid(1010);
seteuid(1010);

/* the reading and writing could be done as wish. */
fp = fopen(file, "r");
if(fp != NULL) {
char word[100] = "";
fscanf(fp, "%s", word);
printf("1010 read %s\\n", word);
fclose(fp);
} else {
perror("1010 read");
}

fp = fopen(file, "w");
if(fp != NULL) {
fprintf(fp, "Hello,again!\\n");
fclose(fp);
} else {
perror("1010 write");
}

fp = fopen(file, "r");
if(fp != NULL) {
char word[100] = "";
fscanf(fp, "%s", word);
printf("1010 read %s\\n", word);
fclose(fp);
} else {
perror("1010 read");
}

/* change the user-id and group-id of the executable-program-self to
another non-exist user-id and group-id */
setgid(0);
setuid(0);
setegid(1011);
seteuid(1011);

/* the reading and writing could not be done as wish. */
fp = fopen(file, "w");
if(fp != NULL) {
fprintf(fp, "Hello,third!\\n");
fclose(fp);
} else {
perror("1010 write");
}

fp = fopen(file, "r");
if(fp != NULL) {
char word[100] = "";
fscanf(fp, "%s", word);
printf("1011 read %s\\n", word);
fclose(fp);
} else {
perror("1011 read");
}

/* add the program to group 1010 */
setgid(0);
setuid(0);
const gid_t grps[]={1010};
setgroups(1, grps);
chmod(folder, 0770);
chmod(file, 0660);
setegid(1011);
seteuid(1011);

/* the reading and writing could be done as wish. */
fp = fopen(file, "w");
if(fp != NULL) {
fprintf(fp, "Hello,fourth!\\n");
fclose(fp);
} else {
perror("1010 write");
}

fp = fopen(file, "r");
if(fp != NULL) {
char word[100] = "";
fscanf(fp, "%s", word);
printf("1011 read %s\\n", word);
fclose(fp);
} else {
perror("1011 read");
}

free(file);

return 0;
}