/*
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 <stdarg.h>
#include <errno.h>
#include <syslog.h>
#include "ldapdiff.h"
char *ldifnormalizedn(char *dn)
{
LDAPDN ldn;
char *ndn;
int rc;
if((rc = ldap_str2dn(dn,&ldn,LDAP_DN_FORMAT_LDAPV3)) != LDAP_SUCCESS){
ldiflog(LOG0,"error: invalid dn [%s]",dn);
ldiflog(LOG0,"ldap_str2dn() failed: file: %s, line: %d",__FILE__,__LINE__);
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
if((rc = ldap_dn2str(ldn,&ndn,LDAP_DN_FORMAT_LDAPV3)) != LDAP_SUCCESS){
ldiflog(LOG0,"ldap_dn2str() failed: file: %s, line: %d",__FILE__,__LINE__);
ldiflog(LOG0,"ldap_err2string(): %s",ldap_err2string(rc));
exit(EXITLDERROR);
}
ldap_dnfree(ldn);
if(strcasecmp(dn,ndn) != 0){
ldiflog(LOG2,"warning: dn normalized [%s]->[%s]",dn,ndn);
}
return ndn;
}
int ldifcheckbase(char *attrbase)
{
char *confbase;
confbase = ldifnormalizedn(ldifgetpconf(CONFBASEDN));
if(strlen(attrbase) < strlen(confbase)){
return -1;
}
if(strcasecmp(attrbase+strlen(attrbase)-strlen(confbase),confbase) != 0){
return -1;
}
free(confbase);
return 0;
}
teignore ldifcheckignore(char *attribute)
{
char *cignore;
char *ctok;
cignore = LDDUP(ldifgetpconf(CONFIGNORE));
ctok = strtok(cignore,", \t");
while(ctok != NULL){
if(strcasecmp(ctok,attribute) == 0){
free(cignore);
return ATTRIGNORE;
}
ctok = strtok(NULL,", \t");
}
free(cignore);
return ATTRCHECK;
}
teignore ldifcheckignoreval(char *value)
{
char *cignore;
char *ctok;
cignore = LDDUP(ldifgetpconf(CONFIGNOREVAL));
ctok = strtok(cignore,", \t");
while(ctok != NULL){
if(strcasecmp(ctok,value) == 0){
free(cignore);
return ATTRIGNORE;
}
ctok = strtok(NULL,", \t");
}
free(cignore);
return ATTRCHECK;
}
int ldifchecknoequality(char *attribute)
{
char *cnoequality;
char *ctok;
cnoequality = LDDUP(ldifgetpconf(CONFNOEQUALITY));
ctok = strtok(cnoequality,", \t");
while(ctok != NULL){
if(strcasecmp(ctok,attribute) == 0){
free(cnoequality);
return 0;
}
ctok = strtok(NULL,", \t");
}
free(cnoequality);
ldiflog(LOG0,"hossa %s",attribute);
return 1;
}
char *ldifcheckalias(char *attribute)
{
char *calias;
char *ctok;
static char realstatic[MAXATTRLEN];
calias = LDDUP(ldifgetpconf(CONFMAPALIAS));
ctok = strtok(calias,",");
while(ctok != NULL){
char *alias;
char *real;
if((real = strchr(ctok,'=')) == NULL){
ldiflog(LOG0,"ldifcheckalias() failed: file %s line %d",__FILE__,__LINE__);
exit(EXITLDERROR);
}
*real = '\0';
real++;
alias = ctok;
ldiftrim(alias);
ldiftrim(real);
if(strlen(real) == 0 || strlen(alias) == 0){
ldiflog(LOG0,"ldifcheckalias() failed: file %s line %d",__FILE__,__LINE__);
exit(EXITLDERROR);
}
if(strcasecmp(attribute,alias) == 0){
ldiflog(LOG2,"attribute %s mapped to %s",attribute,real);
sprintf(realstatic,"%s",real);
free(calias);
return realstatic;
}
ctok = strtok(NULL,",");
}
free(calias);
return attribute;
}
void ldifaddentry(struct s_ldif *sldif,char *var,char *val,size_t val_len,teattrtype val_type)
{
struct s_ldifentry *psldifentry;
struct s_ldifval *psldifval;
struct s_ldifval *tsldifval;
if(sldif == NULL){
/* this should never happen */
ldiflog(LOG0,"fatal error: file %s line %d",__FILE__,__LINE__);
exit(EXITLDERROR);
}
psldifval = LDALLOC(1,sizeof(struct s_ldifval));
psldifval->val = LDBINDUP(val,val_len);
psldifval->val_len = val_len;
psldifentry = sldif->attrlist;
while(psldifentry != NULL){
if(strcasecmp(psldifentry->var,var) == 0){
tsldifval = psldifentry->vallist;
while(tsldifval->next != NULL){
tsldifval = tsldifval->next;
}
tsldifval->next = psldifval;
return;
}
psldifentry = psldifentry->next;
}
psldifentry = LDALLOC(1,sizeof(struct s_ldifentry));
psldifentry->var = LDDUP(var);
psldifentry->vallist = psldifval;
psldifentry->val_type = val_type;
if(sldif->attrlist == NULL){
sldif->attrlist = psldifentry;
}
else{
struct s_ldifentry *tsldifentry;
tsldifentry = sldif->attrlist;
while(tsldifentry->next != NULL){
tsldifentry = tsldifentry->next;
}
tsldifentry->next = psldifentry;
}
}
struct s_ldif* ldifadd(struct s_ldif** sldif,char *dnvar,char* dnval)
{
struct s_ldif *psldif;
psldif = LDALLOC(1,sizeof(struct s_ldif));
psldif->dnvar = LDDUP(dnvar);
psldif->dnval = LDDUP(dnval);
if(*sldif == NULL){
*sldif = psldif;
}
else{
struct s_ldif *tsldif;
tsldif = *sldif;
while(tsldif->next != NULL){
tsldif = tsldif->next;
}
tsldif->next = psldif;
}
return psldif;
}
void ldiffree(struct s_ldif** sldif)
{
struct s_ldif *psldif;
struct s_ldif *tpsldif;
psldif = *sldif;
while(psldif != NULL){
struct s_ldifentry *psldifentry;
struct s_ldifentry *tpsldifentry;
psldifentry = psldif->attrlist;
while(psldifentry != NULL){
struct s_ldifval *psldifval;
struct s_ldifval *tpsldifval;
psldifval = psldifentry->vallist;
while(psldifval != NULL){
free(psldifval->val);
tpsldifval = psldifval;
psldifval = psldifval->next;
free(tpsldifval);
}
free(psldifentry->var);
tpsldifentry = psldifentry;
psldifentry = psldifentry->next;
free(tpsldifentry);
}
free(psldif->dnvar);
free(psldif->dnval);
tpsldif = psldif;
psldif = psldif->next;
free(tpsldif);
}
*sldif = NULL;
}
int ldifgetfilter(struct s_ldifentry *sldifentry,char *filter)
{
struct s_ldifentry *psldifentry;
struct s_ldifval *psldifval;
char *cfilter;
char *cgroup;
char *ctok;
cfilter = LDDUP(ldifgetpconf(CONFFILTER));
cgroup = LDDUP(ldifgetpconf(CONFGROUP));
ctok = strtok(cfilter,",");
while(ctok != NULL){
psldifentry = sldifentry;
while(psldifentry != NULL){
if(strcasecmp(ctok,psldifentry->var) == 0){
int count;
if(psldifentry->val_type == ATTRBIN){
ldiflog(LOG0,"error: filter attribute [%s] is binary",ctok);
exit(EXITLDERROR);
}
count = 0;
psldifval = psldifentry->vallist;
while(psldifval != NULL){
char *cval;
cval = LDALLOC(psldifval->val_len+1,sizeof(char));
strncpy(cval,psldifval->val,psldifval->val_len);
sprintf(filter,"(&(%s)(%s=%s))",cgroup,ctok,cval);
free(cval);
count++;
psldifval = psldifval->next;
}
if(count > 1){
ldiflog(LOG0,"error: filter attribute [%s] not single valued",ctok);
exit(EXITLDERROR);
}
free(cgroup);
free(cfilter);
return 0;
}
psldifentry = psldifentry->next;
}
ctok = strtok(NULL,",");
}
free(cfilter);
return -1;
}
void *ldifalloc(size_t nelem,size_t elsize,char* file,int line)
{
void *p;
if((p = calloc(nelem,elsize)) == NULL){
ldiflog(LOG0,"calloc() failed file:%s line:%d %s",file,line,strerror(errno));
exit(EXITLDERROR);
}
return(p);
}
char *ldifdup(char* s,char* file,int line)
{
char *p;
if((p = strdup(s)) == NULL){
ldiflog(LOG0,"strdup() failed file:%s line:%d %s",file,line,strerror(errno));
exit(EXITLDERROR);
}
return(p);
}
char *ldifbindup(char* s,size_t len,char *file,int line)
{
char *p;
if((p = calloc(len,sizeof(char))) == NULL){
ldiflog(LOG0,"calloc() failed file:%s line:%d %s",file,line,strerror(errno));
exit(EXITLDERROR);
}
return (char*)memcpy(p,s,len);
}
int ldifconfnormalize(char *s,char *var,char *val)
{
char *valtmp;
if((valtmp = strchr(s,':')) == NULL){
return -1;
}
strncpy(var,s,valtmp - s);
var[valtmp - s] = '\0';
ldiftrim(var);
strcpy(val,valtmp+1);
ldiftrim(val);
if(var[0] == '\0' || val[0] == '\0'){
return -1;
}
return 0;
}
void ldiftrim(char *s)
{
int c1 = 0;
int c2 = 0;
int f = 0;
if(s == NULL){
return;
}
while(s[c1] != 0){
if((s[c1] != ' ' && s[c1] != '\t') || f == 1){
s[c2] = s[c1];
f = 1;
c2++;
}
c1++;
}
s[c2] = 0;
c1 = strlen(s) - 1;
while(c1 >= 0){
if(s[c1] == ' ' || s[c1] == '\t'){
s[c1] = 0;
}
else{
break;
}
c1--;
}
}
int ldifgetfacility(char *facility)
{
struct s_syslogcodes {
char *c_name;
int c_val;
} syslogcodes[] = {
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }};
int count = 0;
while(syslogcodes[count].c_name != NULL){
if(strcmp(facility,syslogcodes[count].c_name) == 0){
return syslogcodes[count].c_val;
}
count++;
}
return -1;
}
syntax highlighted by Code2HTML, v. 0.9.1