Tests for new security context stuff.
authorTim Potter <tpot@samba.org>
Fri, 23 Jun 2000 06:21:08 +0000 (06:21 +0000)
committerTim Potter <tpot@samba.org>
Fri, 23 Jun 2000 06:21:08 +0000 (06:21 +0000)
(This used to be commit 85a68bc449a071d21e03ad4f54c1e784831a9bb5)

12 files changed:
testsuite/smbd/Makefile.sec_ctx [new file with mode: 0644]
testsuite/smbd/sec_ctx.exp [new file with mode: 0644]
testsuite/smbd/sec_ctx1.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_current_user.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_flow.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_groups.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_nonroot.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_root.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_stack.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_torture.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_utils.c [new file with mode: 0644]
testsuite/smbd/sec_ctx_utils.h [new file with mode: 0644]

diff --git a/testsuite/smbd/Makefile.sec_ctx b/testsuite/smbd/Makefile.sec_ctx
new file mode 100644 (file)
index 0000000..c45ab5b
--- /dev/null
@@ -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 (file)
index 0000000..0831400
--- /dev/null
@@ -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 (file)
index 0000000..b74b6ed
--- /dev/null
@@ -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 (file)
index 0000000..5b7da0e
--- /dev/null
@@ -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 (file)
index 0000000..7b25178
--- /dev/null
@@ -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 (file)
index 0000000..61d77f6
--- /dev/null
@@ -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 (file)
index 0000000..18bba7e
--- /dev/null
@@ -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 (file)
index 0000000..f2e46f0
--- /dev/null
@@ -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 (file)
index 0000000..f6952fa
--- /dev/null
@@ -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 (file)
index 0000000..effee06
--- /dev/null
@@ -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 (file)
index 0000000..4d05881
--- /dev/null
@@ -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 (file)
index 0000000..1f4bde8
--- /dev/null
@@ -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 */