summaryrefslogtreecommitdiff
path: root/auth/auth_kerb_sspi.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth/auth_kerb_sspi.c')
-rw-r--r--auth/auth_kerb_sspi.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/auth/auth_kerb_sspi.c b/auth/auth_kerb_sspi.c
index db28ab1..ba023cb 100644
--- a/auth/auth_kerb_sspi.c
+++ b/auth/auth_kerb_sspi.c
@@ -14,6 +14,7 @@
*/
#include "auth_kerb.h"
+#include "serf.h"
#ifdef SERF_USE_SSPI
#include <apr.h>
@@ -22,6 +23,11 @@
#define SECURITY_WIN32
#include <sspi.h>
+/* SEC_E_MUTUAL_AUTH_FAILED is not defined in Windows Platform SDK 5.0. */
+#ifndef SEC_E_MUTUAL_AUTH_FAILED
+#define SEC_E_MUTUAL_AUTH_FAILED _HRESULT_TYPEDEF_(0x80090363L)
+#endif
+
struct serf__kerb_context_t
{
CredHandle sspi_credentials;
@@ -29,6 +35,45 @@ struct serf__kerb_context_t
BOOL initalized;
};
+/* Map SECURITY_STATUS from SSPI to APR error code. Some error codes mapped
+ * to our own codes and some to Win32 error codes:
+ * http://support.microsoft.com/kb/113996
+ */
+static apr_status_t
+map_sspi_status(SECURITY_STATUS sspi_status)
+{
+ switch(sspi_status)
+ {
+ case SEC_E_INSUFFICIENT_MEMORY:
+ return APR_FROM_OS_ERROR(ERROR_NO_SYSTEM_RESOURCES);
+ case SEC_E_INVALID_HANDLE:
+ return APR_FROM_OS_ERROR(ERROR_INVALID_HANDLE);
+ case SEC_E_UNSUPPORTED_FUNCTION:
+ return APR_FROM_OS_ERROR(ERROR_INVALID_FUNCTION);
+ case SEC_E_TARGET_UNKNOWN:
+ return APR_FROM_OS_ERROR(ERROR_BAD_NETPATH);
+ case SEC_E_INTERNAL_ERROR:
+ return APR_FROM_OS_ERROR(ERROR_INTERNAL_ERROR);
+ case SEC_E_SECPKG_NOT_FOUND:
+ case SEC_E_BAD_PKGID:
+ return APR_FROM_OS_ERROR(ERROR_NO_SUCH_PACKAGE);
+ case SEC_E_NO_IMPERSONATION:
+ return APR_FROM_OS_ERROR(ERROR_CANNOT_IMPERSONATE);
+ case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+ return APR_FROM_OS_ERROR(ERROR_NO_LOGON_SERVERS);
+ case SEC_E_UNTRUSTED_ROOT:
+ return APR_FROM_OS_ERROR(ERROR_TRUST_FAILURE);
+ case SEC_E_WRONG_PRINCIPAL:
+ return APR_FROM_OS_ERROR(ERROR_WRONG_TARGET_NAME);
+ case SEC_E_MUTUAL_AUTH_FAILED:
+ return APR_FROM_OS_ERROR(ERROR_MUTUAL_AUTH_FAILED);
+ case SEC_E_TIME_SKEW:
+ return APR_FROM_OS_ERROR(ERROR_TIME_SKEW);
+ default:
+ return SERF_ERROR_AUTHN_FAILED;
+ }
+}
+
/* Cleans the SSPI context object, when the pool used to create it gets
cleared or destroyed. */
static apr_status_t
@@ -81,7 +126,7 @@ serf__kerb_create_sec_context(serf__kerb_context_t **ctx_p,
&ctx->sspi_credentials, NULL);
if (FAILED(sspi_status)) {
- return APR_EGENERAL;
+ return map_sspi_status(sspi_status);
}
*ctx_p = ctx;
@@ -116,6 +161,19 @@ get_canonical_hostname(const char **canonname,
}
apr_status_t
+serf__kerb_reset_sec_context(serf__kerb_context_t *ctx)
+{
+ if (SecIsValidHandle(&ctx->sspi_context)) {
+ DeleteSecurityContext(&ctx->sspi_context);
+ SecInvalidateHandle(&ctx->sspi_context);
+ }
+
+ ctx->initalized = FALSE;
+
+ return APR_SUCCESS;
+}
+
+apr_status_t
serf__kerb_init_sec_context(serf__kerb_context_t *ctx,
const char *service,
const char *hostname,
@@ -203,8 +261,8 @@ serf__kerb_init_sec_context(serf__kerb_context_t *ctx,
return APR_SUCCESS;
default:
- return APR_EGENERAL;
+ return map_sspi_status(status);
}
}
-#endif /* SERF_USE_SSPI */ \ No newline at end of file
+#endif /* SERF_USE_SSPI */