1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /* Open operation C testcase */
  28 
  29 #include "nfsgen.h"
  30 
  31 /* Functions */
  32 int scenarioA(int mode, int oflag, int expect[]);
  33 int scenarioB(int mode, int oflag, int expect[]);
  34 int scenarioC(int mode, int oflag, int expect[]);
  35 int scenarioD(int mode, int oflag, int expect[]);
  36 int scenarioE(int mode, int oflag, int expect[]);
  37 
  38 /* Globals */
  39 
  40 static char *filename = NULL;
  41 char    *buf = NULL;
  42 
  43 /*
  44  * Main test loop.
  45  */
  46 
  47 int
  48 main(int argc, char **argv)
  49 {
  50         int             i, j;
  51         int             ret = OK;
  52         char            *deleg, *scen, *mode_index, *oflag_index;
  53         static int      mode_set[] = {0600, 0400, 0200, 000},
  54                         mode_setC[] = {0660, 0600, 0440, 0400, 0220, 0200,
  55                                         000},
  56                         oflag_set[] = {O_EXCL|O_RDWR, O_RDWR, O_WRONLY,
  57                                         O_RDONLY};
  58         static int      expectA[4][4][4] =
  59         {
  60         {       {OK,            OK,     OK,     OK},
  61                 {OK,            OK,     OK,     OK},
  62                 {OK,            OK,     EBADF,  OK},
  63                 {OK,            OK,     OK,     EBADF}},
  64         {       {EACCES,        EBADF,  EBADF,  EBADF},
  65                 {EACCES,        EBADF,  EBADF,  EBADF},
  66                 {EACCES,        EBADF,  EBADF,  EBADF},
  67                 {OK,            OK,     OK,     EBADF}},
  68         {       {EACCES,        EBADF,  EBADF,  EBADF},
  69                 {EACCES,        EBADF,  EBADF,  EBADF},
  70                 {OK,            OK,     EBADF,  OK},
  71                 {EACCES,        EBADF,  EBADF,  EBADF}},
  72         {       {EACCES,        EBADF,  EBADF,  EBADF},
  73                 {EACCES,        EBADF,  EBADF,  EBADF},
  74                 {EACCES,        EBADF,  EBADF,  EBADF},
  75                 {EACCES,        EBADF,  EBADF,  EBADF}}
  76         };
  77 
  78         static int      expectB[4][4][4] =
  79         {
  80         {       {OK,            OK,     OK,     OK},
  81                 {OK,            OK,     OK,     OK},
  82                 {OK,            OK,     EBADF,  OK},
  83                 {OK,            OK,     OK,     EBADF}},
  84         {       {EACCES,        EBADF,  EBADF,  EBADF},
  85                 {EACCES,        EBADF,  EBADF,  EBADF},
  86                 {EACCES,        EBADF,  EBADF,  EBADF},
  87                 {OK,            OK,     OK,     EBADF}},
  88         {       {EACCES,        EBADF,  EBADF,  EBADF},
  89                 {EACCES,        EBADF,  EBADF,  EBADF},
  90                 {OK,            OK,     EBADF,  OK},
  91                 {EACCES,        EBADF,  EBADF,  EBADF}},
  92         {       {EACCES,        EBADF,  EBADF,  EBADF},
  93                 {EACCES,        EBADF,  EBADF,  EBADF},
  94                 {EACCES,        EBADF,  EBADF,  EBADF},
  95                 {EACCES,        EBADF,  EBADF,  EBADF}}
  96         };
  97 
  98         static int      expectC[7][4][6] =
  99         {
 100         {       {OK,            OK,     OK,     OK,     OK,     OK},
 101                 {OK,            OK,     OK,     OK,     OK,     OK},
 102                 {OK,            OK,     EBADF,  OK,     EBADF,  OK},
 103                 {OK,            OK,     OK,     EBADF,  OK,     EBADF}},
 104         {       {OK,            OK,     OK,     OK,     EBADF,  EBADF},
 105                 {OK,            OK,     OK,     OK,     EBADF,  EBADF},
 106                 {OK,            OK,     EBADF,  OK,     EBADF,  EBADF},
 107                 {OK,            OK,     OK,     EBADF,  EBADF,  EBADF}},
 108         {       {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 109                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 110                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 111                 {OK,            OK,     OK,     EBADF,  OK,     EBADF}},
 112         {       {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 113                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 114                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 115                 {OK,            OK,     OK,     EBADF,  EBADF,  EBADF}},
 116         {       {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 117                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 118                 {OK,            OK,     EBADF,  OK,     EBADF,  OK},
 119                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF}},
 120         {       {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 121                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 122                 {OK,            OK,     EBADF,  OK,     EBADF,  EBADF},
 123                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF}},
 124         {       {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 125                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 126                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF},
 127                 {EACCES,        EBADF,  EBADF,  EBADF,  EBADF,  EBADF}}
 128         };
 129 
 130         if ((buf = malloc(256)) == NULL) {
 131                 perror("main()- malloc() for buf");
 132                 return (NOOK);
 133         }
 134 
 135         parse_args(argc, argv);
 136 
 137         filename = lfilename;
 138 
 139         dprint("Try to remove test files, to avoid errors.\n");
 140         unlink_file(filename);
 141         unlink_file("olinkfile.txt");
 142 
 143         /* modify name to include delgation policy */
 144         if ((deleg = getenv("DELG")) != NULL) {
 145                 if (strcasecmp(deleg, "on") == 0) {
 146                         strcat(Testname, "_Deleg");
 147                 }
 148                 if (strcasecmp(deleg, "off") == 0) {
 149                         strcat(Testname, "_NoDeleg");
 150                 }
 151         }
 152 
 153         scen = getenv("SCENARIO");
 154         if (!scen) {
 155                 printf("The scenario was not specified");
 156                 return (NOOK);
 157         }
 158 
 159         if ((mode_index = getenv("MODE_INDEX")) != NULL) {
 160                 i = atoi(mode_index);
 161                 if ((i > 3) && (strcmp(scen, "C") != 0)) {
 162                         printf("The mode index(%d) is more than 3 "\
 163                             "with scenario %s", i, scen);
 164                         return (NOOK);
 165                 } else if (i > 6) {
 166                         printf("The mode index(%d) is more than 6 "\
 167                             "with scenario %s", i, scen);
 168                         return (NOOK);
 169                 }
 170         }
 171 
 172         if ((oflag_index = getenv("OFLAG_INDEX")) != NULL) {
 173                 j = atoi(oflag_index);
 174                 if (j > 3) {
 175                         printf("The oflag index(%d) is more than 3 "\
 176                             "with scenario %s", i, scen);
 177                         return (NOOK);
 178                 }
 179         }
 180 
 181         /* run tests */
 182         switch (*scen) {
 183         case 'A':
 184                 ret = scenarioA(mode_set[i], oflag_set[j], expectA[i][j]);
 185                 break;
 186         case 'B':
 187                 ret = scenarioB(mode_set[i], oflag_set[j], expectB[i][j]);
 188                 break;
 189         case 'C':
 190                 ret = scenarioC(mode_setC[i], oflag_set[j], expectC[i][j]);
 191                 break;
 192         case 'D':
 193                 ret = scenarioD(mode_set[i], oflag_set[j], NULL);
 194                 break;
 195         case 'E':
 196                 ret = scenarioE(0755, O_TRUNC, OK);
 197                 break;
 198         default:
 199                 printf("Set invalid scenario(%s)", scen);
 200                 return (NOOK);
 201         }
 202 
 203         if (buf != NULL)
 204                 free(buf);
 205         if (GLOBdata != NULL)
 206                 free(GLOBdata);
 207 
 208         exit_test(ret);
 209         return (ret);    /* unreachable, used to quiet lint */
 210 }
 211 
 212 int
 213 scenarioA(int mode, int oflag, int expect[])
 214 {
 215         int fd1, fd2;
 216         char *DD;
 217         int ret = OK;
 218 
 219         scen = "ScenA";
 220         scen_mode = mode;
 221         scen_flag = oflag;
 222         expecterr = expect[0];
 223 
 224         fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and "\
 225             "oflag = %s\n\n", mode, oflagstr(oflag));
 226 
 227         DD = strbackup("#123456789#123456789#123456789");
 228 
 229         if (create_test_data_file(filename, mode)) {
 230                 printf("The scenario initialization failed, "\
 231                     "and other subassertions won't run.\n\n");
 232                 exit_test(NOOK);
 233         }
 234 
 235 /* assertion a) */
 236         assertion("a", "Open a file (fd1)", "multiple");
 237         fd1 = open_file(filename, oflag, mode);
 238         tresult(expect[0], errno);
 239         admerrors(ASSERT);
 240         if (fd1 < 0) {
 241                 if (expect[0] == OK) {
 242                         printf("scenarioA{rest}: open call\n");
 243                         printf("\t Test OTHER: unexpected open failure\n");
 244                         ret = NOOK;
 245                 }
 246                 print("Scenario A, skipping rest of scenario.\n");
 247                 goto clean_up;
 248         }
 249 
 250 /* assertion a1) */
 251         assertion("a1", "dup() fd1 desc on fd2", "multiple");
 252         fd2 = dupfile(fd1);
 253         tresult(expect[1], errno);
 254         admerrors(ASSERT);
 255 
 256         /* initialize pipes and create the child */
 257         initialize();
 258 
 259         if (me == PARENT) {
 260 /* assertion b) */
 261                 assertion("b", "Parent close the first file desc (fd1)",
 262                     errtostr(expect[1]));
 263                 close_file(fd1, filename);
 264                 tresult(expect[1], errno);
 265                 admerrors(ASSERT);
 266                 contch();
 267                 waitp();
 268         }
 269 
 270         if (me == CHILD) {
 271                 waitch();
 272 
 273 /* assertion c) */
 274                 assertion("c", "Child checks read/write on fd1 and fd2",
 275                     "multiple");
 276                 read_file(fd1, filename, buf, 0, 26);
 277                 tresult(expect[2], errno);
 278                 read_file(fd2, filename, buf, 0, 26);
 279                 tresult(expect[2], errno);
 280 
 281                 write_file(fd1, filename, DD, 0, 26);
 282                 tresult(expect[3], errno);
 283                 write_file(fd2, filename, DD, 0, 26);
 284                 tresult(expect[3], errno);
 285                 admerrors(ASSERT);
 286                 contp();
 287                 waitch();
 288         }
 289 
 290         if (me == PARENT) {
 291 /* assertion d) */
 292                 assertion("d", "Parent checks read/write on fd1 and fd2",
 293                     "multiple");
 294                 read_file(fd1, filename, buf, 0, 26);
 295                 tresult(EBADF, errno);
 296                 read_file(fd2, filename, buf, 0, 26);
 297                 tresult(expect[2], errno);
 298 
 299                 write_file(fd1, filename, DD, 0, 26);
 300                 tresult(EBADF, errno);
 301                 write_file(fd2, filename, DD, 0, 26);
 302                 tresult(expect[3], errno);
 303                 admerrors(ASSERT);
 304                 contch();
 305                 waitp();
 306         }
 307 
 308         if (me == CHILD) {
 309 /* assertion e) */
 310                 assertion("e", "Child closes both fd1 and fd2", "multiple");
 311                 close_file(fd1, filename);
 312                 tresult(expect[1], errno);
 313                 close_file(fd2, filename);
 314                 tresult(expect[1], errno);
 315                 admerrors(ASSERT);
 316                 contp();
 317                 wait_send_cresult();
 318 
 319                 while (1)
 320                         sleep(1);
 321         }
 322 
 323         if (me == PARENT) {
 324 /* assertion f) */
 325                 assertion("f", "Parent checks read/write on fd1 and fd2,\n"
 326                     "\tand kill child proc", "multiple");
 327                 read_file(fd1, filename, buf, 0, 26);
 328                 tresult(EBADF, errno);
 329                 read_file(fd2, filename, buf, 0, 26);
 330                 tresult(expect[2], errno);
 331 
 332                 write_file(fd1, filename, DD, 0, 26);
 333                 tresult(EBADF, errno);
 334                 write_file(fd2, filename, DD, 0, 26);
 335                 tresult(expect[3], errno);
 336                 admerrors(ASSERT);
 337 
 338                 if (wait_get_cresult())
 339                         ret = NOOK;
 340                 kill_child(OK);
 341 
 342 /* assertion g) */
 343                 assertion("g", "Parent checks read/write on fd1 and fd2",
 344                     "multiple");
 345                 read_file(fd1, filename, buf, 0, 26);
 346                 tresult(EBADF, errno);
 347                 read_file(fd2, filename, buf, 0, 26);
 348                 tresult(expect[2], errno);
 349 
 350                 write_file(fd1, filename, DD, 0, 26);
 351                 tresult(EBADF, errno);
 352                 write_file(fd2, filename, DD, 0, 26);
 353                 tresult(expect[3], errno);
 354                 admerrors(ASSERT);
 355                 goto clean_up;
 356         }
 357 
 358         if (me == CHILD) {
 359                 print("ERROR: child should be dead. Quitting ...\n");
 360                 exit_test(NOOK);
 361         }
 362 
 363 clean_up:
 364         {
 365         int tmp = debug;
 366         int tme = showerror;
 367 
 368         debug = 0;
 369         showerror = 0;
 370         close_file(fd1, filename);
 371         showerror = tme;
 372         debug = tmp;
 373 
 374         close_file(fd2, filename);
 375         unlink_file(filename);
 376         }
 377 
 378         if (admerrors(SCENARIO))
 379                 ret = NOOK;
 380         print("Scenario A finished.\n\n\n");
 381         return (ret);
 382 }
 383 
 384 int
 385 scenarioB(int mode, int oflag, int expect[])
 386 {
 387         int fd1, fd2;
 388         char *DD;
 389         int ret = OK;
 390 
 391         scen = "ScenB";
 392         scen_mode = mode;
 393         scen_flag = oflag;
 394         expecterr = expect[0];
 395 
 396         fprintf(stdout, "\n\nExecuting Scenario B, with mode = 0%o and "\
 397             "oflag = %s\n\n", mode, oflagstr(oflag));
 398 
 399         DD = strbackup("#123456789#123456789#123456789");
 400 
 401         if ((create_test_data_file(filename, mode)) ||
 402             link_file(filename, "olinkfile.txt")) {
 403                 printf("The scenario initialization failed, "\
 404                     "and other subassertions won't run.\n\n");
 405                 exit_test(NOOK);
 406         }
 407 
 408 /* assertion a) */
 409         assertion("a", "Open a file using file desc fd1", errtostr(expect[0]));
 410         fd1 = open_file(filename, oflag, mode);
 411         tresult(expect[0], errno);
 412         admerrors(ASSERT);
 413 
 414 /* assertion b) */
 415         assertion("b", "Open hardlink to original file using fd2",
 416             errtostr(expect[0]));
 417         fd2 = open_file("olinkfile.txt", oflag, mode);
 418         tresult(expect[0], errno);
 419         admerrors(ASSERT);
 420         if (fd2 < 0) {
 421                 if (expect[0] == OK) {
 422                         printf("scenarioB{rest}: open calls\n");
 423                         printf("\t Test OTHER: unexpected open failure\n");
 424                 }
 425                 print("Scenario B, skipping rest of scenario.\n");
 426                 goto clean_up;
 427         }
 428 
 429         /* initialize pipes and create the child */
 430         initialize();
 431 
 432         if (me == PARENT) {
 433 /* assertion c) */
 434                 assertion("c", "Parent close fd1", errtostr(expect[1]));
 435                 close_file(fd1, filename);
 436                 tresult(expect[1], errno);
 437                 admerrors(ASSERT);
 438                 contch();
 439                 waitp();
 440         }
 441 
 442         if (me == CHILD) {
 443                 waitch();
 444 
 445 /* assertion d) */
 446                 assertion("d", "Child checks read/write on fd1 and fd2",
 447                     "multiple");
 448                 read_file(fd1, filename, buf, 0, 26);
 449                 tresult(expect[2], errno);
 450                 read_file(fd2, "olinkfile.txt", buf, 0, 26);
 451                 tresult(expect[2], errno);
 452 
 453                 write_file(fd1, filename, DD, 0, 26);
 454                 tresult(expect[3], errno);
 455                 write_file(fd2, "olinkfile.txt", DD, 0, 26);
 456                 tresult(expect[3], errno);
 457                 admerrors(ASSERT);
 458                 contp();
 459                 waitch();
 460         }
 461 
 462         if (me == PARENT) {
 463 /* assertion e) */
 464                 assertion("e", "Parent checks read/write on fd1 and fd2",
 465                     "multiple");
 466                 read_file(fd1, filename, buf, 0, 26);
 467                 tresult(EBADF, errno);
 468                 read_file(fd2, "olinkfile.txt", buf, 0, 26);
 469                 tresult(expect[2], errno);
 470 
 471                 write_file(fd1, filename, DD, 0, 26);
 472                 tresult(EBADF, errno);
 473                 write_file(fd2, "olinkfile.txt", DD, 0, 26);
 474                 tresult(expect[3], errno);
 475                 admerrors(ASSERT);
 476                 contch();
 477                 waitp();
 478         }
 479 
 480         if (me == CHILD) {
 481 /* assertion f) */
 482                 assertion("f", "Child closes fd1 and fd2", "multiple");
 483                 close_file(fd1, filename);
 484                 tresult(expect[1], errno);
 485                 close_file(fd2, "olinkfile.txt");
 486                 tresult(expect[1], errno);
 487                 admerrors(ASSERT);
 488                 contp();
 489                 wait_send_cresult();
 490 
 491                 while (1)
 492                         sleep(1);
 493         }
 494 
 495         if (me == PARENT) {
 496 /* assertion g) */
 497                 assertion("g", "Parent checks read/write on fd1 and fd2,\n"
 498                     "\tand kills child proc", "multiple");
 499                 read_file(fd1, filename, buf, 0, 26);
 500                 tresult(EBADF, errno);
 501                 read_file(fd2, "olinkfile.txt", buf, 0, 26);
 502                 tresult(expect[2], errno);
 503 
 504                 write_file(fd1, filename, DD, 0, 26);
 505                 tresult(EBADF, errno);
 506                 write_file(fd2, "olinkfile.txt", DD, 0, 26);
 507                 tresult(expect[3], errno);
 508                 admerrors(ASSERT);
 509 
 510                 if (wait_get_cresult())
 511                         ret = NOOK;
 512                 kill_child(OK);
 513 
 514 /* assertion h) */
 515                 assertion("h", "Parent checks read/write on fd1 and fd2",
 516                     "multiple");
 517                 read_file(fd1, filename, buf, 0, 26);
 518                 tresult(EBADF, errno);
 519                 read_file(fd2, "olinkfile.txt", buf, 0, 26);
 520                 tresult(expect[2], errno);
 521 
 522                 write_file(fd1, filename, DD, 0, 26);
 523                 tresult(EBADF, errno);
 524                 write_file(fd2, "olinkfile.txt", DD, 0, 26);
 525                 tresult(expect[3], errno);
 526                 admerrors(ASSERT);
 527                 goto clean_up;
 528         }
 529 
 530         if (me == CHILD) {
 531                 print("ERROR: child should be dead. Quitting ...\n");
 532                 exit_test(NOOK);
 533         }
 534 
 535 clean_up:
 536         {
 537         int tmp = debug;
 538         int tme = showerror;
 539 
 540         debug = 0;
 541         showerror = 0;
 542         close_file(fd1, filename);
 543         showerror = tme;
 544         debug = tmp;
 545 
 546         close_file(fd2, "olinkfile.txt");
 547         unlink_file(filename);
 548         unlink_file("olinkfile.txt");
 549         }
 550 
 551         if (admerrors(SCENARIO))
 552                 ret = NOOK;
 553         print("Scenario B finished.\n\n\n\n");
 554         return (ret);
 555 }
 556 
 557 int
 558 scenarioC(int mode, int oflag, int expect[])
 559 {
 560         int     fd1, fd2, fd3;
 561         char    *DD;
 562         char    tmp[512];
 563         int     ret = OK;
 564 
 565         scen = "ScenC";
 566         scen_mode = mode;
 567         scen_flag = oflag;
 568         expecterr = expect[0];
 569 
 570         fprintf(stdout, "\n\nExecuting Scenario C, with mode = 0%o and "\
 571             "oflag = %s\n\n", mode, oflagstr(oflag));
 572 
 573         DD = strbackup("#123456789#123456789#123456789");
 574 
 575         if ((create_test_data_file(filename, mode)) ||
 576             link_file(filename, "olinkfile.txt")) {
 577                 printf("The scenario initialization failed, "\
 578                     "and other subassertions won't run.\n\n");
 579                 exit_test(NOOK);
 580         }
 581 
 582 /* assertion a) */
 583         assertion("a", "Open a file using file desc fd1", errtostr(expect[0]));
 584         fd1 = open_file(filename, oflag, mode);
 585         tresult(expect[0], errno);
 586         admerrors(ASSERT);
 587         if (fd1 < 0) {
 588                 if (expect[0] == OK) {
 589                         printf("scenarioC{rest}: open calls\n");
 590                         printf("\t Test OTHER: unexpected open failure\n");
 591                 }
 592                 print("Scenario C, skipping rest of scenario.\n");
 593                 goto clean_up;
 594         }
 595 
 596 /* assertion b) */
 597         assertion("b", "Open hardlink to original file using fd2",
 598             errtostr(expect[0]));
 599         fd2 = open_file("olinkfile.txt", oflag, mode);
 600         tresult(expect[0], errno);
 601         admerrors(ASSERT);
 602 
 603 /* assertion c) */
 604         assertion("c", "dup() original file using fd3", errtostr(expect[1]));
 605         fd3 = dupfile(fd1);
 606         tresult(expect[1], errno);
 607         admerrors(ASSERT);
 608 
 609         /* initialize pipes and create the child */
 610         initialize();
 611 
 612         if (me == PARENT) {
 613 /* assertion d) */
 614                 assertion("d", "Parent closes all file descriptors",
 615                     "multiple");
 616                 close_file(fd1, filename);
 617                 tresult(expect[1], errno);
 618                 close_file(fd2, "olinkfile.txt");
 619                 tresult(expect[1], errno);
 620                 close_file(fd3, filename);
 621                 tresult(expect[1], errno);
 622                 admerrors(ASSERT);
 623 
 624                 contch();
 625                 waitp();
 626         }
 627 
 628         if (me == CHILD) {
 629                 waitch();
 630 
 631                 close_file(fd1, filename);
 632                 close_file(fd2, "olinkfile.txt");
 633 
 634 /* assertion e) */
 635                 sprintf(tmp, "Child change credentials to owner %ld,"
 636                 "\n\treopen file on fd1, hardlink on fd2, check read/write all"
 637                 "3 fds\n\tand close fd1 and fd2", uid2);
 638                 assertion("e", tmp, "multiple");
 639 
 640                 if (Seteuid(0) < 0) {
 641                         print("Scenario C, seteuid(root) failed, skipping"\
 642                             " rest of scenario\n");
 643                         goto child_end;
 644                 }
 645                 if (Seteuid(uid2) < 0) {
 646                         print("Scenario C, seteuid(%d) failed, skipping"\
 647                             " rest of scenario ...\n", uid2);
 648                         goto child_end;
 649                 }
 650 
 651                 expecterr = (expect[4] == EBADF) ? EACCES : OK;
 652                 fd1 = open_file(filename, oflag, mode);
 653                 fd2 = open_file("olinkfile.txt", oflag, mode);
 654 
 655                 read_file(fd1, filename, buf, 0, 26);
 656                 tresult(expect[4], errno);
 657                 read_file(fd2, "olinkfile.txt", buf, 0, 26);
 658                 tresult(expect[4], errno);
 659                 read_file(fd3, "olinkfile.txt", buf, 0, 26);
 660                 tresult(expect[2], errno);
 661 
 662                 write_file(fd1, filename, DD, 0, 26);
 663                 tresult(expect[5], errno);
 664                 write_file(fd2, "olinkfile.txt", DD, 0, 26);
 665                 tresult(expect[5], errno);
 666                 write_file(fd3, "olinkfile.txt", DD, 0, 26);
 667                 tresult(expect[3], errno);
 668 
 669                 close_file(fd1, filename);
 670                 close_file(fd2, "olinkfile.txt");
 671 
 672                 admerrors(ASSERT);
 673 
 674 
 675 /* assertion f) */
 676                 sprintf(tmp, "Child change credentials to owner %ld, group %ld,"
 677                 "\n\treopen file on fd1, hardlink on fd2, check read/write all"
 678                 "3 fds\n\tand close fd1 and fd2", uid2, gid2);
 679                 assertion("f", tmp, "multiple");
 680 
 681                 if (Seteuid(0) < 0) {
 682                         print("Scenario C, seteuid(root) failed, skipping"\
 683                             " rest of scenario ...\n");
 684                         goto child_end;
 685                 }
 686                 if (Setegid(gid2) < 0) {
 687                         print("Scenario C, setegid(%d) failed, skipping"\
 688                             "rest of scenario ...\n", gid2);
 689                         goto child_end;
 690                 }
 691                 {
 692                 gid_t gid = gid2;
 693 
 694                 if (Setgroups(1, &gid) < 0) {
 695                         print("Scenario C, setgroups(1, %d) failed, "\
 696                             "skipping rest of scenario ...\n", gid);
 697                         goto child_end;
 698                 }
 699                 }
 700                 if (Seteuid(uid2) < 0) {
 701                         print("Scenario C, seteuid(%d) failed, skipping"\
 702                             " rest of scenario ...\n", uid2);
 703                         goto child_end;
 704                 }
 705 
 706                 expecterr = EACCES;
 707                 fd1 = open_file(filename, oflag, mode);
 708                 fd2 = open_file("olinkfile.txt", oflag, mode);
 709 
 710                 if (debug != 0)
 711                         system("ls -la *file.txt; id -ap");
 712                 read_file(fd1, filename, buf, 0, 26);
 713                 tresult(EBADF, errno);
 714                 read_file(fd2, "olinkfile.txt", buf, 0, 26);
 715                 tresult(EBADF, errno);
 716                 read_file(fd3, "olinkfile.txt", buf, 0, 26);
 717                 tresult(expect[2], errno);
 718 
 719                 write_file(fd1, filename, DD, 0, 26);
 720                 tresult(EBADF, errno);
 721                 write_file(fd2, "olinkfile.txt", DD, 0, 26);
 722                 tresult(EBADF, errno);
 723                 write_file(fd3, "olinkfile.txt", DD, 0, 26);
 724                 tresult(expect[3], errno);
 725 
 726                 close_file(fd1, filename);
 727                 close_file(fd2, "olinkfile.txt");
 728 
 729                 admerrors(ASSERT);
 730 
 731                 contp();
 732                 wait_send_cresult();
 733 
 734                 while (1)
 735                         sleep(1);
 736         }
 737 
 738         if (me == PARENT) {
 739                 if (wait_get_cresult())
 740                         ret = NOOK;
 741 
 742                 kill_child(OK);
 743 
 744                 goto clean_up;
 745         }
 746 
 747         if (me == CHILD) {
 748                 print("ERROR: child should be dead. Quitting ...\n");
 749                 exit_test(NOOK);
 750         }
 751 
 752 child_end:
 753         tresult(OK, errno);
 754         admerrors(ASSERT);
 755 
 756         contp();
 757         while (1)
 758                 sleep(1);
 759 
 760 clean_up:
 761         unlink_file(filename);
 762         unlink_file("olinkfile.txt");
 763 
 764         if (admerrors(SCENARIO))
 765                 ret = NOOK;
 766         print("Scenario C finished.\n\n\n\n");
 767         return (ret);
 768 }
 769 
 770 int
 771 scenarioD(int mode, int oflag, int expect[])
 772 {
 773         int fd1, fd2, fd3;
 774         char *DD;
 775         int ret = OK;
 776 
 777         scen = "ScenD";
 778         scen_mode = mode;
 779         scen_flag = oflag;
 780         expecterr = NOOK;
 781 
 782         fprintf(stdout, "\n\nExecuting Scenario D, with mode = 0%o and "\
 783             "oflag = %s\n\n", mode, oflagstr(oflag));
 784 
 785         DD = strbackup("#123456789#123456789#123456789");
 786 
 787         if ((create_test_data_file(filename, mode)) ||
 788             link_file(filename, "olinkfile.txt")) {
 789                 printf("The scenario initialization failed, "\
 790                     "and other subassertions won't run.\n\n");
 791                 exit_test(NOOK);
 792         }
 793 
 794 /* assertion a) */
 795         assertion("a",
 796             "Opens a file on file desc fd1 and change permissions to 0000",
 797             "multiple");
 798         fd1 = open_file(filename, oflag, mode);
 799         tresult(OK, errno);
 800         chmod_file(fd1, filename, 0000);
 801         tresult(OK, errno);
 802         admerrors(ASSERT);
 803 
 804         expecterr = EACCES;
 805 
 806         if (fd1 < 0) {
 807                 if (expect[0] == OK) {
 808                         printf("scenarioD{rest}: open calls\n");
 809                         printf("\t Test OTHER: unexpected open failure\n");
 810                 }
 811                 print("Scenario D, skipping rest of scenario.\n");
 812                 goto clean_up;
 813         }
 814 
 815         /* initialize pipes and create the child */
 816         initialize();
 817 
 818         if (me == PARENT) {
 819                 sleep(1);       /* let child start */
 820                 contch();
 821                 waitp();
 822         }
 823 
 824         if (me == CHILD) {
 825                 waitch();
 826 
 827 /* assertion b) */
 828                 assertion("b", "Child opens the file on file desc fd3",
 829                     errtostr(EACCES));
 830                 fd3 = open_file(filename, oflag, mode);
 831                 tresult(EACCES, errno);
 832                 admerrors(ASSERT);
 833 
 834 /* assertion c) */
 835                 assertion("c", "Child opens the a hardlink to file on fd2",
 836                     errtostr(EACCES));
 837                 fd2 = open_file("olinkfile.txt", oflag, mode);
 838                 tresult(EACCES, errno);
 839                 admerrors(ASSERT);
 840 
 841                 contp();
 842                 wait_send_cresult();
 843 
 844                 while (1)
 845                         sleep(1);
 846         }
 847 
 848         if (me == PARENT) {
 849                 goto clean_up;
 850         }
 851 
 852         if (me == CHILD) {
 853                 print("ERROR: child should be dead. Quitting ...\n");
 854                 exit_test(NOOK);
 855         }
 856 
 857 clean_up:
 858         close_file(fd1, filename);
 859 
 860         if (wait_get_cresult())
 861                 ret = NOOK;
 862         kill_child(OK);
 863 
 864         unlink_file(filename);
 865         unlink_file("olinkfile.txt");
 866 
 867         if (admerrors(SCENARIO))
 868                 ret = NOOK;
 869         print("Scenario D finished.\n\n\n\n");
 870         return (ret);
 871 }
 872 
 873 int
 874 scenarioE(int mode, int oflag, int expect[])
 875 {
 876         int     fd1, fd2;
 877 
 878         scen = "ScenE";
 879         scen_mode = mode;
 880         scen_flag = oflag;
 881         expecterr = OK;
 882         int ret = OK;
 883 
 884         fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and " \
 885             "oflag = %s\n\n", mode, oflagstr(oflag));
 886 
 887         /* assertion a ) */
 888         assertion("a", "open a file with trunc option after a success open \
 889         will success", errtostr(expecterr));
 890         errno = OK;
 891         fd1 = open_file(filename, O_CREAT, scen_mode);
 892         tresult(OK, errno);
 893         fd2 = open_file(filename, scen_flag, scen_mode);
 894         tresult(OK, errno);
 895         admerrors(ASSERT);
 896         if (fd1 > 0)
 897                 close_file(fd1, filename);
 898         if (fd2 > 0)
 899                 close_file(fd2, filename);
 900         unlink_file(filename);
 901 
 902         if (admerrors(SCENARIO))
 903                 ret = NOOK;
 904         print("Scenario E finished.\n\n\n");
 905         return (ret);
 906 }