--- /dev/null	Mon Aug  5 17:19:41 2019
+++ new/usr/src/test/nfsgen-tests/tests/openlock/opentest.c	Mon Aug  5 17:19:41 2019
@@ -0,0 +1,906 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Open operation C testcase */
+
+#include "nfsgen.h"
+
+/* Functions */
+int scenarioA(int mode, int oflag, int expect[]);
+int scenarioB(int mode, int oflag, int expect[]);
+int scenarioC(int mode, int oflag, int expect[]);
+int scenarioD(int mode, int oflag, int expect[]);
+int scenarioE(int mode, int oflag, int expect[]);
+
+/* Globals */
+
+static char *filename = NULL;
+char	*buf = NULL;
+
+/*
+ * Main test loop.
+ */
+
+int
+main(int argc, char **argv)
+{
+	int		i, j;
+	int		ret = OK;
+	char		*deleg, *scen, *mode_index, *oflag_index;
+	static int	mode_set[] = {0600, 0400, 0200, 000},
+			mode_setC[] = {0660, 0600, 0440, 0400, 0220, 0200,
+					000},
+			oflag_set[] = {O_EXCL|O_RDWR, O_RDWR, O_WRONLY,
+					O_RDONLY};
+	static int	expectA[4][4][4] =
+	{
+	{	{OK,		OK,	OK,	OK},
+		{OK,		OK,	OK,	OK},
+		{OK,		OK,	EBADF,	OK},
+		{OK,		OK,	OK,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	OK,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	EBADF,	OK},
+		{EACCES,	EBADF,	EBADF,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF}}
+	};
+
+	static int	expectB[4][4][4] =
+	{
+	{	{OK,		OK,	OK,	OK},
+		{OK,		OK,	OK,	OK},
+		{OK,		OK,	EBADF,	OK},
+		{OK,		OK,	OK,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	OK,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	EBADF,	OK},
+		{EACCES,	EBADF,	EBADF,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF}}
+	};
+
+	static int	expectC[7][4][6] =
+	{
+	{	{OK,		OK,	OK,	OK,	OK,	OK},
+		{OK,		OK,	OK,	OK,	OK,	OK},
+		{OK,		OK,	EBADF,	OK,	EBADF,	OK},
+		{OK,		OK,	OK,	EBADF,	OK,	EBADF}},
+	{	{OK,		OK,	OK,	OK,	EBADF,	EBADF},
+		{OK,		OK,	OK,	OK,	EBADF,	EBADF},
+		{OK,		OK,	EBADF,	OK,	EBADF,	EBADF},
+		{OK,		OK,	OK,	EBADF,	EBADF,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	OK,	EBADF,	OK,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	OK,	EBADF,	EBADF,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	EBADF,	OK,	EBADF,	OK},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{OK,		OK,	EBADF,	OK,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF}},
+	{	{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF},
+		{EACCES,	EBADF,	EBADF,	EBADF,	EBADF,	EBADF}}
+	};
+
+	if ((buf = malloc(256)) == NULL) {
+		perror("main()- malloc() for buf");
+		return (NOOK);
+	}
+
+	parse_args(argc, argv);
+
+	filename = lfilename;
+
+	dprint("Try to remove test files, to avoid errors.\n");
+	unlink_file(filename);
+	unlink_file("olinkfile.txt");
+
+	/* modify name to include delgation policy */
+	if ((deleg = getenv("DELG")) != NULL) {
+		if (strcasecmp(deleg, "on") == 0) {
+			strcat(Testname, "_Deleg");
+		}
+		if (strcasecmp(deleg, "off") == 0) {
+			strcat(Testname, "_NoDeleg");
+		}
+	}
+
+	scen = getenv("SCENARIO");
+	if (!scen) {
+		printf("The scenario was not specified");
+		return (NOOK);
+	}
+
+	if ((mode_index = getenv("MODE_INDEX")) != NULL) {
+		i = atoi(mode_index);
+		if ((i > 3) && (strcmp(scen, "C") != 0)) {
+			printf("The mode index(%d) is more than 3 "\
+			    "with scenario %s", i, scen);
+			return (NOOK);
+		} else if (i > 6) {
+			printf("The mode index(%d) is more than 6 "\
+			    "with scenario %s", i, scen);
+			return (NOOK);
+		}
+	}
+
+	if ((oflag_index = getenv("OFLAG_INDEX")) != NULL) {
+		j = atoi(oflag_index);
+		if (j > 3) {
+			printf("The oflag index(%d) is more than 3 "\
+			    "with scenario %s", i, scen);
+			return (NOOK);
+		}
+	}
+
+	/* run tests */
+	switch (*scen) {
+	case 'A':
+		ret = scenarioA(mode_set[i], oflag_set[j], expectA[i][j]);
+		break;
+	case 'B':
+		ret = scenarioB(mode_set[i], oflag_set[j], expectB[i][j]);
+		break;
+	case 'C':
+		ret = scenarioC(mode_setC[i], oflag_set[j], expectC[i][j]);
+		break;
+	case 'D':
+		ret = scenarioD(mode_set[i], oflag_set[j], NULL);
+		break;
+	case 'E':
+		ret = scenarioE(0755, O_TRUNC, OK);
+		break;
+	default:
+		printf("Set invalid scenario(%s)", scen);
+		return (NOOK);
+	}
+
+	if (buf != NULL)
+		free(buf);
+	if (GLOBdata != NULL)
+		free(GLOBdata);
+
+	exit_test(ret);
+	return (ret);	 /* unreachable, used to quiet lint */
+}
+
+int
+scenarioA(int mode, int oflag, int expect[])
+{
+	int fd1, fd2;
+	char *DD;
+	int ret = OK;
+
+	scen = "ScenA";
+	scen_mode = mode;
+	scen_flag = oflag;
+	expecterr = expect[0];
+
+	fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and "\
+	    "oflag = %s\n\n", mode, oflagstr(oflag));
+
+	DD = strbackup("#123456789#123456789#123456789");
+
+	if (create_test_data_file(filename, mode)) {
+		printf("The scenario initialization failed, "\
+		    "and other subassertions won't run.\n\n");
+		exit_test(NOOK);
+	}
+
+/* assertion a) */
+	assertion("a", "Open a file (fd1)", "multiple");
+	fd1 = open_file(filename, oflag, mode);
+	tresult(expect[0], errno);
+	admerrors(ASSERT);
+	if (fd1 < 0) {
+		if (expect[0] == OK) {
+			printf("scenarioA{rest}: open call\n");
+			printf("\t Test OTHER: unexpected open failure\n");
+			ret = NOOK;
+		}
+		print("Scenario A, skipping rest of scenario.\n");
+		goto clean_up;
+	}
+
+/* assertion a1) */
+	assertion("a1", "dup() fd1 desc on fd2", "multiple");
+	fd2 = dupfile(fd1);
+	tresult(expect[1], errno);
+	admerrors(ASSERT);
+
+	/* initialize pipes and create the child */
+	initialize();
+
+	if (me == PARENT) {
+/* assertion b) */
+		assertion("b", "Parent close the first file desc (fd1)",
+		    errtostr(expect[1]));
+		close_file(fd1, filename);
+		tresult(expect[1], errno);
+		admerrors(ASSERT);
+		contch();
+		waitp();
+	}
+
+	if (me == CHILD) {
+		waitch();
+
+/* assertion c) */
+		assertion("c", "Child checks read/write on fd1 and fd2",
+		    "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(expect[2], errno);
+		read_file(fd2, filename, buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(expect[3], errno);
+		write_file(fd2, filename, DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+		contp();
+		waitch();
+	}
+
+	if (me == PARENT) {
+/* assertion d) */
+		assertion("d", "Parent checks read/write on fd1 and fd2",
+		    "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, filename, buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, filename, DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+		contch();
+		waitp();
+	}
+
+	if (me == CHILD) {
+/* assertion e) */
+		assertion("e", "Child closes both fd1 and fd2", "multiple");
+		close_file(fd1, filename);
+		tresult(expect[1], errno);
+		close_file(fd2, filename);
+		tresult(expect[1], errno);
+		admerrors(ASSERT);
+		contp();
+		wait_send_cresult();
+
+		while (1)
+			sleep(1);
+	}
+
+	if (me == PARENT) {
+/* assertion f) */
+		assertion("f", "Parent checks read/write on fd1 and fd2,\n"
+		    "\tand kill child proc", "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, filename, buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, filename, DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+
+		if (wait_get_cresult())
+			ret = NOOK;
+		kill_child(OK);
+
+/* assertion g) */
+		assertion("g", "Parent checks read/write on fd1 and fd2",
+		    "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, filename, buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, filename, DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+		goto clean_up;
+	}
+
+	if (me == CHILD) {
+		print("ERROR: child should be dead. Quitting ...\n");
+		exit_test(NOOK);
+	}
+
+clean_up:
+	{
+	int tmp = debug;
+	int tme = showerror;
+
+	debug = 0;
+	showerror = 0;
+	close_file(fd1, filename);
+	showerror = tme;
+	debug = tmp;
+
+	close_file(fd2, filename);
+	unlink_file(filename);
+	}
+
+	if (admerrors(SCENARIO))
+		ret = NOOK;
+	print("Scenario A finished.\n\n\n");
+	return (ret);
+}
+
+int
+scenarioB(int mode, int oflag, int expect[])
+{
+	int fd1, fd2;
+	char *DD;
+	int ret = OK;
+
+	scen = "ScenB";
+	scen_mode = mode;
+	scen_flag = oflag;
+	expecterr = expect[0];
+
+	fprintf(stdout, "\n\nExecuting Scenario B, with mode = 0%o and "\
+	    "oflag = %s\n\n", mode, oflagstr(oflag));
+
+	DD = strbackup("#123456789#123456789#123456789");
+
+	if ((create_test_data_file(filename, mode)) ||
+	    link_file(filename, "olinkfile.txt")) {
+		printf("The scenario initialization failed, "\
+		    "and other subassertions won't run.\n\n");
+		exit_test(NOOK);
+	}
+
+/* assertion a) */
+	assertion("a", "Open a file using file desc fd1", errtostr(expect[0]));
+	fd1 = open_file(filename, oflag, mode);
+	tresult(expect[0], errno);
+	admerrors(ASSERT);
+
+/* assertion b) */
+	assertion("b", "Open hardlink to original file using fd2",
+	    errtostr(expect[0]));
+	fd2 = open_file("olinkfile.txt", oflag, mode);
+	tresult(expect[0], errno);
+	admerrors(ASSERT);
+	if (fd2 < 0) {
+		if (expect[0] == OK) {
+			printf("scenarioB{rest}: open calls\n");
+			printf("\t Test OTHER: unexpected open failure\n");
+		}
+		print("Scenario B, skipping rest of scenario.\n");
+		goto clean_up;
+	}
+
+	/* initialize pipes and create the child */
+	initialize();
+
+	if (me == PARENT) {
+/* assertion c) */
+		assertion("c", "Parent close fd1", errtostr(expect[1]));
+		close_file(fd1, filename);
+		tresult(expect[1], errno);
+		admerrors(ASSERT);
+		contch();
+		waitp();
+	}
+
+	if (me == CHILD) {
+		waitch();
+
+/* assertion d) */
+		assertion("d", "Child checks read/write on fd1 and fd2",
+		    "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(expect[2], errno);
+		read_file(fd2, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(expect[3], errno);
+		write_file(fd2, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+		contp();
+		waitch();
+	}
+
+	if (me == PARENT) {
+/* assertion e) */
+		assertion("e", "Parent checks read/write on fd1 and fd2",
+		    "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+		contch();
+		waitp();
+	}
+
+	if (me == CHILD) {
+/* assertion f) */
+		assertion("f", "Child closes fd1 and fd2", "multiple");
+		close_file(fd1, filename);
+		tresult(expect[1], errno);
+		close_file(fd2, "olinkfile.txt");
+		tresult(expect[1], errno);
+		admerrors(ASSERT);
+		contp();
+		wait_send_cresult();
+
+		while (1)
+			sleep(1);
+	}
+
+	if (me == PARENT) {
+/* assertion g) */
+		assertion("g", "Parent checks read/write on fd1 and fd2,\n"
+		    "\tand kills child proc", "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+
+		if (wait_get_cresult())
+			ret = NOOK;
+		kill_child(OK);
+
+/* assertion h) */
+		assertion("h", "Parent checks read/write on fd1 and fd2",
+		    "multiple");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[3], errno);
+		admerrors(ASSERT);
+		goto clean_up;
+	}
+
+	if (me == CHILD) {
+		print("ERROR: child should be dead. Quitting ...\n");
+		exit_test(NOOK);
+	}
+
+clean_up:
+	{
+	int tmp = debug;
+	int tme = showerror;
+
+	debug = 0;
+	showerror = 0;
+	close_file(fd1, filename);
+	showerror = tme;
+	debug = tmp;
+
+	close_file(fd2, "olinkfile.txt");
+	unlink_file(filename);
+	unlink_file("olinkfile.txt");
+	}
+
+	if (admerrors(SCENARIO))
+		ret = NOOK;
+	print("Scenario B finished.\n\n\n\n");
+	return (ret);
+}
+
+int
+scenarioC(int mode, int oflag, int expect[])
+{
+	int	fd1, fd2, fd3;
+	char	*DD;
+	char	tmp[512];
+	int	ret = OK;
+
+	scen = "ScenC";
+	scen_mode = mode;
+	scen_flag = oflag;
+	expecterr = expect[0];
+
+	fprintf(stdout, "\n\nExecuting Scenario C, with mode = 0%o and "\
+	    "oflag = %s\n\n", mode, oflagstr(oflag));
+
+	DD = strbackup("#123456789#123456789#123456789");
+
+	if ((create_test_data_file(filename, mode)) ||
+	    link_file(filename, "olinkfile.txt")) {
+		printf("The scenario initialization failed, "\
+		    "and other subassertions won't run.\n\n");
+		exit_test(NOOK);
+	}
+
+/* assertion a) */
+	assertion("a", "Open a file using file desc fd1", errtostr(expect[0]));
+	fd1 = open_file(filename, oflag, mode);
+	tresult(expect[0], errno);
+	admerrors(ASSERT);
+	if (fd1 < 0) {
+		if (expect[0] == OK) {
+			printf("scenarioC{rest}: open calls\n");
+			printf("\t Test OTHER: unexpected open failure\n");
+		}
+		print("Scenario C, skipping rest of scenario.\n");
+		goto clean_up;
+	}
+
+/* assertion b) */
+	assertion("b", "Open hardlink to original file using fd2",
+	    errtostr(expect[0]));
+	fd2 = open_file("olinkfile.txt", oflag, mode);
+	tresult(expect[0], errno);
+	admerrors(ASSERT);
+
+/* assertion c) */
+	assertion("c", "dup() original file using fd3", errtostr(expect[1]));
+	fd3 = dupfile(fd1);
+	tresult(expect[1], errno);
+	admerrors(ASSERT);
+
+	/* initialize pipes and create the child */
+	initialize();
+
+	if (me == PARENT) {
+/* assertion d) */
+		assertion("d", "Parent closes all file descriptors",
+		    "multiple");
+		close_file(fd1, filename);
+		tresult(expect[1], errno);
+		close_file(fd2, "olinkfile.txt");
+		tresult(expect[1], errno);
+		close_file(fd3, filename);
+		tresult(expect[1], errno);
+		admerrors(ASSERT);
+
+		contch();
+		waitp();
+	}
+
+	if (me == CHILD) {
+		waitch();
+
+		close_file(fd1, filename);
+		close_file(fd2, "olinkfile.txt");
+
+/* assertion e) */
+		sprintf(tmp, "Child change credentials to owner %ld,"
+		"\n\treopen file on fd1, hardlink on fd2, check read/write all"
+		"3 fds\n\tand close fd1 and fd2", uid2);
+		assertion("e", tmp, "multiple");
+
+		if (Seteuid(0) < 0) {
+			print("Scenario C, seteuid(root) failed, skipping"\
+			    " rest of scenario\n");
+			goto child_end;
+		}
+		if (Seteuid(uid2) < 0) {
+			print("Scenario C, seteuid(%d) failed, skipping"\
+			    " rest of scenario ...\n", uid2);
+			goto child_end;
+		}
+
+		expecterr = (expect[4] == EBADF) ? EACCES : OK;
+		fd1 = open_file(filename, oflag, mode);
+		fd2 = open_file("olinkfile.txt", oflag, mode);
+
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(expect[4], errno);
+		read_file(fd2, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[4], errno);
+		read_file(fd3, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(expect[5], errno);
+		write_file(fd2, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[5], errno);
+		write_file(fd3, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[3], errno);
+
+		close_file(fd1, filename);
+		close_file(fd2, "olinkfile.txt");
+
+		admerrors(ASSERT);
+
+
+/* assertion f) */
+		sprintf(tmp, "Child change credentials to owner %ld, group %ld,"
+		"\n\treopen file on fd1, hardlink on fd2, check read/write all"
+		"3 fds\n\tand close fd1 and fd2", uid2, gid2);
+		assertion("f", tmp, "multiple");
+
+		if (Seteuid(0) < 0) {
+			print("Scenario C, seteuid(root) failed, skipping"\
+			    " rest of scenario ...\n");
+			goto child_end;
+		}
+		if (Setegid(gid2) < 0) {
+			print("Scenario C, setegid(%d) failed, skipping"\
+			    "rest of scenario ...\n", gid2);
+			goto child_end;
+		}
+		{
+		gid_t gid = gid2;
+
+		if (Setgroups(1, &gid) < 0) {
+			print("Scenario C, setgroups(1, %d) failed, "\
+			    "skipping rest of scenario ...\n", gid);
+			goto child_end;
+		}
+		}
+		if (Seteuid(uid2) < 0) {
+			print("Scenario C, seteuid(%d) failed, skipping"\
+			    " rest of scenario ...\n", uid2);
+			goto child_end;
+		}
+
+		expecterr = EACCES;
+		fd1 = open_file(filename, oflag, mode);
+		fd2 = open_file("olinkfile.txt", oflag, mode);
+
+		if (debug != 0)
+			system("ls -la *file.txt; id -ap");
+		read_file(fd1, filename, buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd2, "olinkfile.txt", buf, 0, 26);
+		tresult(EBADF, errno);
+		read_file(fd3, "olinkfile.txt", buf, 0, 26);
+		tresult(expect[2], errno);
+
+		write_file(fd1, filename, DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd2, "olinkfile.txt", DD, 0, 26);
+		tresult(EBADF, errno);
+		write_file(fd3, "olinkfile.txt", DD, 0, 26);
+		tresult(expect[3], errno);
+
+		close_file(fd1, filename);
+		close_file(fd2, "olinkfile.txt");
+
+		admerrors(ASSERT);
+
+		contp();
+		wait_send_cresult();
+
+		while (1)
+			sleep(1);
+	}
+
+	if (me == PARENT) {
+		if (wait_get_cresult())
+			ret = NOOK;
+
+		kill_child(OK);
+
+		goto clean_up;
+	}
+
+	if (me == CHILD) {
+		print("ERROR: child should be dead. Quitting ...\n");
+		exit_test(NOOK);
+	}
+
+child_end:
+	tresult(OK, errno);
+	admerrors(ASSERT);
+
+	contp();
+	while (1)
+		sleep(1);
+
+clean_up:
+	unlink_file(filename);
+	unlink_file("olinkfile.txt");
+
+	if (admerrors(SCENARIO))
+		ret = NOOK;
+	print("Scenario C finished.\n\n\n\n");
+	return (ret);
+}
+
+int
+scenarioD(int mode, int oflag, int expect[])
+{
+	int fd1, fd2, fd3;
+	char *DD;
+	int ret = OK;
+
+	scen = "ScenD";
+	scen_mode = mode;
+	scen_flag = oflag;
+	expecterr = NOOK;
+
+	fprintf(stdout, "\n\nExecuting Scenario D, with mode = 0%o and "\
+	    "oflag = %s\n\n", mode, oflagstr(oflag));
+
+	DD = strbackup("#123456789#123456789#123456789");
+
+	if ((create_test_data_file(filename, mode)) ||
+	    link_file(filename, "olinkfile.txt")) {
+		printf("The scenario initialization failed, "\
+		    "and other subassertions won't run.\n\n");
+		exit_test(NOOK);
+	}
+
+/* assertion a) */
+	assertion("a",
+	    "Opens a file on file desc fd1 and change permissions to 0000",
+	    "multiple");
+	fd1 = open_file(filename, oflag, mode);
+	tresult(OK, errno);
+	chmod_file(fd1, filename, 0000);
+	tresult(OK, errno);
+	admerrors(ASSERT);
+
+	expecterr = EACCES;
+
+	if (fd1 < 0) {
+		if (expect[0] == OK) {
+			printf("scenarioD{rest}: open calls\n");
+			printf("\t Test OTHER: unexpected open failure\n");
+		}
+		print("Scenario D, skipping rest of scenario.\n");
+		goto clean_up;
+	}
+
+	/* initialize pipes and create the child */
+	initialize();
+
+	if (me == PARENT) {
+		sleep(1);	/* let child start */
+		contch();
+		waitp();
+	}
+
+	if (me == CHILD) {
+		waitch();
+
+/* assertion b) */
+		assertion("b", "Child opens the file on file desc fd3",
+		    errtostr(EACCES));
+		fd3 = open_file(filename, oflag, mode);
+		tresult(EACCES, errno);
+		admerrors(ASSERT);
+
+/* assertion c) */
+		assertion("c", "Child opens the a hardlink to file on fd2",
+		    errtostr(EACCES));
+		fd2 = open_file("olinkfile.txt", oflag, mode);
+		tresult(EACCES, errno);
+		admerrors(ASSERT);
+
+		contp();
+		wait_send_cresult();
+
+		while (1)
+			sleep(1);
+	}
+
+	if (me == PARENT) {
+		goto clean_up;
+	}
+
+	if (me == CHILD) {
+		print("ERROR: child should be dead. Quitting ...\n");
+		exit_test(NOOK);
+	}
+
+clean_up:
+	close_file(fd1, filename);
+
+	if (wait_get_cresult())
+		ret = NOOK;
+	kill_child(OK);
+
+	unlink_file(filename);
+	unlink_file("olinkfile.txt");
+
+	if (admerrors(SCENARIO))
+		ret = NOOK;
+	print("Scenario D finished.\n\n\n\n");
+	return (ret);
+}
+
+int
+scenarioE(int mode, int oflag, int expect[])
+{
+	int	fd1, fd2;
+
+	scen = "ScenE";
+	scen_mode = mode;
+	scen_flag = oflag;
+	expecterr = OK;
+	int ret = OK;
+
+	fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and " \
+	    "oflag = %s\n\n", mode, oflagstr(oflag));
+
+	/* assertion a ) */
+	assertion("a", "open a file with trunc option after a success open \
+	will success", errtostr(expecterr));
+	errno = OK;
+	fd1 = open_file(filename, O_CREAT, scen_mode);
+	tresult(OK, errno);
+	fd2 = open_file(filename, scen_flag, scen_mode);
+	tresult(OK, errno);
+	admerrors(ASSERT);
+	if (fd1 > 0)
+		close_file(fd1, filename);
+	if (fd2 > 0)
+		close_file(fd2, filename);
+	unlink_file(filename);
+
+	if (admerrors(SCENARIO))
+		ret = NOOK;
+	print("Scenario E finished.\n\n\n");
+	return (ret);
+}
