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