Added authoritative support.
[mod_auth_kerb.cvs/.git] / apache2 / auth_user.c
1 int kerb_authenticate_user(request_rec *r) {
2         const char *name;               /* AuthName specified */
3         const char *type;               /* AuthType specified */
4         int KerberosV5 = 0;             /* Kerberos V5 check enabled */
5         int KerberosV4 = 0;             /* Kerberos V4 check enabled */
6         int KerberosV4first = 0;        /* Kerberos V4 check first */
7         const char *sent_pw;            /* Password sent by browser */
8         const char *t;                  /* Return value holder */
9         int res;                        /* Response holder */
10         int retcode;                    /* Return code holder */
11
12         kerb_auth_config *conf =
13                 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
14                                         &kerb_auth_module);
15
16         const char *auth_line = apr_table_get(r->headers_in,
17                                         (PROXYREQ_PROXY == r->proxyreq)
18                                                 ? "Proxy-Authorization"
19                                                 : "Authorization");
20
21         type = ap_auth_type(r);
22
23         if (type != NULL) {
24 #ifdef KRB5
25                 if ((strncasecmp(type, "KerberosV5", 10) == 0) ||
26                     (strncasecmp(conf->krb_auth_type, "KerberosV5", 10) == 0)) {
27                         KerberosV5 = 1;
28                 }
29 #endif /* KRB5 */
30
31 #ifdef KRB4
32                 if ((strncasecmp(type, "KerberosV4", 10) == 0) ||
33                     (strncasecmp(conf->krb_auth_type, "KerberosV4", 10) == 0)) {
34                         KerberosV4 = 1;
35                 }
36 #endif /* KRB4 */
37
38 #if defined(KRB5) && defined(KRB4)
39                 if ((strncasecmp(type, "KerberosDualV5V4", 15) == 0) ||
40                     (strncasecmp(conf->krb_auth_type, "KerberosDualV5V4", 15) == 0)) {
41                         KerberosV5 = 1;
42                         KerberosV4 = 1;
43                 }
44
45                 if ((strncasecmp(type, "KerberosDualV4V5", 15) == 0) ||
46                     (strncasecmp(conf->krb_auth_type, "KerberosDualV4V5", 15) == 0)) {
47                         KerberosV5 = 1;
48                         KerberosV4 = 1;
49                         KerberosV4first = 1;
50                 }
51 #endif /* KRB5 && KRB4 */
52         }
53
54         if (!KerberosV4 && !KerberosV5) {
55                 if (conf->krb_authoritative) {
56                         return HTTP_UNAUTHORIZED;
57                 }
58                 else {
59                         return DECLINED;
60                 }
61         }
62
63         name = ap_auth_name(r);
64         if (!name) {
65                 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
66                         0, r, "need AuthName: %s", r->uri);
67                 return HTTP_INTERNAL_SERVER_ERROR;
68         }
69
70         if (!auth_line) {
71                 apr_table_set(r->err_headers_out, "WWW-Authenticate",
72                         (char *)apr_pstrcat(r->pool, "Basic realm=\"", name, "\"", NULL));
73                 return HTTP_UNAUTHORIZED;
74         }
75
76         type = ap_getword_white(r->pool, &auth_line);
77         t = ap_pbase64decode(r->pool, auth_line);
78         r->user = ap_getword_nulls(r->pool, &t, ':');
79         r->ap_auth_type = "Kerberos";
80         sent_pw = ap_getword_white(r->pool, &t);
81
82         retcode = DECLINED;
83
84 #ifdef KRB5
85         if (KerberosV5 && !KerberosV4first && retcode != OK) {
86                 r->ap_auth_type = "KerberosV5";
87                 if (kerb5_password_validate(r->user, sent_pw)) {
88                         retcode = OK;
89                 }
90                 else {
91                         retcode = conf->krb_fail_status;
92                 }
93         }
94 #endif /* KRB5 */
95
96 #ifdef KRB4
97         if (KerberosV4 && retcode != OK) {
98                 r->ap_auth_type = "KerberosV4";
99                 if (kerb4_password_validate(r->user, sent_pw)) {
100                         retcode = OK;
101                 }
102                 else {
103                         retcode = conf->krb_fail_status;
104                 }
105         }
106 #endif /* KRB4 */
107
108 #if defined(KRB5) && defined(KRB4)
109         if (KerberosV5 && KerberosV4first && retcode != OK) {
110                 r->ap_auth_type = "KerberosV5";
111                 if (kerb5_password_validate(r->user, sent_pw)) {
112                         retcode = OK;
113                 }
114                 else {
115                         retcode = conf->krb_fail_status;
116                 }
117         }
118 #endif /* KRB5 && KRB4 */
119
120         if (conf->krb_authoritative && retcode == DECLINED) {
121                 return HTTP_UNAUTHORIZED;
122         }
123         else {
124                 return retcode;
125         }
126 }