construct a primary group token for groups from a message
*/
static int construct_primary_group_token(struct ldb_module *module,
- struct ldb_message *msg)
+ struct ldb_message *msg)
{
struct ldb_context *ldb;
uint32_t primary_group_token;
-
+
ldb = ldb_module_get_ctx(module);
-
- /* this is horrendously inefficient! we're doing a subtree
- * search for every DN we return. So that's N^2 in the
- * total number of objects! */
- if (samdb_search_count(ldb, msg->dn, "(objectclass=group)") == 1) {
+ if (ldb_match_msg_objectclass(msg, "group") == 1) {
primary_group_token
= samdb_result_rid_from_sid(ldb, msg, "objectSid", 0);
+ if (primary_group_token == 0) {
+ return LDB_SUCCESS;
+ }
+
return samdb_msg_add_int(ldb, ldb, msg, "primaryGroupToken",
primary_group_token);
} else {
const struct ldb_val *parent_guid;
const char *attrs[] = { "objectGUID", NULL };
int ret;
+ struct ldb_val v;
/* TODO: In the future, this needs to honour the partition boundaries */
struct ldb_dn *parent_dn = ldb_dn_get_parent(msg, msg->dn);
- if (parent_dn == NULL){
+ if (parent_dn == NULL) {
DEBUG(4,(__location__ ": Failed to find parent for dn %s\n",
ldb_dn_get_linearized(msg->dn)));
return LDB_SUCCESS;
ret = dsdb_module_search_dn(module, msg, &res, parent_dn, attrs, DSDB_SEARCH_SHOW_DELETED);
talloc_free(parent_dn);
/* if there is no parentGUID for this object, then return */
- if (ret == LDB_ERR_NO_SUCH_OBJECT){
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
DEBUG(4,(__location__ ": Parent dn for %s does not exist \n",
ldb_dn_get_linearized(msg->dn)));
return LDB_SUCCESS;
return LDB_SUCCESS;
}
- talloc_steal(msg->elements, parent_guid->data);
+ v = data_blob_dup_talloc(res, parent_guid);
+ if (!v.data) {
+ talloc_free(res);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ret = ldb_msg_add_steal_value(msg, "parentGUID", &v);
talloc_free(res);
- return ldb_msg_add_value(msg, "parentGUID", parent_guid, 0);
+ return ret;
}
/*
static const struct {
const char *attr;
const char *replace;
+ const char *extra_attr;
int (*constructor)(struct ldb_module *, struct ldb_message *);
} search_sub[] = {
- { "createTimestamp", "whenCreated", NULL },
- { "modifyTimestamp", "whenChanged", NULL },
- { "structuralObjectClass", "objectClass", NULL },
- { "canonicalName", "distinguishedName", construct_canonical_name },
- { "primaryGroupToken", "objectSid", construct_primary_group_token },
- { "parentGUID", NULL, construct_parent_guid },
- { "subSchemaSubEntry", NULL, construct_subschema_subentry }
+ { "createTimestamp", "whenCreated", NULL , NULL },
+ { "modifyTimestamp", "whenChanged", NULL , NULL },
+ { "structuralObjectClass", "objectClass", NULL , NULL },
+ { "canonicalName", "distinguishedName", NULL , construct_canonical_name },
+ { "primaryGroupToken", "objectClass", "objectSid", construct_primary_group_token },
+ { "parentGUID", NULL, NULL, construct_parent_guid },
+ { "subSchemaSubEntry", NULL, NULL, construct_subschema_subentry }
};
const char *attr;
enum op_remove op;
} operational_remove[] = {
- { "nTSecurityDescriptor", OPERATIONAL_REMOVE_UNASKED },
- { "parentGUID", OPERATIONAL_REMOVE_ALWAYS },
- { "replPropertyMetaData", OPERATIONAL_REMOVE_UNASKED },
- { "ntPwdHistory", OPERATIONAL_REMOVE_UNASKED },
- { "lmPwdHistory", OPERATIONAL_REMOVE_UNASKED },
- { "unicodePwd", OPERATIONAL_REMOVE_UNASKED },
- { "supplementalCredentials", OPERATIONAL_REMOVE_UNASKED },
- { "dBCSPwd", OPERATIONAL_REMOVE_UNASKED }
+ { "nTSecurityDescriptor", OPERATIONAL_REMOVE_UNASKED },
+ { "parentGUID", OPERATIONAL_REMOVE_ALWAYS },
+ { "replPropertyMetaData", OPERATIONAL_REMOVE_UNASKED },
+ { "unicodePwd", OPERATIONAL_REMOVE_UNASKED },
+ { "dBCSPwd", OPERATIONAL_REMOVE_UNASKED },
+ { "ntPwdHistory", OPERATIONAL_REMOVE_UNASKED },
+ { "lmPwdHistory", OPERATIONAL_REMOVE_UNASKED },
+ { "supplementalCredentials", OPERATIONAL_REMOVE_UNASKED }
};
/* remove the added search attribute, unless it was
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, "*")) {
- continue;
+ if (search_sub[i].replace != NULL &&
+ !ldb_attr_in_list(attrs, search_sub[i].replace) &&
+ !ldb_attr_in_list(attrs, "*")) {
+ 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_msg_remove_attr(msg, search_sub[i].extra_attr);
}
-
- ldb_msg_remove_attr(msg, search_sub[i].replace);
}
}
for (i=0;i<ARRAY_SIZE(search_sub);i++) {
if (ldb_attr_cmp(ac->attrs[a], search_sub[i].attr) == 0 &&
search_sub[i].replace) {
+
+ if (search_sub[i].extra_attr) {
+ const char **search_attrs2;
+ /* Only adds to the end of the list */
+ search_attrs2 = ldb_attr_list_copy_add(req, search_attrs
+ ? search_attrs
+ : ac->attrs,
+ search_sub[i].extra_attr);
+ if (search_attrs2 == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ /* may be NULL, talloc_free() doesn't mind */
+ talloc_free(search_attrs);
+ search_attrs = search_attrs2;
+ }
+
if (!search_attrs) {
search_attrs = ldb_attr_list_copy(req, ac->attrs);
if (search_attrs == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
}
+ /* Despite the ldb_attr_list_copy_add, this is safe as that fn only adds to the end */
search_attrs[a] = search_sub[i].replace;
}
}