1 /*
2     ldapdiff
3     Copyright (C) 2000-2008 Thomas.Reith@rhoen.de
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <lber.h>
20 #include <ldap.h>
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include "ldapdiff.h"
28 
29 static struct s_conf asdefconf[] = {
30  {NULL, SECTIONGLOBAL,  CONFLDAPHOST,        "ldaphost",        NULL },
31  {NULL, SECTIONGLOBAL,  CONFLDAPPORT,        "ldapport",        NULL },
32  {NULL, SECTIONGLOBAL,  CONFROOTDN,          "rootdn",          NULL },
33  {NULL, SECTIONGLOBAL,  CONFROOTPW,          "rootpw",          NULL },
34  {NULL, SECTIONGLOBAL,  CONFMODFILE,         "modfile",         NULL },
35  {NULL, SECTIONGLOBAL,  CONFADDFILE,         "addfile",         NULL },
36  {NULL, SECTIONGLOBAL,  CONFONLINEUPDATE,    "onlineupdate",    NULL },
37  {NULL, SECTIONGLOBAL,  CONFOFFLINEUPDATE,   "offlineupdate",   NULL },
38  {NULL, SECTIONGLOBAL,  CONFONLINEERRFATAL,  "onlineerrfatal",  NULL },
39  {NULL, SECTIONGLOBAL,  CONFICONV,           "iconv",           NULL },
40  {NULL, SECTIONGLOBAL,  CONFLDIFCHARSET,     "ldifcharset",     NULL },
41  {NULL, SECTIONGLOBAL,  CONFLDAPCHARSET,     "ldapcharset",     NULL },
42  {NULL, SECTIONGLOBAL,  CONFSCHEMACHECK,     "schemacheck",     NULL },
43  {NULL, SECTIONGLOBAL,  CONFSCHEMABASE,      "schemabase",      NULL },
44  {NULL, SECTIONGLOBAL,  CONFSCHEMAFILTER,    "schemafilter",    NULL },
45  {NULL, SECTIONGLOBAL,  CONFSCHEMAATTRIBUTE, "schemaattribute", NULL },
46  {NULL, SECTIONGLOBAL,  CONFMANAGEDSAIT,     "managedsait",     NULL },
47  {NULL, SECTIONPROFILE, CONFBASEDN,          "basedn",          NULL },
48  {NULL, SECTIONPROFILE, CONFFILTER,          "filter",          NULL },
49  {NULL, SECTIONPROFILE, CONFSCOPE,           "scope",           NULL },
50  {NULL, SECTIONPROFILE, CONFGROUP,           "group",           NULL },
51  {NULL, SECTIONPROFILE, CONFIGNORE,          "ignore",          NULL },
52  {NULL, SECTIONPROFILE, CONFIGNOREVAL,       "ignoreval",       NULL },
53  {NULL, SECTIONPROFILE, CONFNOEQUALITY,      "noequality",      NULL },
54  {NULL, SECTIONPROFILE, CONFMAPALIAS,        "mapalias",        NULL },
55  {NULL, SECTIONPROFILE, CONFDELETEENTRY,     "deleteentry",     NULL },
56  {NULL, SECTIONPROFILE, CONFDELETEATTRIBUTE, "deleteattribute", NULL },
57  {NULL, SECTIONPROFILE, CONFMODIFYBYDELADD,  "modifybydeladd",  NULL },
58  {NULL, SECTIONPROFILE, CONFADDENTRY,        "addentry",        NULL },
59  {NULL, SECTIONNONE,    CONFNONE,            NULL,              NULL }
60 };
61 
62 static struct s_conf *asconf[MAXCONFVAR];
63 
getconf(char * section,tevarid varid)64 static char *getconf(char *section,tevarid varid)
65 {
66  int   count = 0;
67  char *var   = "unknown";
68 
69  while(asconf[count] != NULL){
70   if(strcmp(section,asconf[count]->section) == 0 && asconf[count]->varid == varid){
71    return asconf[count]->val;
72   }
73   count++;
74  }
75 
76  count=0;
77  while(asdefconf[count].varid != CONFNONE){
78   if(asdefconf[count].varid == varid){
79    var = asdefconf[count].var;
80   }
81   count++;
82  }
83 
84  ldiflog(LOG0,"error: requested variable [%s]:%s not found",section,var);
85  exit(EXITLDERROR);
86 
87  return NULL;
88 }
89 
ldifgetgconf(tevarid varid)90 char *ldifgetgconf(tevarid varid)
91 {
92  return getconf(SECTGLOB,varid);
93 }
94 
ldifgetpconf(tevarid varid)95 char *ldifgetpconf(tevarid varid)
96 {
97  extern char *profile;
98  return getconf(profile,varid);
99 }
100 
confcheck(char * section)101 static void confcheck(char *section)
102 {
103  static struct s_conf *ascmpconf[MAXCONFVAR];
104  int           count;
105  int           cmpcount;
106  int           found;
107  tesectiontype sectiontype;
108 
109  count    = 0;
110  cmpcount = 0;
111  while(asconf[count] != NULL){
112   if(strcmp(asconf[count]->section,section) == 0){
113    ascmpconf[cmpcount] = asconf[count];
114    cmpcount++;
115   }
116   count++;
117  }
118  ascmpconf[cmpcount] = NULL;
119 
120  sectiontype = SECTIONPROFILE;
121  if(strcmp(section,SECTGLOB) == 0){
122   sectiontype = SECTIONGLOBAL;
123  }
124 
125  count    = 0;
126  while(asdefconf[count].varid != CONFNONE){
127   if(asdefconf[count].sectiontype == sectiontype){
128    cmpcount = 0;
129    found    = 0;
130    while(ascmpconf[cmpcount] != NULL){
131     if(strcmp(asdefconf[count].var,ascmpconf[cmpcount]->var) == 0){
132      found++;
133     }
134     cmpcount++;
135    }
136    if(found == 0){
137     ldiflog(LOG0,"config error: parameter [%s] %s missing",section,asdefconf[count].var);
138     exit(EXITLDERROR);
139    }
140   }
141   count++;
142  }
143 
144  count    = 0;
145  while(ascmpconf[count] != NULL){
146   cmpcount = count + 1;
147   while(ascmpconf[cmpcount] != NULL){
148    if(strcmp(ascmpconf[count]->var,ascmpconf[cmpcount]->var) == 0 &&
149       strcmp(ascmpconf[count]->section,ascmpconf[cmpcount]->section) == 0){
150     ldiflog(LOG0,"config error: parameter [%s] %s already defined",ascmpconf[cmpcount]->section,ascmpconf[cmpcount]->var);
151     exit(EXITLDERROR);
152    }
153    cmpcount++;
154   }
155   count++;
156  }
157 }
158 
ldifinitconf(char * cfile)159 void ldifinitconf(char* cfile)
160 {
161  FILE *f;
162  char  line[MAXATTRLEN];
163  char  section[MAXATTRLEN];
164  char  var[MAXATTRLEN];
165  char  val[MAXATTRLEN];
166  int   count;
167  int   confcount;
168  int   found;
169  int   clines  = 0;
170 
171  /* intialize asconf array */
172  for(confcount = 0;confcount < MAXCONFVAR;confcount++){
173   asconf[confcount] = NULL;
174  }
175 
176  ldiflog(LOG1,"config file:       [%s]",cfile);
177 
178  if((f = fopen(cfile,"r")) == NULL){
179   ldiflog(LOG0,"fopen() of %s failed: file: %s, line: %d",cfile,__FILE__,__LINE__);
180   exit(EXITLDERROR);
181  }
182 
183  confcount  = 0;
184  section[0] = 0;
185  while(fgets(line,sizeof(line),f) != NULL){
186   int ccount;
187 
188   clines++;
189 
190   /* strip '\n' '\r' and '#' */
191   ccount = 0;
192   while(line[ccount] != '\0'){
193    if(line[ccount] == '\n' || line[ccount] == '\r' || line[ccount] == '#'){
194     line[ccount] = '\0';
195     break;
196    }
197    ccount++;
198   }
199   if(strlen(line) == 0){
200    continue;
201   }
202 
203   if(strchr(line,'[') != NULL && strchr(line,']') != NULL){
204    int seclength;
205    seclength = strchr(line,']') - strchr(line,'[') - 1;
206    if(seclength > 0){
207 
208     if(strlen(section) != 0){
209      confcheck(section);
210     }
211 
212     memset(section,0,MAXATTRLEN * sizeof(char));
213     strncpy(section,strchr(line,'[') + 1,seclength);
214     ldiflog(LOG2,"config: processing section   [%s]",section);
215     continue;
216    }
217   }
218 
219   if(ldifconfnormalize(line,var,val) == -1){
220    ldiflog(LOG0,"config error: parse error in line %d: [%s]",clines,line);
221    exit(EXITLDERROR);
222   }
223 
224   if(strlen(section) != 0 && strlen(var) != 0 && strlen(val) != 0){
225    count = 0;
226    found = 0;
227    while(asdefconf[count].varid != CONFNONE){
228     if(strcmp(asdefconf[count].var,var) == 0){
229      struct s_conf *psconf;
230 
231      psconf = LDALLOC(1,sizeof(struct s_conf));
232      psconf->section     = LDDUP(section);
233      psconf->sectiontype = asdefconf[count].sectiontype;
234      psconf->varid       = asdefconf[count].varid;
235      psconf->var         = LDDUP(var);
236      psconf->val         = LDDUP(val);
237      asconf[confcount]   = psconf;
238      ldiflog(LOG2,"config: processing parameter [%s] %s: %s",section,var,val);
239      confcount++;
240      found = 1;
241     }
242     count++;
243    }
244    if(found == 0){
245     ldiflog(LOG0,"config error: unknown parameter [%s] %s: %s",section,var,val);
246     exit(EXITLDERROR);
247    }
248   }
249  }
250  /* the last section should be checked, too */
251  if(strlen(section) != 0){
252   confcheck(section);
253  }
254 
255  fclose(f);
256 }
257