/*
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"
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;i<ldap_count_values_len(pberval);i++){
ldifaddentry(psldap,attr,pberval[i]->bv_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);
}
}
syntax highlighted by Code2HTML, v. 0.9.1