#include "dsdb/samdb/samdb.h"
#include "dsdb/samdb/ldb_modules/util.h"
+#include "auth/auth.h"
+#include "libcli/security/dom_sid.h"
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
#endif
ldb = ldb_module_get_ctx(module);
if (ldb_match_msg_objectclass(msg, "group") == 1) {
primary_group_token
- = samdb_result_rid_from_sid(ldb, msg, "objectSid", 0);
+ = samdb_result_rid_from_sid(msg, msg, "objectSid", 0);
if (primary_group_token == 0) {
return LDB_SUCCESS;
}
- return samdb_msg_add_int(ldb, ldb, msg, "primaryGroupToken",
+ return samdb_msg_add_int(ldb, msg, msg, "primaryGroupToken",
primary_group_token);
} else {
return LDB_SUCCESS;
}
}
+/*
+ construct the token groups for SAM objects from a message
+*/
+static int construct_token_groups(struct ldb_module *module,
+ struct ldb_message *msg)
+{
+ struct ldb_context *ldb;
+ const struct dom_sid *sid;
+
+ ldb = ldb_module_get_ctx(module);
+
+ sid = samdb_result_dom_sid(msg, msg, "objectSid");
+ if (sid != NULL) {
+ NTSTATUS status;
+ uint32_t prim_group_rid;
+ struct dom_sid **sids = NULL;
+ unsigned int i, num_sids = 0;
+ int ret;
+
+ prim_group_rid = samdb_result_uint(msg, "primaryGroupID", 0);
+ if (prim_group_rid != 0) {
+ struct dom_sid *prim_group_sid;
+
+ prim_group_sid = dom_sid_add_rid(msg,
+ samdb_domain_sid(ldb),
+ prim_group_rid);
+ if (prim_group_sid == NULL) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* onlyChilds = false, we want to consider also the
+ * "primaryGroupID" for membership */
+ status = authsam_expand_nested_groups(ldb,
+ prim_group_sid,
+ false, msg,
+ &sids, &num_sids);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ for (i = 0; i < num_sids; i++) {
+ ret = samdb_msg_add_dom_sid(ldb, msg, msg,
+ "tokenGroups",
+ sids[i]);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(sids);
+ return ret;
+ }
+ }
+
+ talloc_free(sids);
+ }
+
+ sids = NULL;
+ num_sids = 0;
+
+ /* onlyChils = true, we don't want to have the SAM object itself
+ * in the result */
+ status = authsam_expand_nested_groups(ldb, sid, true, msg,
+ &sids, &num_sids);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ for (i = 0; i < num_sids; i++) {
+ ret = samdb_msg_add_dom_sid(ldb, msg, msg,
+ "tokenGroups", sids[i]);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(sids);
+ return ret;
+ }
+ }
+
+ talloc_free(sids);
+ }
+
+ return LDB_SUCCESS;
+}
+
+/*
+ construct the parent GUID for an entry from a message
+*/
static int construct_parent_guid(struct ldb_module *module,
struct ldb_message *msg)
{
{ "structuralObjectClass", "objectClass", NULL , NULL },
{ "canonicalName", "distinguishedName", NULL , construct_canonical_name },
{ "primaryGroupToken", "objectClass", "objectSid", construct_primary_group_token },
+ { "tokenGroups", "objectSid", "primaryGroupID", construct_token_groups },
{ "parentGUID", NULL, NULL, construct_parent_guid },
{ "subSchemaSubEntry", NULL, NULL, construct_subschema_subentry }
};
bool sd_flags_set)
{
struct ldb_context *ldb;
- int i, a=0;
+ unsigned int i, a = 0;
+ bool constructed_attributes = false;
ldb = ldb_module_get_ctx(module);
/* construct the new attribute, using either a supplied
constructor or a simple copy */
+ constructed_attributes = true;
if (search_sub[i].constructor != NULL) {
if (search_sub[i].constructor(module, msg) != LDB_SUCCESS) {
goto failed;
search_sub[i].attr) != LDB_SUCCESS) {
goto failed;
}
+ }
+ }
- /* remove the added search attribute, unless it was
- asked for by the user */
+ /* Deletion of the search helper attributes are needed if:
+ * - we generated constructed attributes and
+ * - we aren't requesting all attributes
+ */
+ if ((constructed_attributes) && (!ldb_attr_in_list(attrs, "*"))) {
+ for (i=0;i<ARRAY_SIZE(search_sub);i++) {
+ /* remove the added search helper attributes, unless
+ * they were asked for by the user */
if (search_sub[i].replace != NULL &&
- !ldb_attr_in_list(attrs, search_sub[i].replace) &&
- !ldb_attr_in_list(attrs, "*")) {
+ !ldb_attr_in_list(attrs, search_sub[i].replace)) {
ldb_msg_remove_attr(msg, search_sub[i].replace);
}
if (search_sub[i].extra_attr != NULL &&
- !ldb_attr_in_list(attrs, search_sub[i].extra_attr) &&
- !ldb_attr_in_list(attrs, "*")) {
+ !ldb_attr_in_list(attrs, search_sub[i].extra_attr)) {
ldb_msg_remove_attr(msg, search_sub[i].extra_attr);
}
}
return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
- /* ignore referrals */
- break;
+ return ldb_module_send_referral(ac->req, ares->referral);
case LDB_REPLY_DONE:
struct operational_context *ac;
struct ldb_request *down_req;
const char **search_attrs = NULL;
- int i, a;
+ unsigned int i, a;
int ret;
ldb = ldb_module_get_ctx(module);