s3:torture: add idmap_tdb_common test code
authorChristian Ambach <ambi@samba.org>
Wed, 22 Feb 2012 14:44:27 +0000 (15:44 +0100)
committerChristian Ambach <ambi@samba.org>
Tue, 1 May 2012 07:32:11 +0000 (09:32 +0200)
source3/Makefile.in
source3/torture/proto.h
source3/torture/test_idmap_tdb_common.c [new file with mode: 0644]
source3/torture/torture.c
source3/wscript_build

index 184dd1fed200c9edf6737b3ef3a7a1de5f21ab07..8b02d6435ca06136615322afd0b941c66a764c5b 100644 (file)
@@ -1281,6 +1281,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
                torture/test_msg.o \
                torture/test_notify.o \
                torture/test_dbwrap_watch.o \
+               torture/test_idmap_tdb_common.o \
                torture/t_strappend.o
 
 SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \
@@ -1376,8 +1377,10 @@ IDMAP_RW_OBJ = winbindd/idmap_rw.o
 
 IDMAP_TDB_COMMON_OBJ = winbindd/idmap_tdb_common.o
 
-IDMAP_OBJ     = winbindd/idmap.o winbindd/idmap_util.o $(IDMAP_RW_OBJ) \
-               $(IDMAP_TDB_COMMON_OBJ) @IDMAP_STATIC@
+IDMAP_UTIL_OBJ = winbindd/idmap_util.o $(IDMAP_RW_OBJ) \
+                $(IDMAP_TDB_COMMON_OBJ)
+
+IDMAP_OBJ     =  winbindd/idmap.o $(IDMAP_UTIL_OBJ) @IDMAP_STATIC@
 
 NSS_INFO_OBJ = winbindd/nss_info.o @NSS_INFO_STATIC@
 
@@ -1968,7 +1971,7 @@ bin/nmblookup: $(BINARY_PREREQS) $(NMBLOOKUP_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LI
 
 bin/smbtorture: $(BINARY_PREREQS) $(SMBTORTURE_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT)
        @echo Linking $@
-       @$(CC) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) \
+       @$(CC) -o $@ $(SMBTORTURE_OBJ) $(IDMAP_UTIL_OBJ) $(LDFLAGS) $(DYNEXP) \
                $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) \
                $(LIBTDB_LIBS) $(ZLIB_LIBS) $(LIBWBCLIENT_LIBS)
 
index 4fde44886908168a5135b7e3cadf4997b48230fb..80618ceb34993773d28117bf2799d9267e97d2df 100644 (file)
@@ -109,5 +109,6 @@ bool run_msg_test(int dummy);
 bool run_notify_bench2(int dummy);
 bool run_notify_bench3(int dummy);
 bool run_dbwrap_watch1(int dummy);
+bool run_idmap_tdb_common_test(int dummy);
 
 #endif /* __TORTURE_H__ */
