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