/* 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" void ldifiterldif(LDAP *ld,struct s_ldif *sldif,struct s_mod **smod,struct s_schema *sschema) { int cn; char *dn; char filter[MAXATTRLEN]; LDAPMessage *lr = NULL; LDAPMessage *lm = NULL; BerElement *berp; struct s_ldif *psldif = NULL; struct s_ldif *psldap = NULL; struct berval **pberval = NULL; psldif = sldif; while(psldif != NULL){ int i; /* generic counter */ int rc; char *attr; /* ldap attribute */ /* find filter criteria */ if(ldifgetfilter(psldif->attrlist,filter) == -1){ ldiflog(LOG1,"warning: ignoring entry [%s]",psldif->dnval); ldiflog(LOG1," filter attribute [%s] doesn't exist",ldifgetpconf(CONFFILTER)); psldif = psldif->next; continue; } #ifndef USE_DEPRECATED_API if((rc = ldap_search_ext_s(ld,ldifgetpconf(CONFBASEDN),LDAP_SCOPE_SUBTREE,filter,NULL,0,NULL,NULL,NULL,LDAP_MAXINT,&lr)) != LDAP_SUCCESS){ ldiflog(LOG0,"ldap_search_ext_s() failed: file: %s, line: %d",__FILE__,__LINE__); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } #else if((rc = ldap_search_s(ld,ldifgetpconf(CONFBASEDN),LDAP_SCOPE_SUBTREE,filter,NULL,0,&lr)) == -1){ ldiflog(LOG0,"ldap_search() failed: file: %s, line: %d",__FILE__,__LINE__); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } #endif if((cn = ldap_count_entries(ld,lr)) == -1){ ldiflog(LOG0,"ldap_count_entries() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } /* if cn > 1, the filter's match is not unique */ if(cn > 1){ ldiflog(LOG0,"error: filter [%s] with %d matches not unique: file: %s, line: %d",filter,cn,__FILE__,__LINE__); exit(EXITLDERROR); } /* a new entry has been found */ if(cn == 0){ ldifadddn(psldif,smod); if(ldap_msgfree(lr) == -1){ ldiflog(LOG0,"ldap_msgfree() failed: file: %s, line: %d",__FILE__,__LINE__); exit(EXITLDERROR); } psldif = psldif->next; continue; } if((lm = ldap_first_entry(ld,lr)) == NULL){ ldiflog(LOG0,"ldap_first_entry() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } if((attr = ldap_first_attribute(ld,lm,&berp)) == NULL){ ldiflog(LOG0,"ldap_first_attribute() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } if((dn = ldap_get_dn(ld,lm)) == NULL){ ldiflog(LOG0,"ldap_get_dn() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } /* it's possible, that the filter matches with (cn==1), but the dn is different. in this case, we add the entry from the ldif file and delete the entry from the ldap server. if "deleteentry == yes", we do nothing and write a warning message */ if(strcasecmp(psldif->dnval,dn) != 0){ if(strcmp(ldifgetpconf(CONFDELETEENTRY),"yes") == 0){ ldifadddn(psldif,smod); } else{ ldiflog(LOG1,"warning: deletion disabled, ignoring moved dn"); } ldap_memfree(dn); if(ldap_msgfree(lr) == -1){ ldiflog(LOG0,"ldap_msgfree() failed: file: %s, line: %d",__FILE__,__LINE__); exit(EXITLDERROR); } psldif = psldif->next; continue; } ldifadd(&psldap,DNNAME,dn); while(attr != NULL){ if((pberval = ldap_get_values_len(ld,lm,attr)) != NULL){ for(i=0;ibv_val,pberval[i]->bv_len,ATTRUNKNOWN); } ldap_value_free_len(pberval); } ldap_memfree(attr); attr = ldap_next_attribute(ld,lm,berp); } /* check ldif (sldif) versus ldap (sldap) and create the delta structs */ ldifcmp(ld,psldif,psldap,smod,sschema); ldap_memfree(dn); ber_free(berp,0); ldiffree(&psldap); if(ldap_msgfree(lr) == -1){ ldiflog(LOG0,"ldap_msgfree() failed: file: %s, line: %d",__FILE__,__LINE__); exit(EXITLDERROR); } psldif = psldif->next; } } void ldifiterldap(LDAP *ld,struct s_ldif *sldif,struct s_mod **smod,struct s_schema *sschema) { int cn; int rc; char *dn; LDAPMessage *lr = NULL; LDAPMessage *lm = NULL; struct s_ldif *psldif = NULL; #ifndef USE_DEPRECATED_API if((rc = ldap_search_ext_s(ld,ldifgetpconf(CONFBASEDN),LDAP_SCOPE_SUBTREE,ldifgetpconf(CONFGROUP),NULL,0,NULL,NULL,NULL,LDAP_MAXINT,&lr)) != LDAP_SUCCESS){ ldiflog(LOG0,"ldap_search_ext_s() failed: file: %s, line: %d",__FILE__,__LINE__); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } #else if((rc = ldap_search_s(ld,ldifgetpconf(CONFBASEDN),LDAP_SCOPE_SUBTREE,ldifgetpconf(CONFGROUP),NULL,0,&lr)) == -1){ ldiflog(LOG0,"ldap_search_s() failed: file: %s, line: %d",__FILE__,__LINE__); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } #endif if((cn = ldap_count_entries(ld,lr)) == -1){ ldiflog(LOG0,"ldap_count_entries() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } if(cn > 0){ if((lm = ldap_first_entry(ld,lr)) == NULL){ ldiflog(LOG0,"ldap_first_entry() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } while(lm != NULL){ int found; if((dn = ldap_get_dn(ld,lm)) == NULL){ ldiflog(LOG0,"ldap_get_dn() failed: file: %s, line: %d",__FILE__,__LINE__); ldap_get_option(ld,LDAP_OPT_ERROR_NUMBER,&rc); ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc)); exit(EXITLDERROR); } found = 0; psldif = sldif; while(psldif != NULL){ if(strcasecmp(psldif->dnval,dn) == 0){ found++; } psldif = psldif->next; } if(found == 0){ ldifdeletedn(DNNAME,dn,smod); } lm = ldap_next_entry(ld,lm); } } ldiflog(LOG2,"search: %d object(s) found with filter [%s]",cn,ldifgetpconf(CONFGROUP)); if(ldap_msgfree(lr) == -1){ ldiflog(LOG0,"ldap_msgfree() failed: file: %s, line: %d",__FILE__,__LINE__); exit(EXITLDERROR); } }