/* 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 . */ #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 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; }