Mercurial > hg > nginx
comparison src/http/modules/ngx_http_access_module.c @ 5233:00dbfac67e48
Access: support for UNIX-domain client addresses (ticket #359).
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Thu, 30 May 2013 18:23:05 +0400 |
parents | ae60a1085c82 |
children | 06c227e9edd0 |
comparison
equal
deleted
inserted
replaced
5232:53eb1e67e432 | 5233:00dbfac67e48 |
---|---|
24 ngx_uint_t deny; /* unsigned deny:1; */ | 24 ngx_uint_t deny; /* unsigned deny:1; */ |
25 } ngx_http_access_rule6_t; | 25 } ngx_http_access_rule6_t; |
26 | 26 |
27 #endif | 27 #endif |
28 | 28 |
29 #if (NGX_HAVE_UNIX_DOMAIN) | |
30 | |
31 typedef struct { | |
32 ngx_uint_t deny; /* unsigned deny:1; */ | |
33 } ngx_http_access_rule_un_t; | |
34 | |
35 #endif | |
36 | |
29 typedef struct { | 37 typedef struct { |
30 ngx_array_t *rules; /* array of ngx_http_access_rule_t */ | 38 ngx_array_t *rules; /* array of ngx_http_access_rule_t */ |
31 #if (NGX_HAVE_INET6) | 39 #if (NGX_HAVE_INET6) |
32 ngx_array_t *rules6; /* array of ngx_http_access_rule6_t */ | 40 ngx_array_t *rules6; /* array of ngx_http_access_rule6_t */ |
41 #endif | |
42 #if (NGX_HAVE_UNIX_DOMAIN) | |
43 ngx_array_t *rules_un; /* array of ngx_http_access_rule_un_t */ | |
33 #endif | 44 #endif |
34 } ngx_http_access_loc_conf_t; | 45 } ngx_http_access_loc_conf_t; |
35 | 46 |
36 | 47 |
37 static ngx_int_t ngx_http_access_handler(ngx_http_request_t *r); | 48 static ngx_int_t ngx_http_access_handler(ngx_http_request_t *r); |
38 static ngx_int_t ngx_http_access_inet(ngx_http_request_t *r, | 49 static ngx_int_t ngx_http_access_inet(ngx_http_request_t *r, |
39 ngx_http_access_loc_conf_t *alcf, in_addr_t addr); | 50 ngx_http_access_loc_conf_t *alcf, in_addr_t addr); |
40 #if (NGX_HAVE_INET6) | 51 #if (NGX_HAVE_INET6) |
41 static ngx_int_t ngx_http_access_inet6(ngx_http_request_t *r, | 52 static ngx_int_t ngx_http_access_inet6(ngx_http_request_t *r, |
42 ngx_http_access_loc_conf_t *alcf, u_char *p); | 53 ngx_http_access_loc_conf_t *alcf, u_char *p); |
54 #endif | |
55 #if (NGX_HAVE_UNIX_DOMAIN) | |
56 static ngx_int_t ngx_http_access_unix(ngx_http_request_t *r, | |
57 ngx_http_access_loc_conf_t *alcf); | |
43 #endif | 58 #endif |
44 static ngx_int_t ngx_http_access_found(ngx_http_request_t *r, ngx_uint_t deny); | 59 static ngx_int_t ngx_http_access_found(ngx_http_request_t *r, ngx_uint_t deny); |
45 static char *ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, | 60 static char *ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, |
46 void *conf); | 61 void *conf); |
47 static void *ngx_http_access_create_loc_conf(ngx_conf_t *cf); | 62 static void *ngx_http_access_create_loc_conf(ngx_conf_t *cf); |
142 | 157 |
143 if (alcf->rules6) { | 158 if (alcf->rules6) { |
144 return ngx_http_access_inet6(r, alcf, p); | 159 return ngx_http_access_inet6(r, alcf, p); |
145 } | 160 } |
146 | 161 |
162 break; | |
163 | |
164 #endif | |
165 | |
166 #if (NGX_HAVE_UNIX_DOMAIN) | |
167 | |
168 case AF_UNIX: | |
169 if (alcf->rules_un) { | |
170 return ngx_http_access_unix(r, alcf); | |
171 } | |
172 | |
173 break; | |
174 | |
147 #endif | 175 #endif |
148 } | 176 } |
149 | 177 |
150 return NGX_DECLINED; | 178 return NGX_DECLINED; |
151 } | 179 } |
219 } | 247 } |
220 | 248 |
221 #endif | 249 #endif |
222 | 250 |
223 | 251 |
252 #if (NGX_HAVE_UNIX_DOMAIN) | |
253 | |
254 static ngx_int_t | |
255 ngx_http_access_unix(ngx_http_request_t *r, ngx_http_access_loc_conf_t *alcf) | |
256 { | |
257 ngx_uint_t i; | |
258 ngx_http_access_rule_un_t *rule_un; | |
259 | |
260 rule_un = alcf->rules_un->elts; | |
261 for (i = 0; i < alcf->rules_un->nelts; i++) { | |
262 return ngx_http_access_found(r, rule_un[i].deny); | |
263 } | |
264 | |
265 return NGX_DECLINED; | |
266 } | |
267 | |
268 #endif | |
269 | |
270 | |
224 static ngx_int_t | 271 static ngx_int_t |
225 ngx_http_access_found(ngx_http_request_t *r, ngx_uint_t deny) | 272 ngx_http_access_found(ngx_http_request_t *r, ngx_uint_t deny) |
226 { | 273 { |
227 ngx_http_core_loc_conf_t *clcf; | 274 ngx_http_core_loc_conf_t *clcf; |
228 | 275 |
244 static char * | 291 static char * |
245 ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 292 ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
246 { | 293 { |
247 ngx_http_access_loc_conf_t *alcf = conf; | 294 ngx_http_access_loc_conf_t *alcf = conf; |
248 | 295 |
249 ngx_int_t rc; | 296 ngx_int_t rc; |
250 ngx_uint_t all; | 297 ngx_uint_t all; |
251 ngx_str_t *value; | 298 ngx_str_t *value; |
252 ngx_cidr_t cidr; | 299 ngx_cidr_t cidr; |
253 ngx_http_access_rule_t *rule; | 300 ngx_http_access_rule_t *rule; |
254 #if (NGX_HAVE_INET6) | 301 #if (NGX_HAVE_INET6) |
255 ngx_http_access_rule6_t *rule6; | 302 ngx_http_access_rule6_t *rule6; |
303 #endif | |
304 #if (NGX_HAVE_UNIX_DOMAIN) | |
305 ngx_http_access_rule_un_t *rule_un; | |
256 #endif | 306 #endif |
257 | 307 |
258 ngx_memzero(&cidr, sizeof(ngx_cidr_t)); | 308 ngx_memzero(&cidr, sizeof(ngx_cidr_t)); |
259 | 309 |
260 value = cf->args->elts; | 310 value = cf->args->elts; |
261 | 311 |
262 all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); | 312 all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0); |
263 | 313 |
264 if (!all) { | 314 if (!all) { |
265 | 315 |
316 #if (NGX_HAVE_UNIX_DOMAIN) | |
317 | |
318 if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) { | |
319 cidr.family = AF_UNIX; | |
320 rc = NGX_OK; | |
321 | |
322 } else { | |
323 rc = ngx_ptocidr(&value[1], &cidr); | |
324 } | |
325 | |
326 #else | |
266 rc = ngx_ptocidr(&value[1], &cidr); | 327 rc = ngx_ptocidr(&value[1], &cidr); |
328 #endif | |
267 | 329 |
268 if (rc == NGX_ERROR) { | 330 if (rc == NGX_ERROR) { |
269 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 331 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
270 "invalid parameter \"%V\"", &value[1]); | 332 "invalid parameter \"%V\"", &value[1]); |
271 return NGX_CONF_ERROR; | 333 return NGX_CONF_ERROR; |
275 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | 337 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
276 "low address bits of %V are meaningless", &value[1]); | 338 "low address bits of %V are meaningless", &value[1]); |
277 } | 339 } |
278 } | 340 } |
279 | 341 |
280 switch (cidr.family) { | 342 if (cidr.family == AF_INET || all) { |
281 | 343 |
282 #if (NGX_HAVE_INET6) | 344 if (alcf->rules == NULL) { |
283 case AF_INET6: | 345 alcf->rules = ngx_array_create(cf->pool, 4, |
284 case 0: /* all */ | 346 sizeof(ngx_http_access_rule_t)); |
347 if (alcf->rules == NULL) { | |
348 return NGX_CONF_ERROR; | |
349 } | |
350 } | |
351 | |
352 rule = ngx_array_push(alcf->rules); | |
353 if (rule == NULL) { | |
354 return NGX_CONF_ERROR; | |
355 } | |
356 | |
357 rule->mask = cidr.u.in.mask; | |
358 rule->addr = cidr.u.in.addr; | |
359 rule->deny = (value[0].data[0] == 'd') ? 1 : 0; | |
360 } | |
361 | |
362 #if (NGX_HAVE_INET6) | |
363 if (cidr.family == AF_INET6 || all) { | |
285 | 364 |
286 if (alcf->rules6 == NULL) { | 365 if (alcf->rules6 == NULL) { |
287 alcf->rules6 = ngx_array_create(cf->pool, 4, | 366 alcf->rules6 = ngx_array_create(cf->pool, 4, |
288 sizeof(ngx_http_access_rule6_t)); | 367 sizeof(ngx_http_access_rule6_t)); |
289 if (alcf->rules6 == NULL) { | 368 if (alcf->rules6 == NULL) { |
297 } | 376 } |
298 | 377 |
299 rule6->mask = cidr.u.in6.mask; | 378 rule6->mask = cidr.u.in6.mask; |
300 rule6->addr = cidr.u.in6.addr; | 379 rule6->addr = cidr.u.in6.addr; |
301 rule6->deny = (value[0].data[0] == 'd') ? 1 : 0; | 380 rule6->deny = (value[0].data[0] == 'd') ? 1 : 0; |
302 | 381 } |
303 if (!all) { | 382 #endif |
304 break; | 383 |
305 } | 384 #if (NGX_HAVE_UNIX_DOMAIN) |
306 | 385 if (cidr.family == AF_UNIX || all) { |
307 /* "all" passes through */ | 386 |
308 #endif | 387 if (alcf->rules_un == NULL) { |
309 | 388 alcf->rules_un = ngx_array_create(cf->pool, 1, |
310 default: /* AF_INET */ | 389 sizeof(ngx_http_access_rule_un_t)); |
311 | 390 if (alcf->rules_un == NULL) { |
312 if (alcf->rules == NULL) { | |
313 alcf->rules = ngx_array_create(cf->pool, 4, | |
314 sizeof(ngx_http_access_rule_t)); | |
315 if (alcf->rules == NULL) { | |
316 return NGX_CONF_ERROR; | 391 return NGX_CONF_ERROR; |
317 } | 392 } |
318 } | 393 } |
319 | 394 |
320 rule = ngx_array_push(alcf->rules); | 395 rule_un = ngx_array_push(alcf->rules_un); |
321 if (rule == NULL) { | 396 if (rule_un == NULL) { |
322 return NGX_CONF_ERROR; | 397 return NGX_CONF_ERROR; |
323 } | 398 } |
324 | 399 |
325 rule->mask = cidr.u.in.mask; | 400 rule_un->deny = (value[0].data[0] == 'd') ? 1 : 0; |
326 rule->addr = cidr.u.in.addr; | 401 } |
327 rule->deny = (value[0].data[0] == 'd') ? 1 : 0; | 402 #endif |
328 } | |
329 | 403 |
330 return NGX_CONF_OK; | 404 return NGX_CONF_OK; |
331 } | 405 } |
332 | 406 |
333 | 407 |
349 ngx_http_access_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | 423 ngx_http_access_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
350 { | 424 { |
351 ngx_http_access_loc_conf_t *prev = parent; | 425 ngx_http_access_loc_conf_t *prev = parent; |
352 ngx_http_access_loc_conf_t *conf = child; | 426 ngx_http_access_loc_conf_t *conf = child; |
353 | 427 |
354 #if (NGX_HAVE_INET6) | 428 if (conf->rules == NULL |
355 | 429 #if (NGX_HAVE_INET6) |
356 if (conf->rules == NULL && conf->rules6 == NULL) { | 430 && conf->rules6 == NULL |
431 #endif | |
432 #if (NGX_HAVE_UNIX_DOMAIN) | |
433 && conf->rules_un == NULL | |
434 #endif | |
435 ) { | |
357 conf->rules = prev->rules; | 436 conf->rules = prev->rules; |
437 #if (NGX_HAVE_INET6) | |
358 conf->rules6 = prev->rules6; | 438 conf->rules6 = prev->rules6; |
359 } | 439 #endif |
360 | 440 #if (NGX_HAVE_UNIX_DOMAIN) |
361 #else | 441 conf->rules_un = prev->rules_un; |
362 | 442 #endif |
363 if (conf->rules == NULL) { | 443 } |
364 conf->rules = prev->rules; | |
365 } | |
366 | |
367 #endif | |
368 | 444 |
369 return NGX_CONF_OK; | 445 return NGX_CONF_OK; |
370 } | 446 } |
371 | 447 |
372 | 448 |