/* 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 #include #include #include #include #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); } }