summaryrefslogtreecommitdiff
path: root/testsuite/smbd
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2000-06-23 06:21:08 +0000
committerTim Potter <tpot@samba.org>2000-06-23 06:21:08 +0000
commitc4f74ddb8344c7daf052484bb3e4bbce9b57db23 (patch)
tree26e462c624e44d4db418dcc1a1ec706d53827f9a /testsuite/smbd
parent0c4d1e7e855743f36d0d3486aa0b9ede32012eb0 (diff)
downloadsamba-c4f74ddb8344c7daf052484bb3e4bbce9b57db23.tar.gz
samba-c4f74ddb8344c7daf052484bb3e4bbce9b57db23.tar.bz2
samba-c4f74ddb8344c7daf052484bb3e4bbce9b57db23.zip
Tests for new security context stuff.
(This used to be commit 85a68bc449a071d21e03ad4f54c1e784831a9bb5)
Diffstat (limited to 'testsuite/smbd')
-rw-r--r--testsuite/smbd/Makefile.sec_ctx57
-rw-r--r--testsuite/smbd/sec_ctx.exp67
-rw-r--r--testsuite/smbd/sec_ctx1.c40
-rw-r--r--testsuite/smbd/sec_ctx_current_user.c114
-rw-r--r--testsuite/smbd/sec_ctx_flow.c73
-rw-r--r--testsuite/smbd/sec_ctx_groups.c131
-rw-r--r--testsuite/smbd/sec_ctx_nonroot.c42
-rw-r--r--testsuite/smbd/sec_ctx_root.c61
-rw-r--r--testsuite/smbd/sec_ctx_stack.c86
-rw-r--r--testsuite/smbd/sec_ctx_torture.c103
-rw-r--r--testsuite/smbd/sec_ctx_utils.c65
-rw-r--r--testsuite/smbd/sec_ctx_utils.h30
12 files changed, 869 insertions, 0 deletions
diff --git a/testsuite/smbd/Makefile.sec_ctx b/testsuite/smbd/Makefile.sec_ctx
new file mode 100644
index 0000000000..c45ab5bb5e
--- /dev/null
+++ b/testsuite/smbd/Makefile.sec_ctx
@@ -0,0 +1,57 @@
+#
+# Makefile for sec_ctx tests
+#
+
+include ../../source/Makefile
+
+# Objects common to all tests
+
+SEC_CTX_OBJ1 = $(RPC_CLIENT_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PARAM_OBJ) \
+ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(UBIQX_OBJ) smbd/password.o smbd/uid.o \
+ smbd/chgpasswd.o smbd/sec_ctx.o
+
+SEC_CTX_OBJS = $(SEC_CTX_OBJ1:%=$(srcdir)/%) sec_ctx_utils.o
+
+# Targets for tests
+
+SEC_CTX_NONROOT_OBJS = $(SEC_CTX_OBJS) sec_ctx_nonroot.o
+
+sec_ctx_nonroot: $(SEC_CTX_NONROOT_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_NONROOT_OBJS) $(LIBS)
+
+SEC_CTX_STACK_OBJS = $(SEC_CTX_OBJS) sec_ctx_stack.o
+
+sec_ctx_stack: $(SEC_CTX_STACK_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_STACK_OBJS) $(LIBS)
+
+SEC_CTX_FLOW_OBJS = $(SEC_CTX_OBJS) sec_ctx_flow.o
+
+sec_ctx_flow: $(SEC_CTX_FLOW_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_FLOW_OBJS) $(LIBS)
+
+SEC_CTX_TORTURE_OBJS = $(SEC_CTX_OBJS) sec_ctx_torture.o
+
+sec_ctx_torture: $(SEC_CTX_TORTURE_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_TORTURE_OBJS) $(LIBS)
+
+SEC_CTX_CURRENT_USER_OBJS = $(SEC_CTX_OBJS) sec_ctx_current_user.o
+
+sec_ctx_current_user: $(SEC_CTX_CURRENT_USER_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_CURRENT_USER_OBJS) $(LIBS)
+
+SEC_CTX_GROUPS_OBJS = $(SEC_CTX_OBJS) sec_ctx_groups.o
+
+sec_ctx_groups: $(SEC_CTX_GROUPS_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_GROUPS_OBJS) $(LIBS)
+
+SEC_CTX_ROOT_OBJS = $(SEC_CTX_OBJS) sec_ctx_root.o
+
+sec_ctx_root: $(SEC_CTX_ROOT_OBJS)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SEC_CTX_ROOT_OBJS) $(LIBS)
diff --git a/testsuite/smbd/sec_ctx.exp b/testsuite/smbd/sec_ctx.exp
new file mode 100644
index 0000000000..0831400e70
--- /dev/null
+++ b/testsuite/smbd/sec_ctx.exp
@@ -0,0 +1,67 @@
+#
+# @(#) Test the push_sec_ctx() and pop_sec_ctx() functions
+#
+
+#
+# Unix SMB/Netbios implementation.
+# Copyright (C) Tim Potter 2000
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+load_lib "compile.exp"
+load_lib "util-defs.exp"
+
+# Non-root test
+
+set test_desc "change sec_ctx as non-root"
+set test_prog "sec_ctx_nonroot"
+simple_make "sec_ctx" $test_prog
+set output [util_start "$srcdir/$subdir/$test_prog"]
+
+if { [regexp "child killed" $output] } {
+ pass $test_desc
+ file delete "$srcdir/$subdir/$test_prog" "$srcdir/$subdir/$test_prog.o"
+} else {
+ fail $test_desc
+}
+
+# Run tests from C files as root
+
+set sec_ctx_tests [list \
+ { "security contexts are stackable" "sec_ctx_stack" } \
+ { "over/underflow tests" "sec_ctx_flow" } \
+ { "torture test" "sec_ctx_torture" } \
+ { "current_user global" "sec_ctx_current_user" } \
+ { "group membership" "sec_ctx_groups" } \
+ { "become root" "sec_ctx_root" } \
+ ]
+
+foreach { test } $sec_ctx_tests {
+ set test_desc [lindex $test 0]
+ set test_file [lindex $test 1]
+
+ simple_make "sec_ctx" $test_file
+ set output [util_start "sudo $srcdir/$subdir/$test_file" ]
+
+ if { [regexp "PASS" $output] } {
+ pass $test_desc
+ file delete "$srcdir/$subdir/$test_file" "$srcdir/$subdir/$test_file.o"
+ } else {
+ fail $test_desc
+ puts $output
+ }
+
+}
diff --git a/testsuite/smbd/sec_ctx1.c b/testsuite/smbd/sec_ctx1.c
new file mode 100644
index 0000000000..b74b6ed900
--- /dev/null
+++ b/testsuite/smbd/sec_ctx1.c
@@ -0,0 +1,40 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+void exit_server(char *reason) {}
+
+int main (int argc, char **argv)
+{
+ /* Become a non-root user */
+
+ setuid(1);
+ setgid(1);
+
+ /* Try to push a security context. This should fail with a
+ smb_assert() error. */
+
+ push_sec_ctx(2, 2);
+ printf("FAIL\n");
+
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_current_user.c b/testsuite/smbd/sec_ctx_current_user.c
new file mode 100644
index 0000000000..5b7da0ef46
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_current_user.c
@@ -0,0 +1,114 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+int main(int argc, char **argv)
+{
+ extern struct current_user current_user;
+ uid_t initial_uid = current_user.uid;
+ gid_t initial_gid = current_user.gid;
+ int ngroups;
+ gid_t *groups;
+
+ init_sec_ctx();
+
+ /* Check initial id */
+
+ if (initial_uid != 0 || initial_gid != 0) {
+ printf("FAIL: current_user not initialised to root\n");
+ return 1;
+ }
+
+ /* Push a context and check current user is updated */
+
+ if (!push_sec_ctx()) {
+ printf("FAIL: push_sec_ctx\n");
+ return 1;
+ }
+
+ set_sec_ctx(1, 2, 0, NULL);
+
+ if (current_user.uid != 1 || current_user.gid != 2) {
+ printf("FAIL: current_user id not updated after push\n");
+ return 1;
+ }
+
+ if (current_user.ngroups != 0 || current_user.groups) {
+ printf("FAIL: current_user groups not updated after push\n");
+ return 1;
+ }
+
+ /* Push another */
+
+ get_random_grouplist(&ngroups, &groups);
+
+ if (!push_sec_ctx()) {
+ printf("FAIL: push_sec_ctx\n");
+ return 1;
+ }
+
+ set_sec_ctx(2, 3, ngroups, groups);
+
+ if (current_user.uid != 2 || current_user.gid != 3) {
+ printf("FAIL: current_user id not updated after second "
+ "push\n");
+ return 1;
+ }
+
+ if (current_user.ngroups != ngroups ||
+ (memcmp(current_user.groups, groups,
+ sizeof(gid_t) * ngroups) != 0)) {
+ printf("FAIL: current_user groups not updated\n");
+ return 1;
+ }
+
+ /* Pop them both off */
+
+ if (!pop_sec_ctx()) {
+ printf("FAIL: pop_sec_ctx\n");
+ return 1;
+ }
+
+ if (current_user.uid != 1 || current_user.gid != 2) {
+ printf("FAIL: current_user not updaded pop\n");
+ return 1;
+ }
+
+ if (!pop_sec_ctx()) {
+ printf("FAIL: pop_sec_ctx\n");
+ return 1;
+ }
+
+ /* Check initial state was returned */
+
+ if (current_user.uid != initial_uid ||
+ current_user.gid != initial_gid) {
+ printf("FAIL: current_user not updaded pop\n");
+ return 1;
+ }
+
+ /* Everything's cool */
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_flow.c b/testsuite/smbd/sec_ctx_flow.c
new file mode 100644
index 0000000000..7b25178467
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_flow.c
@@ -0,0 +1,73 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+int main (int argc, char **argv)
+{
+ int i;
+
+ init_sec_ctx();
+
+ /* Check for underflow */
+
+ if (!push_sec_ctx()) {
+ printf("FAIL: push_sec_ctx\n");
+ return 1;
+ }
+
+ set_sec_ctx(1, 1, 0, NULL);
+
+ if (!pop_sec_ctx()) {
+ printf("FAIL: pop_sec_ctx\n");
+ return 1;
+ }
+
+ if (pop_sec_ctx()) {
+ printf("FAIL: underflow push_sec_ctx\n");
+ return 1;
+ }
+
+ /* Check for overflow */
+
+ for (i = 0; i < MAX_SEC_CTX_DEPTH + 1; i++) {
+ BOOL result;
+
+ result = push_sec_ctx();
+ set_sec_ctx(i, i, 0, NULL);
+
+ if ((i < MAX_SEC_CTX_DEPTH) && !result) {
+ printf("FAIL: push_sec_ctx(%d)\n", i);
+ return 1;
+ }
+
+ if ((i == MAX_SEC_CTX_DEPTH + 1) && result) {
+ printf("FAIL: overflow push_sec_ctx(%d)\n", i);
+ return 1;
+ }
+ }
+
+ /* Everything's cool */
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_groups.c b/testsuite/smbd/sec_ctx_groups.c
new file mode 100644
index 0000000000..61d77f6f4f
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_groups.c
@@ -0,0 +1,131 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+int main (int argc, char **argv)
+{
+ int ngroups, initial_ngroups, check_ngroups, final_ngroups;
+ gid_t *groups, *initial_groups, *check_groups, *final_groups;
+ int i;
+
+ init_sec_ctx();
+
+ /* Save current groups */
+
+ initial_ngroups = sys_getgroups(0, NULL);
+ initial_groups = malloc(sizeof(gid_t) * initial_ngroups);
+ sys_getgroups(initial_ngroups, initial_groups);
+
+ printf("Initial groups are: ");
+ for (i = 0; i < initial_ngroups; i++) {
+ printf("%d, ", initial_groups[i]);
+ }
+ printf("\n");
+
+ /* Push a context plus groups */
+
+ get_random_grouplist(&ngroups, &groups);
+
+ printf("Random groups are: ");
+ for (i = 0; i < ngroups; i++) {
+ printf("%d, ", groups[i]);
+ }
+ printf("\n");
+
+ if (!push_sec_ctx()) {
+ printf("FAIL: push_sec_ctx\n");
+ return 1;
+ }
+
+ set_sec_ctx(1, 2, ngroups, groups);
+
+ /* Check grouplist stuck */
+
+ check_ngroups = sys_getgroups(0, NULL);
+ check_groups = malloc(sizeof(gid_t) * check_ngroups);
+ sys_getgroups(check_ngroups, check_groups);
+
+ printf("Actual groups are: ");
+ for (i = 0; i < check_ngroups; i++) {
+ printf("%d, ", check_groups[i]);
+ }
+ printf("\n");
+
+ if (ngroups != check_ngroups) {
+ printf("FAIL: number of groups differs\n");
+ return 1;
+ }
+
+ for (i = 0; i < ngroups; i++) {
+ if (groups[i] != check_groups[i]) {
+ printf("FAIL: group %d differs\n", i);
+ return 1;
+ }
+ }
+
+ safe_free(groups);
+ safe_free(check_groups);
+
+ /* Pop and check initial groups are back */
+
+ if (!pop_sec_ctx()) {
+ printf("FAIL: pop_sec_ctx\n");
+ return 1;
+ }
+
+ final_ngroups = sys_getgroups(0, NULL);
+ final_groups = malloc(sizeof(gid_t) * final_ngroups);
+ sys_getgroups(final_ngroups, final_groups);
+
+ printf("Final groups are: ");
+ for (i = 0; i < final_ngroups; i++) {
+ printf("%d, ", final_groups[i]);
+ }
+ printf("\n");
+
+ if (initial_ngroups != final_ngroups) {
+ printf("FAIL: final number of groups differ\n");
+ return 1;
+ }
+
+ for (i = 0; i < initial_ngroups; i++) {
+ if (initial_groups[i] != final_groups[i]) {
+ printf("FAIL: final group %d differs\n", i);
+ return 1;
+ }
+ }
+
+ printf("Final groups are: ");
+ for (i = 0; i < final_ngroups; i++) {
+ printf("%d, ", final_groups[i]);
+ }
+ printf("\n");
+
+ safe_free(initial_groups);
+ safe_free(final_groups);
+
+ /* Everything's cool */
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_nonroot.c b/testsuite/smbd/sec_ctx_nonroot.c
new file mode 100644
index 0000000000..18bba7e280
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_nonroot.c
@@ -0,0 +1,42 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+int main (int argc, char **argv)
+{
+ init_sec_ctx();
+
+ /* Become a non-root user */
+
+ setuid(1);
+ setgid(1);
+
+ /* Try to push a security context. This should fail with a
+ smb_assert() error. */
+
+ push_sec_ctx();
+ set_sec_ctx(2, 2, 0, NULL);
+ printf("FAIL\n");
+
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_root.c b/testsuite/smbd/sec_ctx_root.c
new file mode 100644
index 0000000000..f2e46f0a5c
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_root.c
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+int main (int argc, char **argv)
+{
+ int ngroups, actual_ngroups;
+ gid_t *groups, *actual_groups;
+ extern struct current_user current_user;
+
+ init_sec_ctx();
+
+ /* Initialise a security context */
+
+ get_random_grouplist(&ngroups, &groups);
+ set_sec_ctx(1, 1, ngroups, groups);
+
+ /* Become root and check */
+
+ set_root_sec_ctx();
+
+ actual_ngroups = getgroups(0, NULL);
+ actual_groups = (gid_t *)malloc(actual_ngroups * sizeof(gid_t));
+
+ getgroups(actual_ngroups, actual_groups);
+
+ if (geteuid() != 0 || getegid() != 0 || actual_ngroups != 0) {
+ printf("FAIL: root id not set\n");
+ return 1;
+ }
+
+ if (current_user.uid != 0 || current_user.gid != 0 ||
+ current_user.ngroups != 0 || current_user.groups) {
+ printf("FAIL: current_user not set correctly\n");
+ return 1;
+ }
+
+ printf("PASS\n");
+
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_stack.c b/testsuite/smbd/sec_ctx_stack.c
new file mode 100644
index 0000000000..f6952fabb4
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_stack.c
@@ -0,0 +1,86 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+int main (int argc, char **argv)
+{
+ BOOL result;
+ int i;
+
+ init_sec_ctx();
+
+ /* Push a whole bunch of security contexts */
+
+ for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) {
+
+ result = push_sec_ctx();
+ set_sec_ctx(i + 1, i + 2, 0, NULL);
+
+ if (!result) {
+ printf("FAIL: push_sec_ctx(%d)\n", i);
+ return 1;
+ }
+
+ printf("pushed context (%d, %d) eff=(%d, %d)\n",
+ getuid(), getgid(), geteuid(), getegid());
+
+ if ((geteuid() != i + 1) || (getegid() != i + 2)) {
+ printf("FAIL: incorrect context pushed\n");
+ return 1;
+ }
+ }
+
+ /* Pop them all off */
+
+ for (i = MAX_SEC_CTX_DEPTH; i > 0; i--) {
+
+ result = pop_sec_ctx();
+
+ if (!result) {
+ printf("FAIL: pop_sec_ctx(%d)\n", i);
+ return 1;
+ }
+
+ printf("popped context (%d, %d) eff=(%d, %d)\n",
+ getuid(), getgid(), geteuid(), getegid());
+
+ printf("i = %d\n",i);
+
+ if (i > 1) {
+ if ((geteuid() != i - 1) || (getegid() != i)) {
+ printf("FAIL: incorrect context popped\n");
+ return 1;
+ }
+ } else {
+ if ((geteuid() != 0) || (getegid() != 0)) {
+ printf("FAIL: incorrect context popped\n");
+ return 1;
+ }
+ }
+ }
+
+ /* Everything's cool */
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_torture.c b/testsuite/smbd/sec_ctx_torture.c
new file mode 100644
index 0000000000..effee069ef
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_torture.c
@@ -0,0 +1,103 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sec_ctx_utils.h"
+
+#define NUM_TESTS 10000
+
+int main (int argc, char **argv)
+{
+ int seed, level = 0, num_tests = 0;
+
+ init_sec_ctx();
+
+ if (argc == 1) {
+ seed = time(NULL);
+ } else {
+ seed = atoi(argv[1]);
+ }
+
+ printf("seed = %d\n", seed);
+
+ while(num_tests < NUM_TESTS) {
+ switch (random() % 2) {
+
+ /* Push a random context */
+
+ case 0:
+ if (level < MAX_SEC_CTX_DEPTH) {
+ int ngroups;
+ gid_t *groups;
+
+ if (!push_sec_ctx()) {
+ printf("FAIL: push random ctx\n");
+ return 1;
+ }
+
+ get_random_grouplist(&ngroups, &groups);
+
+ set_sec_ctx(random() % 32767,
+ random() % 32767,
+ ngroups, groups);
+
+ if (!verify_current_groups(ngroups,
+ groups)) {
+ printf("FAIL: groups did not stick\n");
+ return 1;
+ }
+
+ printf("pushed (%d, %d) eff=(%d, %d)\n",
+ getuid(), getgid(), geteuid(),
+ getegid());
+
+ level++;
+ num_tests++;
+
+ free(groups);
+ }
+ break;
+
+ /* Pop a random context */
+
+ case 1:
+ if (level > 0) {
+ if (!pop_sec_ctx()) {
+ printf("FAIL: pop random ctx\n");
+ return 1;
+ }
+
+ printf("popped (%d, %d) eff=(%d, %d)\n",
+ getuid(), getgid(), geteuid(),
+ getegid());
+
+ level--;
+ num_tests++;
+ }
+ break;
+ }
+ }
+
+ /* Everything's cool */
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/testsuite/smbd/sec_ctx_utils.c b/testsuite/smbd/sec_ctx_utils.c
new file mode 100644
index 0000000000..4d0588196d
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_utils.c
@@ -0,0 +1,65 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* Keep linker happy */
+
+void exit_server(char *reason) {}
+
+/* Generate random list of groups */
+
+void get_random_grouplist(int *ngroups, gid_t **groups)
+{
+ int i;
+
+ *ngroups = random() % groups_max();
+ *groups = malloc(*ngroups * sizeof(gid_t));
+
+ if (!groups) {
+ printf("FAIL: malloc random grouplist\n");
+ return 1;
+ }
+
+ for (i = 0; i < *ngroups; i++) {
+ (*groups)[i] = random() % 32767;
+ }
+}
+
+/* Check a list of groups with current groups */
+
+BOOL verify_current_groups(int ngroups, gid_t *groups)
+{
+ int actual_ngroups;
+ gid_t *actual_groups;
+
+ actual_ngroups = getgroups(0, NULL);
+ actual_groups = (gid_t *)malloc(actual_ngroups * sizeof(gid_t));
+
+ getgroups(actual_ngroups, actual_groups);
+
+ if (actual_ngroups != ngroups) {
+ return False;
+ }
+
+ return memcmp(actual_groups, groups, actual_ngroups *
+ sizeof(gid_t)) == 0;
+}
diff --git a/testsuite/smbd/sec_ctx_utils.h b/testsuite/smbd/sec_ctx_utils.h
new file mode 100644
index 0000000000..1f4bde841e
--- /dev/null
+++ b/testsuite/smbd/sec_ctx_utils.h
@@ -0,0 +1,30 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Security context tests
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SEC_CTX_UTILS_H
+#define _SEC_CTX_UTILS_H
+
+/* Function prototypes */
+
+void get_random_grouplist(int *ngroups, gid_t **groups);
+BOOL verify_current_groups(int ngroups, gid_t *groups);
+
+#endif /* _SEC_CTX_UTILS_H */