Added support for fail_status and authkerberos options.
[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                 return DECLINED;
56         }
57
58         name = ap_auth_name(r);
59         if (!name) {
60                 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
61                         0, r, "need AuthName: %s", r->uri);
62                 return HTTP_INTERNAL_SERVER_ERROR;
63         }
64
65         if (!auth_line) {
66                 apr_table_set(r->err_headers_out, "WWW-Authenticate",
67                         (char *)apr_pstrcat(r->pool, "Basic realm=\"", name, "\"", NULL));
68                 return HTTP_UNAUTHORIZED;
69         }
70
71         type = ap_getword_white(r->pool, &auth_line);
72         t = ap_pbase64decode(r->pool, auth_line);
73         r->user = ap_getword_nulls(r->pool, &t, ':');
74         r->ap_auth_type = "Kerberos";
75         sent_pw = ap_getword_white(r->pool, &t);
76
77         retcode = DECLINED;
78
79 #ifdef KRB5
80         if (KerberosV5 && !KerberosV4first && retcode != OK) {
81                 r->ap_auth_type = "KerberosV5";
82                 if (kerb5_password_validate(r->user, sent_pw)) {
83                         retcode = OK;
84                 }
85                 else {
86                         retcode = conf->krb_fail_status;
87                 }
88         }
89 #endif /* KRB5 */
90
91 #ifdef KRB4
92         if (KerberosV4 && retcode != OK) {
93                 r->ap_auth_type = "KerberosV4";
94                 if (kerb4_password_validate(r->user, sent_pw)) {
95                         retcode = OK;
96                 }
97                 else {
98                         retcode = conf->krb_fail_status;
99                 }
100         }
101 #endif /* KRB4 */
102
103 #if defined(KRB5) && defined(KRB4)
104         if (KerberosV5 && KerberosV4first && retcode != OK) {
105                 r->ap_auth_type = "KerberosV5";
106                 if (kerb5_password_validate(r->user, sent_pw)) {
107                         retcode = OK;
108                 }
109                 else {
110                         retcode = conf->krb_fail_status;
111                 }
112         }
113 #endif /* KRB5 && KRB4 */
114
115         return retcode;
116 }