Re: problem with Kerberose and TDS 7.2
Frediano Ziglio <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
2011/5/7 Frediano Ziglio <[email protected]>: > Il giorno ven, 06/05/2011 alle 18.41 -0400, [email protected] ha > scritto: >> Using bsqlodbc and TDS 7.2 with Kerberos, I get a protocol error. Dropping to >> 7.1 works, as does using a non-kerberos login: >> >> $ TDSVER=7.2 TDSDUMP=dump bsqlodbc -S $S -v <<< "select cast('1 mar 2011' as date) as march" || less -S dump >> bsqlodbc:273: Verbose operation enabled >> bsqlodbc: error -1: SQLConnect: SQL_ERROR: failed >> bsqlodbc: error 20020: 08S01: [unixODBC][FreeTDS][SQL Server]Bad token from the server: Datastream processing out of sync >> "[unixODBC][FreeTDS][SQL Server]Unable to connect to data source" >> >> Start of dump: >> >> log.c:196:Starting log file for FreeTDS 0.83.dev.20110103 >> on 2011-05-06 18:34:25 with debug flags 0x4fff. >> iconv.c:330:tds_iconv_open(0x1914a440, UTF-8) >> iconv.c:187:local name for ISO-8859-1 is ISO-8859-1 >> iconv.c:187:local name for UTF-8 is UTF-8 >> iconv.c:187:local name for UCS-2LE is UCS-2LE >> iconv.c:187:local name for UCS-2BE is UCS-2BE >> iconv.c:349:setting up conversions for client charset "UTF-8" >> iconv.c:351:preparing iconv for "UTF-8" <-> "UCS-2LE" conversion >> iconv.c:391:preparing iconv for "ISO-8859-1" <-> "UCS-2LE" conversion >> iconv.c:394:tds_iconv_open: done >> net.c:205:Connecting to xx.xx.xx.xx port xxx (TDS version 7.2) >> net.c:270:tds_open_socket: connect(2) returned "Operation now in progress" >> net.c:310:tds_open_socket() succeeded >> util.c:156:Changed query state from DEAD to IDLE >> net.c:741:Sending packet >> 0000 12 01 00 3a 00 00 00 00-00 00 1a 00 06 01 00 20 |...:.... ....... | >> 0010 00 01 02 00 21 00 0c 03-00 2d 00 04 04 00 31 00 |....!... .-....1.| >> 0020 01 ff 09 00 00 00 00 00-02 4d 53 53 51 4c 53 65 |........ .MSSQLSe| >> 0030 72 76 65 72 00 d8 06 00-00 00 |rver.... ..| >> >> net.c:555:Received header >> 0000 04 01 00 2b 00 00 01 00- |...+....| >> >> net.c:609:Received packet >> 0000 04 01 00 2b 00 00 01 00-00 00 1a 00 06 01 00 20 |...+.... ....... | >> 0010 00 01 02 00 21 00 01 03-00 22 00 00 04 00 22 00 |....!... ."....".| >> 0020 01 ff 0a 32 06 40 00 00-02 00 00 |...2.@.. ...| >> >> login.c:1051:detected flag 2 >> gssapi.c:172:kerberos name MSSQLSvc/[deleted...] >> login.c:776:quietly sending TDS 7+ login packet >> token.c:328:tds_process_login_tokens() >> net.c:555:Received header >> 0000 04 01 00 91 00 00 01 00- |........| >> >> net.c:609:Received packet >> 0000 04 01 00 91 00 00 01 00-ed 86 00 60 81 83 06 09 |........ ...`....| >> 0010 2a 86 48 86 f7 12 01 02-02 02 00 6f 74 30 72 a0 |*.H..... ...ot0r.| >> 0020 03 02 01 05 a1 03 02 01-0f a2 66 30 64 a0 03 02 |........ ..f0d...| >> 0030 01 17 a2 5d 04 5b 4f 9d-cc 42 98 44 53 4f e4 b9 |...].[O. .B.DSO..| >> 0040 1f 72 6f 69 16 58 88 1e-bc 2a 54 ca a5 0d eb d3 |.roi.X.. .*T.....| >> 0050 1c 47 70 cb de 79 3c 54-84 6e 6f 37 d2 5e fc dc |.Gp..y<T .no7.^..| >> 0060 b3 d5 5f 82 dc 06 13 2a-73 1e 22 6c 70 78 26 11 |.._....* s."lpx&.| >> 0070 81 7b 31 9a cd 49 35 39-dd 25 84 0c 81 4a 41 9e |.{1..I59 .%...JA.| >> 0080 b2 a4 28 ce 20 c3 3f d4-23 87 7d de 22 87 cd 24 |..(. .?. #.}."..$| >> 0090 31 - |1| >> >> token.c:337:looking for login token, got ed(AUTH) >> token.c:456:TDS_AUTH_TOKEN PDU size 134 >> token.c:337:looking for login token, got 60() >> token.c:122:tds_process_default_tokens() marker is 60() >> util.c:156:Changed query state from IDLE to DEAD >> util.c:331:tdserror(0x19149060, 0x1914a440, 20020, 0) >> odbc.c:2271:msgno 20020 20003 >> util.c:361:tdserror: client library returned TDS_INT_CANCEL(2) >> util.c:384:tdserror: returning TDS_INT_CANCEL(2) >> token.c:256:Unknown marker: 96(60)!! >> login.c:460:login packet accepted >> == end == >> >> Well, not exactly *accepted*. >> > > I see two problems. In gssapi.c tds_gss_handle_next is not expected to > receive authentication so it returns fail. In token.c, > tds_process_login_tokens fail for tds_process_auth is ignored leading to > protocol mismatch. To solve second just remove TDS_AUTH_TOKEN case in > tds_process_login_tokens. The first... I don't know, I note in gssapi.c > that there are some lines commented out > > /* > if (maj_stat == GSS_S_CONTINUE_NEEDED) { > if (recv_token(s, &token_flags, &recv_tok) < 0) { > (void) gss_release_name(&min_stat, > &target_name); > return -1; > } > token_ptr = &recv_tok; > } > */ > > Probably recv_token would read our authentication token !! > > freddy77 > Mumble... but is Kerberose the romantic version of Kerberos ?? :) Try this patch ;-) bye freddy77 _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds
kerberos.diff
(application/octet-stream, 4.8 KB)
Index: freetds92/src/tds/gssapi.c
===================================================================
--- freetds92.orig/src/tds/gssapi.c 2011-05-07 22:38:41.562516002 +0200
+++ freetds92/src/tds/gssapi.c 2011-05-07 22:38:41.582516002 +0200
@@ -86,6 +86,7 @@
gss_ctx_id_t gss_context;
gss_name_t target_name;
char *sname;
+ OM_uint32 last_stat;
} TDSGSSAUTH;
static int
@@ -111,10 +112,44 @@
return TDS_SUCCEED;
}
+static int tds_gss_continue(TDSSOCKET * tds, struct tds_gss_auth *auth, gss_buffer_desc *token_ptr);
+
static int
tds_gss_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t len)
{
- return TDS_FAIL;
+ int res;
+ gss_buffer_desc recv_tok;
+
+ if (((struct tds_gss_auth *) auth)->last_stat != GSS_S_CONTINUE_NEEDED)
+ return TDS_FAIL;
+
+ if (auth->packet) {
+ OM_uint32 min_stat;
+ gss_buffer_desc send_tok;
+
+ send_tok.value = (void *) auth->packet;
+ send_tok.length = auth->packet_len;
+ gss_release_buffer(&min_stat, &send_tok);
+ auth->packet = NULL;
+ }
+
+ recv_tok.length = len;
+ recv_tok.value = (char* ) malloc(len);
+ if (!recv_tok.value)
+ return TDS_FAIL;
+ tds_get_n(tds, recv_tok.value, len);
+
+ res = tds_gss_continue(tds, (struct tds_gss_auth *) auth, &recv_tok);
+ free(recv_tok.value);
+ if (res != TDS_SUCCEED)
+ return TDS_FAIL;
+
+ if (auth->packet_len) {
+ tds->out_flag = TDS7_AUTH;
+ tds_put_n(tds, auth->packet, auth->packet_len);
+ return tds_flush_packet(tds);
+ }
+ return TDS_SUCCEED;
}
/**
@@ -137,15 +172,13 @@
* a bit more verbose
* dinamically load library ??
*/
- gss_buffer_desc send_tok, *token_ptr;
+ gss_buffer_desc send_tok;
OM_uint32 maj_stat, min_stat;
/* 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" };
- OM_uint32 ret_flags;
const char *server_name;
/* Storage for reentrant getaddrby* calls */
char buffer[4096];
- int gssapi_flags;
struct tds_gss_auth *auth = (struct tds_gss_auth *) calloc(1, sizeof(struct tds_gss_auth));
@@ -154,6 +187,8 @@
auth->tds_auth.free = tds_gss_free;
auth->tds_auth.handle_next = tds_gss_handle_next;
+ auth->gss_context = GSS_C_NO_CONTEXT;
+ auth->last_stat = GSS_S_COMPLETE;
server_name = tds_dstr_cstr(&tds->connection->server_host_name);
if (strchr(server_name, '.') == NULL) {
@@ -178,11 +213,26 @@
send_tok.value = auth->sname;
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) {
+
+ if (maj_stat != GSS_S_COMPLETE
+ || tds_gss_continue(tds, auth, GSS_C_NO_BUFFER) == TDS_FAIL) {
tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
return NULL;
}
+ return (TDSAUTHENTICATION *) auth;
+}
+
+static int
+tds_gss_continue(TDSSOCKET * tds, struct tds_gss_auth *auth, gss_buffer_desc *token_ptr)
+{
+ gss_buffer_desc send_tok;
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 ret_flags;
+ int gssapi_flags;
+
+ auth->last_stat = GSS_S_COMPLETE;
+
send_tok.value = NULL;
send_tok.length = 0;
@@ -202,9 +252,6 @@
* and only if the server has another token to send us.
*/
- token_ptr = GSS_C_NO_BUFFER;
- auth->gss_context = GSS_C_NO_CONTEXT;
-
/* We may ask for delegation based on config in the tds.conf and other conf files */
/* We always want to ask for the mutual, replay, and integ flags */
gssapi_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG;
@@ -219,25 +266,10 @@
token_ptr, NULL, /* ignore mech type */
&send_tok, &ret_flags, NULL); /* ignore time_rec */
-/*
- if (token_ptr != GSS_C_NO_BUFFER)
- free(recv_tok.value);
-*/
-
-/*
- if (send_tok.length != 0) {
- if (send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok) < 0) {
- (void) gss_release_buffer(&min_stat, &send_tok);
- (void) gss_release_name(&min_stat, &target_name);
- return -1;
- }
-*/
-/* (void) gss_release_buffer(&min_stat, &send_tok); */
-
+ auth->last_stat = maj_stat;
if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
gss_release_buffer(&min_stat, &send_tok);
- tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
- return NULL;
+ return TDS_FAIL;
}
/*
@@ -252,7 +284,7 @@
auth->tds_auth.packet = (TDS_UCHAR *) send_tok.value;
auth->tds_auth.packet_len = send_tok.length;
- return (TDSAUTHENTICATION *) auth;
+ return TDS_SUCCEED;
}
#endif
Index: freetds92/src/tds/token.c
===================================================================
--- freetds92.orig/src/tds/token.c 2011-05-07 22:38:41.582516002 +0200
+++ freetds92/src/tds/token.c 2011-05-07 22:38:41.582516002 +0200
@@ -337,9 +337,6 @@
tdsdump_log(TDS_DBG_FUNC, "looking for login token, got %x(%s)\n", marker, tds_token_name(marker));
switch (marker) {
- case TDS_AUTH_TOKEN:
- tds_process_auth(tds);
- break;
case TDS_LOGINACK_TOKEN:
/* TODO function */
tds->tds71rev1 = 0;