/[smeserver]/rpms/samba/sme10/samba-v4-6-fix-cross-realm-refferals.patch
ViewVC logotype

Annotation of /rpms/samba/sme10/samba-v4-6-fix-cross-realm-refferals.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (hide annotations) (download)
Wed Aug 9 04:48:48 2023 UTC (10 months, 1 week ago) by jpp
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
FILE REMOVED
Initial import

1 jpp 1.1 From 76aae7405595ca76bc0419a97f4a69e0ed528b32 Mon Sep 17 00:00:00 2001
2     From: Stefan Metzmacher <metze@samba.org>
3     Date: Thu, 29 Dec 2016 14:00:36 +0100
4     Subject: [PATCH 01/20] s4:gensec_gssapi: the value
5     gensec_get_target_principal() should overwrite gensec_get_target_hostname()
6    
7     If gensec_get_target_principal() has a value, we no longer have to verify
8     the gensec_get_target_hostname() value, it can be just an ipadress.
9    
10     Signed-off-by: Stefan Metzmacher <metze@samba.org>
11     Reviewed-by: Andreas Schneider <asn@samba.org>
12     (cherry picked from commit 48bcca566ebb3a5385b15b0525d7fbdd06361e04)
13     ---
14     source4/auth/gensec/gensec_gssapi.c | 24 ++++++++++++++++++------
15     1 file changed, 18 insertions(+), 6 deletions(-)
16    
17     diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
18     index a6c4019aa6f..3974c3d42a0 100644
19     --- a/source4/auth/gensec/gensec_gssapi.c
20     +++ b/source4/auth/gensec/gensec_gssapi.c
21     @@ -307,7 +307,15 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
22     gss_buffer_desc name_token;
23     gss_OID name_type;
24     OM_uint32 maj_stat, min_stat;
25     + const char *target_principal = NULL;
26     const char *hostname = gensec_get_target_hostname(gensec_security);
27     + const char *service = gensec_get_target_service(gensec_security);
28     + const char *realm = cli_credentials_get_realm(creds);
29     +
30     + target_principal = gensec_get_target_principal(gensec_security);
31     + if (target_principal != NULL) {
32     + goto do_start;
33     + }
34    
35     if (!hostname) {
36     DEBUG(3, ("No hostname for target computer passed in, cannot use kerberos for this connection\n"));
37     @@ -322,6 +330,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
38     return NT_STATUS_INVALID_PARAMETER;
39     }
40    
41     +do_start:
42     +
43     nt_status = gensec_gssapi_start(gensec_security);
44     if (!NT_STATUS_IS_OK(nt_status)) {
45     return nt_status;
46     @@ -333,16 +343,18 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
47     gensec_gssapi_state->gss_want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
48     }
49    
50     - gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
51     - if (gensec_gssapi_state->target_principal) {
52     + if (target_principal != NULL) {
53     name_type = GSS_C_NULL_OID;
54     } else {
55     - gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
56     - gensec_get_target_service(gensec_security),
57     - hostname, cli_credentials_get_realm(creds));
58     -
59     + target_principal = talloc_asprintf(gensec_gssapi_state,
60     + "%s/%s@%s", service, hostname, realm);
61     + if (target_principal == NULL) {
62     + return NT_STATUS_NO_MEMORY;
63     + }
64     name_type = GSS_C_NT_USER_NAME;
65     }
66     + gensec_gssapi_state->target_principal = target_principal;
67     +
68     name_token.value = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
69     name_token.length = strlen(gensec_gssapi_state->target_principal);
70    
71     --
72     2.12.0
73    
74    
75     From 12d74cd165db3603ba2f3a58343e9a82fb22ee93 Mon Sep 17 00:00:00 2001
76     From: Stefan Metzmacher <metze@samba.org>
77     Date: Thu, 29 Dec 2016 15:20:00 +0100
78     Subject: [PATCH 02/20] s4:gensec_gssapi: require a realm in
79     gensec_gssapi_client_start()
80    
81     Signed-off-by: Stefan Metzmacher <metze@samba.org>
82     Reviewed-by: Andreas Schneider <asn@samba.org>
83     (cherry picked from commit 3a870baee8d9dbe5359f04a108814afc27e57d46)
84     ---
85     source4/auth/gensec/gensec_gssapi.c | 10 ++++++++++
86     1 file changed, 10 insertions(+)
87    
88     diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
89     index 3974c3d42a0..957cfa4229d 100644
90     --- a/source4/auth/gensec/gensec_gssapi.c
91     +++ b/source4/auth/gensec/gensec_gssapi.c
92     @@ -330,6 +330,16 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
93     return NT_STATUS_INVALID_PARAMETER;
94     }
95    
96     + if (realm == NULL) {
97     + const char *cred_name = cli_credentials_get_unparsed_name(creds,
98     + gensec_security);
99     + DEBUG(3, ("cli_credentials(%s) without realm, "
100     + "cannot use kerberos for this connection %s/%s\n",
101     + cred_name, service, hostname));
102     + talloc_free(discard_const_p(char, cred_name));
103     + return NT_STATUS_INVALID_PARAMETER;
104     + }
105     +
106     do_start:
107    
108     nt_status = gensec_gssapi_start(gensec_security);
109     --
110     2.12.0
111    
112    
113     From beb9e4379333872ff1e5a3422ba70ccb409e9915 Mon Sep 17 00:00:00 2001
114     From: Andreas Schneider <asn@samba.org>
115     Date: Mon, 6 Mar 2017 09:13:09 +0100
116     Subject: [PATCH 03/20] testprogs: Use smbclient by default in
117     test_kinit_trusts
118    
119     This is the tool we use by default and we should test with it.
120    
121     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
122    
123     Signed-off-by: Andreas Schneider <asn@samba.org>
124     Reviewed-by: Stefan Metzmacher <metze@samba.org>
125     (cherry picked from commit 9b3ff90dbc5cc1017dfc89831a1081272e6c2356)
126     ---
127     testprogs/blackbox/test_kinit_trusts_heimdal.sh | 2 +-
128     1 file changed, 1 insertion(+), 1 deletion(-)
129    
130     diff --git a/testprogs/blackbox/test_kinit_trusts_heimdal.sh b/testprogs/blackbox/test_kinit_trusts_heimdal.sh
131     index 073e0e7517e..040bf919203 100755
132     --- a/testprogs/blackbox/test_kinit_trusts_heimdal.sh
133     +++ b/testprogs/blackbox/test_kinit_trusts_heimdal.sh
134     @@ -32,7 +32,7 @@ if test -x $samba4bindir/samba4kinit; then
135     samba4kinit=$samba4bindir/samba4kinit
136     fi
137    
138     -smbclient="$samba4bindir/smbclient4"
139     +smbclient="$samba4bindir/smbclient"
140     wbinfo="$samba4bindir/wbinfo"
141     rpcclient="$samba4bindir/rpcclient"
142     samba_tool="$samba4bindir/samba-tool"
143     --
144     2.12.0
145    
146    
147     From 7feebdec869ed633bea612630ebca8d9b85a3e2e Mon Sep 17 00:00:00 2001
148     From: Andreas Schneider <asn@samba.org>
149     Date: Mon, 6 Mar 2017 09:15:45 +0100
150     Subject: [PATCH 04/20] testprogs: Add kinit_trusts tests with smbclient4
151    
152     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
153    
154     Signed-off-by: Andreas Schneider <asn@samba.org>
155     Reviewed-by: Stefan Metzmacher <metze@samba.org>
156     (cherry picked from commit 42bd003f468ab95b6ac97c774e2cd217d06c05ed)
157     ---
158     testprogs/blackbox/test_kinit_trusts_heimdal.sh | 8 ++++++++
159     1 file changed, 8 insertions(+)
160    
161     diff --git a/testprogs/blackbox/test_kinit_trusts_heimdal.sh b/testprogs/blackbox/test_kinit_trusts_heimdal.sh
162     index 040bf919203..e67f77361a4 100755
163     --- a/testprogs/blackbox/test_kinit_trusts_heimdal.sh
164     +++ b/testprogs/blackbox/test_kinit_trusts_heimdal.sh
165     @@ -52,8 +52,16 @@ rm -rf $KRB5CCNAME_PATH
166     echo $TRUST_PASSWORD > $PREFIX/tmppassfile
167     testit "kinit with password" $samba4kinit $enctype --password-file=$PREFIX/tmppassfile --request-pac $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
168     test_smbclient "Test login with user kerberos ccache" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
169     +rm -rf $KRB5CCNAME_PATH
170     +
171     +# Test with smbclient4
172     +smbclient="$samba4bindir/smbclient4"
173     +testit "kinit with password" $samba4kinit $enctype --password-file=$PREFIX/tmppassfile --request-pac $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
174     +test_smbclient "Test login with user kerberos ccache (smbclient4)" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
175     +rm -rf $KRB5CCNAME_PATH
176    
177     testit "kinit with password (enterprise style)" $samba4kinit $enctype --enterprise --password-file=$PREFIX/tmppassfile --request-pac $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
178     +smbclient="$samba4bindir/smbclient"
179     test_smbclient "Test login with user kerberos ccache" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
180    
181     if test x"${TYPE}" = x"forest" ;then
182     --
183     2.12.0
184    
185    
186     From cae7475df03e7d464dc8642a7a02dad388215d1e Mon Sep 17 00:00:00 2001
187     From: Andreas Schneider <asn@samba.org>
188     Date: Wed, 8 Mar 2017 10:40:08 +0100
189     Subject: [PATCH 05/20] krb5_wrap: Do not return an empty realm from
190     smb_krb5_get_realm_from_hostname()
191    
192     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
193    
194     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
195    
196     Signed-off-by: Andreas Schneider <asn@samba.org>
197     Signed-off-by: Stefan Metzmacher <metze@samba.org>
198     (cherry picked from commit 946f9dd1170be63b91e31ce825ea123f3c07329b)
199     ---
200     lib/krb5_wrap/krb5_samba.c | 4 +++-
201     1 file changed, 3 insertions(+), 1 deletion(-)
202    
203     diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
204     index 10b42dec53f..9dc7304d566 100644
205     --- a/lib/krb5_wrap/krb5_samba.c
206     +++ b/lib/krb5_wrap/krb5_samba.c
207     @@ -2691,7 +2691,9 @@ static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
208     goto out;
209     }
210    
211     - if (realm_list && realm_list[0]) {
212     + if (realm_list != NULL &&
213     + realm_list[0] != NULL &&
214     + realm_list[0][0] != '\0') {
215     realm = talloc_strdup(mem_ctx, realm_list[0]);
216     }
217    
218     --
219     2.12.0
220    
221    
222     From 1d2b4a00e2a1213df81192e01f2d833ed4a6ec54 Mon Sep 17 00:00:00 2001
223     From: Andreas Schneider <asn@samba.org>
224     Date: Wed, 8 Mar 2017 10:48:52 +0100
225     Subject: [PATCH 06/20] krb5_wrap: Try to guess the correct realm from the
226     service hostname
227    
228     If we do not get a realm mapping from the krb5.conf or from the Kerberos
229     library try to guess it from the service hostname. The guessing of the
230     realm from the service hostname is already implemented in Heimdal. This
231     makes the behavior of smb_krb5_get_realm_from_hostname() consistent
232     with both MIT and Heimdal.
233    
234     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
235    
236     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
237    
238     Signed-off-by: Andreas Schneider <asn@samba.org>
239     Signed-off-by: Stefan Metzmacher <metze@samba.org>
240     (cherry picked from commit 65228925ab3c4da4ae299f77cae219fc7d37cc68)
241     ---
242     lib/krb5_wrap/krb5_samba.c | 13 +++++++++++++
243     1 file changed, 13 insertions(+)
244    
245     diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
246     index 9dc7304d566..f8ef9f1df0f 100644
247     --- a/lib/krb5_wrap/krb5_samba.c
248     +++ b/lib/krb5_wrap/krb5_samba.c
249     @@ -2695,6 +2695,19 @@ static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
250     realm_list[0] != NULL &&
251     realm_list[0][0] != '\0') {
252     realm = talloc_strdup(mem_ctx, realm_list[0]);
253     + } else {
254     + const char *p = NULL;
255     +
256     + /*
257     + * "dc6.samba2003.example.com"
258     + * returns a realm of "SAMBA2003.EXAMPLE.COM"
259     + *
260     + * "dc6." returns realm as NULL
261     + */
262     + p = strchr_m(hostname, '.');
263     + if (p != NULL && p[1] != '\0') {
264     + realm = talloc_strdup_upper(mem_ctx, p + 1);
265     + }
266     }
267    
268     out:
269     --
270     2.12.0
271    
272    
273     From 0e99683587c9047055ca6432fae0a11604710b69 Mon Sep 17 00:00:00 2001
274     From: Andreas Schneider <asn@samba.org>
275     Date: Wed, 8 Mar 2017 11:56:30 +0100
276     Subject: [PATCH 07/20] krb5_wrap: pass client_realm to
277     smb_krb5_get_realm_from_hostname()
278    
279     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
280    
281     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
282    
283     Signed-off-by: Andreas Schneider <asn@samba.org>
284     Signed-off-by: Stefan Metzmacher <metze@samba.org>
285     (cherry picked from commit f0c4fcace586197d5c170f6a9dcc175df23e3802)
286     ---
287     lib/krb5_wrap/krb5_samba.c | 16 ++++++++++++++--
288     1 file changed, 14 insertions(+), 2 deletions(-)
289    
290     diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
291     index f8ef9f1df0f..36bcc65e22a 100644
292     --- a/lib/krb5_wrap/krb5_samba.c
293     +++ b/lib/krb5_wrap/krb5_samba.c
294     @@ -2664,7 +2664,8 @@ static char *smb_krb5_get_default_realm_from_ccache(TALLOC_CTX *mem_ctx)
295     ************************************************************************/
296    
297     static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
298     - const char *hostname)
299     + const char *hostname,
300     + const char *client_realm)
301     {
302     #if defined(HAVE_KRB5_REALM_TYPE)
303     /* Heimdal. */
304     @@ -2695,6 +2696,9 @@ static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
305     realm_list[0] != NULL &&
306     realm_list[0][0] != '\0') {
307     realm = talloc_strdup(mem_ctx, realm_list[0]);
308     + if (realm == NULL) {
309     + goto out;
310     + }
311     } else {
312     const char *p = NULL;
313    
314     @@ -2707,9 +2711,16 @@ static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
315     p = strchr_m(hostname, '.');
316     if (p != NULL && p[1] != '\0') {
317     realm = talloc_strdup_upper(mem_ctx, p + 1);
318     + if (realm == NULL) {
319     + goto out;
320     + }
321     }
322     }
323    
324     + if (realm == NULL) {
325     + realm = talloc_strdup(mem_ctx, client_realm);
326     + }
327     +
328     out:
329    
330     if (ctx) {
331     @@ -2752,7 +2763,8 @@ char *smb_krb5_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
332     if (host) {
333     /* DNS name. */
334     realm = smb_krb5_get_realm_from_hostname(talloc_tos(),
335     - remote_name);
336     + remote_name,
337     + default_realm);
338     } else {
339     /* NetBIOS name - use our realm. */
340     realm = smb_krb5_get_default_realm_from_ccache(talloc_tos());
341     --
342     2.12.0
343    
344    
345     From 6876b0d12f8aad4448f4a7d770db7ff129df6c50 Mon Sep 17 00:00:00 2001
346     From: Andreas Schneider <asn@samba.org>
347     Date: Wed, 8 Mar 2017 11:56:30 +0100
348     Subject: [PATCH 08/20] krb5_wrap: Make smb_krb5_get_realm_from_hostname()
349     public
350    
351     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
352    
353     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
354    
355     Signed-off-by: Andreas Schneider <asn@samba.org>
356     Signed-off-by: Stefan Metzmacher <metze@samba.org>
357     (cherry picked from commit 339a2ecb3f05d0c9e860a5dd59b8bdbc51d4ffa7)
358     ---
359     lib/krb5_wrap/krb5_samba.c | 28 +++++++++++++++++++++-------
360     lib/krb5_wrap/krb5_samba.h | 4 ++++
361     2 files changed, 25 insertions(+), 7 deletions(-)
362    
363     diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
364     index 36bcc65e22a..2b0ec6bfa0e 100644
365     --- a/lib/krb5_wrap/krb5_samba.c
366     +++ b/lib/krb5_wrap/krb5_samba.c
367     @@ -2659,13 +2659,27 @@ static char *smb_krb5_get_default_realm_from_ccache(TALLOC_CTX *mem_ctx)
368     return realm;
369     }
370    
371     -/************************************************************************
372     - Routine to get the realm from a given DNS name.
373     -************************************************************************/
374     -
375     -static char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
376     - const char *hostname,
377     - const char *client_realm)
378     +/**
379     + * @brief Get the realm from the service hostname.
380     + *
381     + * This function will look for a domain realm mapping in the [domain_realm]
382     + * section of the krb5.conf first and fallback to extract the realm from
383     + * the provided service hostname. As a last resort it will return the
384     + * provided client_realm.
385     + *
386     + * @param[in] mem_ctx The talloc context
387     + *
388     + * @param[in] hostname The service hostname
389     + *
390     + * @param[in] client_realm If we can not find a mapping, fall back to
391     + * this realm.
392     + *
393     + * @return The realm to use for the service hostname, NULL if a fatal error
394     + * occured.
395     + */
396     +char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
397     + const char *hostname,
398     + const char *client_realm)
399     {
400     #if defined(HAVE_KRB5_REALM_TYPE)
401     /* Heimdal. */
402     diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
403     index 71e81ea26e1..accae449a0e 100644
404     --- a/lib/krb5_wrap/krb5_samba.h
405     +++ b/lib/krb5_wrap/krb5_samba.h
406     @@ -314,6 +314,10 @@ krb5_error_code smb_krb5_principal_set_realm(krb5_context context,
407     krb5_principal principal,
408     const char *realm);
409    
410     +char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
411     + const char *hostname,
412     + const char *client_realm);
413     +
414     char *smb_krb5_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
415     const char *service,
416     const char *remote_name,
417     --
418     2.12.0
419    
420    
421     From 08a81c315129c3d07637a8a5064b4ef988864efd Mon Sep 17 00:00:00 2001
422     From: Andreas Schneider <asn@samba.org>
423     Date: Mon, 6 Mar 2017 09:19:13 +0100
424     Subject: [PATCH 09/20] s4:gensec-gssapi: Create a helper function to setup
425     server_principal
426    
427     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
428    
429     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
430    
431     Signed-off-by: Andreas Schneider <asn@samba.org>
432     Signed-off-by: Stefan Metzmacher <metze@samba.org>
433     (cherry picked from commit 8f7c4529420316b553c80cd3d19b6996525b029a)
434     ---
435     source4/auth/gensec/gensec_gssapi.c | 88 +++++++++++++++++++++++++------------
436     source4/auth/gensec/gensec_gssapi.h | 2 +-
437     2 files changed, 61 insertions(+), 29 deletions(-)
438    
439     diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
440     index 957cfa4229d..ec57d193714 100644
441     --- a/source4/auth/gensec/gensec_gssapi.c
442     +++ b/source4/auth/gensec/gensec_gssapi.c
443     @@ -83,6 +83,56 @@ static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_st
444     return 0;
445     }
446    
447     +static NTSTATUS gensec_gssapi_setup_server_principal(TALLOC_CTX *mem_ctx,
448     + const char *target_principal,
449     + const char *service,
450     + const char *hostname,
451     + const char *realm,
452     + const gss_OID mech,
453     + char **pserver_principal,
454     + gss_name_t *pserver_name)
455     +{
456     + char *server_principal = NULL;
457     + gss_buffer_desc name_token;
458     + gss_OID name_type;
459     + OM_uint32 maj_stat, min_stat = 0;
460     +
461     + if (target_principal != NULL) {
462     + server_principal = talloc_strdup(mem_ctx, target_principal);
463     + name_type = GSS_C_NULL_OID;
464     + } else {
465     + server_principal = talloc_asprintf(mem_ctx,
466     + "%s/%s@%s",
467     + service, hostname, realm);
468     + name_type = GSS_C_NT_USER_NAME;
469     + }
470     + if (server_principal == NULL) {
471     + return NT_STATUS_NO_MEMORY;
472     + }
473     +
474     + name_token.value = (uint8_t *)server_principal;
475     + name_token.length = strlen(server_principal);
476     +
477     + maj_stat = gss_import_name(&min_stat,
478     + &name_token,
479     + name_type,
480     + pserver_name);
481     + if (maj_stat) {
482     + DBG_WARNING("GSS Import name of %s failed: %s\n",
483     + server_principal,
484     + gssapi_error_string(mem_ctx,
485     + maj_stat,
486     + min_stat,
487     + mech));
488     + TALLOC_FREE(server_principal);
489     + return NT_STATUS_INVALID_PARAMETER;
490     + }
491     +
492     + *pserver_principal = server_principal;
493     +
494     + return NT_STATUS_OK;
495     +}
496     +
497     static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
498     {
499     struct gensec_gssapi_state *gensec_gssapi_state;
500     @@ -304,9 +354,6 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
501     struct gensec_gssapi_state *gensec_gssapi_state;
502     struct cli_credentials *creds = gensec_get_credentials(gensec_security);
503     NTSTATUS nt_status;
504     - gss_buffer_desc name_token;
505     - gss_OID name_type;
506     - OM_uint32 maj_stat, min_stat;
507     const char *target_principal = NULL;
508     const char *hostname = gensec_get_target_hostname(gensec_security);
509     const char *service = gensec_get_target_service(gensec_security);
510     @@ -353,31 +400,16 @@ do_start:
511     gensec_gssapi_state->gss_want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
512     }
513    
514     - if (target_principal != NULL) {
515     - name_type = GSS_C_NULL_OID;
516     - } else {
517     - target_principal = talloc_asprintf(gensec_gssapi_state,
518     - "%s/%s@%s", service, hostname, realm);
519     - if (target_principal == NULL) {
520     - return NT_STATUS_NO_MEMORY;
521     - }
522     - name_type = GSS_C_NT_USER_NAME;
523     - }
524     - gensec_gssapi_state->target_principal = target_principal;
525     -
526     - name_token.value = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
527     - name_token.length = strlen(gensec_gssapi_state->target_principal);
528     -
529     -
530     - maj_stat = gss_import_name (&min_stat,
531     - &name_token,
532     - name_type,
533     - &gensec_gssapi_state->server_name);
534     - if (maj_stat) {
535     - DEBUG(2, ("GSS Import name of %s failed: %s\n",
536     - (char *)name_token.value,
537     - gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
538     - return NT_STATUS_INVALID_PARAMETER;
539     + nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state,
540     + target_principal,
541     + service,
542     + hostname,
543     + realm,
544     + gensec_gssapi_state->gss_oid,
545     + &gensec_gssapi_state->target_principal,
546     + &gensec_gssapi_state->server_name);
547     + if (!NT_STATUS_IS_OK(nt_status)) {
548     + return nt_status;
549     }
550    
551     return NT_STATUS_OK;
552     diff --git a/source4/auth/gensec/gensec_gssapi.h b/source4/auth/gensec/gensec_gssapi.h
553     index cf0e3a8d914..d788b5ebc38 100644
554     --- a/source4/auth/gensec/gensec_gssapi.h
555     +++ b/source4/auth/gensec/gensec_gssapi.h
556     @@ -65,5 +65,5 @@ struct gensec_gssapi_state {
557     int gss_exchange_count;
558     size_t sig_size;
559    
560     - const char *target_principal;
561     + char *target_principal;
562     };
563     --
564     2.12.0
565    
566    
567     From 78a76c53e9b0e7caf67a43eeb7929a4fe94fa25e Mon Sep 17 00:00:00 2001
568     From: Andreas Schneider <asn@samba.org>
569     Date: Wed, 8 Mar 2017 12:34:59 +0100
570     Subject: [PATCH 10/20] s4:gensec_gssapi: Move setup of service_principal to
571     update function
572    
573     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
574    
575     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
576    
577     Signed-off-by: Andreas Schneider <asn@samba.org>
578     Signed-off-by: Stefan Metzmacher <metze@samba.org>
579     (cherry picked from commit bf6358bf035e7ad48bd15cc2164afab2a19e7ad6)
580     ---
581     source4/auth/gensec/gensec_gssapi.c | 33 ++++++++++++++++++++-------------
582     1 file changed, 20 insertions(+), 13 deletions(-)
583    
584     diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
585     index ec57d193714..6cb4431e0d9 100644
586     --- a/source4/auth/gensec/gensec_gssapi.c
587     +++ b/source4/auth/gensec/gensec_gssapi.c
588     @@ -400,18 +400,6 @@ do_start:
589     gensec_gssapi_state->gss_want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
590     }
591    
592     - nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state,
593     - target_principal,
594     - service,
595     - hostname,
596     - realm,
597     - gensec_gssapi_state->gss_oid,
598     - &gensec_gssapi_state->target_principal,
599     - &gensec_gssapi_state->server_name);
600     - if (!NT_STATUS_IS_OK(nt_status)) {
601     - return nt_status;
602     - }
603     -
604     return NT_STATUS_OK;
605     }
606    
607     @@ -452,7 +440,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
608     OM_uint32 min_stat2;
609     gss_buffer_desc input_token = { 0, NULL };
610     gss_buffer_desc output_token = { 0, NULL };
611     -
612     + struct cli_credentials *cli_creds = gensec_get_credentials(gensec_security);
613     + const char *target_principal = gensec_get_target_principal(gensec_security);
614     + const char *hostname = gensec_get_target_hostname(gensec_security);
615     + const char *service = gensec_get_target_service(gensec_security);
616     + const char *client_realm = cli_credentials_get_realm(cli_creds);
617     gss_OID gss_oid_p = NULL;
618     OM_uint32 time_req = 0;
619     OM_uint32 time_rec = 0;
620     @@ -491,6 +483,21 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
621     return NT_STATUS_INTERNAL_ERROR;
622     }
623     #endif
624     +
625     + if (gensec_gssapi_state->server_name == NULL) {
626     + nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state,
627     + target_principal,
628     + service,
629     + hostname,
630     + client_realm,
631     + gensec_gssapi_state->gss_oid,
632     + &gensec_gssapi_state->target_principal,
633     + &gensec_gssapi_state->server_name);
634     + if (!NT_STATUS_IS_OK(nt_status)) {
635     + return nt_status;
636     + }
637     + }
638     +
639     maj_stat = gss_init_sec_context(&min_stat,
640     gensec_gssapi_state->client_cred->creds,
641     &gensec_gssapi_state->gssapi_context,
642     --
643     2.12.0
644    
645    
646     From 7541d4a3c1a665925c8d3aa97963729874c70761 Mon Sep 17 00:00:00 2001
647     From: Andreas Schneider <asn@samba.org>
648     Date: Wed, 8 Mar 2017 11:03:17 +0100
649     Subject: [PATCH 11/20] s4:gensec_gssapi: Use
650     smb_krb5_get_realm_from_hostname()
651    
652     With credentials for administrator@FOREST1.EXAMPLE.COM
653     this patch changes the target_principal for
654     the ldap service of host dc2.forest2.example.com
655     from
656    
657     ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
658    
659     to
660    
661     ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM
662    
663     Typically ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
664     should be used in order to allow the KDC of FOREST1.EXAMPLE.COM
665     to generate a referral ticket for
666     krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM.
667    
668     The problem is that KDCs only return such referral tickets
669     if there's a forest trust between FOREST1.EXAMPLE.COM
670     and FOREST2.EXAMPLE.COM. If there's only an external domain
671     trust between FOREST1.EXAMPLE.COM and FOREST2.EXAMPLE.COM
672     the KDC of FOREST1.EXAMPLE.COM will respond with S_PRINCIPAL_UNKNOWN
673     when being asked for ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM.
674    
675     In the case of an external trust the client can still ask
676     explicitly for krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM
677     and the KDC of FOREST1.EXAMPLE.COM will generate it.
678    
679     From there the client can use the
680     krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM
681     ticket and ask a KDC of FOREST2.EXAMPLE.COM for a
682     service ticket for ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM.
683    
684     With Heimdal we'll get the fallback on S_PRINCIPAL_UNKNOWN behavior
685     when we pass ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM as
686     target principal. As _krb5_get_cred_kdc_any() first calls
687     get_cred_kdc_referral() (which always starts with the client realm)
688     and falls back to get_cred_kdc_capath() (which starts with the given realm).
689    
690     MIT krb5 only tries the given realm of the target principal,
691     if we want to autodetect support for transitive forest trusts,
692     we'll have to do the fallback ourself.
693    
694     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
695    
696     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
697    
698     Signed-off-by: Andreas Schneider <asn@samba.org>
699     Signed-off-by: Stefan Metzmacher <metze@samba.org>
700     (cherry picked from commit 3781eb250173981a8890b82d1ff9358f144034cd)
701     ---
702     source4/auth/gensec/gensec_gssapi.c | 62 ++++++++++++++++++++++++++++++++++++-
703     1 file changed, 61 insertions(+), 1 deletion(-)
704    
705     diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
706     index 6cb4431e0d9..57392a04e60 100644
707     --- a/source4/auth/gensec/gensec_gssapi.c
708     +++ b/source4/auth/gensec/gensec_gssapi.c
709     @@ -445,6 +445,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
710     const char *hostname = gensec_get_target_hostname(gensec_security);
711     const char *service = gensec_get_target_service(gensec_security);
712     const char *client_realm = cli_credentials_get_realm(cli_creds);
713     + const char *server_realm = NULL;
714     gss_OID gss_oid_p = NULL;
715     OM_uint32 time_req = 0;
716     OM_uint32 time_rec = 0;
717     @@ -484,12 +485,71 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
718     }
719     #endif
720    
721     + /*
722     + * With credentials for
723     + * administrator@FOREST1.EXAMPLE.COM this patch changes
724     + * the target_principal for the ldap service of host
725     + * dc2.forest2.example.com from
726     + *
727     + * ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
728     + *
729     + * to
730     + *
731     + * ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM
732     + *
733     + * Typically
734     + * ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
735     + * should be used in order to allow the KDC of
736     + * FOREST1.EXAMPLE.COM to generate a referral ticket
737     + * for krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM.
738     + *
739     + * The problem is that KDCs only return such referral
740     + * tickets if there's a forest trust between
741     + * FOREST1.EXAMPLE.COM and FOREST2.EXAMPLE.COM. If
742     + * there's only an external domain trust between
743     + * FOREST1.EXAMPLE.COM and FOREST2.EXAMPLE.COM the KDC
744     + * of FOREST1.EXAMPLE.COM will respond with
745     + * S_PRINCIPAL_UNKNOWN when being asked for
746     + * ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM.
747     + *
748     + * In the case of an external trust the client can
749     + * still ask explicitly for
750     + * krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM and
751     + * the KDC of FOREST1.EXAMPLE.COM will generate it.
752     + *
753     + * From there the client can use the
754     + * krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM
755     + * ticket and ask a KDC of FOREST2.EXAMPLE.COM for a
756     + * service ticket for
757     + * ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM.
758     + *
759     + * With Heimdal we'll get the fallback on
760     + * S_PRINCIPAL_UNKNOWN behavior when we pass
761     + * ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM as
762     + * target principal. As _krb5_get_cred_kdc_any() first
763     + * calls get_cred_kdc_referral() (which always starts
764     + * with the client realm) and falls back to
765     + * get_cred_kdc_capath() (which starts with the given
766     + * realm).
767     + *
768     + * MIT krb5 only tries the given realm of the target
769     + * principal, if we want to autodetect support for
770     + * transitive forest trusts, would have to do the
771     + * fallback ourself.
772     + */
773     if (gensec_gssapi_state->server_name == NULL) {
774     + server_realm = smb_krb5_get_realm_from_hostname(gensec_gssapi_state,
775     + hostname,
776     + client_realm);
777     + if (server_realm == NULL) {
778     + return NT_STATUS_NO_MEMORY;
779     + }
780     +
781     nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state,
782     target_principal,
783     service,
784     hostname,
785     - client_realm,
786     + server_realm,
787     gensec_gssapi_state->gss_oid,
788     &gensec_gssapi_state->target_principal,
789     &gensec_gssapi_state->server_name);
790     --
791     2.12.0
792    
793    
794     From 97935a1164d328b466bc305c37869e78d306173a Mon Sep 17 00:00:00 2001
795     From: Andreas Schneider <asn@samba.org>
796     Date: Wed, 8 Mar 2017 13:10:05 +0100
797     Subject: [PATCH 12/20] s4:gensec_gssapi: Correctly handle external trusts with
798     MIT
799    
800     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
801    
802     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
803    
804     Signed-off-by: Andreas Schneider <asn@samba.org>
805     Signed-off-by: Stefan Metzmacher <metze@samba.org>
806     (cherry picked from commit 2dd4887648bf006a577e03fc027e881738ca04ab)
807     ---
808     source4/auth/gensec/gensec_gssapi.c | 51 +++++++++++++++++++++++++++++++++++++
809     1 file changed, 51 insertions(+)
810    
811     diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
812     index 57392a04e60..61911aae9d9 100644
813     --- a/source4/auth/gensec/gensec_gssapi.c
814     +++ b/source4/auth/gensec/gensec_gssapi.c
815     @@ -464,6 +464,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
816     switch (gensec_security->gensec_role) {
817     case GENSEC_CLIENT:
818     {
819     + bool fallback = false;
820     #ifdef SAMBA4_USES_HEIMDAL
821     struct gsskrb5_send_to_kdc send_to_kdc;
822     krb5_error_code ret;
823     @@ -537,6 +538,48 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
824     * transitive forest trusts, would have to do the
825     * fallback ourself.
826     */
827     +#ifndef SAMBA4_USES_HEIMDAL
828     + if (gensec_gssapi_state->server_name == NULL) {
829     + nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state,
830     + target_principal,
831     + service,
832     + hostname,
833     + client_realm,
834     + gensec_gssapi_state->gss_oid,
835     + &gensec_gssapi_state->target_principal,
836     + &gensec_gssapi_state->server_name);
837     + if (!NT_STATUS_IS_OK(nt_status)) {
838     + return nt_status;
839     + }
840     +
841     + maj_stat = gss_init_sec_context(&min_stat,
842     + gensec_gssapi_state->client_cred->creds,
843     + &gensec_gssapi_state->gssapi_context,
844     + gensec_gssapi_state->server_name,
845     + gensec_gssapi_state->gss_oid,
846     + gensec_gssapi_state->gss_want_flags,
847     + time_req,
848     + gensec_gssapi_state->input_chan_bindings,
849     + &input_token,
850     + &gss_oid_p,
851     + &output_token,
852     + &gensec_gssapi_state->gss_got_flags, /* ret flags */
853     + &time_rec);
854     + if (maj_stat != GSS_S_FAILURE) {
855     + goto init_sec_context_done;
856     + }
857     + if (min_stat != (OM_uint32)KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
858     + goto init_sec_context_done;
859     + }
860     + if (target_principal != NULL) {
861     + goto init_sec_context_done;
862     + }
863     +
864     + fallback = true;
865     + TALLOC_FREE(gensec_gssapi_state->target_principal);
866     + gss_release_name(&min_stat2, &gensec_gssapi_state->server_name);
867     + }
868     +#endif /* !SAMBA4_USES_HEIMDAL */
869     if (gensec_gssapi_state->server_name == NULL) {
870     server_realm = smb_krb5_get_realm_from_hostname(gensec_gssapi_state,
871     hostname,
872     @@ -545,6 +588,11 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
873     return NT_STATUS_NO_MEMORY;
874     }
875    
876     + if (fallback &&
877     + strequal(client_realm, server_realm)) {
878     + goto init_sec_context_done;
879     + }
880     +
881     nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state,
882     target_principal,
883     service,
884     @@ -571,6 +619,9 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
885     &output_token,
886     &gensec_gssapi_state->gss_got_flags, /* ret flags */
887     &time_rec);
888     + goto init_sec_context_done;
889     + /* JUMP! */
890     +init_sec_context_done:
891     if (gss_oid_p) {
892     gensec_gssapi_state->gss_oid = gss_oid_p;
893     }
894     --
895     2.12.0
896    
897    
898     From 71a49b84ebb8d45d91d21ebf92d3c7302b24f490 Mon Sep 17 00:00:00 2001
899     From: Andreas Schneider <asn@samba.org>
900     Date: Thu, 9 Mar 2017 07:54:29 +0100
901     Subject: [PATCH 13/20] s3:gse: Use smb_krb5_get_realm_from_hostname()
902    
903     With credentials for administrator@FOREST1.EXAMPLE.COM
904     this patch changes the target_principal for
905     the ldap service of host dc2.forest2.example.com
906     from
907    
908     ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
909    
910     to
911    
912     ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM
913    
914     Typically ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
915     should be used in order to allow the KDC of FOREST1.EXAMPLE.COM
916     to generate a referral ticket for
917     krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM.
918    
919     The problem is that KDCs only return such referral tickets
920     if there's a forest trust between FOREST1.EXAMPLE.COM
921     and FOREST2.EXAMPLE.COM. If there's only an external domain
922     trust between FOREST1.EXAMPLE.COM and FOREST2.EXAMPLE.COM
923     the KDC of FOREST1.EXAMPLE.COM will respond with S_PRINCIPAL_UNKNOWN
924     when being asked for ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM.
925    
926     In the case of an external trust the client can still ask
927     explicitly for krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM
928     and the KDC of FOREST1.EXAMPLE.COM will generate it.
929    
930     From there the client can use the
931     krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM
932     ticket and ask a KDC of FOREST2.EXAMPLE.COM for a
933     service ticket for ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM.
934    
935     With Heimdal we'll get the fallback on S_PRINCIPAL_UNKNOWN behavior
936     when we pass ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM as
937     target principal. As _krb5_get_cred_kdc_any() first calls
938     get_cred_kdc_referral() (which always starts with the client realm)
939     and falls back to get_cred_kdc_capath() (which starts with the given realm).
940    
941     MIT krb5 only tries the given realm of the target principal,
942     if we want to autodetect support for transitive forest trusts,
943     we'll have to do the fallback ourself.
944    
945     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
946    
947     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
948    
949     Signed-off-by: Andreas Schneider <asn@samba.org>
950     Signed-off-by: Stefan Metzmacher <metze@samba.org>
951     (cherry picked from commit a3d95ed9037fb8b14a451da02dcadf011485ae34)
952     ---
953     source3/librpc/crypto/gse.c | 93 +++++++++++++++++++++++++++++++++------------
954     1 file changed, 68 insertions(+), 25 deletions(-)
955    
956     diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
957     index abf20bc7dfd..57632f6cc8f 100644
958     --- a/source3/librpc/crypto/gse.c
959     +++ b/source3/librpc/crypto/gse.c
960     @@ -120,6 +120,54 @@ static int gse_context_destructor(void *ptr)
961     return 0;
962     }
963    
964     +static NTSTATUS gse_setup_server_principal(TALLOC_CTX *mem_ctx,
965     + const char *target_principal,
966     + const char *service,
967     + const char *hostname,
968     + const char *realm,
969     + char **pserver_principal,
970     + gss_name_t *pserver_name)
971     +{
972     + char *server_principal = NULL;
973     + gss_buffer_desc name_token;
974     + gss_OID name_type;
975     + OM_uint32 maj_stat, min_stat = 0;
976     +
977     + if (target_principal != NULL) {
978     + server_principal = talloc_strdup(mem_ctx, target_principal);
979     + name_type = GSS_C_NULL_OID;
980     + } else {
981     + server_principal = talloc_asprintf(mem_ctx,
982     + "%s/%s@%s",
983     + service,
984     + hostname,
985     + realm);
986     + name_type = GSS_C_NT_USER_NAME;
987     + }
988     + if (server_principal == NULL) {
989     + return NT_STATUS_NO_MEMORY;
990     + }
991     +
992     + name_token.value = (uint8_t *)server_principal;
993     + name_token.length = strlen(server_principal);
994     +
995     + maj_stat = gss_import_name(&min_stat,
996     + &name_token,
997     + name_type,
998     + pserver_name);
999     + if (maj_stat) {
1000     + DBG_WARNING("GSS Import name of %s failed: %s\n",
1001     + server_principal,
1002     + gse_errstr(mem_ctx, maj_stat, min_stat));
1003     + TALLOC_FREE(server_principal);
1004     + return NT_STATUS_INVALID_PARAMETER;
1005     + }
1006     +
1007     + *pserver_principal = server_principal;
1008     +
1009     + return NT_STATUS_OK;
1010     +}
1011     +
1012     static NTSTATUS gse_context_init(TALLOC_CTX *mem_ctx,
1013     bool do_sign, bool do_seal,
1014     const char *ccache_name,
1015     @@ -203,11 +251,12 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
1016     {
1017     struct gse_context *gse_ctx;
1018     OM_uint32 gss_maj, gss_min;
1019     - gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER;
1020     #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
1021     gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
1022     gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X);
1023     #endif
1024     + char *server_principal = NULL;
1025     + char *server_realm = NULL;
1026     NTSTATUS status;
1027    
1028     if (!server || !service) {
1029     @@ -223,30 +272,24 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
1030    
1031     /* Guess the realm based on the supplied service, and avoid the GSS libs
1032     doing DNS lookups which may fail.
1033     -
1034     - TODO: Loop with the KDC on some more combinations (local
1035     - realm in particular), possibly falling back to
1036     - GSS_C_NT_HOSTBASED_SERVICE
1037     */
1038     - name_buffer.value =
1039     - smb_krb5_get_principal_from_service_hostname(gse_ctx,
1040     - service,
1041     - server,
1042     - realm);
1043     - if (!name_buffer.value) {
1044     - status = NT_STATUS_NO_MEMORY;
1045     - goto err_out;
1046     + server_realm = smb_krb5_get_realm_from_hostname(mem_ctx,
1047     + server,
1048     + realm);
1049     + if (server_realm == NULL) {
1050     + return NT_STATUS_NO_MEMORY;
1051     }
1052     - name_buffer.length = strlen((char *)name_buffer.value);
1053     - gss_maj = gss_import_name(&gss_min, &name_buffer,
1054     - GSS_C_NT_USER_NAME,
1055     - &gse_ctx->server_name);
1056     - if (gss_maj) {
1057     - DEBUG(5, ("gss_import_name failed for %s, with [%s]\n",
1058     - (char *)name_buffer.value,
1059     - gse_errstr(gse_ctx, gss_maj, gss_min)));
1060     - status = NT_STATUS_INTERNAL_ERROR;
1061     - goto err_out;
1062     +
1063     + status = gse_setup_server_principal(mem_ctx,
1064     + NULL,
1065     + service,
1066     + server,
1067     + server_realm,
1068     + &server_principal,
1069     + &gse_ctx->server_name);
1070     + TALLOC_FREE(server_realm);
1071     + if (!NT_STATUS_IS_OK(status)) {
1072     + return status;
1073     }
1074    
1075     /* TODO: get krb5 ticket using username/password, if no valid
1076     @@ -299,11 +342,11 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
1077     #endif
1078    
1079     *_gse_ctx = gse_ctx;
1080     - TALLOC_FREE(name_buffer.value);
1081     + TALLOC_FREE(server_principal);
1082     return NT_STATUS_OK;
1083    
1084     err_out:
1085     - TALLOC_FREE(name_buffer.value);
1086     + TALLOC_FREE(server_principal);
1087     TALLOC_FREE(gse_ctx);
1088     return status;
1089     }
1090     --
1091     2.12.0
1092    
1093    
1094     From 905cdd3ee1fea0bf0e2081da4489934944c55fa9 Mon Sep 17 00:00:00 2001
1095     From: Andreas Schneider <asn@samba.org>
1096     Date: Thu, 9 Mar 2017 09:10:12 +0100
1097     Subject: [PATCH 14/20] krb5_wrap: Remove obsolete
1098     smb_krb5_get_principal_from_service_hostname()
1099    
1100     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1101    
1102     Signed-off-by: Andreas Schneider <asn@samba.org>
1103     Reviewed-by: Stefan Metzmacher <metze@samba.org>
1104     (cherry picked from commit 804e828d52ec922f3970e847652ab1ee5538b9b0)
1105     ---
1106     lib/krb5_wrap/krb5_samba.c | 111 ---------------------------------------------
1107     lib/krb5_wrap/krb5_samba.h | 5 --
1108     2 files changed, 116 deletions(-)
1109    
1110     diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
1111     index 2b0ec6bfa0e..0b67ea52a19 100644
1112     --- a/lib/krb5_wrap/krb5_samba.c
1113     +++ b/lib/krb5_wrap/krb5_samba.c
1114     @@ -2604,61 +2604,6 @@ krb5_error_code smb_krb5_principal_set_realm(krb5_context context,
1115     }
1116    
1117    
1118     -/************************************************************************
1119     - Routine to get the default realm from the kerberos credentials cache.
1120     - Caller must free if the return value is not NULL.
1121     -************************************************************************/
1122     -
1123     -static char *smb_krb5_get_default_realm_from_ccache(TALLOC_CTX *mem_ctx)
1124     -{
1125     - char *realm = NULL;
1126     - krb5_context ctx = NULL;
1127     - krb5_ccache cc = NULL;
1128     - krb5_principal princ = NULL;
1129     -
1130     - initialize_krb5_error_table();
1131     - if (krb5_init_context(&ctx)) {
1132     - return NULL;
1133     - }
1134     -
1135     - DEBUG(5,("kerberos_get_default_realm_from_ccache: "
1136     - "Trying to read krb5 cache: %s\n",
1137     - krb5_cc_default_name(ctx)));
1138     - if (krb5_cc_default(ctx, &cc)) {
1139     - DEBUG(5,("kerberos_get_default_realm_from_ccache: "
1140     - "failed to read default cache\n"));
1141     - goto out;
1142     - }
1143     - if (krb5_cc_get_principal(ctx, cc, &princ)) {
1144     - DEBUG(5,("kerberos_get_default_realm_from_ccache: "
1145     - "failed to get default principal\n"));
1146     - goto out;
1147     - }
1148     -
1149     -#if defined(HAVE_KRB5_PRINCIPAL_GET_REALM)
1150     - realm = talloc_strdup(mem_ctx, krb5_principal_get_realm(ctx, princ));
1151     -#elif defined(HAVE_KRB5_PRINC_REALM)
1152     - {
1153     - krb5_data *realm_data = krb5_princ_realm(ctx, princ);
1154     - realm = talloc_strndup(mem_ctx, realm_data->data, realm_data->length);
1155     - }
1156     -#endif
1157     -
1158     - out:
1159     -
1160     - if (ctx) {
1161     - if (princ) {
1162     - krb5_free_principal(ctx, princ);
1163     - }
1164     - if (cc) {
1165     - krb5_cc_close(ctx, cc);
1166     - }
1167     - krb5_free_context(ctx);
1168     - }
1169     -
1170     - return realm;
1171     -}
1172     -
1173     /**
1174     * @brief Get the realm from the service hostname.
1175     *
1176     @@ -2749,62 +2694,6 @@ char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
1177     }
1178    
1179     /**
1180     - * @brief Get the principal as a string from the service hostname.
1181     - *
1182     - * @param[in] mem_ctx The talloc context
1183     - *
1184     - * @param[in] service The service name
1185     - *
1186     - * @param[in] remote_name The remote name
1187     - *
1188     - * @param[in] default_realm The default_realm if we cannot get it from the
1189     - * hostname or netbios name.
1190     - *
1191     - * @return A talloc'ed principal string or NULL if an error occured.
1192     - *
1193     - * The caller needs to free the principal with talloc_free() if it isn't needed
1194     - * anymore.
1195     - */
1196     -char *smb_krb5_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
1197     - const char *service,
1198     - const char *remote_name,
1199     - const char *default_realm)
1200     -{
1201     - char *realm = NULL;
1202     - char *host = NULL;
1203     - char *principal;
1204     - host = strchr_m(remote_name, '.');
1205     - if (host) {
1206     - /* DNS name. */
1207     - realm = smb_krb5_get_realm_from_hostname(talloc_tos(),
1208     - remote_name,
1209     - default_realm);
1210     - } else {
1211     - /* NetBIOS name - use our realm. */
1212     - realm = smb_krb5_get_default_realm_from_ccache(talloc_tos());
1213     - }
1214     -
1215     - if (realm == NULL || *realm == '\0') {
1216     - realm = talloc_strdup(talloc_tos(), default_realm);
1217     - if (!realm) {
1218     - return NULL;
1219     - }
1220     - DEBUG(3,("Cannot get realm from, "
1221     - "desthost %s or default ccache. Using default "
1222     - "smb.conf realm %s\n",
1223     - remote_name,
1224     - realm));
1225     - }
1226     -
1227     - principal = talloc_asprintf(mem_ctx,
1228     - "%s/%s@%s",
1229     - service, remote_name,
1230     - realm);
1231     - TALLOC_FREE(realm);
1232     - return principal;
1233     -}
1234     -
1235     -/**
1236     * @brief Get an error string from a Kerberos error code.
1237     *
1238     * @param[in] context The library context.
1239     diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
1240     index accae449a0e..c921538efcb 100644
1241     --- a/lib/krb5_wrap/krb5_samba.h
1242     +++ b/lib/krb5_wrap/krb5_samba.h
1243     @@ -318,11 +318,6 @@ char *smb_krb5_get_realm_from_hostname(TALLOC_CTX *mem_ctx,
1244     const char *hostname,
1245     const char *client_realm);
1246    
1247     -char *smb_krb5_get_principal_from_service_hostname(TALLOC_CTX *mem_ctx,
1248     - const char *service,
1249     - const char *remote_name,
1250     - const char *default_realm);
1251     -
1252     char *smb_get_krb5_error_message(krb5_context context,
1253     krb5_error_code code,
1254     TALLOC_CTX *mem_ctx);
1255     --
1256     2.12.0
1257    
1258    
1259     From 0ea7203430b580e93816035b8201ddd11346cd4e Mon Sep 17 00:00:00 2001
1260     From: Andreas Schneider <asn@samba.org>
1261     Date: Mon, 6 Mar 2017 08:16:11 +0100
1262     Subject: [PATCH 15/20] s3:gse: Pass down the gensec_security pointer
1263    
1264     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1265    
1266     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1267    
1268     Signed-off-by: Andreas Schneider <asn@samba.org>
1269     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1270     (cherry picked from commit e6b1e58874de30d094f9bce474479cfddb39d3fc)
1271     ---
1272     source3/librpc/crypto/gse.c | 19 ++++++++++++-------
1273     1 file changed, 12 insertions(+), 7 deletions(-)
1274    
1275     diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
1276     index 57632f6cc8f..5a39522a828 100644
1277     --- a/source3/librpc/crypto/gse.c
1278     +++ b/source3/librpc/crypto/gse.c
1279     @@ -352,10 +352,13 @@ err_out:
1280     }
1281    
1282     static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1283     - struct gse_context *gse_ctx,
1284     + struct gensec_security *gensec_security,
1285     const DATA_BLOB *token_in,
1286     DATA_BLOB *token_out)
1287     {
1288     + struct gse_context *gse_ctx =
1289     + talloc_get_type_abort(gensec_security->private_data,
1290     + struct gse_context);
1291     OM_uint32 gss_maj, gss_min;
1292     gss_buffer_desc in_data;
1293     gss_buffer_desc out_data;
1294     @@ -542,10 +545,13 @@ done:
1295     }
1296    
1297     static NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,
1298     - struct gse_context *gse_ctx,
1299     + struct gensec_security *gensec_security,
1300     const DATA_BLOB *token_in,
1301     DATA_BLOB *token_out)
1302     {
1303     + struct gse_context *gse_ctx =
1304     + talloc_get_type_abort(gensec_security->private_data,
1305     + struct gse_context);
1306     OM_uint32 gss_maj, gss_min;
1307     gss_buffer_desc in_data;
1308     gss_buffer_desc out_data;
1309     @@ -762,17 +768,16 @@ static NTSTATUS gensec_gse_update(struct gensec_security *gensec_security,
1310     const DATA_BLOB in, DATA_BLOB *out)
1311     {
1312     NTSTATUS status;
1313     - struct gse_context *gse_ctx =
1314     - talloc_get_type_abort(gensec_security->private_data,
1315     - struct gse_context);
1316    
1317     switch (gensec_security->gensec_role) {
1318     case GENSEC_CLIENT:
1319     - status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1320     + status = gse_get_client_auth_token(mem_ctx,
1321     + gensec_security,
1322     &in, out);
1323     break;
1324     case GENSEC_SERVER:
1325     - status = gse_get_server_auth_token(mem_ctx, gse_ctx,
1326     + status = gse_get_server_auth_token(mem_ctx,
1327     + gensec_security,
1328     &in, out);
1329     break;
1330     }
1331     --
1332     2.12.0
1333    
1334    
1335     From 36b353247939414cd7f91abd27bfc553bd62c06f Mon Sep 17 00:00:00 2001
1336     From: Andreas Schneider <asn@samba.org>
1337     Date: Thu, 9 Mar 2017 08:05:26 +0100
1338     Subject: [PATCH 16/20] s3:gse: Move setup of service_principal to update
1339     function
1340    
1341     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1342    
1343     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1344    
1345     Signed-off-by: Andreas Schneider <asn@samba.org>
1346     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1347     (cherry picked from commit 3ba1ad1f8c7871070d0ecbe5d49c5c44afe98bbf)
1348     ---
1349     source3/librpc/crypto/gse.c | 97 +++++++++++++++++++++++++++++++++------------
1350     1 file changed, 71 insertions(+), 26 deletions(-)
1351    
1352     diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
1353     index 5a39522a828..3580181061e 100644
1354     --- a/source3/librpc/crypto/gse.c
1355     +++ b/source3/librpc/crypto/gse.c
1356     @@ -255,8 +255,6 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
1357     gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
1358     gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X);
1359     #endif
1360     - char *server_principal = NULL;
1361     - char *server_realm = NULL;
1362     NTSTATUS status;
1363    
1364     if (!server || !service) {
1365     @@ -270,28 +268,6 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
1366     return NT_STATUS_NO_MEMORY;
1367     }
1368    
1369     - /* Guess the realm based on the supplied service, and avoid the GSS libs
1370     - doing DNS lookups which may fail.
1371     - */
1372     - server_realm = smb_krb5_get_realm_from_hostname(mem_ctx,
1373     - server,
1374     - realm);
1375     - if (server_realm == NULL) {
1376     - return NT_STATUS_NO_MEMORY;
1377     - }
1378     -
1379     - status = gse_setup_server_principal(mem_ctx,
1380     - NULL,
1381     - service,
1382     - server,
1383     - server_realm,
1384     - &server_principal,
1385     - &gse_ctx->server_name);
1386     - TALLOC_FREE(server_realm);
1387     - if (!NT_STATUS_IS_OK(status)) {
1388     - return status;
1389     - }
1390     -
1391     /* TODO: get krb5 ticket using username/password, if no valid
1392     * one already available in ccache */
1393    
1394     @@ -342,11 +318,9 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
1395     #endif
1396    
1397     *_gse_ctx = gse_ctx;
1398     - TALLOC_FREE(server_principal);
1399     return NT_STATUS_OK;
1400    
1401     err_out:
1402     - TALLOC_FREE(server_principal);
1403     TALLOC_FREE(gse_ctx);
1404     return status;
1405     }
1406     @@ -366,10 +340,81 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1407     NTSTATUS status;
1408     OM_uint32 time_rec = 0;
1409     struct timeval tv;
1410     + struct cli_credentials *cli_creds = gensec_get_credentials(gensec_security);
1411     + const char *hostname = gensec_get_target_hostname(gensec_security);
1412     + const char *service = gensec_get_target_service(gensec_security);
1413     + const char *client_realm = cli_credentials_get_realm(cli_creds);
1414     + char *server_principal = NULL;
1415     + char *server_realm = NULL;
1416    
1417     in_data.value = token_in->data;
1418     in_data.length = token_in->length;
1419    
1420     + /*
1421     + * With credentials for administrator@FOREST1.EXAMPLE.COM this patch
1422     + * changes the target_principal for the ldap service of host
1423     + * dc2.forest2.example.com from
1424     + *
1425     + * ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM
1426     + *
1427     + * to
1428     + *
1429     + * ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM
1430     + *
1431     + * Typically ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM should be
1432     + * used in order to allow the KDC of FOREST1.EXAMPLE.COM to generate a
1433     + * referral ticket for krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM.
1434     + *
1435     + * The problem is that KDCs only return such referral tickets if
1436     + * there's a forest trust between FOREST1.EXAMPLE.COM and
1437     + * FOREST2.EXAMPLE.COM. If there's only an external domain trust
1438     + * between FOREST1.EXAMPLE.COM and FOREST2.EXAMPLE.COM the KDC of
1439     + * FOREST1.EXAMPLE.COM will respond with S_PRINCIPAL_UNKNOWN when being
1440     + * asked for ldap/dc2.forest2.example.com@FOREST1.EXAMPLE.COM.
1441     + *
1442     + * In the case of an external trust the client can still ask explicitly
1443     + * for krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM and the KDC of
1444     + * FOREST1.EXAMPLE.COM will generate it.
1445     + *
1446     + * From there the client can use the
1447     + * krbtgt/FOREST2.EXAMPLE.COM@FOREST1.EXAMPLE.COM ticket and ask a KDC
1448     + * of FOREST2.EXAMPLE.COM for a service ticket for
1449     + * ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM.
1450     + *
1451     + * With Heimdal we'll get the fallback on S_PRINCIPAL_UNKNOWN behavior
1452     + * when we pass ldap/dc2.forest2.example.com@FOREST2.EXAMPLE.COM as
1453     + * target principal. As _krb5_get_cred_kdc_any() first calls
1454     + * get_cred_kdc_referral() (which always starts with the client realm)
1455     + * and falls back to get_cred_kdc_capath() (which starts with the given
1456     + * realm).
1457     + *
1458     + * MIT krb5 only tries the given realm of the target principal, if we
1459     + * want to autodetect support for transitive forest trusts, would have
1460     + * to do the fallback ourself.
1461     + */
1462     + if (gse_ctx->server_name == NULL) {
1463     + server_realm = smb_krb5_get_realm_from_hostname(mem_ctx,
1464     + hostname,
1465     + client_realm);
1466     + if (server_realm == NULL) {
1467     + return NT_STATUS_NO_MEMORY;
1468     + }
1469     +
1470     + status = gse_setup_server_principal(mem_ctx,
1471     + NULL,
1472     + service,
1473     + hostname,
1474     + server_realm,
1475     + &server_principal,
1476     + &gse_ctx->server_name);
1477     + TALLOC_FREE(server_realm);
1478     + if (!NT_STATUS_IS_OK(status)) {
1479     + return status;
1480     + }
1481     +
1482     + TALLOC_FREE(server_principal);
1483     + }
1484     +
1485     gss_maj = gss_init_sec_context(&gss_min,
1486     gse_ctx->creds,
1487     &gse_ctx->gssapi_context,
1488     --
1489     2.12.0
1490    
1491    
1492     From 5ca321eaa79cdf9de1166f49365051d4d67560f9 Mon Sep 17 00:00:00 2001
1493     From: Andreas Schneider <asn@samba.org>
1494     Date: Thu, 9 Mar 2017 08:11:07 +0100
1495     Subject: [PATCH 17/20] s3:gse: Check if we have a target_princpal set we
1496     should use
1497    
1498     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1499    
1500     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1501    
1502     Signed-off-by: Andreas Schneider <asn@samba.org>
1503     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1504     (cherry picked from commit ada31d65d6c5929d2fbddfea5611a5f5fe5a0d74)
1505     ---
1506     source3/librpc/crypto/gse.c | 3 ++-
1507     1 file changed, 2 insertions(+), 1 deletion(-)
1508    
1509     diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
1510     index 3580181061e..721fd8c1625 100644
1511     --- a/source3/librpc/crypto/gse.c
1512     +++ b/source3/librpc/crypto/gse.c
1513     @@ -341,6 +341,7 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1514     OM_uint32 time_rec = 0;
1515     struct timeval tv;
1516     struct cli_credentials *cli_creds = gensec_get_credentials(gensec_security);
1517     + const char *target_principal = gensec_get_target_principal(gensec_security);
1518     const char *hostname = gensec_get_target_hostname(gensec_security);
1519     const char *service = gensec_get_target_service(gensec_security);
1520     const char *client_realm = cli_credentials_get_realm(cli_creds);
1521     @@ -401,7 +402,7 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1522     }
1523    
1524     status = gse_setup_server_principal(mem_ctx,
1525     - NULL,
1526     + target_principal,
1527     service,
1528     hostname,
1529     server_realm,
1530     --
1531     2.12.0
1532    
1533    
1534     From 8b88c6bf158e5da0cc238472390f3346aa05ef53 Mon Sep 17 00:00:00 2001
1535     From: Andreas Schneider <asn@samba.org>
1536     Date: Thu, 9 Mar 2017 08:18:27 +0100
1537     Subject: [PATCH 18/20] s3:gse: Correctly handle external trusts with MIT
1538    
1539     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1540    
1541     Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
1542    
1543     Signed-off-by: Andreas Schneider <asn@samba.org>
1544     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1545     (cherry picked from commit b8bca7d08fe05758e536767b1146cdcdd8b9fee3)
1546     ---
1547     source3/librpc/crypto/gse.c | 54 +++++++++++++++++++++++++++++++++++++++++++++
1548     1 file changed, 54 insertions(+)
1549    
1550     diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c
1551     index 721fd8c1625..3abf774633b 100644
1552     --- a/source3/librpc/crypto/gse.c
1553     +++ b/source3/librpc/crypto/gse.c
1554     @@ -347,6 +347,7 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1555     const char *client_realm = cli_credentials_get_realm(cli_creds);
1556     char *server_principal = NULL;
1557     char *server_realm = NULL;
1558     + bool fallback = false;
1559    
1560     in_data.value = token_in->data;
1561     in_data.length = token_in->length;
1562     @@ -393,6 +394,50 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1563     * want to autodetect support for transitive forest trusts, would have
1564     * to do the fallback ourself.
1565     */
1566     +#ifndef SAMBA4_USES_HEIMDAL
1567     + if (gse_ctx->server_name == NULL) {
1568     + OM_uint32 gss_min2 = 0;
1569     +
1570     + status = gse_setup_server_principal(mem_ctx,
1571     + target_principal,
1572     + service,
1573     + hostname,
1574     + client_realm,
1575     + &server_principal,
1576     + &gse_ctx->server_name);
1577     + if (!NT_STATUS_IS_OK(status)) {
1578     + return status;
1579     + }
1580     +
1581     + gss_maj = gss_init_sec_context(&gss_min,
1582     + gse_ctx->creds,
1583     + &gse_ctx->gssapi_context,
1584     + gse_ctx->server_name,
1585     + &gse_ctx->gss_mech,
1586     + gse_ctx->gss_want_flags,
1587     + 0,
1588     + GSS_C_NO_CHANNEL_BINDINGS,
1589     + &in_data,
1590     + NULL,
1591     + &out_data,
1592     + &gse_ctx->gss_got_flags,
1593     + &time_rec);
1594     + if (gss_maj != GSS_S_FAILURE) {
1595     + goto init_sec_context_done;
1596     + }
1597     + if (gss_min != (OM_uint32)KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
1598     + goto init_sec_context_done;
1599     + }
1600     + if (target_principal != NULL) {
1601     + goto init_sec_context_done;
1602     + }
1603     +
1604     + fallback = true;
1605     + TALLOC_FREE(server_principal);
1606     + gss_release_name(&gss_min2, &gse_ctx->server_name);
1607     + }
1608     +#endif /* !SAMBA4_USES_HEIMDAL */
1609     +
1610     if (gse_ctx->server_name == NULL) {
1611     server_realm = smb_krb5_get_realm_from_hostname(mem_ctx,
1612     hostname,
1613     @@ -401,6 +446,11 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1614     return NT_STATUS_NO_MEMORY;
1615     }
1616    
1617     + if (fallback &&
1618     + strequal(client_realm, server_realm)) {
1619     + goto init_sec_context_done;
1620     + }
1621     +
1622     status = gse_setup_server_principal(mem_ctx,
1623     target_principal,
1624     service,
1625     @@ -425,6 +475,10 @@ static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
1626     0, GSS_C_NO_CHANNEL_BINDINGS,
1627     &in_data, NULL, &out_data,
1628     &gse_ctx->gss_got_flags, &time_rec);
1629     + goto init_sec_context_done;
1630     + /* JUMP! */
1631     +init_sec_context_done:
1632     +
1633     switch (gss_maj) {
1634     case GSS_S_COMPLETE:
1635     /* we are done with it */
1636     --
1637     2.12.0
1638    
1639    
1640     From 290de34d42477022d8b5a236b3d0953a178c5e40 Mon Sep 17 00:00:00 2001
1641     From: Stefan Metzmacher <metze@samba.org>
1642     Date: Sun, 29 Jan 2017 17:19:14 +0100
1643     Subject: [PATCH 19/20] HEIMDAL:kdc: make it possible to disable the principal
1644     based referral detection
1645    
1646     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1647    
1648     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1649     Reviewed-by: Andreas Schneider <asn@samba.org>
1650     (cherry picked from commit 209886e95c3afe1e4e50bacc30b40a543856a7a0)
1651     ---
1652     source4/heimdal/kdc/default_config.c | 1 +
1653     source4/heimdal/kdc/kdc.h | 2 ++
1654     source4/heimdal/kdc/krb5tgs.c | 4 +++-
1655     3 files changed, 6 insertions(+), 1 deletion(-)
1656    
1657     diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c
1658     index 6fbf5fdae15..0129c5d3c54 100644
1659     --- a/source4/heimdal/kdc/default_config.c
1660     +++ b/source4/heimdal/kdc/default_config.c
1661     @@ -55,6 +55,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
1662     c->preauth_use_strongest_session_key = FALSE;
1663     c->tgs_use_strongest_session_key = FALSE;
1664     c->use_strongest_server_key = TRUE;
1665     + c->autodetect_referrals = TRUE;
1666     c->check_ticket_addresses = TRUE;
1667     c->allow_null_ticket_addresses = TRUE;
1668     c->allow_anonymous = FALSE;
1669     diff --git a/source4/heimdal/kdc/kdc.h b/source4/heimdal/kdc/kdc.h
1670     index 9d52fd4c2ec..16263d6919b 100644
1671     --- a/source4/heimdal/kdc/kdc.h
1672     +++ b/source4/heimdal/kdc/kdc.h
1673     @@ -69,6 +69,8 @@ typedef struct krb5_kdc_configuration {
1674     krb5_boolean allow_anonymous;
1675     enum krb5_kdc_trpolicy trpolicy;
1676    
1677     + krb5_boolean autodetect_referrals;
1678     +
1679     krb5_boolean enable_pkinit;
1680     krb5_boolean pkinit_princ_in_cert;
1681     const char *pkinit_kdc_identity;
1682     diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
1683     index 334a6eb1dc8..a888788bb6f 100644
1684     --- a/source4/heimdal/kdc/krb5tgs.c
1685     +++ b/source4/heimdal/kdc/krb5tgs.c
1686     @@ -1660,7 +1660,9 @@ server_lookup:
1687     Realm req_rlm;
1688     krb5_realm *realms;
1689    
1690     - if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
1691     + if (!config->autodetect_referrals) {
1692     + /* noop */
1693     + } else if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
1694     if(nloop++ < 2) {
1695     new_rlm = find_rpath(context, tgt->crealm, req_rlm);
1696     if(new_rlm) {
1697     --
1698     2.12.0
1699    
1700    
1701     From b98d399a9b3076443fa12fab5f5e13b8d6e2fe26 Mon Sep 17 00:00:00 2001
1702     From: Stefan Metzmacher <metze@samba.org>
1703     Date: Sun, 29 Jan 2017 17:20:09 +0100
1704     Subject: [PATCH 20/20] s4:kdc: disable principal based autodetected referral
1705     detection
1706    
1707     BUG: https://bugzilla.samba.org/show_bug.cgi?id=12554
1708    
1709     Signed-off-by: Stefan Metzmacher <metze@samba.org>
1710     Reviewed-by: Andreas Schneider <asn@samba.org>
1711     (cherry picked from commit 3314bf52aaef60ef5cc1110587b53064df7c475d)
1712     ---
1713     source4/kdc/kdc-heimdal.c | 2 ++
1714     1 file changed, 2 insertions(+)
1715    
1716     diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c
1717     index f2927e5cb9f..061296a4f40 100644
1718     --- a/source4/kdc/kdc-heimdal.c
1719     +++ b/source4/kdc/kdc-heimdal.c
1720     @@ -379,6 +379,8 @@ static void kdc_task_init(struct task_server *task)
1721     kdc_config->tgs_use_strongest_session_key = false;
1722     kdc_config->use_strongest_server_key = true;
1723    
1724     + kdc_config->autodetect_referrals = false;
1725     +
1726     /* Register hdb-samba4 hooks for use as a keytab */
1727    
1728     kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
1729     --
1730     2.12.0
1731    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed