mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
s4:samldb LDB module - improve the "get_single_valued_attr" call and move it into "ldb_modules/util.c"
It will be used by other LDB modules as well.
This commit is contained in:
parent
4311438528
commit
b78bf4d721
@ -756,53 +756,6 @@ static int samldb_schema_info_update(struct samldb_ctx *ac)
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets back a single-valued attribute by the rules of the SAM triggers when
|
||||
* performing a modify operation
|
||||
*/
|
||||
static int samldb_get_single_valued_attr(struct samldb_ctx *ac,
|
||||
const char *attr_name,
|
||||
struct ldb_message_element **attr)
|
||||
{
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
struct ldb_message_element *el = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* We've to walk over all modification entries and consider the
|
||||
* "attr_name" ones.
|
||||
*
|
||||
* 1.) Add operations aren't allowed and there is returned
|
||||
* "ATTRIBUTE_OR_VALUE_EXISTS".
|
||||
* 2.) Replace operations are allowed but the last one is taken
|
||||
* 3.) Delete operations are also not allowed and there is returned
|
||||
* "UNWILLING_TO_PERFORM".
|
||||
*
|
||||
* If "el" is afterwards NULL then that means we've nothing to do here.
|
||||
*/
|
||||
for (i = 0; i < ac->msg->num_elements; i++) {
|
||||
if (ldb_attr_cmp(ac->msg->elements[i].name, attr_name) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
el = &ac->msg->elements[i];
|
||||
if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_ADD) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"samldb: attribute '%s' already exists!",
|
||||
attr_name);
|
||||
return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
|
||||
}
|
||||
if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"samldb: attribute '%s' cannot be deleted!",
|
||||
attr_name);
|
||||
return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
}
|
||||
|
||||
*attr = el;
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Objectclass" trigger (MS-SAMR 3.1.1.8.1)
|
||||
*
|
||||
@ -1056,10 +1009,7 @@ static int samldb_prim_group_change(struct samldb_ctx *ac)
|
||||
struct ldb_dn *prev_prim_group_dn, *new_prim_group_dn;
|
||||
int ret;
|
||||
|
||||
ret = samldb_get_single_valued_attr(ac, "primaryGroupID", &el);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
el = dsdb_get_single_valued_attr(ac->msg, "primaryGroupID");
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
@ -1204,10 +1154,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac)
|
||||
struct ldb_message *tmp_msg;
|
||||
int ret;
|
||||
|
||||
ret = samldb_get_single_valued_attr(ac, "userAccountControl", &el);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl");
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
@ -1280,10 +1227,7 @@ static int samldb_group_type_change(struct samldb_ctx *ac)
|
||||
struct ldb_message *tmp_msg;
|
||||
int ret;
|
||||
|
||||
ret = samldb_get_single_valued_attr(ac, "groupType", &el);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
el = dsdb_get_single_valued_attr(ac->msg, "groupType");
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
@ -1369,10 +1313,7 @@ static int samldb_sam_accountname_check(struct samldb_ctx *ac)
|
||||
struct ldb_message *tmp_msg;
|
||||
int ret;
|
||||
|
||||
ret = samldb_get_single_valued_attr(ac, "sAMAccountName", &el);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
el = dsdb_get_single_valued_attr(ac->msg, "sAMAccountName");
|
||||
if (el == NULL) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
@ -1529,27 +1470,8 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac)
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* Here it's not the same logic as with "samldb_get_single_valued_attr".
|
||||
* We need to:
|
||||
*
|
||||
* - consider "add" and "replace" operations - the last value we take
|
||||
* - ignore "delete" operations - obviously this attribute isn't
|
||||
* write protected
|
||||
*/
|
||||
for (i = 0; i < ac->msg->num_elements; i++) {
|
||||
if ((ldb_attr_cmp(ac->msg->elements[i].name,
|
||||
"dNSHostName") == 0) &&
|
||||
(LDB_FLAG_MOD_TYPE(ac->msg->elements[i].flags)
|
||||
!= LDB_FLAG_MOD_DELETE)) {
|
||||
el = &ac->msg->elements[i];
|
||||
}
|
||||
if ((ldb_attr_cmp(ac->msg->elements[i].name,
|
||||
"sAMAccountName") == 0) &&
|
||||
(LDB_FLAG_MOD_TYPE(ac->msg->elements[i].flags)
|
||||
!= LDB_FLAG_MOD_DELETE)) {
|
||||
el2 = &ac->msg->elements[i];
|
||||
}
|
||||
}
|
||||
el = dsdb_get_single_valued_attr(ac->msg, "dNSHostName");
|
||||
el2 = dsdb_get_single_valued_attr(ac->msg, "sAMAccountName");
|
||||
if ((el == NULL) && (el2 == NULL)) {
|
||||
/* we are not affected */
|
||||
return LDB_SUCCESS;
|
||||
|
@ -1108,3 +1108,33 @@ void dsdb_req_chain_debug(struct ldb_request *req, int level)
|
||||
DEBUG(level, ("%s\n", s));
|
||||
talloc_free(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets back a single-valued attribute by the rules of the DSDB triggers when
|
||||
* performing a modify operation.
|
||||
*
|
||||
* In order that the constraint checking by the "objectclass_attrs" LDB module
|
||||
* does work properly, the change request should remain similar or only be
|
||||
* enhanced (no other modifications as deletions, variations).
|
||||
*/
|
||||
struct ldb_message_element *dsdb_get_single_valued_attr(struct ldb_message *msg,
|
||||
const char *attr_name)
|
||||
{
|
||||
struct ldb_message_element *el = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* We've to walk over all modification entries and consider the last
|
||||
* non-delete one which belongs to "attr_name".
|
||||
*
|
||||
* If "el" is NULL afterwards then that means there was no interesting
|
||||
* change entry. */
|
||||
for (i = 0; i < msg->num_elements; i++) {
|
||||
if ((ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) &&
|
||||
(LDB_FLAG_MOD_TYPE(msg->elements[i].flags)
|
||||
!= LDB_FLAG_MOD_DELETE)) {
|
||||
el = &msg->elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user