lib/krb5_wrap/krb5_samba.c smb_krb5_s4u2self_send fallback to krb5_get_credentials_fo...
authorStefan Metzmacher <metze@samba.org>
Wed, 4 Dec 2019 13:34:16 +0000 (13:34 +0000)
committerStefan Metzmacher <metze@samba.org>
Thu, 6 Aug 2020 12:03:26 +0000 (14:03 +0200)
lib/krb5_wrap/krb5_samba.c

index 3f77b7db6487214e7b885a1cbb652aa8a029fc6f..a624432c87c10ed4cf699e09cc6ba1f33dd9f0b4 100644 (file)
@@ -4718,7 +4718,9 @@ static void smb_krb5_s4u2self_cleanup(struct tevent_req *req,
        }
 }
 
+#ifdef HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE
 static void smb_krb5_s4u2self_done(struct tevent_req *subreq);
+#endif
 
 struct tevent_req *smb_krb5_s4u2self_send(TALLOC_CTX *mem_ctx,
                                          struct tevent_context *ev,
@@ -4730,9 +4732,14 @@ struct tevent_req *smb_krb5_s4u2self_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req = NULL;
        struct smb_krb5_s4u2self_state *state = NULL;
-       struct tevent_req *subreq = NULL;
        NTSTATUS status;
        krb5_error_code k5ret;
+#ifdef HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE
+       struct tevent_req *subreq = NULL;
+#else /* NOT HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE */
+       krb5_creds *out_creds = NULL;
+#endif /* NOT HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE */
+
 
        req = tevent_req_create(mem_ctx, &state,
                                struct smb_krb5_s4u2self_state);
@@ -4756,14 +4763,6 @@ struct tevent_req *smb_krb5_s4u2self_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       k5ret = smb_krb5_parse_name(state->krb5_ctx,
-                                   state->impersonate_principal_str,
-                                   &state->impersonate_principal);
-       status = krb5_to_nt_status(k5ret);
-       if (tevent_req_nterror(req, status)) {
-               return tevent_req_post(req, ev);
-       }
-
        k5ret = krb5_cc_get_principal(state->krb5_ctx,
                                      state->service_ccache,
                                      &state->in_creds.client);
@@ -4790,6 +4789,7 @@ struct tevent_req *smb_krb5_s4u2self_send(TALLOC_CTX *mem_ctx,
                }
        }
 
+#ifdef HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE
        k5ret = krb5_tkt_creds_init(state->krb5_ctx,
                                    state->service_ccache,
                                    &state->in_creds,
@@ -4802,14 +4802,10 @@ struct tevent_req *smb_krb5_s4u2self_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-#ifdef HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE
        k5ret = krb5_tkt_creds_set_impersonate(state->krb5_ctx,
                                               state->creds_ctx,
                                               state->impersonate_principal);
        status = krb5_to_nt_status(k5ret);
-#else
-       status = NT_STATUS_NO_S4U_PROT_SUPPORT;
-#endif
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
        }
@@ -4825,8 +4821,39 @@ struct tevent_req *smb_krb5_s4u2self_send(TALLOC_CTX *mem_ctx,
        tevent_req_set_callback(subreq, smb_krb5_s4u2self_done, req);
 
        return req;
+#else /* NOT HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE */
+       krb5_free_principal(state->krb5_ctx, state->in_creds.client);
+       k5ret = smb_krb5_parse_name(state->krb5_ctx,
+                                   state->impersonate_principal_str,
+                                   &state->in_creds.client);
+       status = krb5_to_nt_status(k5ret);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
+       k5ret = krb5_get_credentials_for_user(state->krb5_ctx,
+                                             KRB5_GC_CANONICALIZE |
+                                             KRB5_GC_FORWARDABLE |
+                                             KRB5_GC_NO_STORE,
+                                             state->service_ccache,
+                                             &state->in_creds,
+                                             NULL, /* krb5_data *subject_cert */
+                                             &out_creds);
+       status = krb5_to_nt_status(k5ret);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
+       state->out_creds = *out_creds;
+       ZERO_STRUCTP(out_creds);
+       krb5_free_creds(state->krb5_ctx, out_creds);
+
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
+#endif /* NOT HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE */
 }
 
+#ifdef HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE
 static void smb_krb5_s4u2self_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
@@ -4854,6 +4881,7 @@ static void smb_krb5_s4u2self_done(struct tevent_req *subreq)
 
        tevent_req_done(req);
 }
+#endif /* HAVE_KRB5_TKT_CREDS_SET_IMPERSONATE */
 
 NTSTATUS smb_krb5_s4u2self_recv(struct tevent_req *req,
                                krb5_creds *creds)