/* return a group map entry for a given sid */ static bool get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) { int ret; struct ldb_dn *dn; struct ldb_result *res=NULL; dn = mapping_dn(ldb, &sid); if (dn == NULL) goto failed; ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res); if (ret != LDB_SUCCESS) { goto failed; } talloc_steal(dn, res); if (res->count != 1) { goto failed; } if (!msg_to_group_map(res->msgs[0], map)) goto failed; talloc_free(dn); return True; failed: talloc_free(dn); return False; }
/* return a group map entry for a given sid */ static bool get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) { int ret; struct ldb_dn *dn; struct ldb_result *res=NULL; bool result = false; dn = mapping_dn(talloc_tos(), &sid); if (dn == NULL) { goto failed; } ret = ldb_search(ldb, dn, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS || res->count != 1) { goto failed; } if (!msg_to_group_map(res->msgs[0], map)) { goto failed; } result = true; failed: talloc_free(dn); return result; }
/* add/remove a member field */ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member, int operation) { fstring string_sid; int ret; struct ldb_message msg; struct ldb_message_element el; struct ldb_val val; TALLOC_CTX *tmp_ctx; GROUP_MAP map; if (!get_group_map_from_sid(*alias, &map)) { sid_to_fstring(string_sid, alias); return NT_STATUS_NO_SUCH_ALIAS; } if ((map.sid_name_use != SID_NAME_ALIAS) && (map.sid_name_use != SID_NAME_WKN_GRP)) { DEBUG(0,("sid_name_use=%d\n", map.sid_name_use)); return NT_STATUS_NO_SUCH_ALIAS; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } msg.dn = mapping_dn(tmp_ctx, alias); if (msg.dn == NULL) { return NT_STATUS_NO_MEMORY; } msg.num_elements = 1; msg.elements = ⪙ el.flags = operation; el.name = talloc_strdup(tmp_ctx, "member"); el.num_values = 1; el.values = &val; sid_to_fstring(string_sid, member); val.data = (uint8_t *)string_sid; val.length = strlen(string_sid); ret = ldb_modify(ldb, &msg); talloc_free(tmp_ctx); if (ret == LDB_ERR_NO_SUCH_OBJECT) { return NT_STATUS_NO_SUCH_ALIAS; } if (operation == LDB_FLAG_MOD_ADD && ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { return NT_STATUS_MEMBER_IN_ALIAS; } return (ret == LDB_SUCCESS ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED); }
/* enumerate sids that have the given alias set in member */ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num) { const char *attrs[] = { "member", NULL }; int ret, i; NTSTATUS status = NT_STATUS_OK; struct ldb_result *res=NULL; struct ldb_dn *dn; struct ldb_message_element *el; *sids = NULL; *num = 0; dn = mapping_dn(ldb, alias); if (dn == NULL) { return NT_STATUS_NO_MEMORY; } ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, attrs, &res); if (ret == LDB_SUCCESS && res->count == 0) { talloc_free(res); talloc_free(dn); return NT_STATUS_OK; } if (ret != LDB_SUCCESS) { talloc_free(dn); return NT_STATUS_INTERNAL_DB_CORRUPTION; } talloc_steal(dn, res); el = ldb_msg_find_element(res->msgs[0], "member"); if (el == NULL) { talloc_free(dn); return NT_STATUS_OK; } for (i=0;i<el->num_values;i++) { DOM_SID sid; string_to_sid(&sid, (const char *)el->values[i].data); status = add_sid_to_array_unique(NULL, &sid, sids, num); if (!NT_STATUS_IS_OK(status)) { goto done; } } done: talloc_free(dn); return status; }
/* Remove a group mapping entry. */ static bool group_map_remove(const DOM_SID *sid) { struct ldb_dn *dn; int ret; dn = mapping_dn(ldb, sid); if (dn == NULL) { return False; } ret = ldb_delete(ldb, dn); talloc_free(dn); return ret == LDB_SUCCESS; }
/* add a group mapping entry */ static bool add_mapping_entry(GROUP_MAP *map, int flag) { struct ldb_message *msg; int ret, i; fstring string_sid; msg = ldb_msg_new(ldb); if (msg == NULL) { return False; } msg->dn = mapping_dn(msg, &map->sid); if (msg->dn == NULL) { goto failed; } if (ldb_msg_add_string(msg, "objectClass", "groupMap") != LDB_SUCCESS || ldb_msg_add_string(msg, "sid", sid_to_fstring(string_sid, &map->sid)) != LDB_SUCCESS || ldb_msg_add_fmt(msg, "gidNumber", "%u", (unsigned)map->gid) != LDB_SUCCESS || ldb_msg_add_fmt(msg, "sidNameUse", "%u", (unsigned)map->sid_name_use) != LDB_SUCCESS || ldb_msg_add_string(msg, "comment", map->comment) != LDB_SUCCESS || ldb_msg_add_string(msg, "ntName", map->nt_name) != LDB_SUCCESS) { goto failed; } ret = ldb_add(ldb, msg); /* if it exists we update it. This is a hangover from the semantics the tdb backend had */ if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { for (i=0;i<msg->num_elements;i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } ret = ldb_modify(ldb, msg); } talloc_free(msg); return ret == LDB_SUCCESS; failed: talloc_free(msg); return False; }