diff --git a/source3/torture/test_idmap_tdb_common.c b/source3/torture/test_idmap_tdb_common.c
new file mode 100644 (file)
index 0000000..e24fc21
--- /dev/null
@@ -0,0 +1,1028 @@
+/*
+   Unix SMB/CIFS implementation.
+   IDMAP TDB common code tester
+
+   Copyright (C) Christian Ambach 2012
+
+   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 "system/filesys.h"
+#include "torture/proto.h"
+#include "idmap.h"
+#include "winbindd/idmap_rw.h"
+#include "winbindd/idmap_tdb_common.h"
+#include "winbindd/winbindd.h"
+#include "winbindd/winbindd_proto.h"
+#include "dbwrap/dbwrap.h"
+#include "dbwrap/dbwrap_open.h"
+#include "../libcli/security/dom_sid.h"
+
+#define HWM_GROUP  "GROUP HWM"
+#define HWM_USER   "USER HWM"
+
+#define LOW_ID 100
+#define HIGH_ID 199
+
+#define TESTDB "/tmp/idmap_test.tdb"
+
+#define DOM_SID1 "S-1-5-21-1234-5678-9012"
+#define DOM_SID2 "S-1-5-21-0123-5678-9012"
+#define DOM_SID3 "S-1-5-21-0012-5678-9012"
+#define DOM_SID4 "S-1-5-21-0001-5678-9012"
+#define DOM_SID5 "S-1-5-21-2345-5678-9012"
+#define DOM_SID6 "S-1-5-21-3456-5678-9012"
+
+/* overwrite some winbind internal functions */
+struct winbindd_domain *find_domain_from_name(const char *domain_name)
+{
+       return NULL;
+}
+
+bool get_global_winbindd_state_offline(void) {
+       return false;
+}
+
+bool winbindd_use_idmap_cache(void) {
+       return false;
+}
+
+bool idmap_is_online(void)
+{
+       return true;
+}
+
+NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
+{
+       return NT_STATUS_OK;
+}
+
+NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
+{
+       return NT_STATUS_OK;
+}
+
+static bool open_db(struct idmap_tdb_common_context *ctx)
+{
+       NTSTATUS status;
+
+       if(ctx->db) {
+               /* already open */
+               return true;
+       }
+
+       unlink(TESTDB);
+
+       ctx->db = db_open(ctx, TESTDB, 0, TDB_DEFAULT,
+                         O_RDWR | O_CREAT | O_EXCL, 0600,
+                         DBWRAP_LOCK_ORDER_1);
+
+       if(dbwrap_transaction_start(ctx->db) != 0) {
+               DEBUG(0, ("Failed to start transaction!\n"));
+               return false;
+       }
+
+       status = dbwrap_store_uint32(ctx->db, ctx->hwmkey_uid, LOW_ID);
+       if(!NT_STATUS_IS_OK(status)) {
+               dbwrap_transaction_cancel(ctx->db);
+               return false;
+       }
+
+       status = dbwrap_store_uint32(ctx->db, ctx->hwmkey_gid, LOW_ID);
+       if(!NT_STATUS_IS_OK(status)) {
+               dbwrap_transaction_cancel(ctx->db);
+               return false;
+       }
+
+       if(dbwrap_transaction_commit(ctx->db) != 0) {
+               DEBUG(0, ("Failed to commit transaction!\n"));
+               return false;
+       }
+
+       return true;
+}
+
+static struct idmap_tdb_common_context *createcontext(TALLOC_CTX *memctx)
+{
+       struct idmap_tdb_common_context *ret;
+
+       ret = talloc_zero(memctx, struct idmap_tdb_common_context);
+       ret->rw_ops = talloc_zero(ret, struct idmap_rw_ops);
+
+       ret->max_id = HIGH_ID;
+       ret->hwmkey_uid = HWM_USER;
+       ret->hwmkey_gid = HWM_GROUP;
+
+       ret->rw_ops->get_new_id = idmap_tdb_common_get_new_id;
+       ret->rw_ops->set_mapping = idmap_tdb_common_set_mapping;
+
+       open_db(ret);
+
+       return ret;
+}
+
+static struct idmap_domain *createdomain(TALLOC_CTX *memctx)
+{
+       struct idmap_domain *dom;
+
+       dom = talloc_zero(memctx, struct idmap_domain);
+       dom->name = "*";
+       dom->low_id = LOW_ID;
+       dom->high_id = HIGH_ID;
+       dom->read_only = false;
+       dom->methods = talloc_zero(dom, struct idmap_methods);
+       dom->methods->sids_to_unixids = idmap_tdb_common_sids_to_unixids;
+       dom->methods->unixids_to_sids = idmap_tdb_common_unixids_to_sids;
+       dom->methods->allocate_id = idmap_tdb_common_get_new_id;
+
+       return dom;
+}
+
+static bool test_getnewid1(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct unixid id;
+
+       id.type = ID_TYPE_UID;
+
+       status = idmap_tdb_common_get_new_id(dom, &id);
+
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_getnewid1: Could not allocate id!\n"));
+               return false;
+       }
+
+       if(id.id == 0) {
+               DEBUG(0, ("test_getnewid1: Allocate returned "
+                         "empty id!\n"));
+               return false;
+       }
+
+       if(id.id > HIGH_ID || id.id < LOW_ID) {
+               DEBUG(0, ("test_getnewid1: Allocate returned "
+                         "out of range id!\n"));
+               return false;
+       }
+
+       DEBUG(0, ("test_getnewid1: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_getnewid2(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct unixid id;
+       int i, left;
+
+       id.type = ID_TYPE_UID;
+
+       status = idmap_tdb_common_get_new_id(dom, &id);
+
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_getnewid2: Could not allocate id!\n"));
+               return false;
+       }
+
+       if(id.id == 0) {
+               DEBUG(0, ("test_getnewid2: Allocate returned "
+                         "empty id!\n"));
+               return false;
+       }
+
+       if(id.id > HIGH_ID || id.id < LOW_ID) {
+               DEBUG(0, ("test_getnewid2: Allocate returned "
+                         "out of range id!\n"));
+               return false;
+       }
+
+       /* how many ids are left? */
+
+       left = HIGH_ID - id.id;
+
+       /* consume them all */
+       for(i = 0; i<left; i++) {
+
+               status = idmap_tdb_common_get_new_id(dom, &id);
+
+               if(!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0, ("test_getnewid2: Allocate returned "
+                                 "error %s\n", nt_errstr(status)));
+                       return false;
+               }
+
+               if(id.id > HIGH_ID) {
+                       DEBUG(0, ("test_getnewid2: Allocate returned "
+                                 "out of range id (%d)!\n", id.id));
+                       return false;
+               }
+       }
+
+       /* one more must fail */
+       status = idmap_tdb_common_get_new_id(dom, &id);
+
+       if(NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_getnewid2: Could allocate id (%d) from "
+                         "depleted pool!\n", id.id));
+               return false;
+       }
+
+       DEBUG(0, ("test_getnewid2: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_setmap1(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map map;
+
+       ZERO_STRUCT(map);
+
+       /* test for correct return code with invalid data */
+
+       status = idmap_tdb_common_set_mapping(dom, NULL);
+       if(!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+               DEBUG(0, ("test_setmap1: bad parameter handling!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_set_mapping(dom, &map);
+       if(!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+               DEBUG(0, ("test_setmap1: bad parameter handling!\n"));
+               return false;
+       }
+
+       map.sid = dom_sid_parse_talloc(memctx, DOM_SID1 "-100");
+
+       map.xid.type = ID_TYPE_NOT_SPECIFIED;
+       map.xid.id = 4711;
+
+       status = idmap_tdb_common_set_mapping(dom, &map);
+       if(!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+               DEBUG(0, ("test_setmap1: bad parameter handling!\n"));
+               return false;
+       }
+
+       /* now the good ones */
+       map.xid.type = ID_TYPE_UID;
+       map.xid.id = 0;
+
+       status = idmap_tdb_common_get_new_id(dom, &(map.xid));
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_setmap1: get_new_uid failed!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_set_mapping(dom, &map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_setmap1: setting UID mapping failed!\n"));
+               return false;
+       }
+
+       /* try to set the same mapping again as group (must fail) */
+
+       map.xid.type = ID_TYPE_GID;
+       status = idmap_tdb_common_set_mapping(dom, &map);
+       if(NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_setmap1: could create map for "
+                         "group and user!\n"));
+               return false;
+       }
+
+       /* now a group with a different SID*/
+       map.xid.id = 0;
+
+       map.sid = dom_sid_parse_talloc(memctx, DOM_SID1 "-101");
+
+       status = idmap_tdb_common_get_new_id(dom, &(map.xid));
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_setmap1: get_new_gid failed!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_set_mapping(dom, &map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_setmap1: setting GID mapping failed!\n"));
+               return false;
+       }
+       DEBUG(0, ("test_setmap1: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_sid2unixid1(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status1, status2, status3;
+       struct id_map map;
+
+       /* check for correct dealing with bad parameters */
+       status1 = idmap_tdb_common_sid_to_unixid(NULL, &map);
+       status2 = idmap_tdb_common_sid_to_unixid(dom, NULL);
+       status3 = idmap_tdb_common_sid_to_unixid(NULL, NULL);
+
+       if(!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status1) ||
+           !NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status2) ||
+           !NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status3)) {
+               DEBUG(0, ("test_setmap1: bad parameter handling!\n"));
+               return false;
+       }
+
+       DEBUG(0, ("test_unixid2sid1: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_sid2unixid2(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map uid_map, gid_map, test_map;
+       bool doagain = true;
+
+       ZERO_STRUCT(uid_map);
+       ZERO_STRUCT(gid_map);
+
+       /* create two mappings for a UID and GID */
+
+again:
+
+       uid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID2 "-1000");
+       uid_map.xid.type = ID_TYPE_UID;
+
+       gid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID2 "-1001");
+       gid_map.xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_new_mapping(dom, &uid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sid2unixid1: could not create uid map!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_new_mapping(dom, &gid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sid2unixid1: could not create gid map!\n"));
+               return false;
+       }
+
+       /* now read them back */
+       ZERO_STRUCT(test_map);
+       test_map.sid = uid_map.sid;
+
+       status = idmap_tdb_common_sid_to_unixid(dom, &test_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sid2unixid1: sid2unixid failed for uid!\n"));
+               return false;
+       }
+
+       if(test_map.xid.id!=uid_map.xid.id) {
+               DEBUG(0, ("test_sid2unixid1: sid2unixid returned wrong uid!\n"));
+               return false;
+       }
+
+       test_map.sid = gid_map.sid;
+
+       status = idmap_tdb_common_sid_to_unixid(dom, &test_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sid2unixid1: sid2unixid failed for gid!\n"));
+               return false;
+       }
+
+       if(test_map.xid.id!=gid_map.xid.id) {
+               DEBUG(0, ("test_sid2unixid1: sid2unixid returned wrong gid!\n"));
+               return false;
+       }
+
+       /*
+        * Go through the same tests again once to see if trying to recreate
+        * a mapping that was already created will work or not
+        */
+       if(doagain) {
+               doagain = false;
+               goto again;
+       }
+
+       DEBUG(0, ("test_sid2unixid1: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_sids2unixids1(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map uid_map, gid_map, **test_maps;
+
+       ZERO_STRUCT(uid_map);
+       ZERO_STRUCT(gid_map);
+
+       /* create two mappings for a UID and GID */
+
+       uid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID4 "-1000");
+       uid_map.xid.type = ID_TYPE_UID;
+
+       gid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID4 "-1001");
+       gid_map.xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_new_mapping(dom, &uid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sids2unixids1: could not create uid map!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_new_mapping(dom, &gid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sids2unixids1: could not create gid map!\n"));
+               return false;
+       }
+
+       /* now read them back  */
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       sid_copy(test_maps[0]->sid, uid_map.sid);
+       sid_copy(test_maps[1]->sid, gid_map.sid);
+
+       status = idmap_tdb_common_sids_to_unixids(dom, test_maps);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sids2sunixids1: sids2unixids failed!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       if(test_maps[0]->xid.id!=uid_map.xid.id ||
+           test_maps[1]->xid.id!=gid_map.xid.id ) {
+               DEBUG(0, ("test_sids2unixids1: sid2unixid returned wrong xid!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       DEBUG(0, ("test_sids2unixids1: PASSED!\n"));
+
+       talloc_free(test_maps);
+
+       return true;
+}
+
+static bool test_sids2unixids2(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map **test_maps;
+       struct unixid save;
+
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       /* ask for two new mappings for a UID and GID */
+       test_maps[0]->sid = dom_sid_parse_talloc(test_maps, DOM_SID4 "-1003");
+       test_maps[0]->xid.type = ID_TYPE_UID;
+       test_maps[1]->sid = dom_sid_parse_talloc(test_maps, DOM_SID4 "-1004");
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_sids_to_unixids(dom, test_maps);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sids2sunixids2: sids2unixids "
+                         "failed (%s)!\n", nt_errstr(status)));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       if(test_maps[0]->xid.id == 0 || test_maps[1]->xid.id == 0) {
+               DEBUG(0, ("test_sids2sunixids2: sids2unixids "
+                         "returned zero ids!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       save = test_maps[1]->xid;
+
+       /* ask for a known and a new mapping at the same time */
+       talloc_free(test_maps);
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       test_maps[0]->sid = dom_sid_parse_talloc(test_maps, DOM_SID4 "-1004");
+       test_maps[0]->xid.type = ID_TYPE_GID;
+       test_maps[1]->sid = dom_sid_parse_talloc(test_maps, DOM_SID4 "-1005");
+       test_maps[1]->xid.type = ID_TYPE_UID;
+
+       status = idmap_tdb_common_sids_to_unixids(dom, test_maps);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sids2sunixids2: sids2unixids (2) "
+                         "failed (%s)!\n", nt_errstr(status)));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       if(test_maps[0]->xid.type != save.type ||
+           test_maps[0]->xid.id != save.id) {
+               DEBUG(0, ("test_sids2sunixids2: second lookup returned "
+                         "different value!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       if(test_maps[1]->xid.id == 0) {
+               DEBUG(0, ("test_sids2sunixids2: sids2unixids "
+                         "returned zero id for mixed mapping request!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       DEBUG(0, ("test_sids2unixids2: PASSED!\n"));
+
+       talloc_free(test_maps);
+
+       return true;
+}
+
+static bool test_sids2unixids3(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map **test_maps;
+       bool retval = true;
+
+       /*
+        * check the mapping states:
+        * NONE_MAPPED, SOME_UNMAPPED, OK (all mapped)
+        *
+        * use the ids created by test_sids2unixids1
+        * need to make dom read-only
+        */
+
+       dom->read_only = true;
+
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       /* NONE_MAPPED first */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->sid = dom_sid_parse_talloc(test_maps,
+                                                "S-1-5-21-1-2-3-4");
+       test_maps[0]->xid.type = ID_TYPE_UID;
+
+       test_maps[1]->sid = dom_sid_parse_talloc(test_maps,
+                                                "S-1-5-21-1-2-3-5");
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_sids_to_unixids(dom, test_maps);
+       if(!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+               DEBUG(0, ("test_sids2unixids3: incorrect status "
+                         "(%s), expected NT_STATUS_NONE_MAPPED!\n",
+                          nt_errstr(status)));
+               retval = false;
+               goto out;
+       }
+
+       /* SOME_UNMAPPED */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->sid = dom_sid_parse_talloc(test_maps,
+                                                DOM_SID4 "-1000");
+       test_maps[0]->xid.type = ID_TYPE_UID;
+       test_maps[1]->sid = dom_sid_parse_talloc(test_maps,
+                                                "S-1-5-21-1-2-3-5");
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_sids_to_unixids(dom, test_maps);
+       if(!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
+               DEBUG(0, ("test_sids2unixids3: incorrect status "
+                         "(%s), expected STATUS_SOME_UNMAPPED!\n",
+                          nt_errstr(status)));
+               retval = false;
+               goto out;
+       }
+
+       /* OK */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->sid = dom_sid_parse_talloc(test_maps,
+                                                DOM_SID4 "-1001");
+       test_maps[1]->sid = dom_sid_parse_talloc(test_maps,
+                                                DOM_SID4 "-1000");
+
+       status = idmap_tdb_common_sids_to_unixids(dom, test_maps);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_sids2unixids3: incorrect status "
+                         "(%s), expected NT_STATUS_OK!\n",
+                          nt_errstr(status)));
+               retval = false;
+               goto out;
+       }
+
+       DEBUG(0, ("test_sids2unixids3: PASSED!\n"));
+
+out:
+       talloc_free(test_maps);
+       dom->read_only = false;
+       return retval;
+}
+
+static bool test_unixid2sid1(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status1, status2, status3;
+       struct id_map map;
+
+       /* check for correct dealing with bad parameters */
+       status1 = idmap_tdb_common_unixid_to_sid(NULL, &map);
+       status2 = idmap_tdb_common_unixid_to_sid(dom, NULL);
+       status3 = idmap_tdb_common_unixid_to_sid(NULL, NULL);
+
+       if(!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status1) ||
+           !NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status2) ||
+           !NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status3)) {
+               DEBUG(0, ("test_setmap1: bad parameter handling!\n"));
+               return false;
+       }
+
+       DEBUG(0, ("test_unixid2sid1: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_unixid2sid2(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map *map;
+       bool retval = true;
+
+       /* ask for mapping that is outside of the range */
+       map = talloc(memctx, struct id_map);
+       map->sid = talloc(map, struct dom_sid);
+
+       map->xid.type = ID_TYPE_UID;
+       map->xid.id = HIGH_ID + 1;
+
+       status = idmap_tdb_common_unixid_to_sid(dom, map);
+       if(NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixid2sid2: unixid2sid returned "
+                         "out-of-range result\n"));
+               retval = false;
+               goto out;
+       }
+
+       DEBUG(0, ("test_unixid2sid2: PASSED!\n"));
+out:
+       talloc_free(map);
+       return retval;
+
+}
+
+static bool test_unixid2sid3(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map uid_map, gid_map, test_map;
+       struct dom_sid testsid;
+
+       ZERO_STRUCT(uid_map);
+       ZERO_STRUCT(gid_map);
+
+       /* create two mappings for a UID and GID */
+       uid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID3 "-1000");
+       uid_map.xid.type = ID_TYPE_UID;
+
+       gid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID3 "-1001");
+       gid_map.xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_new_mapping(dom, &uid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixid2sid3: could not create uid map!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_new_mapping(dom, &gid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixid2sid3: could not create gid map!\n"));
+               return false;
+       }
+
+       /* now read them back */
+       ZERO_STRUCT(test_map);
+       test_map.xid.id = uid_map.xid.id;
+       test_map.xid.type = ID_TYPE_UID;
+       test_map.sid = &testsid;
+
+       status = idmap_tdb_common_unixid_to_sid(dom, &test_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixid2sid3: unixid2sid failed for uid!\n"));
+               return false;
+       }
+
+       if(test_map.xid.type!=uid_map.xid.type) {
+               DEBUG(0, ("test_unixid2sid3: unixid2sid returned wrong type!\n"));
+               return false;
+       }
+
+       if(!dom_sid_equal(test_map.sid, uid_map.sid)) {
+               DEBUG(0, ("test_unixid2sid3: unixid2sid returned wrong SID!\n"));
+               return false;
+       }
+
+       ZERO_STRUCT(test_map);
+       test_map.xid.id = gid_map.xid.id;
+       test_map.xid.type = ID_TYPE_GID;
+       test_map.sid = &testsid;
+
+       status = idmap_tdb_common_unixid_to_sid(dom, &test_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixid2sid3: unixid2sid failed for gid!\n"));
+               return false;
+       }
+
+       if(test_map.xid.type!=gid_map.xid.type) {
+               DEBUG(0, ("test_unixid2sid3: unixid2sid returned wrong type!\n"));
+               return false;
+       }
+
+       if(!dom_sid_equal(test_map.sid,gid_map.sid)) {
+               DEBUG(0, ("test_unixid2sid3: unixid2sid returned wrong SID!\n"));
+               return false;
+       }
+
+       DEBUG(0, ("test_unixid2sid3: PASSED!\n"));
+
+       return true;
+}
+
+static bool test_unixids2sids1(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map uid_map, gid_map, **test_maps;
+
+       ZERO_STRUCT(uid_map);
+       ZERO_STRUCT(gid_map);
+
+       /* create two mappings for a UID and GID */
+
+       uid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID5 "-1000");
+       uid_map.xid.type = ID_TYPE_UID;
+
+       gid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID5 "-1001");
+       gid_map.xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_new_mapping(dom, &uid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids1: could not create uid map!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_new_mapping(dom, &gid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids1: could not create gid map!\n"));
+               return false;
+       }
+
+       /* now read them back  */
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->xid.id = uid_map.xid.id;
+       test_maps[0]->xid.type = ID_TYPE_UID;
+       test_maps[1]->xid.id = gid_map.xid.id;
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_unixids_to_sids(dom, test_maps);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids1: unixids2sids failed!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       if(!dom_sid_equal(test_maps[0]->sid, uid_map.sid) ||
+           !dom_sid_equal(test_maps[1]->sid, gid_map.sid) ) {
+               DEBUG(0, ("test_unixids2sids1: unixids2sids returned wrong sid!\n"));
+               talloc_free(test_maps);
+               return false;
+       }
+
+       DEBUG(0, ("test_unixids2sids1: PASSED!\n"));
+
+       talloc_free(test_maps);
+
+       return true;
+}
+
+static bool test_unixids2sids2(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map **test_maps;
+       bool retval = true;
+
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       /* ask for two unknown mappings for a UID and GID */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->xid.id = HIGH_ID - 1;
+       test_maps[0]->xid.type = ID_TYPE_UID;
+       test_maps[1]->xid.id = HIGH_ID - 1;
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_unixids_to_sids(dom, test_maps);
+       if(NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids2: unixids2sids succeeded "
+                         "unexpectedly!\n"));
+               retval = false;
+               goto out;
+       }
+
+       DEBUG(0, ("test_unixids2sids2: PASSED!\n"));
+
+out:
+       talloc_free(test_maps);
+
+       return retval;;
+}
+
+static bool test_unixids2sids3(TALLOC_CTX *memctx, struct idmap_domain *dom)
+{
+       NTSTATUS status;
+       struct id_map uid_map, gid_map, **test_maps;
+       bool retval = true;
+
+       ZERO_STRUCT(uid_map);
+       ZERO_STRUCT(gid_map);
+
+       /* create two mappings for a UID and GID */
+       uid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID6 "-1000");
+       uid_map.xid.type = ID_TYPE_UID;
+
+       gid_map.sid = dom_sid_parse_talloc(memctx, DOM_SID6 "-1001");
+       gid_map.xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_new_mapping(dom, &uid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids3: could not create uid map!\n"));
+               return false;
+       }
+
+       status = idmap_tdb_common_new_mapping(dom, &gid_map);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids3: could not create gid map!\n"));
+               return false;
+       }
+
+       /*
+        * check the mapping states:
+        * NONE_MAPPED, SOME_UNMAPPED, OK (all mapped)
+        */
+       test_maps = talloc_zero_array(memctx, struct id_map*, 3);
+
+       test_maps[0] = talloc(test_maps, struct id_map);
+       test_maps[1] = talloc(test_maps, struct id_map);
+       test_maps[2] = NULL;
+
+       /* NONE_MAPPED first */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+
+       test_maps[0]->xid.id = HIGH_ID - 1;
+       test_maps[0]->xid.type = ID_TYPE_UID;
+
+       test_maps[1]->xid.id = HIGH_ID - 1;
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_unixids_to_sids(dom, test_maps);
+       if(!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+               DEBUG(0, ("test_unixids2sids3: incorrect status "
+                         "(%s), expected NT_STATUS_NONE_MAPPED!\n",
+                          nt_errstr(status)));
+               retval = false;
+               goto out;
+       }
+
+       /* SOME_UNMAPPED */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->xid = uid_map.xid;
+       test_maps[1]->xid.id = HIGH_ID - 1;
+       test_maps[1]->xid.type = ID_TYPE_GID;
+
+       status = idmap_tdb_common_unixids_to_sids(dom, test_maps);
+       if(!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
+               DEBUG(0, ("test_unixids2sids3: incorrect status "
+                         "(%s), expected STATUS_SOME_UNMAPPED!\n",
+                          nt_errstr(status)));
+               retval = false;
+               goto out;
+       }
+
+       /* OK */
+       test_maps[0]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[1]->sid = talloc(test_maps, struct dom_sid);
+       test_maps[0]->xid = uid_map.xid;
+       test_maps[1]->xid = gid_map.xid;
+
+       status = idmap_tdb_common_unixids_to_sids(dom, test_maps);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("test_unixids2sids3: incorrect status "
+                         "(%s), expected NT_STATUS_OK!\n",
+                          nt_errstr(status)));
+               retval = false;
+               goto out;
+       }
+
+       DEBUG(0, ("test_unixids2sids3: PASSED!\n"));
+
+out:
+       talloc_free(test_maps);
+       return retval;
+}
+
+#define CHECKRESULT(r) if(!r) {return r;}
+
+bool run_idmap_tdb_common_test(int dummy)
+{
+       bool result;
+       struct idmap_tdb_common_context *ctx;
+       struct idmap_domain *dom;
+
+       TALLOC_CTX *memctx = talloc_new(NULL);
+       TALLOC_CTX *stack = talloc_stackframe();
+
+       ctx = createcontext(memctx);
+
+       dom = createdomain(memctx);
+
+       dom->private_data = ctx;
+
+       /* test a single allocation from pool (no mapping) */
+       result = test_getnewid1(memctx, dom);
+       CHECKRESULT(result);
+
+       /* test idmap_tdb_common_set_mapping */
+       result = test_setmap1(memctx, dom);
+       CHECKRESULT(result);
+
+       /* test idmap_tdb_common_sid_to_unixid */
+       result = test_sid2unixid1(memctx, dom);
+       CHECKRESULT(result);
+       result = test_sid2unixid2(memctx, dom);
+       CHECKRESULT(result);
+
+       /* test idmap_tdb_common_sids_to_unixids */
+       result = test_sids2unixids1(memctx, dom);
+       CHECKRESULT(result);
+       result = test_sids2unixids2(memctx, dom);
+       CHECKRESULT(result);
+       result = test_sids2unixids3(memctx, dom);
+       CHECKRESULT(result);
+
+       /* test idmap_tdb_common_unixid_to_sid */
+       result = test_unixid2sid1(memctx, dom);
+       CHECKRESULT(result);
+       result = test_unixid2sid2(memctx, dom);
+       CHECKRESULT(result);
+       result = test_unixid2sid3(memctx, dom);
+       CHECKRESULT(result);
+
+       /* test idmap_tdb_common_unixids_to_sids */
+       result = test_unixids2sids1(memctx, dom);
+       CHECKRESULT(result);
+       result = test_unixids2sids2(memctx, dom);
+       CHECKRESULT(result);
+       result = test_unixids2sids3(memctx, dom);
+       CHECKRESULT(result);
+
+       /* test filling up the range */
+       result = test_getnewid2(memctx, dom);
+       CHECKRESULT(result);
+
+       talloc_free(memctx);
+       talloc_free(stack);
+
+       return true;
+}
index 530e935a5c22b5932416d863511ba63f07921e9b..962d0e7967383fcd253295149eca656865ed5e9f 100644 (file)
@@ -8935,6 +8935,7 @@ static struct {
        { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
        { "LOCAL-sprintf_append", run_local_sprintf_append, 0},
        { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
+       { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
        {NULL, NULL, 0}};
 
 
index 26df82b0e6f8c75578574ab071ceaa34b215a768..dc0175090b1d1855869c7c1634648007a7809a97 100755 (executable)
@@ -558,6 +558,7 @@ SMBTORTURE_SRC1 = '''torture/torture.c torture/nbio.c torture/scanner.c torture/
                torture/test_notify.c
                lib/tevent_barrier.c
                torture/test_dbwrap_watch.c
+               torture/test_idmap_tdb_common.c
                 torture/t_strappend.c'''
 
 SMBTORTURE_SRC = '''${SMBTORTURE_SRC1}
@@ -1394,6 +1395,7 @@ bld.SAMBA3_BINARY('smbtorture' + bld.env.suffix3,
                  TLDAP
                  RPC_NDR_ECHO
                  WB_REQTRANS
+                idmap
                  ''',
                  vars=locals())