summaryrefslogtreecommitdiffstats
path: root/source3/torture/test_idmap_tdb_common.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /source3/torture/test_idmap_tdb_common.c
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source3/torture/test_idmap_tdb_common.c')
-rw-r--r--source3/torture/test_idmap_tdb_common.c1047
1 files changed, 1047 insertions, 0 deletions
diff --git a/source3/torture/test_idmap_tdb_common.c b/source3/torture/test_idmap_tdb_common.c
new file mode 100644
index 0000000..825ee3e
--- /dev/null
+++ b/source3/torture/test_idmap_tdb_common.c
@@ -0,0 +1,1047 @@
+/*
+ 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 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;
+}
+
+static bool open_db(struct idmap_tdb_common_context *ctx)
+{
+ NTSTATUS status;
+ char *db_path;
+
+ if(ctx->db) {
+ /* already open */
+ return true;
+ }
+
+ db_path = talloc_asprintf(talloc_tos(), "%s/idmap_test.tdb",
+ lp_private_dir());
+ if(!db_path) {
+ DEBUG(0, ("Out of memory!\n"));
+ return false;
+ }
+
+ ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT,
+ O_RDWR | O_CREAT, 0600,
+ DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
+
+ if(!ctx->db) {
+ DEBUG(0, ("Failed to open database: %s\n", strerror(errno)));
+ return false;
+ }
+
+ if(dbwrap_transaction_start(ctx->db) != 0) {
+ DEBUG(0, ("Failed to start transaction!\n"));
+ return false;
+ }
+
+ status = dbwrap_store_uint32_bystring(ctx->db, ctx->hwmkey_uid,
+ LOW_ID);
+ if(!NT_STATUS_IS_OK(status)) {
+ dbwrap_transaction_cancel(ctx->db);
+ return false;
+ }
+
+ status = dbwrap_store_uint32_bystring(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 NTSTATUS idmap_test_tdb_db_init(struct idmap_domain *dom)
+{
+ struct idmap_tdb_common_context *ret;
+
+ DBG_DEBUG("called for domain '%s'\n", dom->name);
+
+ ret = talloc_zero(dom, struct idmap_tdb_common_context);
+ if (ret == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ ret->rw_ops = talloc_zero(ret, struct idmap_rw_ops);
+ if (ret->rw_ops == NULL) {
+ TALLOC_FREE(ret);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ 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;
+
+ if (!open_db(ret)) {
+ TALLOC_FREE(ret);
+ return NT_STATUS_INTERNAL_ERROR;
+ };
+
+ dom->private_data = ret;
+
+ return NT_STATUS_OK;
+}
+
+static struct idmap_domain *createdomain(TALLOC_CTX *memctx)
+{
+ struct idmap_domain *dom;
+ struct idmap_methods *m;
+
+ dom = talloc_zero(memctx, struct idmap_domain);
+ dom->name = "*";
+ dom->low_id = LOW_ID;
+ dom->high_id = HIGH_ID;
+ dom->read_only = false;
+ m = talloc_zero(dom, struct idmap_methods);
+ *m = (struct idmap_methods) {
+ .init = idmap_test_tdb_db_init,
+ .sids_to_unixids = idmap_tdb_common_sids_to_unixids,
+ .unixids_to_sids = idmap_tdb_common_unixids_to_sids,
+ .allocate_id = idmap_tdb_common_get_new_id,
+ };
+ dom->methods = m;
+
+ 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_sid2unixid2: 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_sid2unixid2: 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_sid2unixid2: sid2unixid failed for uid!\n"));
+ return false;
+ }
+
+ if(test_map.xid.id!=uid_map.xid.id) {
+ DEBUG(0, ("test_sid2unixid2: 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_sid2unixid2: sid2unixid failed for gid!\n"));
+ return false;
+ }
+
+ if(test_map.xid.id!=gid_map.xid.id) {
+ DEBUG(0, ("test_sid2unixid2: 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_sid2unixid2: 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) {TALLOC_FREE(stack); return r;}
+
+bool run_idmap_tdb_common_test(int dummy)
+{
+ bool result;
+ struct idmap_domain *dom;
+ TALLOC_CTX *stack = talloc_stackframe();
+ TALLOC_CTX *memctx = talloc_new(stack);
+ NTSTATUS status;
+
+ dom = createdomain(memctx);
+ if (dom == NULL) {
+ TALLOC_FREE(stack);
+ return false;
+ }
+
+ status = dom->methods->init(dom);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(stack);
+ return false;
+ }
+
+ /* 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(stack);
+
+ return true;
+}