|  | // SPDX-License-Identifier: GPL-2.0+ | 
|  | /* | 
|  | *   Copyright (c) International Business Machines  Corp., 2000 | 
|  | */ | 
|  |  | 
|  | /* | 
|  | *  FILE(s)     : fs_perms.c simpletest.sh textx.o Makefile README | 
|  | *  DESCRIPTION : Regression test for Linux filesystem permissions. | 
|  | *  AUTHOR      : Jeff Martin (martinjn@us.ibm.com) | 
|  | *  HISTORY     : | 
|  | *     (04/12/01)v.99  First attempt at using C for fs-regression test.  Only tests read and write bits. | 
|  | *     (04/19/01)v1.0  Added test for execute bit. | 
|  | *     (05/23/01)v1.1  Added command line parameter to specify test file. | 
|  | *     (07/12/01)v1.2  Removed conf file and went to command line parameters. | 
|  | * | 
|  | */ | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include <string.h> | 
|  | #include <ctype.h> | 
|  | #include <sys/stat.h> | 
|  | #include <sys/types.h> | 
|  | #include <stdlib.h> | 
|  | #include <unistd.h> | 
|  | #include <sys/wait.h> | 
|  | #include <time.h> | 
|  | #include <utime.h> | 
|  |  | 
|  | int testsetup(mode_t mode, int cuserId, int cgroupId); | 
|  | int testfperm(int userId, int groupId, char* fperm); | 
|  |  | 
|  | int main( int argc, char *argv[]) { | 
|  | char *fperm; | 
|  | int result, exresult=0,  cuserId=0, cgroupId=0, userId=0, groupId=0; | 
|  | mode_t mode; | 
|  |  | 
|  | switch (argc) { | 
|  | case 8: | 
|  | mode = strtol(argv[1],(char**)NULL,010); | 
|  | cuserId = atoi(argv[2]); | 
|  | cgroupId = atoi(argv[3]); | 
|  | userId = atoi(argv[4]); | 
|  | groupId = atoi(argv[5]); | 
|  | fperm = argv[6]; | 
|  | exresult = atoi(argv[7]); | 
|  | break; | 
|  | default: | 
|  | printf("Usage: %s <mode of file> <UID of file> <GID of file> <UID of tester> <GID of tester> <permission to test r|w|x|t|T> <expected result as 0|1>\n",argv[0]); | 
|  | exit(0); | 
|  | } | 
|  |  | 
|  | testsetup(mode,cuserId,cgroupId); | 
|  | result=testfperm(userId,groupId,fperm); | 
|  | system("rm -f test.file"); | 
|  | printf("%s a %03o file owned by (%d/%d) as user/group(%d/%d)  ",fperm,mode,cuserId,cgroupId,userId,groupId); | 
|  | if (result == exresult) { | 
|  | printf("PASS\n"); | 
|  | exit(0); | 
|  | } | 
|  | else { | 
|  | printf("FAIL\n"); | 
|  | exit(1); | 
|  | } | 
|  | } | 
|  |  | 
|  | int testsetup(mode_t mode, int cuserId, int cgroupId) { | 
|  | system("cp testx.file test.file"); | 
|  | chmod("test.file",mode); | 
|  | chown("test.file",cuserId,cgroupId); | 
|  | return(0); | 
|  | } | 
|  |  | 
|  | int testfperm(int userId, int groupId, char* fperm) { | 
|  |  | 
|  | int ret; | 
|  |  | 
|  | /*  SET CURRENT USER/GROUP PERMISSIONS */ | 
|  | ret = -1; | 
|  | if(setegid(groupId)) { | 
|  | printf("could not setegid to %d.\n",groupId); | 
|  | goto out; | 
|  | } | 
|  | if(seteuid(userId)) { | 
|  | printf("could not seteuid to %d.\n",userId); | 
|  | goto out; | 
|  | } | 
|  |  | 
|  | if (!strcmp("x", fperm)) { | 
|  | int status; | 
|  | pid_t pid; | 
|  |  | 
|  | pid = fork(); | 
|  | if (pid == 0) { | 
|  | execlp("./test.file","test.file",NULL); | 
|  | exit(0); | 
|  | } | 
|  | wait(&status); | 
|  | ret = WEXITSTATUS(status); | 
|  | } else if (!strcmp("t", fperm)) { | 
|  | ret = utime("test.file", NULL) ? 0 : 1; | 
|  | } else if (!strcmp("T", fperm)) { | 
|  | time_t now = time(NULL); | 
|  | struct utimbuf times = { | 
|  | .actime = now - 1, | 
|  | .modtime = now - 1 | 
|  | }; | 
|  |  | 
|  | ret = utime("test.file", ×) ? 0 : 1; | 
|  | } else { | 
|  | FILE *file; | 
|  |  | 
|  | if((file = fopen("test.file",fperm))){ | 
|  | fclose(file); | 
|  | ret = 1; | 
|  | goto out; | 
|  | } else { | 
|  | ret = 0; | 
|  | goto out; | 
|  | } | 
|  | } | 
|  |  | 
|  | out: | 
|  | seteuid(0); | 
|  | setegid(0); | 
|  | return ret; | 
|  | } |