The branch, master has been updated via f5a0ccc selftest: re-enable nsswrapper integration testing for dc and member environments. via 975073a s4-torture: cleanup nsswrapper test a little by removing nwrap references. via 64e0231 s4-torture: re-add nss-wrapper torture testsuite. from e2ed224 doc-xml: Add 'sharesec' reference to 'access based share enum'
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit f5a0ccc228ce1ef7d9e0e660308b5bfa15d8cf76 Author: Michael Adam <ob...@samba.org> Date: Mon Feb 2 16:16:45 2015 +0100 selftest: re-enable nsswrapper integration testing for dc and member environments. There are some failures: - The dc environment fails consistently due to duplicate uid, (for the calling user and the domain administrator). ==> Marked as knownfail. - The s3member environment only fails under very strange circumstances: - one needs to run the unix.whoami test in the member and s3member environment for the local.nss test to fail in the s3member:local env. The failure is then related to builtin administrators sharing a gid with a different group. --> This is really really strange!!! ==> Marked as knownfail. Pair-Programmed-With: Guenther Deschner <g...@samba.org> Signed-off-by: Michael Adam <ob...@samba.org> Signed-off-by: Günther Deschner <g...@samba.org> Autobuild-User(master): Günther Deschner <g...@samba.org> Autobuild-Date(master): Mon Mar 2 19:50:55 CET 2015 on sn-devel-104 commit 975073adc1dece6ab65dcb0bf533b583fbab1d38 Author: Günther Deschner <g...@samba.org> Date: Sat Feb 7 14:10:01 2015 +0100 s4-torture: cleanup nsswrapper test a little by removing nwrap references. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 64e0231c52dbb99d6f1671201bd6369efa7ecf49 Author: Günther Deschner <g...@samba.org> Date: Mon Feb 2 14:50:30 2015 +0100 s4-torture: re-add nss-wrapper torture testsuite. (The testsuite got removed with 5bb410f85312196bb24e62a6a0b8350576433dc6). Although nss_wrapper now also has an upstream testsuite, it is still important to run the older torture testsuite within Samba so we have some testing on nss_winbind correctnes and consistency. Guenther Signed-off-by: Günther Deschner <g...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/knownfail | 14 + source3/selftest/tests.py | 5 +- source4/torture/local/local.c | 1 + source4/torture/local/nss_tests.c | 954 ++++++++++++++++++++++++++++++++++++ source4/torture/local/wscript_build | 3 +- 5 files changed, 975 insertions(+), 2 deletions(-) create mode 100644 source4/torture/local/nss_tests.c Changeset truncated at 500 lines: diff --git a/selftest/knownfail b/selftest/knownfail index fef56a1..b3cc2d6 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -273,6 +273,20 @@ ^samba.wbinfo_simple.\(s4member:local\).--user-groups ^samba.nss.test using winbind\(s4member:local\) # +# These fail since dc assigns the local user's uid to SAMBADOMAIN/Administrator +# hence we have a duplicate UID in nsswitch. +# +^samba3.local.nss.reentrant enumeration crosschecks\(dc:local\) +^samba3.local.nss.reentrant enumeration\(dc:local\) +^samba3.local.nss.enumeration\(dc:local\) +# +# These fail only if we run the unix.whoami test before them +# in the member and s3member environments. ==> Strange!!! +# +^samba3.local.nss.reentrant enumeration crosschecks\(s3member:local\) +^samba3.local.nss.reentrant enumeration\(s3member:local\) +^samba3.local.nss.enumeration\(s3member:local\) +# # These just happen to fail for some reason (probably because they run against the s4 winbind) # ^samba4.winbind.struct.getdcname\(s3member:local\) diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 0a59903..ab34cd5 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -280,7 +280,7 @@ rpc = ["rpc.authcontext", "rpc.samba3.bind", "rpc.samba3.srvsvc", "rpc.samba3.sh "rpc.netlogon.admin", "rpc.schannel", "rpc.schannel2", "rpc.bench-schannel1", "rpc.schannel_anon_setpw", "rpc.join", "rpc.bind"] -local = ["local.ndr"] +local = ["local.nss", "local.ndr"] idmap = [ "idmap.rfc2307" ] @@ -376,6 +376,9 @@ for t in tests: plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$%', description="anonymous password set") plansmbtorture4testsuite(t, "s3dc_schannel", '//$SERVER_IP/tmp -U$%', description="anonymous password set (schannel enforced server-side)") plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$%', description="anonymous password set") + elif t == "local.nss": + for env in ["s3dc:local", "s3member:local", "member:local", "plugin_s4_dc:local", "dc:local"]: + plansmbtorture4testsuite(t, env, '//$SERVER/tmp -U$USERNAME%$PASSWORD') else: plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c index f69c95e..45cc712 100644 --- a/source4/torture/local/local.c +++ b/source4/torture/local/local.c @@ -69,6 +69,7 @@ torture_dsdb_syntax, torture_registry, torture_local_verif_trailer, + torture_local_nss, NULL }; diff --git a/source4/torture/local/nss_tests.c b/source4/torture/local/nss_tests.c new file mode 100644 index 0000000..a6baf21 --- /dev/null +++ b/source4/torture/local/nss_tests.c @@ -0,0 +1,954 @@ +/* + Unix SMB/CIFS implementation. + + local testing of the nss wrapper + + Copyright (C) Guenther Deschner 2009-2010 + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" + +#include "torture/torture.h" +#include "torture/local/proto.h" +#include "lib/replace/system/passwd.h" + +static bool copy_passwd(struct torture_context *tctx, + const struct passwd *pwd, + struct passwd *p) +{ + p->pw_name = talloc_strdup(tctx, pwd->pw_name); + p->pw_passwd = talloc_strdup(tctx, pwd->pw_passwd); + p->pw_uid = pwd->pw_uid; + p->pw_gid = pwd->pw_gid; + p->pw_gecos = talloc_strdup(tctx, pwd->pw_gecos); + p->pw_dir = talloc_strdup(tctx, pwd->pw_dir); + p->pw_shell = talloc_strdup(tctx, pwd->pw_shell); + + return true; +} + +static void print_passwd(struct passwd *pwd) +{ + printf("%s:%s:%lu:%lu:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + (unsigned long)pwd->pw_uid, + (unsigned long)pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); +} + + +static bool test_getpwnam(struct torture_context *tctx, + const char *name, + struct passwd *pwd_p) +{ + struct passwd *pwd; + + torture_comment(tctx, "Testing getpwnam: %s\n", name); + + pwd = getpwnam(name); + if (pwd) { + print_passwd(pwd); + } + + if (pwd_p) { + copy_passwd(tctx, pwd, pwd_p); + } + + return pwd ? true : false; +} + +static bool test_getpwnam_r(struct torture_context *tctx, + const char *name, + struct passwd *pwd_p) +{ + struct passwd pwd, *pwdp; + char buffer[4096]; + int ret; + + torture_comment(tctx, "Testing getpwnam_r: %s\n", name); + + ret = getpwnam_r(name, &pwd, buffer, sizeof(buffer), &pwdp); + if (ret != 0) { + if (ret != ENOENT) { + torture_comment(tctx, "got %d return code\n", ret); + } + return false; + } + + print_passwd(&pwd); + + if (pwd_p) { + copy_passwd(tctx, &pwd, pwd_p); + } + + return true; +} + +static bool test_getpwuid(struct torture_context *tctx, + uid_t uid, + struct passwd *pwd_p) +{ + struct passwd *pwd; + + torture_comment(tctx, "Testing getpwuid: %lu\n", (unsigned long)uid); + + pwd = getpwuid(uid); + if (pwd) { + print_passwd(pwd); + } + + if (pwd_p) { + copy_passwd(tctx, pwd, pwd_p); + } + + return pwd ? true : false; +} + +static bool test_getpwuid_r(struct torture_context *tctx, + uid_t uid, + struct passwd *pwd_p) +{ + struct passwd pwd, *pwdp; + char buffer[4096]; + int ret; + + torture_comment(tctx, "Testing getpwuid_r: %lu\n", (unsigned long)uid); + + ret = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &pwdp); + if (ret != 0) { + if (ret != ENOENT) { + torture_comment(tctx, "got %d return code\n", ret); + } + return false; + } + + print_passwd(&pwd); + + if (pwd_p) { + copy_passwd(tctx, &pwd, pwd_p); + } + + return true; +} + + +static bool copy_group(struct torture_context *tctx, + const struct group *grp, + struct group *g) +{ + int i; + + g->gr_name = talloc_strdup(tctx, grp->gr_name); + g->gr_passwd = talloc_strdup(tctx, grp->gr_passwd); + g->gr_gid = grp->gr_gid; + g->gr_mem = NULL; + + for (i=0; grp->gr_mem && grp->gr_mem[i]; i++) { + g->gr_mem = talloc_realloc(tctx, g->gr_mem, char *, i + 2); + g->gr_mem[i] = talloc_strdup(g->gr_mem, grp->gr_mem[i]); + g->gr_mem[i+1] = NULL; + } + + return true; +} + +static void print_group(struct group *grp) +{ + int i; + printf("%s:%s:%lu:", + grp->gr_name, + grp->gr_passwd, + (unsigned long)grp->gr_gid); + + if ((grp->gr_mem == NULL) || !grp->gr_mem[0]) { + printf("\n"); + return; + } + + for (i=0; grp->gr_mem[i+1]; i++) { + printf("%s,", grp->gr_mem[i]); + } + printf("%s\n", grp->gr_mem[i]); +} + +static bool test_getgrnam(struct torture_context *tctx, + const char *name, + struct group *grp_p) +{ + struct group *grp; + + torture_comment(tctx, "Testing getgrnam: %s\n", name); + + grp = getgrnam(name); + if (grp) { + print_group(grp); + } + + if (grp_p) { + copy_group(tctx, grp, grp_p); + } + + return grp ? true : false; +} + +static bool test_getgrnam_r(struct torture_context *tctx, + const char *name, + struct group *grp_p) +{ + struct group grp, *grpp; + char buffer[4096]; + int ret; + + torture_comment(tctx, "Testing getgrnam_r: %s\n", name); + + ret = getgrnam_r(name, &grp, buffer, sizeof(buffer), &grpp); + if (ret != 0) { + if (ret != ENOENT) { + torture_comment(tctx, "got %d return code\n", ret); + } + return false; + } + + print_group(&grp); + + if (grp_p) { + copy_group(tctx, &grp, grp_p); + } + + return true; +} + + +static bool test_getgrgid(struct torture_context *tctx, + gid_t gid, + struct group *grp_p) +{ + struct group *grp; + + torture_comment(tctx, "Testing getgrgid: %lu\n", (unsigned long)gid); + + grp = getgrgid(gid); + if (grp) { + print_group(grp); + } + + if (grp_p) { + copy_group(tctx, grp, grp_p); + } + + return grp ? true : false; +} + +static bool test_getgrgid_r(struct torture_context *tctx, + gid_t gid, + struct group *grp_p) +{ + struct group grp, *grpp; + char buffer[4096]; + int ret; + + torture_comment(tctx, "Testing getgrgid_r: %lu\n", (unsigned long)gid); + + ret = getgrgid_r(gid, &grp, buffer, sizeof(buffer), &grpp); + if (ret != 0) { + if (ret != ENOENT) { + torture_comment(tctx, "got %d return code\n", ret); + } + return false; + } + + print_group(&grp); + + if (grp_p) { + copy_group(tctx, &grp, grp_p); + } + + return true; +} + +static bool test_enum_passwd(struct torture_context *tctx, + struct passwd **pwd_array_p, + size_t *num_pwd_p) +{ + struct passwd *pwd; + struct passwd *pwd_array = NULL; + size_t num_pwd = 0; + + torture_comment(tctx, "Testing setpwent\n"); + setpwent(); + + while ((pwd = getpwent()) != NULL) { + torture_comment(tctx, "Testing getpwent\n"); + + print_passwd(pwd); + if (pwd_array_p && num_pwd_p) { + pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1); + torture_assert(tctx, pwd_array, "out of memory"); + copy_passwd(tctx, pwd, &pwd_array[num_pwd]); + num_pwd++; + } + } + + torture_comment(tctx, "Testing endpwent\n"); + endpwent(); + + if (pwd_array_p) { + *pwd_array_p = pwd_array; + } + if (num_pwd_p) { + *num_pwd_p = num_pwd; + } + + return true; +} + +static bool test_enum_r_passwd(struct torture_context *tctx, + struct passwd **pwd_array_p, + size_t *num_pwd_p) +{ + struct passwd pwd, *pwdp; + struct passwd *pwd_array = NULL; + size_t num_pwd = 0; + char buffer[4096]; + int ret; + + torture_comment(tctx, "Testing setpwent\n"); + setpwent(); + + while (1) { + torture_comment(tctx, "Testing getpwent_r\n"); + + ret = getpwent_r(&pwd, buffer, sizeof(buffer), &pwdp); + if (ret != 0) { + if (ret != ENOENT) { + torture_comment(tctx, "got %d return code\n", ret); + } + break; + } + print_passwd(&pwd); + if (pwd_array_p && num_pwd_p) { + pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1); + torture_assert(tctx, pwd_array, "out of memory"); + copy_passwd(tctx, &pwd, &pwd_array[num_pwd]); + num_pwd++; + } + } + + torture_comment(tctx, "Testing endpwent\n"); + endpwent(); + + if (pwd_array_p) { + *pwd_array_p = pwd_array; + } + if (num_pwd_p) { + *num_pwd_p = num_pwd; + } + + return true; +} + +static bool torture_assert_passwd_equal(struct torture_context *tctx, + const struct passwd *p1, + const struct passwd *p2, + const char *comment) +{ + torture_assert_str_equal(tctx, p1->pw_name, p2->pw_name, comment); + torture_assert_str_equal(tctx, p1->pw_passwd, p2->pw_passwd, comment); + torture_assert_int_equal(tctx, p1->pw_uid, p2->pw_uid, comment); + torture_assert_int_equal(tctx, p1->pw_gid, p2->pw_gid, comment); + torture_assert_str_equal(tctx, p1->pw_gecos, p2->pw_gecos, comment); + torture_assert_str_equal(tctx, p1->pw_dir, p2->pw_dir, comment); + torture_assert_str_equal(tctx, p1->pw_shell, p2->pw_shell, comment); + + return true; +} + +static bool test_passwd(struct torture_context *tctx) +{ + int i; + struct passwd *pwd, pwd1, pwd2; + size_t num_pwd; + + torture_assert(tctx, test_enum_passwd(tctx, &pwd, &num_pwd), + "failed to enumerate passwd"); + + for (i=0; i < num_pwd; i++) { + torture_assert(tctx, test_getpwnam(tctx, pwd[i].pw_name, &pwd1), + "failed to call getpwnam for enumerated user"); + torture_assert_passwd_equal(tctx, &pwd[i], &pwd1, + "getpwent and getpwnam gave different results"); + torture_assert(tctx, test_getpwuid(tctx, pwd[i].pw_uid, &pwd2), + "failed to call getpwuid for enumerated user"); + torture_assert_passwd_equal(tctx, &pwd[i], &pwd2, + "getpwent and getpwuid gave different results"); + torture_assert_passwd_equal(tctx, &pwd1, &pwd2, + "getpwnam and getpwuid gave different results"); + } + + return true; +} + +static bool test_passwd_r(struct torture_context *tctx) +{ + int i; + struct passwd *pwd, pwd1, pwd2; + size_t num_pwd; + + torture_assert(tctx, test_enum_r_passwd(tctx, &pwd, &num_pwd), + "failed to enumerate passwd"); + + for (i=0; i < num_pwd; i++) { + torture_assert(tctx, test_getpwnam_r(tctx, pwd[i].pw_name, &pwd1), + "failed to call getpwnam_r for enumerated user"); + torture_assert_passwd_equal(tctx, &pwd[i], &pwd1, + "getpwent_r and getpwnam_r gave different results"); + torture_assert(tctx, test_getpwuid_r(tctx, pwd[i].pw_uid, &pwd2), + "failed to call getpwuid_r for enumerated user"); + torture_assert_passwd_equal(tctx, &pwd[i], &pwd2, + "getpwent_r and getpwuid_r gave different results"); + torture_assert_passwd_equal(tctx, &pwd1, &pwd2, + "getpwnam_r and getpwuid_r gave different results"); + } + + return true; +} + +static bool test_passwd_r_cross(struct torture_context *tctx) +{ + int i; -- Samba Shared Repository