/* 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 #include #include #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; }