[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freetds
Subject:    [freetds] How to specify SPN when server is in a different realm
From:       Mike Slifcak <slif () bellsouth ! net>
Date:       2011-08-12 3:47:51
Message-ID: 4E44A267.2010203 () bellsouth ! net
[Download RAW message or body]

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


["realm.patch" (text/x-patch)]

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 mailing list
FreeTDS@lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic