/*
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 <string.h>
#include <stdlib.h>
#include <time.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include "ldapdiff.h"
/* global variables */
char *profile = NULL;
char *logfile = NULL;
int facility = -1;
int loglevel = 0;
static void printusage()
{
printf("usage: ldapdiff [options] -p profile\n");
printf(" options: -c configfile\n");
printf(" options: -d loglevel 0|1|2\n");
printf(" options: -f ldiffile\n");
printf(" options: -l logfile\n");
printf(" options: -s local[0-7] (syslog facility)\n");
printf(" options: -v (print version and exit)\n");
}
int main(int argc,char* argv[])
{
extern char *optarg;
extern int optind;
int option;
int ldapoption;
int rc;
int ldapdiffrc = EXITLDOK;
int errflag = 0;
char *cfile = NULL;
char *ifile = NULL;
char *ldapuri = NULL;
LDAP *ld;
LDAPURLDesc url;
struct s_ldif *sldif = NULL;
struct s_ldif *sldifstart = NULL;
struct s_mod *smod = NULL;
struct s_schema *sschema = NULL;
struct berval passwd;
struct berval *spasswd;
time_t tstart;
time_t tend;
time(&tstart);
while ((option = getopt(argc, argv, "c:d:f:l:p:s:vh")) != EOF){
switch(option){
case 'c':
cfile = optarg;
break;
case 'd':
loglevel = atoi(optarg);
break;
case 'f':
ifile = optarg;
break;
case 'h':
printf("%s\n",VERSION);
printf("%s\n",COPYING);
printusage();
exit(EXITLDOK);
break;
case 'l':
logfile = optarg;
break;
case 'p':
profile = optarg;
break;
case 's':
if((facility = ldifgetfacility(optarg)) == -1){
errflag++;
}
break;
case 'v':
printf("%s\n",VERSION);
printf("%s\n",COPYING);
exit(EXITLDOK);
break;
default:
errflag++;
}
}
if(errflag != 0 || profile == NULL){
printusage();
exit(EXITLDERROR);
}
/* log version information, always */
ldiflog(LOG1,"%s",VERSION);
ldiflog(LOG1,"%s",COPYING);
ldiflog(LOG1,"profile: [%s]",profile);
if(cfile == NULL){
cfile = LDAPCONF;
}
ldifinitconf(cfile);
#ifndef USE_DEPRECATED_API
memset(&url,0,sizeof(url));
url.lud_scheme = "ldap";
url.lud_host = ldifgetgconf(CONFLDAPHOST);
url.lud_port = atoi(ldifgetgconf(CONFLDAPPORT));
url.lud_scope = LDAP_SCOPE_DEFAULT;
ldapuri = ldap_url_desc2str(&url);
if((rc = ldap_initialize(&ld,ldapuri)) != LDAP_SUCCESS){
ldiflog(LOG0,"ldap_initialize() failed: file: %s, line: %d",__FILE__,__LINE__);
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
#else
if((ld = ldap_open(ldifgetgconf(CONFLDAPHOST),atoi(ldifgetgconf(CONFLDAPPORT)))) == NULL){
ldiflog(LOG0,"ldap_open() failed: file: %s, line: %d",__FILE__,__LINE__);
perror("perror(): ");
exit(EXITLDERROR);
}
#endif
ldapoption = LDAP_NO_LIMIT;
if(ldap_set_option(ld,LDAP_OPT_SIZELIMIT,&ldapoption) == -1){
ldiflog(LOG0,"ldap_set_option() failed: file: %s, line: %d",__FILE__,__LINE__);
exit(EXITLDERROR);
}
ldapoption = LDAP_VERSION3;
if(ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,&ldapoption) == -1){
ldiflog(LOG0,"ldap_set_option() failed: file: %s, line: %d",__FILE__,__LINE__);
exit(EXITLDERROR);
}
#ifndef USE_DEPRECATED_API
passwd.bv_val = ldifgetgconf(CONFROOTPW);
passwd.bv_len = strlen(passwd.bv_val);
if((rc = ldap_sasl_bind_s(ld,ldifgetgconf(CONFROOTDN),NULL,&passwd,NULL,NULL,&spasswd)) != LDAP_SUCCESS){
ldiflog(LOG0,"ldap_sasl_bind_s() failed: file: %s, line: %d",__FILE__,__LINE__);
#else
if((rc = ldap_bind_s(ld,ldifgetgconf(CONFROOTDN),ldifgetgconf(CONFROOTPW),LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS){
ldiflog(LOG0,"ldap_bind_s() failed: file: %s, line: %d",__FILE__,__LINE__);
#endif
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
/* read ldif input */
ldifread(&sldif,ifile);
if(sldif == NULL){
ldiflog(LOG1,"no ldif entries found, normal exit...");
exit(EXITLDOK);
}
sldifstart = sldif;
/* build the schema cache */
ldifschemacreate(ld,&sschema);
/* replace all aliases with the real attribute names */
ldifschemareplacealiases(sldif,sschema);
/* compare ldif file against ldap server */
ldifiterldif(ld,sldifstart,&smod,sschema);
/* compare ldap server against ldif file */
ldifiterldap(ld,sldifstart,&smod,sschema);
ldiffree(&sldifstart);
ldifstats(smod);
if(strcmp(ldifgetgconf(CONFONLINEUPDATE),"yes") == 0){
if(ldifmodify(ld,smod,sschema) != 0){
ldapdiffrc = EXITLDWARNING;
}
}
if(strcmp(ldifgetgconf(CONFOFFLINEUPDATE),"yes") == 0){
ldifwrite(smod,sschema);
}
/* free the schema cache */
ldifschemafree(&sschema);
#ifndef USE_DEPRECATED_API
if((rc = ldap_set_option(ld,LDAP_OPT_SERVER_CONTROLS,NULL)) != LDAP_OPT_SUCCESS){
ldiflog(LOG0,"ldap_set_option() failed: file: %s, line: %d",__FILE__,__LINE__);
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
if((rc = ldap_unbind_ext_s(ld,NULL,NULL)) != LDAP_OPT_SUCCESS){
ldiflog(LOG0,"ldap_unbind_ext() failed: file: %s, line: %d",__FILE__,__LINE__);
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
#else
if(ldap_unbind(ld) == -1){
ldiflog(LOG0,"ldap_unbind() failed: file: %s, line: %d",__FILE__,__LINE__);
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
#endif
/* calculate execution time */
time(&tend);
ldiflog(LOG1,"time: %10d seconds",tend - tstart);
exit(ldapdiffrc);
}
syntax highlighted by Code2HTML, v. 0.9.1