+ if (!mag_acquire_creds(req, cfg, desired_mechs,
+ cred_usage, &acquired_cred, NULL)) {
+ goto done;
+ }
+
+ if (auth_type == AUTH_TYPE_BASIC) {
+ if (cred_usage == GSS_C_BOTH) {
+ /* If GSS_C_BOTH is used then inquire_cred will return the client
+ * name instead of the SPN of the server credentials. Therefore we
+ * need to acquire a different set of credential setting
+ * GSS_C_ACCEPT explicitly */
+ if (!mag_acquire_creds(req, cfg, cfg->allowed_mechs,
+ GSS_C_ACCEPT, &server_cred, NULL)) {
+ goto done;
+ }
+ } else {
+ server_cred = acquired_cred;
+ }
+ maj = gss_inquire_cred(&min, server_cred, &server,
+ NULL, NULL, NULL);
+ if (GSS_ERROR(maj)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
+ "%s", mag_error(req, "gss_inquired_cred_() "
+ "failed", maj, min));
+ goto done;
+ }
+ if (server_cred != acquired_cred) {
+ gss_release_cred(&min, &server_cred);
+ }
+
+#ifdef HAVE_CRED_STORE
+ if (cfg->deleg_ccache_dir) {
+ /* delegate ourselves credentials so we store them as requested */
+ init_flags |= GSS_C_DELEG_FLAG;
+ }
+#endif
+
+ /* output and input are inverted here, this is intentional */
+ maj = gss_init_sec_context(&min, user_cred, &user_ctx, server,
+ GSS_C_NO_OID, init_flags, 300,
+ GSS_C_NO_CHANNEL_BINDINGS, &output,
+ NULL, &input, NULL, NULL);
+ if (GSS_ERROR(maj)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
+ "%s", mag_error(req, "gss_init_sec_context() "
+ "failed", maj, min));
+ goto done;
+ }
+ }
+
+ if (auth_type == AUTH_TYPE_NEGOTIATE &&
+ cfg->allowed_mechs != GSS_C_NO_OID_SET) {
+ maj = gss_set_neg_mechs(&min, acquired_cred, cfg->allowed_mechs);
+ if (GSS_ERROR(maj)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req, "%s",
+ mag_error(req, "gss_set_neg_mechs() failed",
+ maj, min));
+ goto done;
+ }
+ }