1/* 2 * Aurélien Charbon - Bull SA 3 * ACL testing basic program 4 * Purpose: setting an acl on a file a verifies that the accesses are right 5 */ 6 7#include <sys/param.h> 8 9#include <stdlib.h> 10#include <sys/types.h> 11#include <sys/time.h> 12#include <sys/stat.h> 13#include <stdio.h> 14#include <string.h> 15#include <dirent.h> 16#include <unistd.h> 17#include <errno.h> 18 19#include "config.h" 20#include "tst_res_flags.h" 21 22#ifdef HAVE_LIBACL 23 24#include <sys/acl.h> 25 26#define OP_READ 0x1 27#define OP_WRITE 0x2 28#define OP_EXEC 0x4 29 30acl_t testacl; 31/* the "typical" acl used for the test */ 32 33static char *permtab[] = 34 { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" }; 35 36struct statstore { 37 /* number of passed tests */ 38 int ok; 39 /* number of failed tests */ 40 int failed; 41} aclstat; 42 43int do_file_op(char *filename) 44{ 45 int exe; 46 int result; 47 uid_t uid; 48 result = 0; 49 FILE *fptr; 50 char str[256] = "./"; 51 52 uid = geteuid(); 53 strcat(str, filename); 54 55 exe = execl(str, NULL, NULL); 56 if (exe == -1 && errno != EACCES) 57 result = result + OP_EXEC; 58 59 fptr = fopen(filename, "r"); 60 if (fptr != NULL) { 61 result = result + OP_READ; 62 fclose(fptr); 63 } 64 65 fptr = fopen(filename, "r+"); 66 if (fptr != NULL) { 67 result = result + OP_WRITE; 68 fclose(fptr); 69 } 70 71 return result; 72} 73 74/* acl with user entries used for the test */ 75acl_t test_acl_user_create(void) 76{ 77 char acl_text[] = 78 "u::rwx,u:user1:rwx,u:user2:rw-,u:user3:r--,u:user4:r-x,u:user5:---,g::r-x,o::r-x,m::rwx"; 79 acl_t acl; 80 acl = acl_from_text(acl_text); 81 return acl; 82} 83 84/* acl with group entries used for the test */ 85 86acl_t test_acl_grp_create(void) 87{ 88 char acl_text[] = 89 "u::rwx,g:grp1:rwx,g:grp2:rw-,g:grp3:r--,g:grp4:r-x,g:grp5:---,g::---,o::r-x,m::rwx"; 90 acl_t acl; 91 acl = acl_from_text(acl_text); 92 return acl; 93} 94 95acl_t test_acl_default_create(void) 96{ 97 char acl_text[] = 98 "u::rwx,u:user1:rwx,u:user2:rw-,u:user3:r--,u:user4:r-x,u:user5:---,g::r-x,m::rwx,o::r-x"; 99 acl_t acl; 100 acl = acl_from_text(acl_text); 101 return acl; 102} 103 104static void report(testnum, expected, result, fail) 105int testnum; /* test number */ 106int expected; /* expected result */ 107int result; /* actual result */ 108int fail; /* fail or warning */ 109{ 110 char *res; 111 if (expected == result) { 112 res = "[OK]"; 113 aclstat.ok++; 114 } else { 115 res = "[FAILED]"; 116 aclstat.failed++; 117 } 118 printf("\ttest #%d - Expected: %s - Obtained: %s - %s\n", testnum, 119 permtab[expected], permtab[result], res); 120 121 fflush(stdout); 122} 123 124/* 125 * set acl in order the file is only readable for the testuser 126 * - try to read 127 * - try to write 128 */ 129static void test1(char *file) 130{ 131 int result; 132 if (seteuid((uid_t) 601) == 0) { 133 result = do_file_op(file); 134 /* expected result = OP_READ || OP_WRITE || OP_EXEC */ 135 report(1, OP_READ + OP_WRITE + OP_EXEC, result); 136 seteuid((uid_t) 0); 137 setegid((gid_t) 0); 138 } 139} 140 141/* 142 * set acl in order the file is only readable for the testgroup 143 * - try to read with test user 144 * - try to write with test user 145 * 146 */ 147 148static void test2(char *file) 149{ 150 int result; 151 if (seteuid((uid_t) 602) == 0) { 152 result = do_file_op(file); 153 /* expected result = OP_READ || OP_WRITE */ 154 report(2, OP_READ + OP_WRITE, result); 155 seteuid((uid_t) 0); 156 } 157} 158 159/* 160 * set acl in order the file is only readable for the testuser 161 * - try to read 162 * - try to write 163 */ 164 165static void test3(char *file) 166{ 167 int result; 168 if (seteuid((uid_t) 603) == 0) { 169 result = do_file_op(file); 170 /* expected result = OP_READ */ 171 report(3, OP_READ, result); 172 seteuid((uid_t) 0); 173 } 174} 175 176/* 177 * set read-write acl on the file for the testuser 178 * - try to read 179 * - try to write 180 */ 181 182static void test4(char *file) 183{ 184 int result; 185 if (seteuid((uid_t) 604) == 0) { 186 result = do_file_op(file); 187 /* expected result = OP_READ || OP_EXEC */ 188 report(4, OP_READ + OP_EXEC, result); 189 seteuid((uid_t) 0); 190 } 191} 192 193static void test5(char *file) 194{ 195 int result; 196 if (seteuid((uid_t) 605) == 0) { 197 result = do_file_op(file); 198 /* expected result = 0x0 */ 199 report(5, 0x00, result); 200 seteuid((uid_t) 0); 201 } 202} 203 204static void testgrp1(char *file) 205{ 206 int result; 207 if (setegid((gid_t) 601) == 0) { 208 if (seteuid((uid_t) 601) == 0) { 209 result = do_file_op(file); 210 /* expected result = OP_READ || OP_WRITE || OP_EXEC */ 211 report(1, OP_READ + OP_WRITE + OP_EXEC, result); 212 seteuid((uid_t) 0); 213 setegid((gid_t) 0); 214 } 215 } 216} 217 218/* 219 * set acl in order the file is only readable for the testgroup 220 * - try to read with test user 221 * - try to write with test user 222 * 223 */ 224 225static void testgrp2(char *file) 226{ 227 int result; 228 if ((setegid((gid_t) 602) == 0) && (seteuid((uid_t) 602) == 0)) { 229 result = do_file_op(file); 230 /* expected result = OP_READ || OP_WRITE */ 231 report(2, OP_READ + OP_WRITE, result); 232 seteuid((uid_t) 0); 233 setegid((gid_t) 0); 234 } 235} 236 237/* 238 * set acl in order the file is only readable for the testuser 239 * - try to read 240 * - try to write 241 */ 242 243static void testgrp3(char *file) 244{ 245 int result; 246 if ((setegid((gid_t) 603) == 0) && (seteuid((uid_t) 603) == 0)) { 247 result = do_file_op(file); 248 /* expected result = OP_READ */ 249 report(3, OP_READ, result); 250 seteuid((uid_t) 0); 251 setegid((gid_t) 0); 252 } 253} 254 255/* 256 * set read-write acl on the file for the testuser 257 * - try to read 258 * - try to write 259 */ 260 261static void testgrp4(char *file) 262{ 263 int result; 264 if (setegid((gid_t) 604) == 0) { 265 if (seteuid((uid_t) 604) == 0) 266 result = do_file_op(file); 267 /* expected result = OP_READ || OP_EXEC */ 268 report(4, OP_READ + OP_EXEC, result); 269 seteuid((uid_t) 0); 270 setegid((gid_t) 0); 271 } 272} 273 274static void testgrp5(char *file) 275{ 276 int result; 277 if (setegid((gid_t) 605) == 0) { 278 if (seteuid((uid_t) 605) == 0) 279 result = do_file_op(file); 280 /* expected result = 0x0 */ 281 report(5, 0x00, result); 282 seteuid((uid_t) 0); 283 setegid((gid_t) 0); 284 } 285} 286 287/* testing default acl */ 288void test_acl_default(char *dir, acl_t acl) 289{ 290 /* set default acl on directory */ 291 /* create a file in this directory */ 292 /* compare the file's acl and the parent directory's one */ 293 int res; 294 acl_t acl1, acl2; 295 296 res = acl_set_file(dir, ACL_TYPE_DEFAULT, acl); 297 acl1 = acl_get_file(dir, ACL_TYPE_DEFAULT); 298 if (res == -1) 299 printf("path = %s **** errno = %d", dir, errno); 300 char *path = strcat(dir, "/testfile"); 301 fopen(path, "w+"); 302 char *cmd = malloc(256); 303 304 strcpy(cmd, "chmod 7777 "); 305 printf(cmd, NULL); 306 strcat(cmd, dir); 307 system(cmd); 308 acl2 = acl_get_file(path, ACL_TYPE_ACCESS); 309 310 test1(path); 311 test2(path); 312 test3(path); 313 test4(path); 314 test5(path); 315} 316 317static void showstats(void) 318{ 319 printf("\nACL TESTS RESULTS: %d passed, %d failed\n\n", aclstat.ok, 320 aclstat.failed); 321} 322 323int main(int argc, char *argv[]) 324{ 325 int result; 326 aclstat.ok = 0; 327 aclstat.failed = 0; 328 acl_t testacl; 329 printf("Test acl with entries on users\n"); 330 testacl = test_acl_user_create(); 331 332 /* set the right acl for the test */ 333 result = acl_set_file(argv[1], ACL_TYPE_ACCESS, testacl); 334 if (result == -1) { 335 printf("setting acl on file %s failed\nBad NFS configuration", 336 argv[1]); 337 exit(1); 338 } 339 test1(argv[1]); 340 test2(argv[1]); 341 test3(argv[1]); 342 test4(argv[1]); 343 test5(argv[1]); 344 acl_free(testacl); 345 printf("\nTest of default acl:\n"); 346 347 testacl = test_acl_default_create(); 348 test_acl_default(argv[2], testacl); 349 350 printf("\nTest acl with entries concerning groups\n"); 351 testacl = test_acl_grp_create(); 352 result = acl_set_file(argv[1], ACL_TYPE_ACCESS, testacl); 353 if (result == -1) 354 printf("setting acl on file %s failed\n", argv[1]); 355 356 testgrp1(argv[1]); 357 testgrp2(argv[1]); 358 testgrp3(argv[1]); 359 testgrp4(argv[1]); 360 testgrp5(argv[1]); 361 362 acl_free(testacl); 363 364 showstats(); 365 return 1; 366} 367#else 368int main(void) 369{ 370 printf("The acl library was missing upon compilation.\n"); 371 return TCONF; 372} 373#endif /* HAVE_LIBACL */ 374