freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
[freetds] How to specify SPN when server is in a different realm (was Re: tds9 and gssapi)
- From: Mike Slifcak <slif AT bellsouth.net>
- To: freetds AT lists.ibiblio.org
- Subject: [freetds] How to specify SPN when server is in a different realm (was Re: tds9 and gssapi)
- Date: Thu, 11 Aug 2011 23:47:51 -0400
Hello.
If client is in one realm, and server is in another realm,
the server's realm name must follow the SPN before presenting it to
gss_import_name:
MSSQLSvc / hostnamefqdn : port @ server_realm_name [spaces for
illustration only!]
tds->connection has no string to hold server realm name ...
How hard would it be to add "ServerRealmName" and "server realm name" tokens
to
the ODBC and baseline configuration parsers?
I've attached an exploratory (compiles, not tested) patch that adds server
realm
before gss_import_name is called.
The patch also adds configuration parsing for the server realm name.
I wasn't sure where to add config for ODBC, so I didn't add that.
Let me know where the patch needs work.
Thanks in advance,
-Mike Slifcak
Offered by: Mike Slifcak Apply to: freetds-0.91.dev.20110804RC2 Impact: add "server realm name" token to config add external realm to SPN during GSSAPI token creation Compiled: Yes Tested: NOT TESTED diff -urp a/include/tds.h b/include/tds.h --- a/include/tds.h 2011-08-11 22:26:20.000000000 -0400 +++ b/include/tds.h 2011-08-11 22:26:33.000000000 -0400 @@ -815,6 +815,7 @@ typedef enum tds_encryption_level { #define TDS_STR_ENCRYPTION_REQUIRE "require" /* Defines to enable optional GSSAPI delegation */ #define TDS_GSSAPI_DELEGATION "enable gssapi delegation" +#define TDS_STR_REALM "server realm name" /* TODO do a better check for alignment than this */ @@ -887,6 +888,7 @@ typedef struct tds_connection unsigned int suppress_language:1; unsigned int gssapi_use_delegation:1; unsigned int use_ntlmv2:1; + DSTR server_realm_name; /**< server realm name (in freetds.conf) */ } TDSCONNECTION; typedef struct tds_locale diff -urp a/src/tds/config.c b/src/tds/config.c --- a/src/tds/config.c 2011-04-15 02:59:16.000000000 -0400 +++ b/src/tds/config.c 2011-08-11 22:33:37.000000000 -0400 @@ -252,6 +252,7 @@ tds_read_config_info(TDSSOCKET * tds, TD tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "text_size", connection->text_size); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "broken_dates", connection->broken_dates); tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "emul_little_endian", connection->emul_little_endian); + tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_realm_name", tds_dstr_cstr(&connection->server_realm_name)); tdsdump_close(); } @@ -622,6 +623,8 @@ tds_parse_conf_section(const char *optio tds_dstr_copy(&connection->server_name, value); } else if (!strcmp(option, TDS_STR_USENTLMV2)) { connection->use_ntlmv2 = tds_config_boolean(value); + } else if (!strcmp(option, TDS_STR_REALM)) { + tds_dstr_copy(&connection->server_realm_name, value); } else { tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s' ... ignoring.\n", option); } diff -urp a/src/tds/gssapi.c b/src/tds/gssapi.c --- a/src/tds/gssapi.c 2011-05-10 09:21:30.000000000 -0400 +++ b/src/tds/gssapi.c 2011-08-11 22:22:55.000000000 -0400 @@ -177,6 +177,7 @@ tds_gss_get_auth(TDSSOCKET * tds) /* same as GSS_KRB5_NT_PRINCIPAL_NAME but do not require .so library */ static gss_OID_desc nt_principal = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01" }; const char *server_name; + const char *server_realm_name; /* Storage for reentrant getaddrby* calls */ char buffer[4096]; @@ -199,11 +200,19 @@ tds_gss_get_auth(TDSSOCKET * tds) if (host && strchr(host->h_name, '.') != NULL) server_name = host->h_name; } - + server_realm_name = tds_dstr_cstr(&tds->connection->server_realm_name); + if (server_realm_name == NULL) { if (asprintf(&auth->sname, "MSSQLSvc/%s:%d", server_name, tds->connection->port) < 0) { tds_gss_free(tds, (TDSAUTHENTICATION *) auth); return NULL; } + } + else { + if (asprintf(&auth->sname, "MSSQLSvc/%s:%d@%s", server_name, tds->connection->port, server_realm_name) < 0) { + tds_gss_free(tds, (TDSAUTHENTICATION *) auth); + return NULL; + } + } tdsdump_log(TDS_DBG_NETWORK, "kerberos name %s\n", auth->sname); /* @@ -214,8 +223,13 @@ tds_gss_get_auth(TDSSOCKET * tds) send_tok.length = strlen(auth->sname); maj_stat = gss_import_name(&min_stat, &send_tok, &nt_principal, &auth->target_name); - if (maj_stat != GSS_S_COMPLETE - || tds_gss_continue(tds, auth, GSS_C_NO_BUFFER) == TDS_FAIL) { + if (maj_stat != GSS_S_COMPLETE) { + tdsdump_log(TDS_DBG_NETWORK, "gss_import_name failed %d\n", maj_stat); + tds_gss_free(tds, (TDSAUTHENTICATION *) auth); + return NULL; + } + + if (tds_gss_continue(tds, auth, GSS_C_NO_BUFFER) == TDS_FAIL) { tds_gss_free(tds, (TDSAUTHENTICATION *) auth); return NULL; } @@ -268,6 +282,8 @@ tds_gss_continue(TDSSOCKET * tds, struct auth->last_stat = maj_stat; if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { + tdsdump_log(TDS_DBG_NETWORK, "gss_init_sec_context flags %x, returns %x\n", gssapi_flags, maj_stat); +/*XX dump send_tok return contents if debug_flags allows,etc. */ gss_release_buffer(&min_stat, &send_tok); return TDS_FAIL; } diff -urp a/src/tds/mem.c b/src/tds/mem.c --- a/src/tds/mem.c 2010-09-28 04:20:11.000000000 -0400 +++ b/src/tds/mem.c 2011-08-11 22:36:35.000000000 -0400 @@ -827,6 +827,7 @@ tds_alloc_connection(TDSLOCALE * locale) tds_dstr_init(&connection->dump_file); tds_dstr_init(&connection->client_charset); tds_dstr_init(&connection->instance_name); + tds_dstr_init(&connection->server_realm_name); /* fill in all hardcoded defaults */ if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER)) @@ -1188,6 +1189,7 @@ tds_free_connection(TDSCONNECTION * conn tds_dstr_free(&connection->password); tds_dstr_free(&connection->library); tds_dstr_free(&connection->instance_name); + tds_dstr_free(&connection->server_realm_name); free(connection); }
- [freetds] How to specify SPN when server is in a different realm (was Re: tds9 and gssapi), Mike Slifcak, 08/11/2011
Archive powered by MHonArc 2.6.24.