Apache HTTPD
mod_authz_core.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Security options etc.
19 *
20 * Module derived from code originally written by Rob McCool
21 *
22 */
23
24#include "apr_strings.h"
25#include "apr_network_io.h"
26#include "apr_md5.h"
27
28#define APR_WANT_STRFUNC
29#define APR_WANT_BYTEFUNC
30#include "apr_want.h"
31
32#include "ap_config.h"
33#include "httpd.h"
34#include "http_config.h"
35#include "http_core.h"
36#include "http_log.h"
37#include "http_request.h"
38#include "http_protocol.h"
39#include "ap_provider.h"
40#include "ap_expr.h"
41
42#include "mod_auth.h"
43
44#if APR_HAVE_NETINET_IN_H
45#include <netinet/in.h>
46#endif
47
48#undef AUTHZ_EXTRA_CONFIGS
49
50typedef struct provider_alias_rec {
51 char *provider_name;
52 char *provider_alias;
58
65
67
82
84
91
92#define UNSET -1
93
97
98module AP_MODULE_DECLARE_DATA authz_core_module;
99
101
103{
104 authz_core_dir_conf *conf = apr_pcalloc(p, sizeof(*conf));
105
106 conf->op = AUTHZ_LOGIC_UNSET;
108
111
112 return (void *)conf;
113}
114
116 void *basev, void *newv)
117{
121
122 if (new->op == AUTHZ_LOGIC_UNSET && !new->section && base->section ) {
123 /* Only authz_forbidden_on_fail has been set in new. Don't treat
124 * it as a new auth config w.r.t. AuthMerging */
125 conf = apr_pmemdup(p, base, sizeof(*base));
126 }
127 else if (new->op == AUTHZ_LOGIC_OFF || new->op == AUTHZ_LOGIC_UNSET ||
128 !(base->section || new->section)) {
129 conf = apr_pmemdup(p, new, sizeof(*new));
130 }
131 else {
133
134 if (base->section) {
135 if (new->section) {
136 section = apr_pcalloc(p, sizeof(*section));
137
138 section->limited =
139 base->section->limited | new->section->limited;
140
141 section->op = new->op;
142 section->is_merged = 1;
143
144 section->first = apr_pmemdup(p, base->section,
145 sizeof(*base->section));
146 section->first->next = apr_pmemdup(p, new->section,
147 sizeof(*new->section));
148 } else {
149 section = apr_pmemdup(p, base->section,
150 sizeof(*base->section));
151 }
152 }
153 else {
154 section = apr_pmemdup(p, new->section, sizeof(*new->section));
155 }
156
157 conf = apr_pcalloc(p, sizeof(*conf));
158
159 conf->section = section;
160 conf->op = new->op;
161 }
162
163 if (new->authz_forbidden_on_fail == UNSET)
164 conf->authz_forbidden_on_fail = base->authz_forbidden_on_fail;
165 else
166 conf->authz_forbidden_on_fail = new->authz_forbidden_on_fail;
167
168 return (void*)conf;
169}
170
171/* Only per-server directive we have is GLOBAL_ONLY */
173 void *basev, void *newv)
174{
175 return basev;
176}
177
179{
181
182 authcfg = apr_pcalloc(p, sizeof(*authcfg));
183 authcfg->alias_rec = apr_hash_make(p);
184
185 return (void *)authcfg;
186}
187
188/* This is a fake authz provider that really merges various authz alias
189 * configurations and then invokes them.
190 */
192 const char *require_args,
193 const void *parsed_require_args)
194{
195 const char *provider_name;
196
197 /* Look up the provider alias in the alias list.
198 * Get the dir_config and call ap_merge_per_dir_configs()
199 * Call the real provider->check_authorization() function
200 * Return the result of the above function call
201 */
202
204
205 if (provider_name) {
208
210 &authz_core_module);
211
212 prvdraliasrec = apr_hash_get(authcfg->alias_rec, provider_name,
214
215 /* If we found the alias provider in the list, then merge the directory
216 configurations and call the real provider */
217 if (prvdraliasrec) {
220
223 prvdraliasrec->sec_auth);
224
225 ret = prvdraliasrec->provider->
226 check_authorization(r, prvdraliasrec->provider_args,
227 prvdraliasrec->provider_parsed_args);
228
230
231 return ret;
232 }
233 }
234
236 "no alias provider found for '%s' (BUG?)",
237 provider_name ? provider_name : "n/a");
238
239 return AUTHZ_DENIED;
240}
241
247
249 const char *args)
250{
251 const char *endp = ap_strrchr_c(args, '>');
252 char *provider_name;
253 char *provider_alias;
254 char *provider_args, *extra_args;
256 int old_overrides = cmd->override;
257 const char *errmsg;
258
259 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
260 if (err != NULL) {
261 return err;
262 }
263
264 if (endp == NULL) {
265 return apr_pstrcat(cmd->pool, cmd->cmd->name,
266 "> directive missing closing '>'", NULL);
267 }
268
269 args = apr_pstrndup(cmd->temp_pool, args, endp - args);
270
271 if (!args[0]) {
272 return apr_pstrcat(cmd->pool, cmd->cmd->name,
273 "> directive requires additional arguments", NULL);
274 }
275
276 /* Pull the real provider name and the alias name from the block header */
277 provider_name = ap_getword_conf(cmd->pool, &args);
278 provider_alias = ap_getword_conf(cmd->pool, &args);
279 provider_args = ap_getword_conf(cmd->pool, &args);
281
282 if (!provider_name[0] || !provider_alias[0]) {
283 return apr_pstrcat(cmd->pool, cmd->cmd->name,
284 "> directive requires additional arguments", NULL);
285 }
286
287 /* We only handle one "Require-Parameters" parameter. If several parameters
288 are needed, they must be enclosed between quotes */
289 if (extra_args && *extra_args) {
290 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(10142)
291 "When several arguments (%s %s...) are passed to a %s directive, "
292 "they must be enclosed in quotation marks. Otherwise, only the "
293 "first one is taken into account",
294 provider_args, extra_args, cmd->cmd->name);
295 }
296
298
299 /* Walk the subsection configuration to get the per_dir config that we will
300 * merge just before the real provider is called.
301 */
302 cmd->override = OR_AUTHCFG | ACCESS_CONF;
303 errmsg = ap_walk_config(cmd->directive->first_child, cmd,
305 cmd->override = old_overrides;
306
307 if (!errmsg) {
310
311 prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(*prvdraliasrec));
312
313 /* Save off the new directory config along with the original
314 * provider name and function pointer data
315 */
316 prvdraliasrec->provider_name = provider_name;
317 prvdraliasrec->provider_alias = provider_alias;
318 prvdraliasrec->provider_args = provider_args;
320 prvdraliasrec->provider =
323
324 /* by the time the config file is used, the provider should be loaded
325 * and registered with us.
326 */
327 if (!prvdraliasrec->provider) {
328 return apr_psprintf(cmd->pool,
329 "Unknown Authz provider: %s",
330 provider_name);
331 }
332 if (prvdraliasrec->provider->parse_require_line) {
333 err = prvdraliasrec->provider->parse_require_line(cmd,
334 provider_args, &prvdraliasrec->provider_parsed_args);
335 if (err)
336 return apr_psprintf(cmd->pool,
337 "Can't parse 'Require %s %s': %s",
338 provider_name, provider_args, err);
339 }
340
341 authcfg = ap_get_module_config(cmd->server->module_config,
342 &authz_core_module);
343
344 apr_hash_set(authcfg->alias_rec, provider_alias,
346
347 /* Register the fake provider so that we get called first */
349 provider_alias, AUTHZ_PROVIDER_VERSION,
352 }
353
354 return errmsg;
355}
356
358{
359 return ((result == AUTHZ_DENIED)
360 ? "denied"
361 : ((result == AUTHZ_GRANTED)
362 ? "granted"
364 ? "denied (no authenticated user yet)"
365 : "neutral")));
366}
367
370{
371 return (section->provider
372 ? apr_pstrcat(p, "Require ", (section->negate ? "not " : ""),
373 section->provider_name, " ",
374 section->provider_args, NULL)
375 : apr_pstrcat(p, section->is_merged ? "AuthMerging " : "<Require",
376 ((section->op == AUTHZ_LOGIC_AND)
377 ? (section->negate ? "NotAll" : "All")
378 : (section->negate ? "None" : "Any")),
379 section->is_merged ? "" : ">", NULL));
380}
381
390
391static const char *add_authz_provider(cmd_parms *cmd, void *config,
392 const char *args)
393{
396 authz_section_conf *child;
397
399
400 if (!strcasecmp(section->provider_name, "not")) {
401 section->provider_name = ap_getword_conf(cmd->pool, &args);
402 section->negate = 1;
403 }
404
405 section->provider_args = args;
406
407 /* lookup and cache the actual provider now */
409 section->provider_name,
411
412 /* by the time the config file is used, the provider should be loaded
413 * and registered with us.
414 */
415 if (!section->provider) {
416 return apr_psprintf(cmd->pool,
417 "Unknown Authz provider: %s",
418 section->provider_name);
419 }
420
421 /* if the provider doesn't provide the appropriate function, reject it */
422 if (!section->provider->check_authorization) {
423 return apr_psprintf(cmd->pool,
424 "The '%s' Authz provider is not supported by any "
425 "of the loaded authorization modules",
426 section->provider_name);
427 }
428
429 section->limited = cmd->limited;
430
431 if (section->provider->parse_require_line) {
432 const char *err;
433 apr_pool_userdata_setn(section->provider_name,
436 cmd->temp_pool);
437 err = section->provider->parse_require_line(cmd, args,
438 &section->provider_parsed_args);
439
440 if (err)
441 return err;
442 }
443
444 if (!conf->section) {
445 conf->section = create_default_section(cmd->pool);
446 }
447
448 if (section->negate && conf->section->op == AUTHZ_LOGIC_OR) {
449 return apr_psprintf(cmd->pool, "negative %s directive has no effect "
450 "in %s directive",
451 cmd->cmd->name,
452 format_authz_command(cmd->pool, conf->section));
453 }
454
455 conf->section->limited |= section->limited;
456
457 child = conf->section->first;
458
459 if (child) {
460 while (child->next) {
461 child = child->next;
462 }
463
464 child->next = section;
465 }
466 else {
467 conf->section->first = section;
468 }
469
470 return NULL;
471}
472
473static const char *add_authz_section(cmd_parms *cmd, void *mconfig,
474 const char *args)
475{
477 const char *endp = ap_strrchr_c(args, '>');
480 int old_overrides = cmd->override;
482 const char *errmsg;
483
484 if (endp == NULL) {
485 return apr_pstrcat(cmd->pool, cmd->cmd->name,
486 "> directive missing closing '>'", NULL);
487 }
488
489 args = apr_pstrndup(cmd->temp_pool, args, endp - args);
490
491 if (args[0]) {
492 return apr_pstrcat(cmd->pool, cmd->cmd->name,
493 "> directive doesn't take additional arguments",
494 NULL);
495 }
496
497 section = apr_pcalloc(cmd->pool, sizeof(*section));
498
499 if (!strcasecmp(cmd->cmd->name, "<RequireAll")) {
501 }
502 else if (!strcasecmp(cmd->cmd->name, "<RequireAny")) {
504 }
505 else if (!strcasecmp(cmd->cmd->name, "<RequireNotAll")) {
507 section->negate = 1;
508 }
509 else {
511 section->negate = 1;
512 }
513
514 conf->section = section;
515
516 /* trigger NOT_IN_LIMIT errors as if this were a <Limit> directive */
517 cmd->limited &= ~(AP_METHOD_BIT << (METHODS - 1));
518
519 cmd->override = OR_AUTHCFG;
520 errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
521 cmd->override = old_overrides;
522
523 cmd->limited = old_limited;
524
525 conf->section = old_section;
526
527 if (errmsg) {
528 return errmsg;
529 }
530
531 if (section->first) {
532 authz_section_conf *child;
533
534 if (!old_section) {
536 }
537
538 if (section->negate && old_section->op == AUTHZ_LOGIC_OR) {
539 return apr_psprintf(cmd->pool, "%s directive has "
540 "no effect in %s directive",
543 }
544
545 old_section->limited |= section->limited;
546
547 if (!section->negate && section->op == old_section->op) {
548 /* be associative */
549 section = section->first;
550 }
551
552 child = old_section->first;
553
554 if (child) {
555 while (child->next) {
556 child = child->next;
557 }
558
559 child->next = section;
560 }
561 else {
563 }
564 }
565 else {
566 return apr_pstrcat(cmd->pool,
568 " directive contains no authorization directives",
569 NULL);
570 }
571
572 return NULL;
573}
574
575static const char *authz_merge_sections(cmd_parms *cmd, void *mconfig,
576 const char *arg)
577{
579
580 if (!strcasecmp(arg, "Off")) {
581 conf->op = AUTHZ_LOGIC_OFF;
582 }
583 else if (!strcasecmp(arg, "And")) {
584 conf->op = AUTHZ_LOGIC_AND;
585 }
586 else if (!strcasecmp(arg, "Or")) {
587 conf->op = AUTHZ_LOGIC_OR;
588 }
589 else {
590 return apr_pstrcat(cmd->pool, cmd->cmd->name, " must be one of: "
591 "Off | And | Or", NULL);
592 }
593
594 return NULL;
595}
596
599{
600 authz_section_conf *prev = NULL;
602 int ret = !OK;
603
604 while (child) {
605 if (child->first) {
606 if (authz_core_check_section(p, s, child, 0) != OK) {
607 return !OK;
608 }
609
610 if (child->negate && child->op != section->op) {
611 authz_section_conf *next = child->next;
612
613 /* avoid one level of recursion when De Morgan permits */
614 child = child->first;
615
616 if (prev) {
617 prev->next = child;
618 }
619 else {
620 section->first = child;
621 }
622
623 do {
624 child->negate = !child->negate;
625 } while (child->next && (child = child->next));
626
627 child->next = next;
628 }
629 }
630
631 prev = child;
632 child = child->next;
633 }
634
635 child = section->first;
636
637 while (child) {
638 if (!child->negate) {
639 ret = OK;
640 break;
641 }
642
643 child = child->next;
644 }
645
646 if (ret != OK) {
648 "%s directive contains only negative authorization directives",
649 is_conf ? "<Directory>, <Location>, or similar"
651 }
652
653 return ret;
654}
655
657 apr_pool_t *ptemp)
658{
660
661 return OK;
662}
663
665 apr_pool_t *ptemp, server_rec *s)
666{
668
669 while (conf) {
670 if (conf->section) {
671 if (authz_core_check_section(p, s, conf->section, 1) != OK) {
672 return !OK;
673 }
674 }
675
676 conf = conf->next;
677 }
678
679 return OK;
680}
681
682static const command_rec authz_cmds[] =
683{
684 AP_INIT_RAW_ARGS("<AuthzProviderAlias", authz_require_alias_section,
686 "container for grouping an authorization provider's "
687 "directives under a provider alias"),
689 "specifies authorization directives "
690 "which one must pass (or not) for a request to suceeed"),
692 "container for grouping authorization directives "
693 "of which none must fail and at least one must pass "
694 "for a request to succeed"),
696 "container for grouping authorization directives "
697 "of which one must pass "
698 "for a request to succeed"),
699#ifdef AUTHZ_EXTRA_CONFIGS
701 "container for grouping authorization directives "
702 "of which some must fail or none must pass "
703 "for a request to succeed"),
704#endif
706 "container for grouping authorization directives "
707 "of which none must pass "
708 "for a request to succeed"),
710 "controls how a <Directory>, <Location>, or similar "
711 "directive's authorization directives are combined with "
712 "those of its predecessor"),
713 AP_INIT_FLAG("AuthzSendForbiddenOnFailure", ap_set_flag_slot_char,
714 (void *)APR_OFFSETOF(authz_core_dir_conf, authz_forbidden_on_fail),
716 "Controls if an authorization failure should result in a "
717 "'403 FORBIDDEN' response instead of the HTTP-conforming "
718 "'401 UNAUTHORIZED'"),
719 {NULL}
720};
721
725{
727
728 /* check to make sure that the request method requires authorization */
729 if (!(section->limited & (AP_METHOD_BIT << r->method_number))) {
732
734 "authorization result of %s: %s "
735 "(directive limited to other methods)",
738
739 return auth_result;
740 }
741
742 if (section->provider) {
744 section->provider_name);
745
747 section->provider->check_authorization(r, section->provider_args,
748 section->provider_parsed_args);
749
751 }
752 else {
754
756
757 while (child) {
759
761
763 return AUTHZ_GENERAL_ERROR;
764 }
765
767 /*
768 * Handling of AUTHZ_DENIED/AUTHZ_DENIED_NO_USER: Return
769 * AUTHZ_DENIED_NO_USER if providing a user may change the
770 * result, AUTHZ_DENIED otherwise.
771 */
772 if (section->op == AUTHZ_LOGIC_AND) {
773 if (child_result == AUTHZ_DENIED) {
775 break;
776 }
779 || (auth_result == AUTHZ_NEUTRAL)) {
781 }
782 }
783 else {
784 /* AUTHZ_LOGIC_OR */
787 break;
788 }
791 || (auth_result == AUTHZ_NEUTRAL)) {
793 }
794 }
795 }
796
797 child = child->next;
798 }
799 }
800
801 if (section->negate) {
802 if (auth_result == AUTHZ_GRANTED) {
804 }
805 else if (auth_result == AUTHZ_DENIED ||
807 /* For negated directives, if the original result was denied
808 * then the new result is neutral since we can not grant
809 * access simply because authorization was not rejected.
810 */
812 }
813 }
814
816 "authorization result of %s: %s",
819
820 return auth_result;
821}
822
824{
827
828 conf = ap_get_module_config(r->per_dir_config, &authz_core_module);
829
830 if (!conf->section) {
831 if (ap_auth_type(r)) {
832 /* there's an AuthType configured, but no authorization
833 * directives applied to support it
834 */
835
837 "AuthType configured with no corresponding "
838 "authorization directives");
839
841 }
842
844 "authorization result: granted (no directives)");
845
846 return OK;
847 }
848
850
851 if (auth_result == AUTHZ_GRANTED) {
852 return OK;
853 }
854 else if (auth_result == AUTHZ_DENIED_NO_USER) {
855 if (after_authn) {
857 "authorization failure (no authenticated user): %s",
858 r->uri);
859 /*
860 * If we're returning 401 to an authenticated user, tell them to
861 * try again. If unauthenticated, note_auth_failure has already
862 * been called during auth.
863 */
864 if (r->user)
866
867 return HTTP_UNAUTHORIZED;
868 }
869 else {
870 /*
871 * We need a user before we can decide what to do.
872 * Get out of the way and proceed with authentication.
873 */
874 return DECLINED;
875 }
876 }
878 if (!after_authn || ap_auth_type(r) == NULL) {
880 "client denied by server configuration: %s%s",
881 r->filename ? "" : "uri ",
882 r->filename ? r->filename : r->uri);
883
884 return HTTP_FORBIDDEN;
885 }
886 else {
888 "user %s: authorization failure for \"%s\": ",
889 r->user, r->uri);
890
891 if (conf->authz_forbidden_on_fail > 0) {
892 return HTTP_FORBIDDEN;
893 }
894 else {
895 /*
896 * If we're returning 401 to an authenticated user, tell them to
897 * try again. If unauthenticated, note_auth_failure has already
898 * been called during auth.
899 */
900 if (r->user)
902 return HTTP_UNAUTHORIZED;
903 }
904 }
905 }
906 else {
907 /* We'll assume that the module has already said what its
908 * error was in the logs.
909 */
911 }
912}
913
915{
916 return authorize_user_core(r, 0);
917}
918
920{
921 return authorize_user_core(r, 1);
922}
923
925{
927
928 conf = ap_get_module_config(r->per_dir_config, &authz_core_module);
929
930 if (conf->section
931 && (conf->section->limited & (AP_METHOD_BIT << r->method_number))) {
932 return 1;
933 }
934
935 return 0;
936}
937
938/*
939 * env authz provider
940 */
941
943 const char *require_line,
944 const void *parsed_require_line)
945{
946 const char *t, *w;
947
948 /* The 'env' provider will allow the configuration to specify a list of
949 env variables to check rather than a single variable. This is different
950 from the previous host based syntax. */
951 t = require_line;
952 while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
953 if (apr_table_get(r->subprocess_env, w)) {
954 return AUTHZ_GRANTED;
955 }
956 }
957
958 return AUTHZ_DENIED;
959}
960
966
967
968/*
969 * all authz provider
970 */
971
973 const char *require_line,
974 const void *parsed_require_line)
975{
977 return AUTHZ_GRANTED;
978 }
979 return AUTHZ_DENIED;
980}
981
982static const char *all_parse_config(cmd_parms *cmd, const char *require_line,
983 const void **parsed_require_line)
984{
985 /*
986 * If the argument to the 'all' provider is 'granted' then just let
987 * everybody in. This would be equivalent to the previous syntax of
988 * 'allow from all'. If the argument is 'denied' we reject everybody,
989 * which is equivalent to 'deny from all'.
990 */
991 if (strcasecmp(require_line, "granted") == 0) {
992 *parsed_require_line = (void *)1;
993 return NULL;
994 }
995 else if (strcasecmp(require_line, "denied") == 0) {
996 /* *parsed_require_line is already NULL */
997 return NULL;
998 }
999 else {
1000 return "Argument for 'Require all' must be 'granted' or 'denied'";
1001 }
1002}
1003
1009
1010
1011/*
1012 * method authz provider
1013 */
1014
1016 const char *require_line,
1017 const void *parsed_require_line)
1018{
1019 const apr_int64_t *allowed = parsed_require_line;
1020 if (*allowed & (AP_METHOD_BIT << r->method_number))
1021 return AUTHZ_GRANTED;
1022 else
1023 return AUTHZ_DENIED;
1024}
1025
1026static const char *method_parse_config(cmd_parms *cmd, const char *require_line,
1027 const void **parsed_require_line)
1028{
1029 const char *w, *t;
1030 apr_int64_t *allowed = apr_pcalloc(cmd->pool, sizeof(apr_int64_t));
1031
1032 t = require_line;
1033
1034 while ((w = ap_getword_conf(cmd->temp_pool, &t)) && w[0]) {
1035 int m = ap_method_number_of(w);
1036 if (m == M_INVALID) {
1037 return apr_pstrcat(cmd->pool, "Invalid Method '", w, "'", NULL);
1038 }
1039
1040 *allowed |= (AP_METHOD_BIT << m);
1041 }
1042
1043 *parsed_require_line = allowed;
1044 return NULL;
1045}
1046
1052
1053/*
1054 * expr authz provider
1055 */
1056
1057#define REQUIRE_EXPR_NOTE "Require_expr_info"
1062
1064{
1065 if (parms->type == AP_EXPR_FUNC_VAR
1066 && strcasecmp(parms->name, "REMOTE_USER") == 0) {
1067 struct require_expr_info *info;
1070 info->want_user = 1;
1071 }
1073}
1074
1075static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
1076 const void **parsed_require_line)
1077{
1078 const char *expr_err = NULL;
1079 struct require_expr_info *info = apr_pcalloc(cmd->pool, sizeof(*info));
1080
1081 /* if the expression happens to be surrounded by quotes, skip them */
1082 if (require_line[0] == '"') {
1083 apr_size_t len = strlen(require_line);
1084
1085 if (require_line[len-1] == '"')
1086 require_line = apr_pstrndup(cmd->temp_pool,
1087 require_line + 1,
1088 len - 2);
1089 }
1090
1092 cmd->temp_pool);
1093 info->expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
1095
1096 if (expr_err)
1097 return apr_pstrcat(cmd->temp_pool,
1098 "Cannot parse expression in require line: ",
1099 expr_err, NULL);
1100
1102
1103 return NULL;
1104}
1105
1107 const char *require_line,
1108 const void *parsed_require_line)
1109{
1110 const char *err = NULL;
1112 int rc = ap_expr_exec(r, info->expr, &err);
1113
1114 if (rc < 0) {
1116 "Error evaluating expression in 'Require expr': %s",
1117 err);
1118 return AUTHZ_GENERAL_ERROR;
1119 }
1120 else if (rc == 0) {
1121 if (info->want_user)
1122 return AUTHZ_DENIED_NO_USER;
1123 else
1124 return AUTHZ_DENIED;
1125 }
1126 else {
1127 return AUTHZ_GRANTED;
1128 }
1129}
1130
1136
1137
1162
1164{
1166 create_authz_core_dir_config, /* dir config creater */
1167 merge_authz_core_dir_config, /* dir merger */
1168 create_authz_core_svr_config, /* server config */
1169 merge_authz_core_svr_config , /* merge server config */
1170 authz_cmds,
1171 register_hooks /* register hooks */
1172};
1173
Symbol export macros and hook functions.
Expression parser.
#define AP_EXPR_FUNC_VAR
Definition ap_expr.h:258
Apache Provider API.
const char apr_size_t len
Definition ap_regex.h:187
APR MD5 Routines.
APR Network library.
APR Strings library.
APR Standard Headers Support.
ap_conf_vector_t * ap_merge_per_dir_configs(apr_pool_t *p, ap_conf_vector_t *base, ap_conf_vector_t *new_conf)
Definition config.c:285
ap_conf_vector_t * ap_create_per_dir_config(apr_pool_t *p)
Definition config.c:366
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
struct ap_conf_vector_t ap_conf_vector_t
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
ap_conf_vector_t * base
const char * ap_set_flag_slot_char(cmd_parms *cmd, void *struct_ptr, int arg)
Definition config.c:1523
void ap_hook_check_config(ap_HOOK_check_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:96
#define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help)
void ap_hook_pre_config(ap_HOOK_pre_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:91
ap_conf_vector_t const char * section
request_rec * r
const char * ap_walk_config(ap_directive_t *conftree, cmd_parms *parms, ap_conf_vector_t *section_vector)
Definition config.c:1360
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
const char * ap_auth_type(request_rec *r)
Definition core.c:793
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_STARTUP
Definition http_log.h:105
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_DEBUG
Definition http_log.h:71
int ap_method_number_of(const char *method)
void ap_note_auth_failure(request_rec *r)
Definition protocol.c:1736
void * ap_lookup_provider(const char *provider_group, const char *provider_name, const char *provider_version)
Definition provider.c:99
apr_status_t ap_register_auth_provider(apr_pool_t *pool, const char *provider_group, const char *provider_name, const char *provider_version, const void *provider, int type)
Definition request.c:2179
#define AP_AUTH_INTERNAL_PER_CONF
void ap_hook_check_access_ex(ap_HOOK_access_checker_ex_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder, int type)
Definition request.c:2206
void ap_hook_check_authz(ap_HOOK_auth_checker_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder, int type)
Definition request.c:2230
void * dummy
Definition http_vhost.h:62
void const char * arg
Definition http_vhost.h:63
#define APR_HOOK_LAST
Definition apr_hooks.h:305
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define APR_REGISTER_OPTIONAL_FN(name)
apr_redis_t * rc
Definition apr_redis.h:173
int ap_expr_lookup_default(ap_expr_lookup_parms *parms)
#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn)
Definition ap_expr.h:340
int ap_expr_exec(request_rec *r, const ap_expr_info_t *expr, const char **err)
#define ACCESS_CONF
#define RSRC_CONF
#define OR_AUTHCFG
#define HTTP_INTERNAL_SERVER_ERROR
Definition httpd.h:535
#define HTTP_FORBIDDEN
Definition httpd.h:511
#define HTTP_UNAUTHORIZED
Definition httpd.h:509
#define AP_METHOD_BIT
Definition httpd.h:629
#define METHODS
Definition httpd.h:624
#define M_INVALID
Definition httpd.h:618
#define STANDARD20_MODULE_STUFF
#define ap_strrchr_c(s, c)
Definition httpd.h:2357
#define AP_DEBUG_ASSERT(exp)
Definition httpd.h:2283
char * ap_getword_conf(apr_pool_t *p, const char **line)
Definition util.c:833
#define GLOBAL_ONLY
const char * ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
Definition core.c:1301
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
apr_array_header_t ** result
int strcasecmp(const char *a, const char *b)
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
apr_interval_time_t t
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
const void * m
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
const char const char *const * args
Apache Configuration.
CORE HTTP Daemon.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
Authentication and Authorization Extension for Apache.
authz_status
Definition mod_auth.h:72
@ AUTHZ_DENIED
Definition mod_auth.h:73
@ AUTHZ_GENERAL_ERROR
Definition mod_auth.h:76
@ AUTHZ_DENIED_NO_USER
Definition mod_auth.h:77
@ AUTHZ_NEUTRAL
Definition mod_auth.h:75
@ AUTHZ_GRANTED
Definition mod_auth.h:74
#define AUTHZ_PROVIDER_NAME_NOTE
Definition mod_auth.h:46
#define AUTHZ_PROVIDER_VERSION
Definition mod_auth.h:42
#define AUTHZ_PROVIDER_GROUP
Definition mod_auth.h:40
static void * create_authz_core_svr_config(apr_pool_t *p, server_rec *s)
static int authz_core_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
static authz_status all_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static authz_section_conf * create_default_section(apr_pool_t *p)
static const char * method_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
static int authorize_user(request_rec *r)
static const char * authz_merge_sections(cmd_parms *cmd, void *mconfig, const char *arg)
authz_logic_op
@ AUTHZ_LOGIC_OFF
@ AUTHZ_LOGIC_UNSET
@ AUTHZ_LOGIC_OR
@ AUTHZ_LOGIC_AND
static authz_status method_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static int authz_core_check_section(apr_pool_t *p, server_rec *s, authz_section_conf *section, int is_conf)
static void * merge_authz_core_svr_config(apr_pool_t *p, void *basev, void *newv)
static const char * expr_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
static int authorize_user_core(request_rec *r, int after_authn)
static int authz_some_auth_required(request_rec *r)
static void * merge_authz_core_dir_config(apr_pool_t *p, void *basev, void *newv)
static const char * format_authz_result(authz_status result)
#define REQUIRE_EXPR_NOTE
static authz_status apply_authz_sections(request_rec *r, authz_section_conf *section, authz_logic_op parent_op)
static int authz_core_check_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static const char * format_authz_command(apr_pool_t *p, authz_section_conf *section)
static const command_rec authz_cmds[]
static const authz_provider authz_method_provider
static int authorize_userless(request_rec *r)
static const authz_provider authz_all_provider
static void register_hooks(apr_pool_t *p)
static const char * all_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
static const authz_provider authz_env_provider
static const authz_provider authz_expr_provider
static authz_core_dir_conf * authz_core_first_dir_conf
static authz_status env_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
#define UNSET
static const char * add_authz_section(cmd_parms *cmd, void *mconfig, const char *args)
static const authz_provider authz_alias_provider
static void * create_authz_core_dir_config(apr_pool_t *p, char *dummy)
static authz_status authz_alias_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static authz_status expr_check_authorization(request_rec *r, const char *require_line, const void *parsed_require_line)
static const char * authz_require_alias_section(cmd_parms *cmd, void *mconfig, const char *args)
static const char * add_authz_provider(cmd_parms *cmd, void *config, const char *args)
static int expr_lookup_fn(ap_expr_lookup_parms *parms)
return NULL
Definition mod_so.c:359
authz_section_conf * section
authz_core_dir_conf * next
authz_logic_op op
signed char authz_forbidden_on_fail
apr_hash_t * alias_rec
const char * provider_args
const authz_provider * provider
const char * provider_name
authz_logic_op op
authz_section_conf * first
const void * provider_parsed_args
authz_section_conf * next
const authz_provider * provider
const void * provider_parsed_args
ap_conf_vector_t * sec_auth
A structure that represents the current request.
Definition httpd.h:845
char * user
Definition httpd.h:1005
char * uri
Definition httpd.h:1016
apr_table_t * notes
Definition httpd.h:985
int method_number
Definition httpd.h:898
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
apr_table_t * subprocess_env
Definition httpd.h:983
server_rec * server
Definition httpd.h:851
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
ap_expr_info_t * expr
A structure to keep track of authorization requirements.
Definition http_core.h:316
A structure to store information for each virtual server.
Definition httpd.h:1322
struct ap_conf_vector_t * module_config
Definition httpd.h:1341
INT info