]>
Commit | Line | Data |
---|---|---|
7f9875bb | 1 | /* ============================================================ |
63a07100 | 2 | * Copyright (c) 2003-2006, Ondrej Sury, Piotr Wadas |
7f9875bb | 3 | * All rights reserved. |
7f9875bb OS |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7f9875bb | 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
7f9875bb OS |
8 | * Unless required by applicable law or agreed to in writing, software |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
866f0833 PW |
13 | * NOTE: only static members must be "used" to build, |
14 | * so for time-to-time used routines we don't declare static | |
7f9875bb | 15 | * mod_vhost_ldap.c --- read virtual host config from LDAP directory |
63a07100 | 16 | * version 2.0 - included ldap-based basic auth & authz |
866f0833 PW |
17 | * remember to add "-lcrypt" in Makefile if there's a need to generate new password |
18 | * for now not needed (validation only), this below is almost copy-paste from apache source, htpasswd.c | |
7f9875bb | 19 | */ |
866f0833 PW |
20 | |
21 | #include "mod_vhost_ldap.h" | |
7f9875bb | 22 | |
866f0833 PW |
23 | module AP_MODULE_DECLARE_DATA vhost_ldap_module; |
24 | /******************************************************************/ | |
25 | char *pw_encrypt (const char *clear, const char *salt) | |
63a07100 | 26 | { |
866f0833 PW |
27 | //this function encrypts password in unix crypt md5 way |
28 | extern char *crypt (__const char *__key, __const char *__salt); | |
29 | static char cipher[128]; | |
30 | char *cp = crypt (clear, salt); | |
31 | strcpy (cipher, cp); | |
32 | return cipher; | |
63a07100 | 33 | } |
866f0833 | 34 | /******************************************************************/ |
63a07100 PW |
35 | static int strschrcount(apr_pool_t * p, const char *src, const char *delim) |
36 | { | |
37 | int i = 1; | |
38 | int x = 0; | |
39 | while(*src++) { | |
40 | if(strcasecmp(apr_pstrndup(p, src, i), (char *) delim) == 0) { | |
41 | x++; | |
42 | } | |
43 | } | |
44 | return x; | |
45 | } | |
866f0833 PW |
46 | /******************************************************************/ |
47 | static void *mvhl_dump_config_request ( mvhl_config *currentconf, request_rec *r) { | |
48 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "BaseDn: %s", currentconf->basedn); | |
49 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "BindDn: %s", currentconf->binddn); | |
50 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "BindPw: %s", currentconf->bindpw); | |
51 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Deref: %d", currentconf->deref); | |
52 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Enabled: %d", currentconf->enabled); | |
53 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "UserFilter: %s", currentconf->filter); | |
54 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "HaveLdapUrl: %d", currentconf->have_ldap_url); | |
55 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "HaveDeref: %d", currentconf->have_deref); | |
56 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Url: %s", currentconf->url); | |
57 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Port: %d", currentconf->port); | |
58 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Scope: %d", currentconf->scope); | |
59 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Fallback: %s", currentconf->fallback); | |
60 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "WucBaseDn: %s", currentconf->wucbasedn); | |
61 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "WlcBaseDn: %s", currentconf->wlcbasedn); | |
62 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "AliasesBaseDn: %s", currentconf->aliasesbasedn); | |
63 | return NULL; | |
64 | } | |
65 | /******************************************************************/ | |
63a07100 PW |
66 | void log_dump_apr_array(request_rec * r, apr_array_header_t * arr, const char *prefix) |
67 | { | |
68 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering log_dump_apr_array"); | |
69 | int x = 0; | |
70 | char **aliases = (char **) arr->elts; | |
71 | for (x = 0; x < arr->nelts; x++) { | |
72 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " log_dump_apr_array val %d %s %s", x, prefix, aliases[x]); | |
73 | } | |
74 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving log_dump_apr_array"); | |
75 | } | |
866f0833 PW |
76 | /******************************************************************/ |
77 | static apr_array_header_t *get_parsed_string_atrr_arr(request_rec * r, const char *server_alias_attrvar_line, const char *delim) | |
63a07100 | 78 | { |
866f0833 PW |
79 | /* |
80 | * This little piece of code creates apr_array from the string seperated by delim. | |
81 | * It's primary usage is to get array of ldap one attribute values, which is | |
82 | * retrieved (when multi-value) as ";" separated string. | |
83 | */ | |
63a07100 PW |
84 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering get_parsed_string_atrr_arr |%s|", server_alias_attrvar_line); |
85 | if(server_alias_attrvar_line) { | |
7f9875bb | 86 | |
63a07100 PW |
87 | apr_collapse_spaces((char *) server_alias_attrvar_line, server_alias_attrvar_line); |
88 | int ccount = strschrcount(r->pool, server_alias_attrvar_line, delim) + 1; | |
7f9875bb | 89 | |
63a07100 PW |
90 | apr_array_header_t *aliases_arr = apr_array_make(r->pool, ccount, sizeof(char *)); |
91 | char **curralias; | |
92 | curralias = (char **) apr_array_push(aliases_arr); | |
7f9875bb | 93 | |
63a07100 PW |
94 | char *curr_server_alias = ap_getword(r->pool, &server_alias_attrvar_line, ';'); |
95 | char *tmp = apr_pstrdup(r->pool, (char *) curr_server_alias);; | |
96 | *curralias = tmp; | |
7f9875bb | 97 | |
6056cddb | 98 | |
63a07100 PW |
99 | while(server_alias_attrvar_line[0]) { |
100 | curr_server_alias = ap_getword(r->pool, &server_alias_attrvar_line, ';'); | |
101 | curralias = (char **) apr_array_push(aliases_arr); | |
102 | tmp = apr_pstrdup(r->pool, (char *) curr_server_alias); | |
103 | *curralias = tmp; | |
104 | } | |
105 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving get_parsed_string_atrr_arr OK"); | |
106 | return aliases_arr; | |
107 | } | |
108 | else | |
109 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving get_parsed_string_atrr_arr NULL"); | |
110 | return NULL; | |
111 | } | |
866f0833 PW |
112 | /******************************************************************/ |
113 | static apr_array_header_t *get_ap_reqs(apr_pool_t * p, mvhl_extconfig_object * extreqc, char *mainservername, char *userlist) | |
63a07100 | 114 | { |
6056cddb | 115 | |
63a07100 | 116 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL," get_ap_reqs Entering"); |
7f9875bb | 117 | |
63a07100 | 118 | apr_array_header_t *res = apr_array_make(p, 2, sizeof(require_line)); |
7f9875bb | 119 | |
63a07100 PW |
120 | require_line *rline; |
121 | apr_int64_t limited = -1; | |
7f9875bb | 122 | |
63a07100 | 123 | rline = (require_line *) apr_array_push(res); |
7f9875bb | 124 | |
63a07100 PW |
125 | //currently we don't support playing with request types |
126 | rline->method_mask = limited; | |
7f9875bb | 127 | |
63a07100 PW |
128 | if(extreqc->extconftype == 1) { |
129 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, " get_ap_reqs require valid-user = TRUE server %s",mainservername); | |
130 | rline->requirement = apr_pstrdup(p, (char *) "valid-user"); | |
131 | } | |
132 | else { | |
133 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, " get_ap_reqs require valid-user = FALSE server %s",mainservername); | |
134 | ||
135 | rline->requirement = apr_pstrdup(p, userlist); | |
136 | } | |
137 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL," Leaving get_ap_reqs, returning require line |require %s|", rline->requirement); | |
138 | return res; | |
139 | } | |
866f0833 PW |
140 | /******************************************************************/ |
141 | static void mvhl_dovhostconfig(request_rec * r, char *attributes[], const char **vals, mvhl_request * reqc) | |
63a07100 | 142 | { |
866f0833 PW |
143 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering vhost configuration"); |
144 | /* | |
145 | * we got 10 attributes to search for, counting from 0 to 9 | |
146 | */ | |
147 | int i; | |
148 | for ( i = 0; i <= 9; i++ ) { | |
149 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " VhostConfig Iteration %d :: will get %s", i, attributes[i]); | |
150 | switch (i) { | |
151 | /* 0 apacheServerName */ | |
152 | case 0: reqc->name = apr_pstrdup(r->pool, vals[i]); break; | |
153 | /* 1 apacheServerAlias - may be null */ | |
154 | case 1: reqc->serveralias = (vals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i],(const char *) ";") : NULL; break; | |
155 | /* 2 apacheDocumentRoot */ | |
156 | case 2: reqc->docroot = apr_pstrdup(r->pool, vals[i]); break; | |
157 | /* 3 apacheSuexecUid */ | |
158 | case 3: reqc->uid = (vals[i]) ? apr_pstrdup(r->pool, vals[i]) : reqc->uid ; break; | |
159 | /* 4 apacheSuexecGid */ | |
160 | case 4: reqc->gid = (vals[i]) ? apr_pstrdup(r->pool, vals[i]): reqc->gid ; break; | |
161 | /* 5 apacheServerAdmin */ | |
162 | case 5: reqc->admin = (vals[i]) ? apr_pstrdup(r->pool, vals[i]) : NULL ; break; | |
163 | /* 6 apacheExtConfigHasRequireLine */ | |
164 | //if there's no HasRequireLine attribute set we assume we don't have reqlines | |
165 | case 6: reqc->has_reqlines = (vals[i] && strcasecmp("TRUE", apr_pstrdup(r->pool, vals[i])) == 0) ? 1 : 0; break; | |
166 | /* 7 apacheLocationOptionsDn */ | |
167 | case 7: reqc->rqlocationlines = (vals[i]) ? reqc->rqlocationlines = (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i], (const char *) ";") : NULL ; break; | |
168 | /* 8 apacheAliasesConfigEnabled */ | |
169 | case 8: reqc->has_aliaslines = ( vals[i] && strcasecmp("TRUE", apr_pstrdup(r->pool, vals[i])) == 0 ) ? 1 : 0; break; | |
170 | /* 9 apacheAliasConfigOptionsDn */ | |
171 | case 9: reqc->aliaseslines = (vals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i], (const char *) ";") : NULL; | |
172 | } | |
63a07100 | 173 | } |
866f0833 PW |
174 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving vhost configuration , exit assignments: "); |
175 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheServerName \'%s\'", reqc->name); | |
176 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheServerAdmin \'%s\'", reqc->admin); | |
177 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheDocumentRoot \'%s\'", reqc->docroot); | |
178 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheSuexecUid \'%s\'", reqc->uid); | |
179 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheSuexecGid \'%s\'", reqc->gid); | |
180 | ||
181 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
182 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
183 | (reqc->has_reqlines && reqc->rqlocationlines ) ? | |
184 | apr_pstrdup(r->pool, "vhost \'%s\' has access control") : | |
185 | apr_pstrdup(r->pool, " vhost \'%s\' doesn't have access control"), | |
186 | reqc->name); | |
187 | ||
188 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
189 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
190 | (reqc->has_aliaslines && reqc->has_aliaslines ) ? | |
191 | apr_pstrdup(r->pool, "vhost \'%s\' has dir aliases") : | |
192 | apr_pstrdup(r->pool, " vhost \'%s\' doesn't have dir aliases"), | |
193 | reqc->name); | |
7f9875bb | 194 | } |
866f0833 PW |
195 | /******************************************************************/ |
196 | static void mvhl_doextconfig(request_rec * r, char *extconfigattributes[], const char **extconfvals, mvhl_extconfig_object * extreqc) | |
63a07100 | 197 | { |
866f0833 PW |
198 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering Access Control config"); |
199 | /* | |
200 | * we got 6 attributes to search for, counting from 0 to 5 | |
201 | */ | |
63a07100 | 202 | int i = 0; |
866f0833 PW |
203 | for ( i = 0; i <= 4; i++ ) { |
204 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Vhost Access Control Iteration %d :: will get %s", i, extconfigattributes[i]); | |
205 | switch (i) { | |
206 | /* 0 apacheExtConfigUri */ | |
207 | case 0: extreqc->exturi = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL ; break; | |
208 | /* 1 apacheExtConfigRequireValidUser | |
209 | * this value determines whether we have "require valid-user" object (TRUE) , | |
210 | * or (FALSE) object "require user johny mary dorothy witch" | |
211 | * here set retrieved value, regardless what it is, to play with it later. | |
212 | */ | |
213 | case 1: extreqc->extconftype = (extconfvals[i] && strcasecmp("TRUE", apr_pstrdup(r->pool, extconfvals[i])) == 0) ? 1 : 0; break; | |
214 | /* 2 apacheExtConfigServerName */ | |
215 | case 2: extreqc->extservername = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL ; break; | |
216 | /* 3 apacheExtConfigObjectName */ | |
217 | case 3: extreqc->extconfname = apr_pstrdup(r->pool, extconfvals[i]); break; | |
218 | /* 4 apacheExtConfigUserDn */ | |
219 | case 4: | |
220 | extreqc->extusers = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL; break; | |
221 | /* 5 apacheExtConfigPath */ | |
222 | case 5: | |
223 | extreqc->extdir = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL ; break; | |
224 | } | |
63a07100 | 225 | } |
866f0833 PW |
226 | |
227 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving Access Control config :: exit assignments"); | |
228 | ||
229 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " This Access Object prompt is \'%s\'", extreqc->extconfname); | |
230 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, | |
231 | (extreqc->exturi ) ? | |
232 | apr_pstrdup(r->pool, " \'%s\' extConfigUri has at least one URI value") : | |
233 | apr_pstrdup(r->pool, " \'%s\' has extConfigUri assigned"), | |
234 | extreqc->extconfname); | |
235 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, | |
236 | (extreqc->extdir ) ? | |
237 | apr_pstrdup(r->pool, " \'%s\' extConfigPath has at least one directory value") : | |
238 | apr_pstrdup(r->pool, " \'%s\' has extConfig assigned"), | |
239 | extreqc->extconfname); | |
240 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
241 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
242 | (extreqc->extconftype) ? | |
243 | apr_pstrdup(r->pool, " \'%s\' requires valid-user") : | |
244 | apr_pstrdup(r->pool, " \'%s\' requires user from userlist"), | |
245 | extreqc->extconfname) ; | |
246 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
247 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
248 | (extreqc->extservername ) ? | |
249 | apr_pstrdup(r->pool, " \'%s\' has at least one serverName assigned") : | |
250 | apr_pstrdup(r->pool, " \'%s\' has no assigned serverNames"), | |
251 | extreqc->extconfname); | |
252 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
253 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
254 | (extreqc->extusers ) ? | |
255 | apr_pstrdup(r->pool, " \'%s\' has at least one webuser object assigned") : | |
256 | apr_pstrdup(r->pool, " \'%s\' has no assigned webusers objects"), | |
257 | extreqc->extconfname ); | |
258 | ||
63a07100 | 259 | } |
866f0833 PW |
260 | /******************************************************************/ |
261 | static void mvhl_doextuserconfig(request_rec * r, char *ldap_webuser_attributes[], const char **extuservals, mvhl_webuser * extuserreqc) | |
7f9875bb | 262 | { |
866f0833 PW |
263 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering extwebuser Config"); |
264 | /* | |
265 | * we got 5 attributes to search for, counting from 0 to 4 | |
266 | */ | |
63a07100 | 267 | int i = 0; |
866f0833 PW |
268 | for ( i = 0; i <= 4; i++ ) { |
269 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Web user Iteration %d :: will get %s", i, ldap_webuser_attributes[i]); | |
270 | switch (i) { | |
271 | /* 0 apacheExtConfigUserName */ | |
272 | case 0: | |
63a07100 | 273 | extuserreqc->webusername = apr_pstrdup(r->pool, extuservals[i]); |
866f0833 PW |
274 | break; |
275 | /* 1 apacheExtConfigUserServerName */ | |
276 | case 1: | |
277 | extuserreqc->webuserserver = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; | |
278 | break; | |
279 | /* 2 userPassword */ | |
280 | case 2: | |
281 | extuserreqc->webuserpassword = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; | |
282 | break; | |
283 | /* 3 apacheExtConfigUserDirectoryName */ | |
284 | case 3: | |
285 | extuserreqc->webuserdirectory = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; | |
286 | break; | |
287 | case 4: | |
288 | /* apacheExtConfigUserLocationUri */ | |
289 | extuserreqc->webuserlocationuri = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; | |
290 | break; | |
291 | ||
63a07100 | 292 | } |
866f0833 PW |
293 | } |
294 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving extwebuser Config :: exit assignments"); | |
295 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " This webuser name is \'%s\'", extuserreqc->webusername); | |
296 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, | |
297 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
298 | ( extuserreqc->webuserserver ) ? | |
299 | apr_pstrdup(r->pool, " \'%s\' has at least one server assigned") : | |
300 | apr_pstrdup(r->pool, " \'%s\' has no serverNames assigned"), | |
301 | extuserreqc->webusername ); | |
302 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
303 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
304 | ( extuserreqc->webuserpassword ) ? | |
305 | apr_pstrdup(r->pool, " \'%s\' has at least one password assigned") : | |
306 | apr_pstrdup(r->pool, " \'%s\' has no passwords assigned"), | |
307 | extuserreqc->webusername ); | |
308 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
309 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
310 | ( extuserreqc->webuserdirectory ) ? | |
311 | apr_pstrdup(r->pool, " \'%s\' has at least one physical directory assigned") : | |
312 | apr_pstrdup(r->pool, " \'%s\' has no physical directories assigned"), | |
313 | extuserreqc->webusername ); | |
314 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, | |
315 | /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ | |
316 | ( extuserreqc->webuserlocationuri ) ? | |
317 | apr_pstrdup(r->pool, " \'%s\' has at least one location assigned") : | |
318 | apr_pstrdup(r->pool, " \'%s\' has no locations assigned"), | |
319 | extuserreqc->webusername ); | |
320 | ||
321 | } | |
322 | /******************************************************************/ | |
323 | static void mvhl_doaliasesconfig(request_rec * r, char *aliases_attributes[], const char **aliasesvals, mvhl_aliasconf_object * aliasreqc){ | |
324 | ||
325 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering aliasObject Config"); | |
326 | /* | |
327 | * we got 4 attributes to search for, counting from 0 to 3 | |
328 | */ | |
329 | int i = 0; | |
330 | ||
331 | for (i = 0; i <= 3; i++ ) { | |
332 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Alias config Iteration %d :: will get %s", i, aliases_attributes[i]); | |
333 | switch (i) { | |
334 | /* 0 apacheAliasConfigSourceUri */ | |
335 | case 0: | |
336 | aliasreqc->aliassourceuri = (apr_array_header_t *) get_parsed_string_atrr_arr(r, aliasesvals[i], (const char *) ";"); | |
337 | //aliasreqc->aliassourceuri = apr_pstrdup(r->pool, aliasesvals[i]); | |
338 | break; | |
339 | /* 1 apacheAliasConfigServerName - MULTI-VALUE */ | |
340 | case 1: | |
341 | aliasreqc->aliasconfservername = (apr_array_header_t *) get_parsed_string_atrr_arr(r, aliasesvals[i], (const char *) ";"); | |
342 | break; | |
343 | /* 2 apacheAliasConfigTargetDir */ | |
344 | case 2: | |
345 | aliasreqc->aliastargetdir = apr_pstrdup(r->pool, aliasesvals[i]); | |
346 | break; | |
347 | /* 3 apacheAliasConfigObjectName */ | |
348 | case 3: | |
349 | aliasreqc->aliasconfname = apr_pstrdup(r->pool, aliasesvals[i]); | |
350 | break; | |
63a07100 | 351 | } |
63a07100 | 352 | } |
866f0833 PW |
353 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving alias Config :: exit assignments"); |
354 | /* defined ldap schema force alias object to have all of these attributes, so there's no way for existing object without any of them*/ | |
355 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " This alias config object name is \'%s\'", aliasreqc->aliasconfname); | |
356 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " \'%s\' has at least one SourceUri assigned", aliasreqc->aliasconfname); | |
357 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " \'%s\' target dir is \'%s\'", aliasreqc->aliasconfname, aliasreqc->aliastargetdir); | |
358 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, apr_pstrdup(r->pool, " \'%s\' has at least one serverName assigned"), aliasreqc->aliasconfname ); | |
8196fae3 | 359 | } |
866f0833 PW |
360 | /******************************************************************/ |
361 | static int mvhl_authenticate_basic_user(request_rec * r) | |
63a07100 | 362 | { |
866f0833 | 363 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering mvhl_authenticate_basic_user"); |
63a07100 | 364 | const char *sent_pw; |
866f0833 PW |
365 | mvhl_webuser *extuserreqc; |
366 | extuserreqc = (mvhl_webuser *) apr_pcalloc(r->pool, sizeof(mvhl_webuser)); | |
63a07100 | 367 | int rc = ap_get_basic_auth_pw(r, &sent_pw); |
866f0833 PW |
368 | if(rc != OK) return rc; |
369 | ||
63a07100 | 370 | if(strtrue(r->user) && strtrue(sent_pw)) { |
866f0833 | 371 | int result = 0; |
63a07100 | 372 | char userfilter[FILTER_LENGTH]; |
63a07100 | 373 | const char *dn = NULL; |
63a07100 | 374 | const char **extuservals = NULL; |
866f0833 PW |
375 | util_ldap_connection_t *ldc = NULL; |
376 | char *ldap_webuser_attributes[] = { "apacheExtConfigUserName", "apacheExtConfigUserServerName", "userPassword", 0 }; | |
377 | mvhl_config *conf = (mvhl_config *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); | |
378 | apr_snprintf(userfilter, FILTER_LENGTH, "(&(apacheExtConfigUserName=%s))", r->user); | |
63a07100 | 379 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " AuthUser search filter: %s", userfilter); |
866f0833 PW |
380 | ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, conf->deref, conf->secure); |
381 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wucbasedn, conf->scope, ldap_webuser_attributes, userfilter, &dn, &extuservals); | |
63a07100 PW |
382 | util_ldap_connection_close(ldc); |
383 | ||
384 | if(extuservals) { | |
385 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " User %s found.", r->user); | |
386 | ||
866f0833 | 387 | mvhl_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); |
63a07100 PW |
388 | |
389 | int x = 0; | |
866f0833 | 390 | //we're checking for each password - if any matches, then we return immediately |
63a07100 | 391 | char **passwords = (char **) extuserreqc->webuserpassword->elts; |
866f0833 | 392 | |
63a07100 | 393 | for (x = 0; x < extuserreqc->webuserpassword->nelts; x++) { |
866f0833 PW |
394 | if ( apr_password_validate(sent_pw, passwords[x]) == OK ) |
395 | { | |
396 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " APR authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); | |
397 | return OK; | |
398 | } | |
399 | ||
400 | char *prefix = "{CRYPT}"; | |
401 | int prefixlen = 7; | |
402 | if ( strcasecmp( apr_pstrndup(r->pool, passwords[x], prefixlen ), prefix ) == 0 ) { | |
403 | char *stripped = passwords[x] + prefixlen; | |
404 | char *userinputhash = pw_encrypt (sent_pw, stripped ); | |
405 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " User entered: \'%s\' ", sent_pw ); | |
406 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Retrieved value: \'%s\'", passwords[x] ); | |
407 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Retrieved value (stripped): \'%s\'", stripped ); | |
408 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " User input hash: \'%s\'", userinputhash ); | |
409 | if ( strcasecmp( userinputhash , stripped ) == 0 ) | |
410 | { | |
411 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Unix authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); | |
412 | return OK; | |
413 | } | |
414 | } | |
415 | ||
416 | if ( strcasecmp(sent_pw,passwords[x]) == 0 ) | |
417 | { | |
418 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Clear text authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); | |
419 | return OK; | |
63a07100 PW |
420 | } |
421 | } | |
63a07100 PW |
422 | } |
423 | else { | |
424 | ap_log_rerror(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, r, " User %s at %s not found", extuserreqc->webusername, r->server->server_hostname); | |
425 | return HTTP_UNAUTHORIZED; | |
426 | } | |
427 | } | |
428 | else { | |
429 | ap_note_basic_auth_failure(r); | |
430 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, | |
431 | ": Both a username and password must be provided : authentication for user %s at %s failed.", | |
432 | extuserreqc->webusername, r->server->server_hostname); | |
433 | return HTTP_UNAUTHORIZED; | |
434 | } | |
435 | ap_note_basic_auth_failure(r); | |
436 | ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, "Authentication for user %s at %s failed.", | |
437 | extuserreqc->webusername, r->server->server_hostname); | |
438 | return HTTP_UNAUTHORIZED; | |
8196fae3 | 439 | |
63a07100 | 440 | } |
866f0833 PW |
441 | /******************************************************************/ |
442 | static int check_mvhl_auth_require(char *user, const char *t, request_rec * r) | |
8196fae3 | 443 | { |
63a07100 PW |
444 | const char *w; |
445 | w = ap_getword(r->pool, &t, ' '); | |
446 | if(!strcmp(w, "valid-user")) { | |
7f9875bb | 447 | |
63a07100 PW |
448 | return OK; |
449 | } | |
8196fae3 | 450 | |
63a07100 PW |
451 | if(!strcmp(w, "user")) { |
452 | while(t[0]) { | |
453 | w = ap_getword_conf(r->pool, &t); | |
454 | if(!strcmp(user, w)) { | |
8196fae3 | 455 | |
63a07100 | 456 | return OK; |
6056cddb | 457 | |
63a07100 PW |
458 | } |
459 | } | |
460 | return HTTP_UNAUTHORIZED; | |
461 | } | |
462 | else { | |
7f9875bb | 463 | |
63a07100 PW |
464 | return HTTP_INTERNAL_SERVER_ERROR; |
465 | } | |
466 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, | |
866f0833 | 467 | ": %s : Reached end of check_mvhl_auth_require!", r->server->server_hostname); |
63a07100 PW |
468 | return HTTP_INTERNAL_SERVER_ERROR; |
469 | } | |
866f0833 PW |
470 | /******************************************************************/ |
471 | static int mvhl_check_auth(request_rec * r) | |
7f9875bb | 472 | { |
63a07100 | 473 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, |
866f0833 | 474 | ": mvhl_check_auth, parsing existing ap_requires for %s at %s ", r->user, r->server->server_hostname); |
63a07100 PW |
475 | char *user = r->user; |
476 | int rv; | |
477 | register int x; | |
478 | const char *t; | |
479 | const apr_array_header_t *reqs_arr = ap_requires(r); | |
480 | ||
481 | require_line *reqs; | |
482 | reqs = (require_line *) reqs_arr->elts; | |
483 | ||
484 | for (x = 0; x < reqs_arr->nelts; x++) { | |
485 | t = reqs[x].requirement; | |
866f0833 | 486 | if((rv = check_mvhl_auth_require(user, t, r)) != HTTP_UNAUTHORIZED) { |
63a07100 PW |
487 | return rv; |
488 | } | |
489 | } | |
7f9875bb | 490 | |
7f9875bb | 491 | |
63a07100 PW |
492 | ap_note_basic_auth_failure(r); |
493 | return HTTP_UNAUTHORIZED; | |
7f9875bb | 494 | } |
866f0833 PW |
495 | /******************************************************************/ |
496 | static void *mvhl_create_sconfig(apr_pool_t * p, server_rec * s) | |
63a07100 | 497 | { |
866f0833 PW |
498 | //ldap://host[:port]/basedn[?attrib[?scope[?filter]]] |
499 | mvhl_config *conf = (mvhl_config *) apr_pcalloc(p, sizeof(mvhl_config)); | |
500 | conf->enabled = 0; | |
63a07100 | 501 | conf->have_ldap_url = 0; |
866f0833 PW |
502 | conf->have_deref = 0; |
503 | conf->scope = LDAP_SCOPE_SUBTREE; | |
504 | conf->deref = never; | |
505 | conf->host = NULL; | |
506 | conf->port = 389; | |
507 | conf->url = NULL; | |
508 | conf->filter = NULL; | |
509 | conf->binddn = NULL; | |
510 | conf->bindpw = NULL; | |
511 | conf->basedn = NULL; | |
512 | conf->wlcbasedn = NULL; | |
513 | conf->wucbasedn = NULL; | |
514 | conf->aliasesbasedn = NULL; | |
515 | conf->fallback = NULL; | |
516 | conf->secure = 0; | |
517 | conf->alias_enabled = 0; | |
518 | conf->loc_auth_enabled = 0; | |
519 | conf->dir_auth_enabled = 0; | |
63a07100 PW |
520 | return conf; |
521 | } | |
866f0833 PW |
522 | /******************************************************************/ |
523 | static void *mvhl_merge_sconfig(apr_pool_t * p, void *parentv, void *childv) | |
7f9875bb | 524 | { |
866f0833 PW |
525 | mvhl_config *parent = (mvhl_config *) parentv; |
526 | mvhl_config *child = (mvhl_config *) childv; | |
527 | mvhl_config *conf = (mvhl_config *) apr_pcalloc(p, sizeof(mvhl_config)); | |
528 | ||
529 | conf->enabled = (child->enabled ? child->enabled : parent->enabled); | |
530 | conf->binddn = (child->binddn ? child->binddn : parent->binddn); | |
531 | conf->bindpw = (child->bindpw ? child->bindpw : parent->bindpw); | |
532 | conf->fallback = (child->fallback ? child->fallback : parent->fallback); | |
533 | conf->alias_enabled = (child->alias_enabled ? child->alias_enabled : parent->alias_enabled); | |
534 | conf->loc_auth_enabled = (child->loc_auth_enabled ? child->loc_auth_enabled : parent->loc_auth_enabled); | |
535 | conf->dir_auth_enabled = (child->dir_auth_enabled ? child->dir_auth_enabled : parent->dir_auth_enabled); | |
63a07100 PW |
536 | |
537 | if(child->have_ldap_url) { | |
538 | conf->have_ldap_url = child->have_ldap_url; | |
539 | conf->url = child->url; | |
540 | conf->host = child->host; | |
541 | conf->port = child->port; | |
542 | conf->basedn = child->basedn; | |
543 | conf->scope = child->scope; | |
544 | conf->filter = child->filter; | |
545 | conf->secure = child->secure; | |
546 | conf->wlcbasedn = child->wlcbasedn; | |
547 | conf->wucbasedn = child->wucbasedn; | |
866f0833 | 548 | conf->aliasesbasedn = child->aliasesbasedn; |
63a07100 | 549 | } |
866f0833 PW |
550 | else |
551 | { | |
63a07100 PW |
552 | conf->have_ldap_url = parent->have_ldap_url; |
553 | conf->url = parent->url; | |
554 | conf->host = parent->host; | |
555 | conf->port = parent->port; | |
556 | conf->basedn = parent->basedn; | |
557 | conf->scope = parent->scope; | |
558 | conf->filter = parent->filter; | |
559 | conf->secure = parent->secure; | |
560 | conf->wlcbasedn = parent->wlcbasedn; | |
561 | conf->wucbasedn = parent->wucbasedn; | |
866f0833 | 562 | conf->aliasesbasedn = parent->aliasesbasedn; |
63a07100 PW |
563 | } |
564 | if(child->have_deref) { | |
565 | conf->have_deref = child->have_deref; | |
566 | conf->deref = child->deref; | |
567 | } | |
866f0833 PW |
568 | else |
569 | { | |
63a07100 PW |
570 | conf->have_deref = parent->have_deref; |
571 | conf->deref = parent->deref; | |
572 | } | |
63a07100 | 573 | return conf; |
7f9875bb | 574 | } |
866f0833 PW |
575 | /******************************************************************/ |
576 | static const char *conf_mvhl_url(cmd_parms * cmd, void *dummy, const char *url) | |
7f9875bb | 577 | { |
63a07100 PW |
578 | int result; |
579 | apr_ldap_url_desc_t *urld; | |
580 | ||
866f0833 | 581 | mvhl_config *conf = (mvhl_config *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); |
63a07100 | 582 | result = apr_ldap_url_parse(url, &(urld)); |
866f0833 | 583 | |
63a07100 PW |
584 | if(result != LDAP_SUCCESS) { |
585 | switch (result) { | |
866f0833 PW |
586 | case LDAP_URL_ERR_MEM: return "0x01 can't allocate memory space"; |
587 | case LDAP_URL_ERR_PARAM: return "0x02 parameter is bad"; | |
588 | case LDAP_URL_ERR_BADSCHEME: return "0x03 URL doesn't begin with ldap[si]://"; | |
589 | case LDAP_URL_ERR_BADENCLOSURE: return "0x04 URL is missing trailing >"; | |
590 | case LDAP_URL_ERR_BADURL: return "0x05 URL is bad"; | |
591 | case LDAP_URL_ERR_BADHOST: return "0x06 host port is bad"; | |
592 | case LDAP_URL_ERR_BADATTRS: return "0x07 bad (or missing) attributes"; | |
593 | case LDAP_URL_ERR_BADSCOPE: return "0x08 scope string is invalid (or missing)"; | |
594 | case LDAP_URL_ERR_BADFILTER: return "0x09 bad or missing filter"; | |
595 | case LDAP_URL_ERR_BADEXTS: return "0x0a bad or missing extensions"; | |
596 | default: return "Could not parse LDAP URL"; | |
63a07100 PW |
597 | } |
598 | } | |
599 | conf->url = apr_pstrdup(cmd->pool, url); | |
600 | ||
601 | /* Set all the values, or at least some sane defaults */ | |
602 | if(conf->host) { | |
603 | char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2); | |
604 | strcpy(p, urld->lud_host); | |
605 | strcat(p, " "); | |
606 | strcat(p, conf->host); | |
607 | conf->host = p; | |
608 | } | |
609 | else { | |
610 | conf->host = urld->lud_host ? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost"; | |
611 | } | |
866f0833 | 612 | |
63a07100 PW |
613 | conf->basedn = urld->lud_dn ? apr_pstrdup(cmd->pool, urld->lud_dn) : ""; |
614 | ||
615 | conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ? LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE; | |
616 | ||
617 | if(urld->lud_filter) { | |
618 | if(urld->lud_filter[0] == '(') { | |
619 | /* | |
866f0833 PW |
620 | * Get rid of the surrounding parentheses; |
621 | * later on when generating the | |
63a07100 PW |
622 | * filter, they'll be put back. |
623 | */ | |
624 | conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter + 1); | |
625 | conf->filter[strlen(conf->filter) - 1] = '\0'; | |
626 | } | |
627 | else { | |
628 | conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter); | |
629 | } | |
630 | } | |
866f0833 | 631 | /*else { |
63a07100 | 632 | conf->filter = "objectClass=apacheConfig"; |
866f0833 | 633 | }*/ |
7f9875bb | 634 | |
63a07100 PW |
635 | /* "ldaps" indicates secure ldap connections desired |
636 | */ | |
637 | if(strncasecmp(url, "ldaps", 5) == 0) { | |
638 | conf->secure = 1; | |
639 | conf->port = urld->lud_port ? urld->lud_port : LDAPS_PORT; | |
7f9875bb | 640 | |
63a07100 PW |
641 | } |
642 | else { | |
643 | conf->secure = 0; | |
644 | conf->port = urld->lud_port ? urld->lud_port : LDAP_PORT; | |
645 | } | |
7f9875bb | 646 | |
63a07100 PW |
647 | conf->have_ldap_url = 1; |
648 | apr_ldap_free_urldesc(urld); | |
649 | return NULL; | |
7f9875bb | 650 | } |
866f0833 PW |
651 | /******************************************************************/ |
652 | static const char *conf_mvhl(cmd_parms *cmd, void *dummy, const char *confval) { | |
653 | ||
654 | if ( strlen(confval) == 0 ) { return NULL; } | |
655 | ||
656 | { | |
657 | //we're getting currently set (or default from mvhl_create_config if not set already) | |
658 | mvhl_config *conf = (mvhl_config *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); | |
659 | int *cmdtype = (int *) cmd->info; | |
660 | char *currval = apr_pstrdup(cmd->pool, confval); | |
661 | switch (*cmdtype) { | |
662 | case 1: | |
663 | conf->enabled = ( strcmp(currval,"On") == 0 )? 1 : 0; | |
664 | break; | |
665 | case 2: | |
666 | conf->binddn = currval; | |
667 | break; | |
668 | case 3: | |
669 | conf->bindpw = currval; | |
670 | break; | |
671 | case 4: | |
672 | //const values: never = 0, searching = 1, finding = 2, always = 3 | |
673 | if ( strcmp(currval,"never") == 0 ) { conf->deref = never; conf->have_deref = 1;} | |
674 | if ( strcmp(currval,"searching")== 0 ) { conf->deref = searching; conf->have_deref = 1;} | |
675 | if ( strcmp(currval,"finding") == 0 ) { conf->deref = finding; conf->have_deref = 1;} | |
676 | if ( strcmp(currval,"always") == 0 ) { conf->deref = always; conf->have_deref = 1;} | |
677 | break; | |
678 | case 5: | |
679 | conf->wlcbasedn = currval; | |
680 | break; | |
681 | case 6: | |
682 | conf->wucbasedn = currval; | |
683 | break; | |
684 | case 7: | |
685 | conf->fallback = currval; | |
686 | break; | |
687 | case 8: | |
688 | conf->aliasesbasedn = currval; | |
689 | break; | |
690 | case 9: | |
691 | conf->alias_enabled = ( strcmp(currval,"On") == 0 )? 1 : 0 ; | |
692 | break; | |
693 | case 10: | |
694 | conf->loc_auth_enabled = ( strcmp(currval,"On") == 0 )? 1 : 0; | |
695 | break; | |
696 | case 11: | |
697 | conf->dir_auth_enabled = ( strcmp(currval,"On") == 0 )? 1 : 0; | |
698 | break; | |
63a07100 | 699 | } |
866f0833 | 700 | return NULL; |
63a07100 | 701 | } |
866f0833 | 702 | |
6056cddb | 703 | } |
866f0833 PW |
704 | /******************************************************************/ |
705 | static int apply_vhost(mvhl_config *conf, const char *hostname, request_rec * r, util_ldap_connection_t *ldc, const char *dn, mvhl_request *reqc ) { | |
6056cddb | 706 | |
63a07100 | 707 | char filtbuf[FILTER_LENGTH]; |
866f0833 PW |
708 | apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname); |
709 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Server search filter: %s", filtbuf); | |
710 | const char **vals = NULL; | |
711 | char *attributes[] = { "apacheServerName", "apacheServerAlias", "apacheDocumentRoot", "apacheSuexecUid","apacheSuexecGid","apacheServerAdmin","apacheExtConfigHasRequireLine","apacheLocationOptionsDn","apacheAliasesConfigEnabled","apacheAliasConfigOptionsDn",0 }; | |
712 | int failures = 0; | |
713 | int result = LDAP_SERVER_DOWN; | |
714 | while(failures++ <= 5 && result == LDAP_SERVER_DOWN) { | |
715 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope, attributes, filtbuf, &dn, &vals); | |
63a07100 | 716 | } |
7f9875bb | 717 | |
866f0833 PW |
718 | /* |
719 | * we don't test conf->host nor connection, because if these failed, declined was already returned | |
720 | * instead, we do a search for specified fallback vhost | |
721 | */ | |
722 | if ( result == LDAP_NO_SUCH_OBJECT ) | |
723 | { | |
724 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Vhost %s not found, will try to fall-back to defined vhost: %s", hostname, conf->fallback); | |
725 | hostname = conf->fallback; | |
726 | apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname); | |
727 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Server search filter: %s", filtbuf); | |
728 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope, attributes, filtbuf, &dn, &vals); | |
729 | } | |
730 | ||
63a07100 | 731 | if(result != LDAP_SUCCESS) { |
866f0833 PW |
732 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Vhost %s defined as fallback not found, err %s", hostname, ldap_err2string(result)); |
733 | return 0; | |
63a07100 | 734 | } |
7f9875bb | 735 | |
63a07100 | 736 | reqc->dn = apr_pstrdup(r->pool, dn); |
866f0833 | 737 | if (vals) { mvhl_dovhostconfig(r, attributes, vals, reqc); } |
63a07100 | 738 | |
866f0833 PW |
739 | if( (reqc->name == NULL) || (reqc->docroot == NULL) || ! (r->uri[0] == '/') ) return 0; |
740 | r->filename = apr_pstrcat(r->pool, reqc->docroot, r->uri, NULL); | |
741 | return 1; | |
742 | ||
743 | } | |
744 | /******************************************************************/ | |
745 | static void apply_aliasing(mvhl_request *reqc, request_rec * r, mvhl_config *conf, util_ldap_connection_t *ldc, const char *dn) { | |
746 | ||
747 | if(reqc->has_aliaslines == 1 && reqc->aliaseslines ) { | |
748 | const char **aliasesconfvals = NULL; | |
749 | char aliasesfilter[FILTER_LENGTH]; | |
750 | char *aliases_attributes[] = { "apacheAliasConfigSourceUri", "apacheAliasConfigServerName", "apacheAliasConfigTargetDir", "apacheAliasConfigObjectName",0 }; | |
751 | mvhl_aliasconf_object *aliasreqc = (mvhl_aliasconf_object *) apr_pcalloc(r->pool, sizeof(mvhl_aliasconf_object)); | |
752 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has alias configuration, need to check if for current uri"); | |
753 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Original r->filename: %s", r->filename); | |
754 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Original r->uri: %s", r->uri); | |
755 | int i = 0; | |
756 | int result = 0; | |
7f9875bb | 757 | |
866f0833 PW |
758 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering Alias Objects search"); |
759 | while(i <= strlen(apr_pstrdup(r->pool, r->uri)) && !aliasesconfvals ) { | |
760 | i++; | |
761 | char *aliasbuff = apr_pstrndup(r->pool, r->uri, i); | |
762 | apr_snprintf(aliasesfilter, FILTER_LENGTH,"(&(%s)(apacheAliasConfigServerName=%s)(apacheAliasConfigSourceUri=%s))", conf->filter, reqc->name, aliasbuff); | |
763 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Alias Object search filter: %s", aliasesfilter); | |
764 | /* we reuse ldap connection opened previously with alias entries, | |
765 | * access control entries and webusers entries searches changing used filter as needed (!!) */ | |
766 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->aliasesbasedn, conf->scope, aliases_attributes, aliasesfilter, &dn, &aliasesconfvals); | |
767 | } | |
768 | ||
769 | if(result != LDAP_SUCCESS) { | |
770 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost aliases config, but probably not for this URI, alias config entry not found"); | |
771 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Tried with ldap search filter: %s", aliasesfilter); | |
772 | } | |
773 | else { | |
774 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This uri has aliases config, configuration object found"); | |
775 | if(aliasesconfvals) { mvhl_doaliasesconfig(r, aliases_attributes, aliasesconfvals, aliasreqc); } | |
776 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Entering alias substitution"); | |
777 | r->filename = apr_pstrcat (r->pool, aliasreqc->aliastargetdir , r->uri + i, NULL); | |
778 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Final filename r->filename: %s", r->filename); | |
779 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Final uri (unchanged) r->uri: %s", r->uri); | |
780 | } | |
781 | ||
63a07100 | 782 | } |
866f0833 PW |
783 | else |
784 | { | |
785 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "This vhost has no aliases, or it is disabled via apacheAliasesConfigEnabled = (FALSE|not set) skipping.."); | |
786 | } | |
787 | } | |
788 | /******************************************************************/ | |
789 | static void apply_location_access_control(mvhl_request *reqc, request_rec * r, mvhl_config *conf, util_ldap_connection_t *ldc, const char *dn) { | |
7f9875bb | 790 | |
63a07100 | 791 | if(reqc->has_reqlines == 1 && reqc->rqlocationlines) { |
866f0833 PW |
792 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has location access control configured, need to check if it's enabled for current uri"); |
793 | int result = 0; | |
794 | int i = 0; | |
795 | char extconffiltbuf[FILTER_LENGTH]; | |
796 | const char **extconfvals = NULL; | |
797 | char *extconfigattributes[] = { "apacheExtConfigUri","apacheExtConfigRequireValidUser","apacheExtConfigServerName","apacheExtConfigObjectName","apacheExtConfigUserDn","apacheExtConfigPath",0}; | |
798 | mvhl_extconfig_object *extreqc = (mvhl_extconfig_object *) apr_pcalloc(r->pool, sizeof(mvhl_extconfig_object)); | |
799 | char *buff = NULL; | |
800 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extConfig Location Objects search"); | |
63a07100 PW |
801 | while(i <= strlen(apr_pstrdup(r->pool, r->uri)) && !extconfvals) { |
802 | i++; | |
866f0833 PW |
803 | buff = apr_pstrndup(r->pool, r->uri, i); |
804 | /* | |
805 | * ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Searching for hostname %s and URI %s, origname is %s", hostname, buff, reqc->name); | |
806 | * uncomment this, if You'd like to see in log how uri gets checked | |
807 | * ap_log_error(APLOG_MARK,APLOG_DEBUG,OK,NULL,"%s", buff); | |
808 | ||
809 | * well, we must had been connecting already, so we don't do more ldap server connection checks, | |
810 | * and we're doing a search with cache_getuser instead of using extConfigObject dn apacheConfig object attribute value(s), | |
811 | * because there's no convenient function in apr api. | |
812 | * vhost location RDN attribute is used actually by some GUI to make things easier | |
813 | * TODO: use some generic ldap functions (?) classic search or implement more ldap routines for apr | |
814 | ||
815 | * so, we do a search below locationDnBase for config object with matches current hostname and uri.. | |
816 | * note, that we took our current uri, and we're searching starting from / adding one by one chararacter | |
817 | * to match config object - access config is always the same as first matching upper url access config. | |
818 | * and more - if someone defined accessobject for /main and /main/subdir, the first one is used. | |
819 | * when upper is deleted - next below is returned, and so far.. | |
820 | * and more - if there are two or more extConfig object for the same combination of server/uri, | |
821 | * then first found is returned and search isn't processed further. | |
822 | ||
823 | * we do a search based on original reqc->name instead of current hostname, to apply rules even if we're accessing | |
824 | * site via ServerAlias name | |
825 | */ | |
826 | apr_snprintf(extconffiltbuf, FILTER_LENGTH,"(&(%s)(apacheExtConfigServerName=%s)(apacheExtConfigUri=%s))", conf->filter, reqc->name, buff); | |
827 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"ExtConfig Location Object search filter: %s", extconffiltbuf); | |
828 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wlcbasedn, conf->scope, extconfigattributes, extconffiltbuf, &dn, &extconfvals); | |
63a07100 PW |
829 | //matched URI, if found, is returned anyway with extconfvals as ldap attribute value. |
830 | } | |
63a07100 PW |
831 | |
832 | if(result != LDAP_SUCCESS) { | |
866f0833 PW |
833 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has access control, but probably not for this URI, access config entry not found"); |
834 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Tried with ldap search filter: %s", extconffiltbuf); | |
63a07100 | 835 | } |
866f0833 PW |
836 | else |
837 | { | |
838 | ||
839 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This uri has access control, configuration object is found"); | |
840 | //we set all into extreqc struct | |
841 | //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extconfig buffer fill"); | |
842 | if(extconfvals) { mvhl_doextconfig(r, extconfigattributes, extconfvals, extreqc); } | |
63a07100 PW |
843 | |
844 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Entering ap_requires generation process"); | |
866f0833 | 845 | core_dir_config *coredirconf = (core_dir_config *) ap_get_module_config(r->per_dir_config, &core_module); |
63a07100 PW |
846 | coredirconf->ap_auth_name = extreqc->extconfname; |
847 | coredirconf->ap_auth_type = (char *) "basic"; | |
848 | char *userlist = "user nobody"; | |
849 | ||
866f0833 PW |
850 | /* |
851 | st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); | |
852 | st->search_cache_ttl = 0; | |
853 | */ | |
854 | char userfilter[FILTER_LENGTH]; | |
855 | /* we'll search for user object with custom filter applied, which has assigned matched location name and which has assigned current servername */ | |
856 | apr_snprintf(userfilter, FILTER_LENGTH, "(&(%s)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserServerName=%s)(apacheExtConfigUserLocationUri=%s))", conf->filter, reqc->name, buff); | |
857 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"User search filter: %s", userfilter); | |
858 | ||
859 | mvhl_webuser *extuserreqc = (mvhl_webuser *) apr_pcalloc(r->pool, sizeof(mvhl_webuser)); | |
860 | int i = 0; | |
63a07100 | 861 | if(extreqc->extusers) { |
866f0833 PW |
862 | log_dump_apr_array(r,extreqc->extusers,"extUser"); |
863 | char **extuserdns = (char **) extreqc->extusers->elts; | |
63a07100 | 864 | for (i = 0; i < extreqc->extusers->nelts; i++) { |
63a07100 PW |
865 | const char **extuservals = NULL; |
866 | int result = 0; | |
866f0833 PW |
867 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "User search basedn: %s", extuserdns[i]); |
868 | //we don't use wucbasedn as we already know what webuser distinguishedname can be | |
869 | char *ldap_webuser_attributes[] = { "apacheExtConfigUserName","apacheExtConfigUserServerName","userPassword", "apacheExtConfigUserDirectoryName", "apacheExtConfigUserLocationUri", 0}; | |
870 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, extuserdns[i], LDAP_SCOPE_BASE, ldap_webuser_attributes, userfilter, &dn, &extuservals); | |
63a07100 | 871 | if(extuservals) { |
866f0833 PW |
872 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 0: %s", extuservals[0]); |
873 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 1: %s", extuservals[1]); | |
874 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 2: %s", extuservals[2]); | |
875 | mvhl_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); | |
876 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current username: %s", extuserreqc->webusername); | |
877 | userlist = apr_pstrcat(r->pool, userlist, " ", extuserreqc->webusername, NULL); | |
878 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current userlist: %s", userlist); | |
63a07100 | 879 | } |
63a07100 | 880 | } |
63a07100 PW |
881 | } |
882 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "final userlist: %s ", userlist); | |
63a07100 PW |
883 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthName set to %s", coredirconf->ap_auth_name); |
884 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthType set to %s", coredirconf->ap_auth_type); | |
885 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Preparing access control line"); | |
866f0833 | 886 | coredirconf->ap_requires = (apr_array_header_t *) get_ap_reqs(r->pool, extreqc, reqc->name, userlist); |
63a07100 PW |
887 | } |
888 | } | |
889 | else { | |
866f0833 | 890 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "This vhost is not configured for access control, or it is disabled via apacheExtConfigHasRequireLine = ( FALSE|not set) skipping.."); |
63a07100 | 891 | } |
866f0833 PW |
892 | } |
893 | /******************************************************************/ | |
894 | static void apply_directory_access_control(mvhl_request *reqc, request_rec * r, mvhl_config *conf, util_ldap_connection_t *ldc, const char *dn) { | |
7f9875bb | 895 | |
866f0833 PW |
896 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has directory access control configured, need to check if it's enabled for current filename"); |
897 | int result = 0; | |
898 | int i = 0; | |
899 | char extconffiltbuf[FILTER_LENGTH]; | |
900 | const char **extconfvals = NULL; | |
901 | char *extconfigattributes[] = { "apacheExtConfigUri","apacheExtConfigRequireValidUser","apacheExtConfigServerName","apacheExtConfigObjectName","apacheExtConfigUserDn","apacheExtConfigPath",0}; | |
902 | mvhl_extconfig_object *extreqc = (mvhl_extconfig_object *) apr_pcalloc(r->pool, sizeof(mvhl_extconfig_object)); | |
903 | char *buff = NULL; | |
904 | ||
905 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extConfig Directory Objects search"); | |
906 | while(i <= strlen(apr_pstrdup(r->pool, r->filename)) && !extconfvals) { | |
907 | i++; | |
908 | buff = apr_pstrndup(r->pool, r->filename, i); | |
909 | /* | |
910 | * ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Searching for hostname %s and URI %s, origname is %s", hostname, buff, reqc->name); | |
911 | * uncomment this, if You'd like to see in log how uri gets checked | |
912 | * ap_log_error(APLOG_MARK,APLOG_DEBUG,OK,NULL,"%s", buff); | |
913 | ||
914 | * well, we must had been connecting already, so we don't do more ldap server connection checks, | |
915 | * and we're doing a search with cache_getuser instead of using extConfigObject dn apacheConfig object attribute value(s), | |
916 | * because there's no convenient function in apr api. | |
917 | * vhost location RDN attribute is used actually by some GUI to make things easier | |
918 | * TODO: use some generic ldap functions (?) classic search or implement more ldap routines for apr | |
919 | ||
920 | * so, we do a search below locationDnBase for config object with matches current hostname and uri.. | |
921 | * note, that we took our current uri, and we're searching starting from / adding one by one chararacter | |
922 | * to match config object - access config is always the same as first matching upper url access config. | |
923 | * and more - if someone defined accessobject for /main and /main/subdir, the first one is used. | |
924 | * when upper is deleted - next below is returned, and so far.. | |
925 | * and more - if there are two or more extConfig object for the same combination of server/uri, | |
926 | * then first found is returned and search isn't processed further. | |
927 | ||
928 | * we do a search based on original reqc->name instead of current hostname, to apply rules even if we're accessing | |
929 | * site via ServerAlias name | |
930 | */ | |
931 | apr_snprintf(extconffiltbuf, FILTER_LENGTH,"(&(%s)(apacheExtConfigPath=%s))", conf->filter, buff); | |
932 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"ExtConfig Directory Object search filter: %s", extconffiltbuf); | |
933 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wlcbasedn, conf->scope, extconfigattributes, extconffiltbuf, &dn, &extconfvals); | |
934 | //matched dir, if found, is returned anyway with extconfvals as ldap attribute value. | |
935 | } | |
9ee2dda1 | 936 | |
866f0833 PW |
937 | if(result != LDAP_SUCCESS) { |
938 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has access control, but probably not for this directory, access config entry not found"); | |
939 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Tried with ldap search filter: %s", extconffiltbuf); | |
940 | } | |
941 | else | |
942 | { | |
943 | ||
944 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This directory has access control, configuration object is found"); | |
945 | //we set all into extreqc struct | |
946 | //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extconfig buffer fill"); | |
947 | if(extconfvals) { mvhl_doextconfig(r, extconfigattributes, extconfvals, extreqc); } | |
948 | ||
949 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Entering ap_requires generation process"); | |
950 | core_dir_config *coredirconf = (core_dir_config *) ap_get_module_config(r->per_dir_config, &core_module); | |
951 | coredirconf->ap_auth_name = extreqc->extconfname; | |
952 | coredirconf->ap_auth_type = (char *) "basic"; | |
953 | char *userlist = "user nobody"; | |
954 | ||
955 | /* | |
956 | st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); | |
957 | st->search_cache_ttl = 0; | |
958 | */ | |
959 | char userfilter[FILTER_LENGTH]; | |
960 | /* we'll search for user object with custom filter applied, which has assigned matched directory name */ | |
961 | apr_snprintf(userfilter, FILTER_LENGTH, "(&(%s)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserDirectoryName=%s))", conf->filter, buff); | |
962 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"User search filter: %s", userfilter); | |
963 | ||
964 | mvhl_webuser *extuserreqc = (mvhl_webuser *) apr_pcalloc(r->pool, sizeof(mvhl_webuser)); | |
965 | int i = 0; | |
966 | if(extreqc->extusers) { | |
967 | log_dump_apr_array(r,extreqc->extusers,"extUser"); | |
968 | char **extuserdns = (char **) extreqc->extusers->elts; | |
969 | for (i = 0; i < extreqc->extusers->nelts; i++) { | |
970 | const char **extuservals = NULL; | |
971 | int result = 0; | |
972 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "User search basedn: %s", extuserdns[i]); | |
973 | //we don't use wucbasedn as we already know what webuser distinguishedname can be | |
974 | char *ldap_webuser_attributes[] = { "apacheExtConfigUserName","apacheExtConfigUserServerName","userPassword", "apacheExtConfigUserDirectoryName", "apacheExtConfigUserLocationUri", 0}; | |
975 | result = util_ldap_cache_getuserdn(r, ldc, conf->url, extuserdns[i], LDAP_SCOPE_BASE, ldap_webuser_attributes, userfilter, &dn, &extuservals); | |
976 | if(extuservals) { | |
977 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 0: %s", extuservals[0]); | |
978 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 1: %s", extuservals[1]); | |
979 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 2: %s", extuservals[2]); | |
980 | mvhl_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); | |
981 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current username: %s", extuserreqc->webusername); | |
982 | userlist = apr_pstrcat(r->pool, userlist, " ", extuserreqc->webusername, NULL); | |
983 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current userlist: %s", userlist); | |
984 | } | |
985 | } | |
986 | } | |
987 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "final userlist: %s ", userlist); | |
988 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthName set to %s", coredirconf->ap_auth_name); | |
989 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthType set to %s", coredirconf->ap_auth_type); | |
990 | ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Preparing access control line"); | |
991 | coredirconf->ap_requires = (apr_array_header_t *) get_ap_reqs(r->pool, extreqc, reqc->name, userlist); | |
63a07100 | 992 | } |
866f0833 PW |
993 | |
994 | } | |
995 | /******************************************************************/ | |
996 | static int mvhl_translate_name(request_rec * r) | |
997 | { | |
998 | request_rec *top = r->main ? r->main : r; | |
999 | apr_table_t *e = top->subprocess_env; | |
1000 | ||
1001 | //module config and current request config objects | |
1002 | mvhl_config *conf = (mvhl_config *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); | |
1003 | mvhl_dump_config_request(conf, r); //debug | |
1004 | // mod_vhost_ldap is disabled or we don't have LDAP Url, we check these as soon as we can (after debugging dump) | |
1005 | if(( conf->enabled == 0) || (! conf->have_ldap_url) || ( ! conf->host ) ) return DECLINED; | |
1006 | ||
1007 | //get core config and current request config, then set current request config | |
1008 | core_server_config *core = (core_server_config *) ap_get_module_config(r->server->module_config, &core_module); | |
1009 | mvhl_request *reqc = (mvhl_request *) apr_pcalloc(r->pool, sizeof(mvhl_request)); | |
1010 | ap_set_module_config(r->request_config, &vhost_ldap_module, reqc); | |
1011 | ||
1012 | const char *hostname = r->hostname; | |
1013 | const char *dn = NULL; | |
1014 | ||
1015 | //we'll reuse ldap connection opened here | |
1016 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Opening LDAP Connection"); | |
1017 | util_ldap_connection_t *ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw,conf->deref, conf->secure); | |
1018 | ||
1019 | //heart of the system :) | |
1020 | if ( conf->enabled == 0 || ! apply_vhost(conf, hostname, r, ldc, dn, reqc ) ) return DECLINED; | |
1021 | if (conf->alias_enabled > 0 ) apply_aliasing(reqc, r, conf, ldc, dn); | |
1022 | if (conf->loc_auth_enabled > 0 ) apply_location_access_control(reqc, r, conf, ldc, dn); | |
1023 | if (conf->dir_auth_enabled > 0 ) apply_directory_access_control(reqc, r, conf, ldc, dn); | |
1024 | ||
1025 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Closing LDAP Connection"); | |
1026 | util_ldap_connection_close(ldc); | |
1027 | ||
1028 | /* finished with Access control for location **********************************/ | |
1029 | top->server->server_hostname = apr_pstrdup(top->pool, reqc->name); | |
1030 | if(reqc->admin) {top->server->server_admin = apr_pstrdup(top->pool, reqc->admin); } | |
7f9875bb | 1031 | |
63a07100 | 1032 | // set environment variables |
63a07100 PW |
1033 | apr_table_addn(e, "SERVER_ROOT", reqc->docroot); |
1034 | core->ap_document_root = apr_pstrdup(top->pool, reqc->docroot); | |
1035 | return OK; | |
7f9875bb | 1036 | } |
866f0833 PW |
1037 | /******************************************************************/ |
1038 | static ap_unix_identity_t *mvhl_suexec_doer(const request_rec * r) | |
7f9875bb | 1039 | { |
63a07100 | 1040 | ap_unix_identity_t *ugid = NULL; |
866f0833 PW |
1041 | mvhl_config *conf = (mvhl_config *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); |
1042 | mvhl_request *req = (mvhl_request *) ap_get_module_config(r->request_config, &vhost_ldap_module); | |
63a07100 PW |
1043 | |
1044 | uid_t uid = -1; | |
1045 | gid_t gid = -1; | |
1046 | ||
63a07100 PW |
1047 | uid = (uid_t) atoll(req->uid); |
1048 | gid = (gid_t) atoll(req->gid); | |
1049 | ||
866f0833 PW |
1050 | // mod_vhost_ldap is disabled or we don't have LDAP Url |
1051 | if( | |
1052 | (uid < MIN_UID) || | |
1053 | (gid < MIN_GID) || | |
1054 | ( conf->enabled == 0 ) || | |
1055 | (!conf->have_ldap_url) || | |
1056 | (req == NULL) || | |
1057 | (req->uid == NULL) || | |
1058 | (req->gid == NULL) || | |
1059 | (ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL | |
1060 | ) { return NULL; } | |
63a07100 PW |
1061 | |
1062 | ugid->uid = uid; | |
1063 | ugid->gid = gid; | |
1064 | ugid->userdir = 0; | |
63a07100 | 1065 | return ugid; |
7f9875bb | 1066 | } |
866f0833 PW |
1067 | /******************************************************************/ |
1068 | static int mvhl_post_config(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) | |
7f9875bb | 1069 | { |
63a07100 | 1070 | /* make sure that mod_ldap (util_ldap) is loaded */ |
866f0833 | 1071 | if(ap_find_linked_module("util_ldap.c") == NULL) {return HTTP_INTERNAL_SERVER_ERROR;} |
63a07100 PW |
1072 | ap_add_version_component(p, MOD_VHOST_LDAP_VERSION); |
1073 | return OK; | |
1074 | } | |
866f0833 PW |
1075 | /******************************************************************/ |
1076 | static const command_rec mvhl_cmds[] = { | |
1077 | AP_INIT_TAKE1("VhostLdapUrl", conf_mvhl_url, NULL, RSRC_CONF,"RFC 2255 URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]]."), | |
1078 | AP_INIT_TAKE1("VhostLdapEnabled", conf_mvhl, MVHL_ENABLED, RSRC_CONF,"Set to off or unset to disable vhost_ldap module completely"), | |
1079 | AP_INIT_TAKE1("VhostAliasesEnabled", conf_mvhl, MVHL_ALIASENABLED, RSRC_CONF,"Set to off or unset to disable ldap-based dir aliases"), | |
1080 | AP_INIT_TAKE1("VhostLocAuthEnabled", conf_mvhl, MVHL_LAUTHENABLED, RSRC_CONF,"Set to off or unset to disable per-location authentication"), | |
1081 | AP_INIT_TAKE1("VhostDirAuthEnabled", conf_mvhl, MVHL_DAUTHENABLED, RSRC_CONF,"Set to off or unset to disable per-location authentication"), | |
1082 | AP_INIT_TAKE1("VhostLdapBindDn", conf_mvhl, MVHL_BINDDN, RSRC_CONF,"DN to use to bind to LDAP server"), | |
1083 | AP_INIT_TAKE1("VhostLdapBindPw", conf_mvhl, MVHL_BINDPW, RSRC_CONF,"Password to use to bind to LDAP server"), | |
1084 | AP_INIT_TAKE1("VhostLdapWlcBaseDn", conf_mvhl, MVHL_WLCBASEDN, RSRC_CONF,"Base DN to do all access control config searches."), | |
1085 | AP_INIT_TAKE1("VhostLdapWucBaseDn", conf_mvhl, MVHL_WUCBASEDN, RSRC_CONF,"Base DN to do all user config searches"), | |
1086 | AP_INIT_TAKE1("VhostLdapAliasesBaseDn", conf_mvhl, MVHL_ALIASBASEDN, RSRC_CONF,"Base DN to do all aliases config searches"), | |
1087 | AP_INIT_TAKE1("VhostLdapFallback", conf_mvhl, MVHL_FALLBACK, RSRC_CONF,"Fallback vhost server name to use - to display not-found info"), | |
1088 | AP_INIT_TAKE1("VhostLdapDeref", conf_mvhl, MVHL_DEREF, RSRC_CONF,"values: never, searching, finding, always"), | |
63a07100 PW |
1089 | {NULL} |
1090 | }; | |
866f0833 PW |
1091 | /******************************************************************/ |
1092 | static void mvhl_register_hooks(apr_pool_t * p) | |
1093 | { | |
1094 | ap_hook_post_config(mvhl_post_config, NULL, NULL, APR_HOOK_MIDDLE); | |
1095 | ap_hook_translate_name(mvhl_translate_name, NULL, NULL, APR_HOOK_MIDDLE); | |
1096 | ap_hook_get_suexec_identity(mvhl_suexec_doer, NULL, NULL, APR_HOOK_MIDDLE); | |
1097 | ap_hook_check_user_id(mvhl_authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE); | |
1098 | ap_hook_auth_checker(mvhl_check_auth, NULL, NULL, APR_HOOK_MIDDLE); | |
1099 | } | |
1100 | /******************************************************************/ | |
7f9875bb | 1101 | module AP_MODULE_DECLARE_DATA vhost_ldap_module = { |
866f0833 PW |
1102 | STANDARD20_MODULE_STUFF, |
1103 | NULL, // create per-directory config structure | |
1104 | NULL, // merge per-directory config structures, default is to override | |
1105 | mvhl_create_sconfig,// called when module configuration data needs to be created/allocated. | |
1106 | mvhl_merge_sconfig, // merge per-server config structures | |
1107 | mvhl_cmds, // Here we pass in the list of new configuration directives. | |
1108 | mvhl_register_hooks,// register me in apache core | |
7f9875bb | 1109 | }; |