diff options
author | Andreas Schneider <asn@samba.org> | 2014-09-23 14:09:41 +0200 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2014-09-26 05:55:34 +0200 |
commit | 83c62bd3f5945bbe295cbfbd153736d4c709b3a6 (patch) | |
tree | 68f59fdd7d364d6156aafd24df0544db425ea991 /source3/libads/sasl.c | |
parent | 69a7e3cfdc8dbba9c8dcfdfae82d2894c7247e15 (diff) | |
download | samba-83c62bd3f5945bbe295cbfbd153736d4c709b3a6.tar.gz samba-83c62bd3f5945bbe295cbfbd153736d4c709b3a6.tar.xz samba-83c62bd3f5945bbe295cbfbd153736d4c709b3a6.zip |
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 <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Diffstat (limited to 'source3/libads/sasl.c')
-rw-r--r-- | source3/libads/sasl.c | 124 |
1 files changed, 66 insertions, 58 deletions
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 6890fb27a7..8a9e1570f9 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, |