/*
ldapdiff
Copyright (C) 2000-2006 Thomas.Reith@rhoen.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <lber.h>
#include <ldap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ldapdiff.h"
static int addentry(LDAP *ld,char *dnval,struct s_modentry *smodentry)
{
LDAPMod **lma;
struct s_modentry *psmodentry;
struct s_ldifval *psmodentryval;
int numval;
int rc;
int count = 0;
int retval = 0;
int numattr = 0;
psmodentry = smodentry;
while(psmodentry != NULL){
numattr++;
psmodentry = psmodentry->next;
}
lma = LDALLOC(numattr + 1,sizeof(LDAPMod*));
psmodentry = smodentry;
while(psmodentry != NULL){
lma[count] = LDALLOC(1,sizeof(LDAPMod));
lma[count]->mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
lma[count]->mod_type = psmodentry->var;
numval = 0;
psmodentryval = psmodentry->vallist;
while(psmodentryval != NULL){
numval++;
psmodentryval = psmodentryval->next;
}
lma[count]->mod_vals.modv_bvals = LDALLOC(numval+1,sizeof(struct berval*));
numval = 0;
psmodentryval = psmodentry->vallist;
while(psmodentryval != NULL){
lma[count]->mod_vals.modv_bvals[numval] = LDALLOC(1,sizeof(struct berval));
lma[count]->mod_vals.modv_bvals[numval]->bv_val = psmodentryval->val;
lma[count]->mod_vals.modv_bvals[numval]->bv_len = psmodentryval->val_len;
numval++;
psmodentryval = psmodentryval->next;
}
count++;
psmodentry = psmodentry->next;
}
#ifndef USE_DEPRECATED_API
if((rc = ldap_add_ext_s(ld,dnval,lma,NULL,NULL)) != LDAP_SUCCESS){
#else
if((rc = ldap_add_s(ld,dnval,lma)) != LDAP_SUCCESS){
#endif
ldiflog(LOG1,"error: onlineadd of %s",dnval);
ldiflog(LOG1,"ldap_err2string(): %s",ldap_err2string(rc));
retval = 1;
}
else{
ldiflog(LOG2,"success: add %s",dnval);
}
numattr = 0;
psmodentry = smodentry;
while(psmodentry != NULL){
numval = 0;
psmodentryval = psmodentry->vallist;
while(psmodentryval != NULL){
free(lma[numattr]->mod_vals.modv_bvals[numval]);
numval++;
psmodentryval = psmodentryval->next;
}
free(lma[numattr]->mod_vals.modv_bvals);
free(lma[numattr]);
numattr++;
psmodentry = psmodentry->next;
}
free(lma);
return retval;
}
static int delentry(LDAP *ld,char *dnval)
{
int rc;
int retval = 0;
#ifndef USE_DEPRECATED_API
if((rc = ldap_delete_ext_s(ld,dnval,NULL,NULL)) != LDAP_SUCCESS){
#else
if((rc = ldap_delete_s(ld,dnval)) != LDAP_SUCCESS){
#endif
ldiflog(LOG1,"error: onlinedelete of %s",dnval);
ldiflog(LOG1,"ldap_err2string(): %s",ldap_err2string(rc));
retval = 1;
}
else{
ldiflog(LOG2,"success: delete %s",dnval);
}
return retval;
}
static int modattr(LDAP *ld,char *dnval,char *var,struct s_ldifval *vallist,int mod_op, char *mod_txt)
{
LDAPMod **lma;
struct s_ldifval *psmodentryval;
int rc;
int retval = 0;
int numval;
switch(mod_op){
case LDAP_MOD_REPLACE: /* no break */
case LDAP_MOD_DELETE: /* no break */
case LDAP_MOD_ADD:
if(var != NULL){
lma = LDALLOC(2,sizeof(LDAPMod*));
lma[0] = LDALLOC(1,sizeof(LDAPMod));
lma[0]->mod_op = mod_op|LDAP_MOD_BVALUES;
lma[0]->mod_type = var;
lma[0]->mod_vals.modv_bvals = NULL;
if(vallist != NULL){
numval = 0;
psmodentryval = vallist;
while(psmodentryval != NULL){
numval++;
psmodentryval = psmodentryval->next;
}
lma[0]->mod_vals.modv_bvals = LDALLOC(numval+1,sizeof(struct berval*));
numval = 0;
psmodentryval = vallist;
while(psmodentryval != NULL){
lma[0]->mod_vals.modv_bvals[numval] = LDALLOC(1,sizeof(struct berval));
lma[0]->mod_vals.modv_bvals[numval]->bv_val = psmodentryval->val;
lma[0]->mod_vals.modv_bvals[numval]->bv_len = psmodentryval->val_len;
numval++;
psmodentryval = psmodentryval->next;
}
}
#ifndef USE_DEPRECATED_API
if((rc = ldap_modify_ext_s(ld,dnval,lma,NULL,NULL)) != LDAP_SUCCESS){
#else
if((rc = ldap_modify_s(ld,dnval,lma)) != LDAP_SUCCESS){
#endif
ldiflog(LOG1,"error: onlinemodify of %s",dnval);
psmodentryval = vallist;
while(psmodentryval != NULL){
ldiflogval(LOG1," %s: %s",var,psmodentryval->val,psmodentryval->val_len);
psmodentryval = psmodentryval->next;
}
ldiflog(LOG1,"ldap_err2string(): %s",ldap_err2string(rc));
retval = 1;
}
else{
ldiflog(LOG2,"success: %-7s %s",mod_txt,dnval);
psmodentryval = vallist;
while(psmodentryval != NULL){
ldiflogval(LOG2," %s: %s",var,psmodentryval->val,psmodentryval->val_len);
psmodentryval = psmodentryval->next;
}
if(vallist == NULL){
ldiflog(LOG2," %s: [no deletion value]",var);
}
}
numval = 0;
psmodentryval = vallist;
while(psmodentryval != NULL){
free(lma[0]->mod_vals.modv_bvals[numval]);
numval++;
psmodentryval = psmodentryval->next;
}
free(lma[0]->mod_vals.modv_bvals);
free(lma[0]);
free(lma);
}
break;
default:
ldiflog(LOG0,"fatal error: file %s line %d",__FILE__,__LINE__);
exit(EXITLDERROR);
}
return retval;
}
int ldifmodify(LDAP *ld,struct s_mod *smod,struct s_schema *sschema)
{
struct s_mod *psmod;
struct s_modentry *psmodentry;
int errcount = 0;
int rc = 0;
psmod = smod;
while(psmod != NULL){
switch(psmod->modtype){
case MODADD:
errcount += addentry(ld,psmod->dnval,psmod->attrlist);
break;
case MODMODIFY:
psmodentry = psmod->attrlist;
while(psmodentry != NULL){
switch(psmodentry->modtype){
case MODATTRADD:
errcount += modattr(ld,psmod->dnval,psmodentry->var,psmodentry->vallist,LDAP_MOD_ADD,"add");
break;
case MODATTRREPLACE:
errcount += modattr(ld,psmod->dnval,psmodentry->var,psmodentry->vallist,LDAP_MOD_REPLACE,"replace");
break;
case MODATTRDELETE:
if(ldifschemaequal(sschema,psmodentry->var) == 1){
errcount += modattr(ld,psmod->dnval,psmodentry->var,psmodentry->vallist,LDAP_MOD_DELETE,"delete");
}
else{
errcount += modattr(ld,psmod->dnval,psmodentry->var,NULL,LDAP_MOD_DELETE,"delete");
}
break;
}
psmodentry = psmodentry->next;
}
break;
case MODDELETE:
errcount += delentry(ld,psmod->dnval);
break;
}
psmod = psmod->next;
}
ldiflog(LOG1,"write: %10d online transactions failed",errcount);
if(errcount > 0){
if(strcmp(ldifgetgconf(CONFONLINEERRFATAL),"yes") == 0){
exit(EXITLDERROR);
}
rc = 1;
}
return rc;
}
syntax highlighted by Code2HTML, v. 0.9.1