/*
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 void cmodentry(struct s_modentry **smodentry,char *var,char *val,size_t val_len,teattrtype val_type,temodentry emodentry)
{
struct s_modentry *psmodentry;
struct s_modentry *ptsmodentry;
struct s_ldifval *psmodentryval;
struct s_ldifval *ptsmodentryval;
if(var == NULL || val == NULL){
return;
}
psmodentryval = LDALLOC(1,sizeof(struct s_ldifval));
psmodentryval->val = LDBINDUP(val,val_len);
psmodentryval->val_len = val_len;
psmodentry = *smodentry;
while(psmodentry != NULL){
if(strcasecmp(psmodentry->var,var) == 0){
ptsmodentryval = psmodentry->vallist;
while(ptsmodentryval->next != NULL){
ptsmodentryval = ptsmodentryval->next;
}
ptsmodentryval->next = psmodentryval;
return;
}
psmodentry = psmodentry->next;
}
ptsmodentry = LDALLOC(1,sizeof(struct s_modentry));
ptsmodentry->var = LDDUP(var);
ptsmodentry->vallist = psmodentryval;
ptsmodentry->val_type = val_type;
ptsmodentry->modtype = emodentry;
if(*smodentry == NULL){
*smodentry = ptsmodentry;
}
else{
struct s_modentry *usmodentry;
usmodentry = *smodentry;
while(usmodentry != NULL){
if(usmodentry->next == NULL){
usmodentry->next = ptsmodentry;
return;
}
usmodentry = usmodentry->next;
}
}
}
static void cmod(struct s_mod **smod,char *dnvar,char *dnval,char *var,char *val,size_t val_len,teattrtype val_type,temod emod,temodentry emodentry)
{
struct s_mod *psmod;
struct s_mod *ptsmod;
psmod = *smod;
while(psmod != NULL){
if(strcmp(psmod->dnval,dnval) == 0 && psmod->modtype == emod){
cmodentry(&psmod->attrlist,var,val,val_len,val_type,emodentry);
return;
}
psmod = psmod->next;
}
ptsmod = LDALLOC(1,sizeof(struct s_mod));
ptsmod->dnvar = LDDUP(dnvar);
ptsmod->dnval = LDDUP(dnval);
ptsmod->modtype = emod;
cmodentry(&ptsmod->attrlist,var,val,val_len,val_type,emodentry);
if(*smod == NULL){
*smod = ptsmod;
}
else{
struct s_mod *usmod;
usmod = *smod;
while(usmod != NULL){
if(usmod->next == NULL){
usmod->next = ptsmod;
return;
}
usmod = usmod->next;
}
}
}
void ldifcmp(LDAP *ld,struct s_ldif *sldif,struct s_ldif *sldap,struct s_mod **smod,struct s_schema *sschema)
{
struct s_ldifentry *psldifentry;
struct s_ldifentry *psldapentry;
struct s_ldifval *psldifval;
struct s_ldifval *psldapval;
int attr_found;
int attr_modifybydeladd = 0;
psldifentry = sldif->attrlist;
while(psldifentry != NULL){
if(ldifcheckignore(psldifentry->var) == ATTRIGNORE){
ldiflog(LOG2,"ignore attr: %s",sldif->dnval);
psldifval = psldifentry->vallist;
while(psldifval != NULL){
ldiflogval(LOG2," %s: %s",psldifentry->var,psldifval->val,psldifval->val_len);
psldifval = psldifval->next;
}
}
else{
attr_found = 0;
psldapentry = sldap->attrlist;
while(psldapentry != NULL){
if(strcasecmp(psldifentry->var,psldapentry->var) == 0){
int ldifcount = 0;
int ldapcount = 0;
attr_found = 1;
psldifval = psldifentry->vallist;
while(psldifval != NULL){
if(ldifcheckignoreval(psldifval->val) != ATTRIGNORE){
ldifcount++;
}
else{
ldiflog(LOG2,"ignore ldif attrval: %s",sldif->dnval);
ldiflog(LOG2,"ignore ldif attrval: %s",psldifval->val);
}
psldifval = psldifval->next;
}
psldapval = psldapentry->vallist;
while(psldapval != NULL){
if(ldifcheckignoreval(psldapval->val) != ATTRIGNORE){
ldapcount++;
}
else{
ldiflog(LOG2,"ignore ldap attrval: %s",sldap->dnval);
ldiflog(LOG2,"ignore ldap attrval: %s",psldapval->val);
}
psldapval = psldapval->next;
}
if(ldapcount == ldifcount){
ldapcount = 0;
psldifval = psldifentry->vallist;
while(psldifval != NULL){
psldapval = psldapentry->vallist;
while(psldapval != NULL){
if(psldifval->val_len == psldapval->val_len){
if(memcmp(psldifval->val,psldapval->val,psldifval->val_len) == 0){
ldapcount++;
}
}
psldapval = psldapval->next;
}
psldifval = psldifval->next;
}
}
if(ldifcount != ldapcount){
/*
case 1: attribute is different in ldif file
*/
ldiflog(LOG2,"replace attr: %s",sldif->dnval);
psldapval = psldapentry->vallist;
while(psldapval != NULL){
ldiflogval(LOG2," %s: %s ->",psldapentry->var,psldapval->val,psldapval->val_len);
psldapval = psldapval->next;
}
psldifval = psldifentry->vallist;
while(psldifval != NULL){
if(strcmp(ldifgetpconf(CONFMODIFYBYDELADD),"yes") != 0){
cmod(smod,sldif->dnvar,sldif->dnval,psldifentry->var,psldifval->val,psldifval->val_len,psldifentry->val_type,MODMODIFY,MODATTRREPLACE);
}
ldiflogval(LOG2," %s: %s",psldifentry->var,psldifval->val,psldifval->val_len);
attr_modifybydeladd = 1;
psldifval = psldifval->next;
}
}
}
psldapentry = psldapentry->next;
}
if(attr_found == 0){
/*
case 2: attribute doesn't exist in ldap
*/
psldifval = psldifentry->vallist;
while(psldifval != NULL){
if(strcmp(ldifgetpconf(CONFMODIFYBYDELADD),"yes") != 0){
cmod(smod,sldif->dnvar,sldif->dnval,psldifentry->var,psldifval->val,psldifval->val_len,psldifentry->val_type,MODMODIFY,MODATTRADD);
}
ldiflog(LOG2,"add attr: %s",sldif->dnval);
ldiflogval(LOG2," %s: %s",psldifentry->var,psldifval->val,psldifval->val_len);
attr_modifybydeladd = 1;
psldifval = psldifval->next;
}
}
}
psldifentry = psldifentry->next;
}
psldapentry = sldap->attrlist;
while(psldapentry != NULL){
if(ldifcheckignore(psldapentry->var) == ATTRIGNORE){
ldiflog(LOG2,"ignore attr: %s",sldap->dnval);
psldapval = psldapentry->vallist;
while(psldapval != NULL){
ldiflogval(LOG2," %s: %s",psldapentry->var,psldapval->val,psldapval->val_len);
psldapval = psldapval->next;
}
}
else{
psldifentry = sldif->attrlist;
attr_found = 0;
while(psldifentry != NULL){
if(strcasecmp(psldapentry->var,psldifentry->var) == 0){
attr_found++;
}
psldifentry = psldifentry->next;
}
if(attr_found == 0){
/*
case 3: attribute doesn't exist in ldif
*/
if((strcmp(ldifgetpconf(CONFDELETEATTRIBUTE),"yes") == 0) ||
(strstr(ldifgetpconf(CONFDELETEATTRIBUTE), psldapentry->var) != NULL)){
psldapval = psldapentry->vallist;
while(psldapval != NULL){
if(strcmp(ldifgetpconf(CONFMODIFYBYDELADD),"yes") != 0){
cmod(smod,sldap->dnvar,sldap->dnval,psldapentry->var,psldapval->val,psldapval->val_len,psldapentry->val_type,MODMODIFY,MODATTRDELETE);
}
ldiflog(LOG2,"delete attr: %s",sldap->dnval);
ldiflogval(LOG2," %s: %s",psldapentry->var,psldapval->val,psldapval->val_len);
attr_modifybydeladd = 1;
psldapval = psldapval->next;
}
}
else{
ldiflog(LOG2,"deletion disabled: %s",sldap->dnval);
}
}
}
psldapentry = psldapentry->next;
}
/*
if there are any replacement attributes and "confmodbydelete: yes" in ldapdiff.conf,
every detected entry will be deleted and the entry from the ldif file will be added
*/
if(attr_modifybydeladd == 1 && strcmp(ldifgetpconf(CONFMODIFYBYDELADD),"yes") == 0){
ldiflog(LOG2,"delete & add: %s",sldif->dnval);
ldifdeletedn(sldif->dnvar,sldif->dnval,smod);
ldifadddn(sldif,smod);
}
}
void ldifadddn(struct s_ldif *sldif,struct s_mod **smod)
{
struct s_ldifentry *psldifentry;
struct s_ldifval *psldifval;
psldifentry = sldif->attrlist;
while(psldifentry != NULL){
if(ldifcheckignore(psldifentry->var) == ATTRIGNORE){
ldiflog(LOG2,"ignore attr: %s",sldif->dnval);
psldifval = psldifentry->vallist;
while(psldifval != NULL){
ldiflogval(LOG2," %s: %s",psldifentry->var,psldifval->val,psldifval->val_len);
psldifval = psldifval->next;
}
}
else{
if(strcmp(ldifgetpconf(CONFADDENTRY),"yes") == 0){
psldifval = psldifentry->vallist;
while(psldifval != NULL){
cmod(smod,sldif->dnvar,sldif->dnval,psldifentry->var,psldifval->val,psldifval->val_len,psldifentry->val_type,MODADD,MODATTRADD);
ldiflog(LOG2,"add entry: %s",sldif->dnval);
ldiflogval(LOG2," %s: %s",psldifentry->var,psldifval->val,psldifval->val_len);
psldifval = psldifval->next;
}
}
else{
ldiflog(LOG2,"addition disabled: %s", sldif->dnval);
}
}
psldifentry = psldifentry->next;
}
}
void ldifdeletedn(char *dnvar,char *dnval,struct s_mod **smod)
{
if(strcmp(ldifgetpconf(CONFDELETEENTRY),"yes") == 0){
cmod(smod,dnvar,dnval,NULL,NULL,0,0,MODDELETE,MODATTRDELETE);
ldiflog(LOG2,"del entry: %s",dnval);
}
else{
ldiflog(LOG2,"deletion disabled: %s",dnval);
}
}
syntax highlighted by Code2HTML, v. 0.9.1