From 5de584d6df36c32aa36e60a820ff1b72cc812f21 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 23 Sep 2014 14:09:41 +0200 Subject: [PATCH] s3-libads: Improve service principle guessing. If the name passed to the net command with the -S options is the long hostname of the domaincontroller and not the 15 char NetBIOS name we should construct a FQDN with the realm to get a Kerberos ticket. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10829 Signed-off-by: Andreas Schneider Reviewed-by: Guenther Deschner (cherry picked from commit 83c62bd3f5945bbe295cbfbd153736d4c709b3a6) --- source3/libads/sasl.c | 124 +++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 33f4e24..1450ff1 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -714,88 +714,96 @@ static void ads_free_service_principal(struct ads_service_principal *p) static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, char **returned_principal) { + ADS_STATUS status = ADS_ERROR(LDAP_NO_MEMORY); char *princ = NULL; + TALLOC_CTX *frame; + char *server = NULL; + char *realm = NULL; + int rc; - if (ads->server.realm && ads->server.ldap_server) { - char *server, *server_realm; - - server = SMB_STRDUP(ads->server.ldap_server); - server_realm = SMB_STRDUP(ads->server.realm); - - if (!server || !server_realm) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); - } + frame = talloc_stackframe(); + if (frame == NULL) { + return ADS_ERROR(LDAP_NO_MEMORY); + } - if (!strlower_m(server)) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); + if (ads->server.realm && ads->server.ldap_server) { + server = strlower_talloc(frame, ads->server.ldap_server); + if (server == NULL) { + goto out; } - if (!strupper_m(server_realm)) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); + realm = strupper_talloc(frame, ads->server.realm); + if (realm == NULL) { + goto out; } - if (asprintf(&princ, "ldap/%s@%s", server, server_realm) == -1) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); - } + /* + * If we got a name which is bigger than a NetBIOS name, + * but isn't a FQDN, create one. + */ + if (strlen(server) > 15 && strstr(server, ".") == NULL) { + char *dnsdomain; - SAFE_FREE(server); - SAFE_FREE(server_realm); + dnsdomain = strlower_talloc(frame, ads->server.realm); + if (dnsdomain == NULL) { + goto out; + } - if (!princ) { - return ADS_ERROR(LDAP_NO_MEMORY); + server = talloc_asprintf(frame, + "%s.%s", + server, dnsdomain); + if (server == NULL) { + goto out; + } } } else if (ads->config.realm && ads->config.ldap_server_name) { - char *server, *server_realm; - - server = SMB_STRDUP(ads->config.ldap_server_name); - server_realm = SMB_STRDUP(ads->config.realm); - - if (!server || !server_realm) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); + server = strlower_talloc(frame, ads->config.ldap_server_name); + if (server == NULL) { + goto out; } - if (!strlower_m(server)) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); + realm = strupper_talloc(frame, ads->config.realm); + if (realm == NULL) { + goto out; } - if (!strupper_m(server_realm)) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); - } - if (asprintf(&princ, "ldap/%s@%s", server, server_realm) == -1) { - SAFE_FREE(server); - SAFE_FREE(server_realm); - return ADS_ERROR(LDAP_NO_MEMORY); - } + /* + * If we got a name which is bigger than a NetBIOS name, + * but isn't a FQDN, create one. + */ + if (strlen(server) > 15 && strstr(server, ".") == NULL) { + char *dnsdomain; - SAFE_FREE(server); - SAFE_FREE(server_realm); + dnsdomain = strlower_talloc(frame, ads->server.realm); + if (dnsdomain == NULL) { + goto out; + } - if (!princ) { - return ADS_ERROR(LDAP_NO_MEMORY); + server = talloc_asprintf(frame, + "%s.%s", + server, dnsdomain); + if (server == NULL) { + goto out; + } } } - if (!princ) { - return ADS_ERROR(LDAP_PARAM_ERROR); + if (server == NULL || realm == NULL) { + goto out; + } + + rc = asprintf(&princ, "ldap/%s@%s", server, realm); + if (rc == -1 || princ == NULL) { + status = ADS_ERROR(LDAP_PARAM_ERROR); + goto out; } *returned_principal = princ; - return ADS_SUCCESS; + status = ADS_SUCCESS; +out: + TALLOC_FREE(frame); + return status; } static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, -- 2.1.0