/* 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 #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_GETOPT_H #include #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); }