memberof.c revision cecec6c15d51544a7365459d14ebf87200eaed54
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen SSSD memberof module
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen Copyright (C) Simo Sorce <idra@samba.org> 2008-2011
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen This program is free software; you can redistribute it and/or modify
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen it under the terms of the GNU General Public License as published by
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen the Free Software Foundation; either version 3 of the License, or
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen (at your option) any later version.
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen This program is distributed in the hope that it will be useful,
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
c27245ef934dbf93c8469fd1ae0519e6971ae64fTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LDB_VERSION
#include <string.h>
#include "ldb_module.h"
#include "dhash.h"
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
struct mbof_val_array {
int num;
struct mbof_dn_array {
int num;
struct mbof_dn {
struct mbof_ctx {
struct mbof_add_operation {
struct mbof_memberuid_op {
struct mbof_add_ctx {
bool terminate;
int num_muops;
int cur_muop;
struct mbof_del_ancestors_ctx {
int num_direct;
int cur;
struct mbof_del_operation {
int num_children;
int next_child;
int num_parents;
int cur_parent;
struct mbof_mod_ctx;
struct mbof_del_ctx {
int num_mus;
int num_muops;
int cur_muop;
int num_ghops;
int cur_ghop;
bool is_mod;
struct mbof_mod_del_op {
struct mbof_mod_ctx {
bool terminate;
if (!ctx) {
return NULL;
return ctx;
const char *objectclass)
if (!el) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
return LDB_ERR_NO_SUCH_ATTRIBUTE;
int *_num_muops,
int flags,
const char *name,
const char *element_name)
if (muops) {
for (i = 0; i < num_muops; i++) {
if (!op) {
struct mbof_memberuid_op,
if (!muops) {
return LDB_ERR_OPERATIONS_ERROR;
num_muops++;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
if (!val) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
if (lastop) {
return LDB_SUCCESS;
if (!addop) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
unsigned int num_gh_vals)
int ret;
return LDB_SUCCESS;
switch (ret) {
case LDB_SUCCESS:
return LDB_SUCCESS;
return ret;
for (j = 0; j < num_gh_vals; j++) {
DB_GHOST);
return ret;
return LDB_SUCCESS;
int i, ret;
if (el) {
return LDB_ERR_UNWILLING_TO_PERFORM;
if (el) {
return LDB_ERR_UNWILLING_TO_PERFORM;
if (!ctx) {
return LDB_ERR_OPERATIONS_ERROR;
if (!add_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
if (!el) {
goto done;
if (!parents) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_INVALID_DN_SYNTAX;
return ret;
done:
req);
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
return LDB_SUCCESS;
int i, j, ret;
const char *val;
const char *name;
if (!parents) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
if (el) {
if (!elval_dn) {
return LDB_ERR_OPERATIONS_ERROR;
if (el) {
if (!valdn) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_INVALID_DN_SYNTAX;
return ret;
switch (ret) {
case LDB_SUCCESS:
if (!name) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return ret;
return ret;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return LDB_SUCCESS;
if (!mdn) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
const char *val;
num = 0;
num++;
if (num == 0) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
char *expression;
const char *dn;
char *clean_dn;
int ret;
if (!ctx) {
return LDB_ERR_OPERATIONS_ERROR;
if (!del_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
if (!first) {
return LDB_ERR_OPERATIONS_ERROR;
if (!dn) {
return LDB_ERR_OPERATIONS_ERROR;
if (sret != 0) {
return LDB_ERR_OPERATIONS_ERROR;
if (!expression) {
return LDB_ERR_OPERATIONS_ERROR;
req);
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
struct ldb_message *,
if (!msg) {
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
int ret;
if (!ares) {
return LDB_SUCCESS;
const char *val;
int ret;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return ret;
int ret;
if (!ares) {
return LDB_SUCCESS;
int i, ret;
return LDB_ERR_INVALID_DN_SYNTAX;
return ret;
if (!delop) {
return LDB_ERR_OPERATIONS_ERROR;
struct mbof_del_operation *,
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
char *expression;
const char *dn;
char *clean_dn;
int ret;
if (!dn) {
return LDB_ERR_OPERATIONS_ERROR;
if (ret != 0) {
return LDB_ERR_OPERATIONS_ERROR;
if (!expression) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
struct ldb_message *,
if (!msg) {
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
if (!anc_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
if (!new_list) {
return LDB_ERR_OPERATIONS_ERROR;
struct ldb_dn *,
return LDB_ERR_OPERATIONS_ERROR;
int ret;
return ret;
int i, j, ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
if (el) {
if (!valdn) {
struct ldb_dn *,
return LDB_SUCCESS;
const char *name;
const char *val;
bool is_user;
int ret;
switch (ret) {
case LDB_SUCCESS:
is_user = true;
is_user = false;
return ret;
if (is_user) {
return LDB_ERR_OPERATIONS_ERROR;
if (!diff) {
return LDB_ERR_OPERATIONS_ERROR;
if (!diff[j]) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
if (!val) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
if (is_user) {
for (k = 0; diff[k]; k++) {
if (diff[k]) {
return ret;
if (!name) {
return LDB_ERR_OPERATIONS_ERROR;
for (i = 0; diff[i]; i++) {
return ret;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int i, ret;
if (el) {
return LDB_ERR_INVALID_DN_SYNTAX;
return ret;
return ret;
if (nextop) {
if (!save) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
return LDB_SUCCESS;
char *name;
int ret;
return LDB_SUCCESS;
switch (ret) {
case LDB_SUCCESS:
return LDB_SUCCESS;
return ret;
if (!name) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return LDB_SUCCESS;
unsigned int num_gh_vals)
int ret;
return LDB_SUCCESS;
switch (ret) {
case LDB_SUCCESS:
return LDB_SUCCESS;
return ret;
for (j = 0; j < num_gh_vals; j++) {
DB_GHOST);
return ret;
return LDB_SUCCESS;
return LDB_SUCCESS;
int ret;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
return ret;
return ret;
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
unsigned int num_values,
int ret;
if (el) {
return LDB_ERR_UNWILLING_TO_PERFORM;
if (el) {
return LDB_ERR_UNWILLING_TO_PERFORM;
if (!ctx) {
return LDB_ERR_OPERATIONS_ERROR;
if (!mod_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
req);
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
return LDB_SUCCESS;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
int ret;
char *expression;
char *clean_dn;
const char *dn;
if (!dn) {
return LDB_ERR_OPERATIONS_ERROR;
if (ret != 0) {
return LDB_ERR_OPERATIONS_ERROR;
if (!expression) {
return LDB_ERR_OPERATIONS_ERROR;
NULL,
return ret;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
if (!el) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
int ret;
if (!ares) {
return LDB_SUCCESS;
int ret;
unsigned long num_values;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
for (i = 0, j = 0; i < num_values; i++) {
if (dup) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
int ret;
if (!ares) {
return LDB_SUCCESS;
int ret;
return ret;
return ret;
*done = true;
return LDB_SUCCESS;
int i, j, ret;
if (!membel) {
return LDB_SUCCESS;
case LDB_FLAG_MOD_ADD:
return ret;
case LDB_FLAG_MOD_DELETE:
if (!el) {
return ret;
case LDB_FLAG_MOD_REPLACE:
if (el) {
return ret;
if (el) {
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
int i, j, ret;
if (!ghel) {
return LDB_SUCCESS;
return LDB_SUCCESS;
case LDB_FLAG_MOD_ADD:
return ret;
case LDB_FLAG_MOD_DELETE:
if (!el) {
return ret;
case LDB_FLAG_MOD_REPLACE:
if (el) {
return ret;
if (el) {
return ret;
if (inherited) {
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
int i, ret;
return ret;
if (!add_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return ret;
int i, ret;
if (!del_ctx) {
return LDB_ERR_OPERATIONS_ERROR;
if (!first) {
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return ret;
if (!ar) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_INVALID_DN_SYNTAX;
return LDB_SUCCESS;
unsigned int num_values,
int i, index;
if (!var) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
return LDB_ERR_OPERATIONS_ERROR;
for (i = 0; i < num_values; i++) {
return LDB_ERR_OPERATIONS_ERROR;
index++;
return LDB_SUCCESS;
return LDB_SUCCESS;
struct mbof_member {
const char *name;
bool orig_has_memberof;
bool orig_has_memberuid;
enum { MBOF_GROUP_TO_DO = 0,
struct mbof_rcmp_context {
const char *name,
if (!src) {
return LDB_ERR_NO_SUCH_ATTRIBUTE;
if (!dest) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
int ret;
if (!ctx) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return ret;
const char *name;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
if (!usr) {
if (name) {
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
return ret;
const char *name;
int ret;
if (!ares) {
case LDB_REPLY_ENTRY:
if (!grp) {
if (name) {
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
switch (ret) {
case HASH_SUCCESS:
case HASH_ERROR_KEY_NOT_FOUND:
return LDB_SUCCESS;
int ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
int ret;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
return LDB_ERR_OPERATIONS_ERROR;
if (!vals) {
return LDB_ERR_OPERATIONS_ERROR;
return LDB_SUCCESS;
unsigned long count;
int flags;
int ret, i;
goto done;
if (!msg) {
goto done;
if (x->memberofs) {
goto done;
if (x->orig_has_memberof) {
goto done;
goto done;
for (i = 0; i < count; i++) {
} else if (x->orig_has_memberof) {
goto done;
if (x->memuids) {
if (x->orig_has_memberuid) {
goto done;
else if (x->orig_has_memberuid) {
goto done;
goto done;
done:
if (!ares) {
case LDB_REPLY_ENTRY:
case LDB_REPLY_REFERRAL:
case LDB_REPLY_DONE:
return LDB_SUCCESS;
int ret;
#ifdef LDB_MODULE_CHECK_VERSION