From e2ad9a97623f80b7e36a0a8f418847d7d3d3b21f Mon Sep 17 00:00:00 2001 From: Victor Luna Date: Sat, 31 Oct 2026 11:51:23 -0500 Subject: [PATCH 1/4] feat: use Kerberos for -E trusted connections on Linux and macOS --- README.md | 13 +++++ go.mod | 7 +++ go.sum | 52 ++++++++++++++++++++ pkg/sqlcmd/kerberos.go | 68 ++++++++++++++++++++++++++ pkg/sqlcmd/kerberos_test.go | 95 +++++++++++++++++++++++++++++++++++++ pkg/sqlcmd/sqlcmd.go | 5 ++ 6 files changed, 240 insertions(+) create mode 100644 pkg/sqlcmd/kerberos.go create mode 100644 pkg/sqlcmd/kerberos_test.go diff --git a/README.md b/README.md index 4a4e436c..21a1befe 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,19 @@ These environment variables can be set to configure some aspects of AAD auth and `SQLCMDCLIENTID` - set this to the identifier of an application registered in your AAD which is authorized to authenticate to Azure SQL Database. Applies to `ActiveDirectoryInteractive` and `ActiveDirectoryPassword` methods. +### Kerberos Authentication on Linux and macOS + +On Linux and macOS, `-E` authenticates with Kerberos using the ticket from `kinit`. + +``` +kinit alice@EXAMPLE.COM +sqlcmd -S sqlhost.example.com,1433 -E +``` + +`KRB5_CONFIG` sets the location of `krb5.conf` (default `/etc/krb5.conf`) and `KRB5CCNAME` sets the credential cache (default `/tmp/krb5cc_`). Only `FILE:` caches are supported, so on Linux distributions that default to `KCM:` or `KEYRING:` (Fedora, RHEL), run `kinit -c FILE:...` and set `KRB5CCNAME`. + +macOS has no `krb5.conf` by default and keeps tickets in an `API:` cache that `sqlcmd` can't read. Create a `krb5.conf` and get a ticket in a file cache, for example `kinit -c FILE:/tmp/krb5cc_$(id -u) alice@EXAMPLE.COM`, or point `KRB5CCNAME` to one. + ### Console colors Sqlcmd now supports syntax coloring the output of `:list` and the results of TSQL queries when output to the terminal. diff --git a/go.mod b/go.mod index df7839da..1fc62ed0 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,14 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/gorilla/mux v1.8.1 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/goidentity/v6 v6.0.1 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/klauspost/compress v1.18.5 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.3 // indirect diff --git a/go.sum b/go.sum index 555b9193..dd48a799 100644 --- a/go.sum +++ b/go.sum @@ -91,10 +91,27 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -187,12 +204,19 @@ github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= @@ -215,34 +239,60 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= @@ -254,8 +304,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= diff --git a/pkg/sqlcmd/kerberos.go b/pkg/sqlcmd/kerberos.go new file mode 100644 index 00000000..12cb6de8 --- /dev/null +++ b/pkg/sqlcmd/kerberos.go @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package sqlcmd + +import ( + "fmt" + "net/url" + "os" + "runtime" + "strings" + + "github.com/microsoft/go-sqlcmd/internal/localizer" + + // Registers the "krb5" authenticator that -E uses outside Windows + _ "github.com/microsoft/go-mssqldb/integratedauth/krb5" +) + +// kerberosConnectionString adds the krb5 authenticator parameters for -E outside Windows, +// where the driver would otherwise default to NTLM, which needs a user name and password. +func kerberosConnectionString(connectionString string) (string, error) { + if runtime.GOOS == "windows" { + return connectionString, nil + } + configFile := os.Getenv("KRB5_CONFIG") + if configFile == "" { + configFile = "/etc/krb5.conf" + } + credCache, err := credentialCachePath(os.Getenv("KRB5CCNAME")) + if err != nil { + return "", err + } + u, err := url.Parse(connectionString) + if err != nil { + return "", err + } + query := u.Query() + query.Set("authenticator", "krb5") + query.Set("krb5-configfile", configFile) + // The driver reads KRBCCNAME, not the MIT standard KRB5CCNAME, so pass the cache explicitly + query.Set("krb5-credcachefile", credCache) + u.RawQuery = query.Encode() + return u.String(), nil +} + +// credentialCachePath returns the file of a FILE: credential cache name, defaulting to /tmp/krb5cc_ +func credentialCachePath(name string) (string, error) { + if name == "" { + return existingCacheFile(fmt.Sprintf("/tmp/krb5cc_%d", os.Getuid())) + } + cacheType, path, found := strings.Cut(name, ":") + if !found || strings.Contains(cacheType, "/") { + return name, nil + } + // The pure Go Kerberos client can't read API: (macOS default), KCM:, KEYRING: or DIR: caches + if !strings.EqualFold(cacheType, "FILE") { + return "", localizer.Errorf("Kerberos credential cache type %s is not supported. Use a FILE: cache in KRB5CCNAME.", cacheType) + } + return path, nil +} + +// existingCacheFile fails early when kinit hasn't written the default cache, instead of the driver's file-not-found error +func existingCacheFile(path string) (string, error) { + if _, err := os.Stat(path); err != nil { + return "", localizer.Errorf("No Kerberos credentials found in %s. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", path) + } + return path, nil +} diff --git a/pkg/sqlcmd/kerberos_test.go b/pkg/sqlcmd/kerberos_test.go new file mode 100644 index 00000000..85fb0e6f --- /dev/null +++ b/pkg/sqlcmd/kerberos_test.go @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package sqlcmd + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/microsoft/go-mssqldb/integratedauth" + "github.com/microsoft/go-mssqldb/msdsn" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCredentialCachePath(t *testing.T) { + tests := []struct { + name, ccname, path string + wantErr bool + }{ + {"FILE prefix", "FILE:/tmp/cc", "/tmp/cc", false}, + {"lowercase prefix", "file:/tmp/cc", "/tmp/cc", false}, + {"no prefix", "/tmp/cc", "/tmp/cc", false}, + {"colon in path", "/tmp/a:b", "/tmp/a:b", false}, + {"API", "API:1234", "", true}, + {"KCM", "KCM:1000", "", true}, + {"KEYRING", "KEYRING:persistent:1000", "", true}, + {"DIR", "DIR:/tmp/cc", "", true}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + path, err := credentialCachePath(test.ccname) + if test.wantErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, test.path, path) + }) + } +} + +func TestExistingCacheFile(t *testing.T) { + path := filepath.Join(t.TempDir(), "krb5cc_test") + _, err := existingCacheFile(path) + require.ErrorContains(t, err, "No Kerberos credentials found in "+path) + + require.NoError(t, os.WriteFile(path, nil, 0o600)) + got, err := existingCacheFile(path) + assert.NoError(t, err) + assert.Equal(t, path, got) +} + +func TestKerberosConnectionString(t *testing.T) { + t.Setenv("KRB5_CONFIG", "/tmp/krb5.conf") + t.Setenv("KRB5CCNAME", "FILE:/tmp/cc") + connect := ConnectSettings{UseTrustedConnection: true, ServerName: "sqlhost,1433"} + base, err := connect.ConnectionString() + require.NoError(t, err) + connstr, err := kerberosConnectionString(base) + require.NoError(t, err) + if runtime.GOOS == "windows" { + assert.Equal(t, base, connstr) + return + } + config, err := msdsn.Parse(connstr) + require.NoError(t, err) + assert.Equal(t, "krb5", config.Parameters["authenticator"]) + assert.Equal(t, "/tmp/krb5.conf", config.Parameters["krb5-configfile"]) + assert.Equal(t, "/tmp/cc", config.Parameters["krb5-credcachefile"]) + + t.Setenv("KRB5_CONFIG", "") + connstr, err = kerberosConnectionString(base) + require.NoError(t, err) + config, err = msdsn.Parse(connstr) + require.NoError(t, err) + assert.Equal(t, "/etc/krb5.conf", config.Parameters["krb5-configfile"]) + + t.Setenv("KRB5CCNAME", "API:1234") + _, err = kerberosConnectionString(base) + assert.Error(t, err) +} + +func TestKrb5ProviderRegistered(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("-E uses SSPI on Windows") + } + config, err := msdsn.Parse("sqlserver://sqlhost?authenticator=krb5&krb5-configfile=/tmp/krb5.conf&krb5-credcachefile=/tmp/cc") + require.NoError(t, err) + _, err = integratedauth.GetIntegratedAuthenticator(config) + assert.NotContains(t, fmt.Sprint(err), "unknown authenticator") +} diff --git a/pkg/sqlcmd/sqlcmd.go b/pkg/sqlcmd/sqlcmd.go index 93637a02..025e5420 100644 --- a/pkg/sqlcmd/sqlcmd.go +++ b/pkg/sqlcmd/sqlcmd.go @@ -271,6 +271,11 @@ func (s *Sqlcmd) ConnectDb(connect *ConnectSettings, nopw bool) error { if err != nil { return err } + if connect.UseTrustedConnection { + if connstr, err = kerberosConnectionString(connstr); err != nil { + return err + } + } if !useAad { var c *mssql.Connector From f4940d0f37946843413432ae46c223c3164dda9c Mon Sep 17 00:00:00 2001 From: Victor Luna Date: Sat, 31 Oct 2026 12:05:02 -0500 Subject: [PATCH 2/4] fix: skip Kerberos for SQL auth and report its errors on :connect --- pkg/sqlcmd/kerberos_test.go | 39 +++++++++++++++++++++++++++++++++++++ pkg/sqlcmd/sqlcmd.go | 5 ++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/pkg/sqlcmd/kerberos_test.go b/pkg/sqlcmd/kerberos_test.go index 85fb0e6f..9181979f 100644 --- a/pkg/sqlcmd/kerberos_test.go +++ b/pkg/sqlcmd/kerberos_test.go @@ -4,10 +4,12 @@ package sqlcmd import ( + "bytes" "fmt" "os" "path/filepath" "runtime" + "strings" "testing" "github.com/microsoft/go-mssqldb/integratedauth" @@ -93,3 +95,40 @@ func TestKrb5ProviderRegistered(t *testing.T) { _, err = integratedauth.GetIntegratedAuthenticator(config) assert.NotContains(t, fmt.Sprint(err), "unknown authenticator") } + +func TestConnectDbKerberos(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("-E uses SSPI on Windows") + } + t.Setenv("KRB5CCNAME", "API:x") + const unsupported = "is not supported" + tests := []struct { + name string + settings ConnectSettings + useCurrent bool + kerberos bool + printed bool + }{ + {"-E alone", ConnectSettings{UseTrustedConnection: true}, false, true, true}, + {"-E on current connection", ConnectSettings{UseTrustedConnection: true}, true, true, false}, + {"-E with SqlPassword", ConnectSettings{UseTrustedConnection: true, AuthenticationMethod: SqlPassword, UserName: "u", Password: "p"}, false, false, false}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.settings.ServerName = "127.0.0.1:1" + s := New(nil, "", InitializeVariables(false)) + buf := &memoryBuffer{buf: new(bytes.Buffer)} + s.SetOutput(buf) + var err error + if test.useCurrent { + s.Connect = &test.settings + err = s.ConnectDb(nil, true) + } else { + err = s.ConnectDb(&test.settings, true) + } + require.Error(t, err) + assert.Equal(t, test.kerberos, strings.Contains(err.Error(), unsupported), "error: %v", err) + assert.Equal(t, test.printed, strings.Contains(buf.buf.String(), unsupported), "output: %q", buf.buf.String()) + }) + } +} diff --git a/pkg/sqlcmd/sqlcmd.go b/pkg/sqlcmd/sqlcmd.go index 025e5420..16e49665 100644 --- a/pkg/sqlcmd/sqlcmd.go +++ b/pkg/sqlcmd/sqlcmd.go @@ -271,8 +271,11 @@ func (s *Sqlcmd) ConnectDb(connect *ConnectSettings, nopw bool) error { if err != nil { return err } - if connect.UseTrustedConnection { + if connect.UseTrustedConnection && !connect.sqlAuthentication() { if connstr, err = kerberosConnectionString(connstr); err != nil { + if newConnection { + fmt.Fprintln(s.GetOutput(), err) + } return err } } From 0b762a76bb501b7b1ef5d23fc7acfdf87a6762b9 Mon Sep 17 00:00:00 2001 From: Victor Luna Date: Sat, 31 Oct 2026 12:29:48 -0500 Subject: [PATCH 3/4] chore: regenerate translations --- internal/translations/catalog.go | 95 +++++++++++-------- .../locales/de-DE/out.gotext.json | 58 +++++++++++ .../locales/en-US/out.gotext.json | 66 +++++++++++++ .../locales/es-ES/out.gotext.json | 58 +++++++++++ .../locales/fr-FR/out.gotext.json | 58 +++++++++++ .../locales/it-IT/out.gotext.json | 58 +++++++++++ .../locales/ja-JP/out.gotext.json | 58 +++++++++++ .../locales/ko-KR/out.gotext.json | 58 +++++++++++ .../locales/pt-BR/out.gotext.json | 58 +++++++++++ .../locales/ru-RU/out.gotext.json | 58 +++++++++++ .../locales/zh-CN/out.gotext.json | 58 +++++++++++ .../locales/zh-TW/out.gotext.json | 58 +++++++++++ 12 files changed, 704 insertions(+), 37 deletions(-) diff --git a/internal/translations/catalog.go b/internal/translations/catalog.go index adcbf40e..e50f9335 100644 --- a/internal/translations/catalog.go +++ b/internal/translations/catalog.go @@ -152,6 +152,7 @@ var messageKeyToIndex = map[string]int{ "Display one or many users from the sqlconfig file": 142, "Display raw byte data": 159, "Display the current-context": 106, + "Do not strip the \"mssql: \" prefix from error messages": 307, "Don't download image. Use already downloaded image": 169, "Download (into container) and attach database (.bak) from URL": 176, "Downloading %s": 196, @@ -193,6 +194,7 @@ var messageKeyToIndex = map[string]int{ "Invalid variable value %s": 302, "Is a container runtime installed on this machine (e.g. Podman or Docker)?": 199, "Is a container runtime running? (Try `%s` or `%s` (list containers), does it return without error?)": 202, + "Kerberos credential cache type %s is not supported. Use a FILE: cache in KRB5CCNAME.": 308, "Legal docs and information: aka.ms/SqlcmdLegal": 223, "Level of mssql driver messages to print": 253, "Line in errorlog to wait for before connecting": 170, @@ -216,14 +218,15 @@ var messageKeyToIndex = map[string]int{ "Name of user to delete": 122, "New password": 271, "New password and exit": 272, - "No context exists with the name: \"%v\"": 155, - "No current context": 20, - "No endpoints to uninstall": 50, - "Now ready for client connections on port %#v": 189, - "Open in Azure Data Studio": 64, - "Open tools (e.g Azure Data Studio) for current context": 10, - "Or, set the environment variable i.e. %s %s=YES ": 178, - "Pass in the %s %s": 89, + "No Kerberos credentials found in %s. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.": 309, + "No context exists with the name: \"%v\"": 155, + "No current context": 20, + "No endpoints to uninstall": 50, + "Now ready for client connections on port %#v": 189, + "Open in Azure Data Studio": 64, + "Open tools (e.g Azure Data Studio) for current context": 10, + "Or, set the environment variable i.e. %s %s=YES ": 178, + "Pass in the %s %s": 89, "Pass in the flag %s to override this safety check for user (non-system) databases": 48, "Password": 261, "Password encryption method (%s) in sqlconfig file": 85, @@ -231,7 +234,8 @@ var messageKeyToIndex = map[string]int{ "Port (next available port from 1433 upwards used by default)": 175, "Press Ctrl+C to exit this process...": 216, "Print version information and exit": 231, - "Prints the output in vertical format. This option sets the sqlcmd scripting variable %s to '%s'. The default is false": 251, + "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable %s to '%s'. The default is false": 306, + "Prints the output in vertical format. This option sets the sqlcmd scripting variable %s to '%s'. The default is false": 251, "Provide a username with the %s flag": 95, "Provide a valid encryption method (%s) with the %s flag": 97, "Provide password in the %s (or %s) environment variable": 93, @@ -250,7 +254,7 @@ var messageKeyToIndex = map[string]int{ "Run a query using [%s] database": 13, "See all release tags for SQL Server, install previous version": 207, "See connection strings": 187, - "Server name override is not supported with the current authentication method": 306, + "Server name override is not supported with the current authentication method": 310, "Servers:": 222, "Set new default database": 14, "Set the current context": 149, @@ -357,7 +361,7 @@ var messageKeyToIndex = map[string]int{ "sqlcmd: Install/Create/Query SQL Server, Azure SQL, and Tools": 285, } -var de_DEIndex = []uint32{ // 308 elements +var de_DEIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x0000003c, 0x0000007e, 0x00000096, 0x000000d1, 0x000000e9, 0x000000fd, 0x00000148, @@ -445,7 +449,8 @@ var de_DEIndex = []uint32{ // 308 elements 0x00004cbf, 0x00004d1a, 0x00004d65, 0x00004d6f, 0x00004d83, 0x00004d9c, 0x00004dc2, 0x00004de2, 0x00004de2, 0x00004de2, 0x00004de2, 0x00004de2, -} // Size: 1256 bytes + 0x00004de2, 0x00004de2, 0x00004de2, 0x00004de2, +} // Size: 1272 bytes const de_DEData string = "" + // Size: 19938 bytes "\x02SQL Server installieren/erstellen, abfragen, deinstallieren\x02Konfi" + @@ -738,7 +743,7 @@ const de_DEData string = "" + // Size: 19938 bytes ":\x02(1 Zeile betroffen)\x02(%[1]d Zeilen betroffen)\x02Ungültiger Varia" + "blenbezeichner %[1]s\x02Ungültiger Variablenwert %[1]s" -var en_USIndex = []uint32{ // 308 elements +var en_USIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x0000002c, 0x00000062, 0x0000007a, 0x000000b3, 0x000000cb, 0x000000de, 0x00000113, @@ -825,10 +830,11 @@ var en_USIndex = []uint32{ // 308 elements 0x00003bf5, 0x00003c26, 0x00003c75, 0x00003c95, 0x00003ca5, 0x00003cfb, 0x00003d40, 0x00003d4a, 0x00003d5b, 0x00003d71, 0x00003d93, 0x00003db0, - 0x00003e0a, 0x00003eba, 0x00003fb5, 0x00004002, -} // Size: 1256 bytes + 0x00003e0a, 0x00003eba, 0x00003fb5, 0x00004034, + 0x0000406a, 0x000040c2, 0x00004130, 0x0000417d, +} // Size: 1272 bytes -const en_USData string = "" + // Size: 16386 bytes +const en_USData string = "" + // Size: 16765 bytes "\x02Install/Create, Query, Uninstall SQL Server\x02View configuration in" + "formation and connection strings\x04\x02\x0a\x0a\x00\x12\x02Feedback:" + "\x0a %[1]s\x02help for backwards compatibility flags (-S, -U, -E etc.)" + @@ -1070,10 +1076,16 @@ const en_USData string = "" + // Size: 16386 bytes "r name sent to SQL Server.\x02Specifies the path to a server certificate" + " file (PEM, DER, or CER) to match against the server's TLS certificate. " + "Use when encryption is enabled (-N true, -N mandatory, or -N strict) for" + - " certificate pinning instead of standard certificate validation.\x02Serv" + - "er name override is not supported with the current authentication method" + " certificate pinning instead of standard certificate validation.\x02Prin" + + "ts the output in ASCII table format. This option sets the sqlcmd scripti" + + "ng variable %[1]s to '%[2]s'. The default is false\x02Do not strip the " + + "\x22mssql: \x22 prefix from error messages\x02Kerberos credential cache " + + "type %[1]s is not supported. Use a FILE: cache in KRB5CCNAME.\x02No Kerb" + + "eros credentials found in %[1]s. Run kinit to get a ticket in a FILE: ca" + + "che, or set KRB5CCNAME to one.\x02Server name override is not supported " + + "with the current authentication method" -var es_ESIndex = []uint32{ // 308 elements +var es_ESIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x00000032, 0x00000081, 0x0000009c, 0x000000ec, 0x0000010d, 0x00000127, 0x0000017f, @@ -1161,7 +1173,8 @@ var es_ESIndex = []uint32{ // 308 elements 0x00004c6c, 0x00004ccf, 0x00004d1d, 0x00004d2a, 0x00004d3c, 0x00004d54, 0x00004d7f, 0x00004da2, 0x00004da2, 0x00004da2, 0x00004da2, 0x00004da2, -} // Size: 1256 bytes + 0x00004da2, 0x00004da2, 0x00004da2, 0x00004da2, +} // Size: 1272 bytes const es_ESData string = "" + // Size: 19874 bytes "\x02Instalar/Crear, Consultar, Desinstalar SQL Server\x02Visualización d" + @@ -1455,7 +1468,7 @@ const es_ESData string = "" + // Size: 19874 bytes " afectadas)\x02Identificador de variable %[1]s no válido\x02Valor de var" + "iable %[1]s no válido" -var fr_FRIndex = []uint32{ // 308 elements +var fr_FRIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x00000037, 0x0000007f, 0x0000009d, 0x000000e1, 0x000000fe, 0x00000117, 0x00000169, @@ -1543,7 +1556,8 @@ var fr_FRIndex = []uint32{ // 308 elements 0x00004fbe, 0x00005014, 0x00005059, 0x00005069, 0x0000507e, 0x00005098, 0x000050bf, 0x000050e1, 0x000050e1, 0x000050e1, 0x000050e1, 0x000050e1, -} // Size: 1256 bytes + 0x000050e1, 0x000050e1, 0x000050e1, 0x000050e1, +} // Size: 1272 bytes const fr_FRData string = "" + // Size: 20705 bytes "\x02Installer/créer, interroger, désinstaller SQL Server\x02Afficher les" + @@ -1847,7 +1861,7 @@ const fr_FRData string = "" + // Size: 20705 bytes "\x02Identifiant de variable invalide %[1]s\x02Valeur de variable invalid" + "e %[1]s" -var it_ITIndex = []uint32{ // 308 elements +var it_ITIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x0000003c, 0x00000088, 0x000000a0, 0x000000f7, 0x00000114, 0x0000012b, 0x0000016a, @@ -1935,7 +1949,8 @@ var it_ITIndex = []uint32{ // 308 elements 0x00004a16, 0x00004a74, 0x00004ac1, 0x00004acb, 0x00004ae0, 0x00004afa, 0x00004b2a, 0x00004b52, 0x00004b52, 0x00004b52, 0x00004b52, 0x00004b52, -} // Size: 1256 bytes + 0x00004b52, 0x00004b52, 0x00004b52, 0x00004b52, +} // Size: 1272 bytes const it_ITData string = "" + // Size: 19282 bytes "\x02Installare/creare, eseguire query, disinstallare SQL Server\x02Visua" + @@ -2221,7 +2236,7 @@ const it_ITData string = "" + // Size: 19282 bytes "riga interessata)\x02(%[1]d righe interessate)\x02Identificatore della v" + "ariabile %[1]s non valido\x02Valore della variabile %[1]s non valido" -var ja_JPIndex = []uint32{ // 308 elements +var ja_JPIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x0000004f, 0x00000077, 0x0000009d, 0x000000d8, 0x000000f8, 0x0000010b, 0x0000014c, @@ -2309,7 +2324,8 @@ var ja_JPIndex = []uint32{ // 308 elements 0x00005d02, 0x00005d7c, 0x00005ddb, 0x00005dec, 0x00005e0c, 0x00005e30, 0x00005e56, 0x00005e79, 0x00005e79, 0x00005e79, 0x00005e79, 0x00005e79, -} // Size: 1256 bytes + 0x00005e79, 0x00005e79, 0x00005e79, 0x00005e79, +} // Size: 1272 bytes const ja_JPData string = "" + // Size: 24185 bytes "\x02インストール/作成、クエリ、SQL Server のアンインストール\x02構成情報と接続文字列の表示\x04\x02\x0a\x0a" + @@ -2474,7 +2490,7 @@ const ja_JPData string = "" + // Size: 24185 bytes "\x02パスワード:\x02(1 行が影響を受けます)\x02(%[1]d 行が影響を受けます)\x02変数識別子 %[1]s が無効です" + "\x02変数値の %[1]s が無効です" -var ko_KRIndex = []uint32{ // 308 elements +var ko_KRIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x00000029, 0x00000053, 0x0000006c, 0x000000b8, 0x000000d0, 0x000000de, 0x00000121, @@ -2562,7 +2578,8 @@ var ko_KRIndex = []uint32{ // 308 elements 0x00004cc5, 0x00004d25, 0x00004d71, 0x00004d79, 0x00004d8e, 0x00004dae, 0x00004dcf, 0x00004dea, 0x00004dea, 0x00004dea, 0x00004dea, 0x00004dea, -} // Size: 1256 bytes + 0x00004dea, 0x00004dea, 0x00004dea, 0x00004dea, +} // Size: 1272 bytes const ko_KRData string = "" + // Size: 19946 bytes "\x02SQL Server 설치/생성, 쿼리, 제거\x02구성 정보 및 연결 문자열 보기\x04\x02\x0a\x0a\x00" + @@ -2719,7 +2736,7 @@ const ko_KRData string = "" + // Size: 19946 bytes "%[6]s\x02암호:\x02(1개 행 적용됨)\x02(영향을 받은 행 %[1]d개)\x02잘못된 변수 식별자 %[1]s\x02잘" + "못된 변수 값 %[1]s" -var pt_BRIndex = []uint32{ // 308 elements +var pt_BRIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x00000034, 0x00000071, 0x0000008d, 0x000000e3, 0x00000103, 0x0000011e, 0x0000016d, @@ -2807,7 +2824,8 @@ var pt_BRIndex = []uint32{ // 308 elements 0x00004920, 0x0000497e, 0x000049c8, 0x000049cf, 0x000049e1, 0x000049f9, 0x00004a24, 0x00004a47, 0x00004a47, 0x00004a47, 0x00004a47, 0x00004a47, -} // Size: 1256 bytes + 0x00004a47, 0x00004a47, 0x00004a47, 0x00004a47, +} // Size: 1272 bytes const pt_BRData string = "" + // Size: 19015 bytes "\x02Instalar/Criar, Consultar, Desinstalar o SQL Server\x02Exibir inform" + @@ -3087,7 +3105,7 @@ const pt_BRData string = "" + // Size: 19015 bytes "fetada)\x02(%[1]d linhas afetadas)\x02Identificador de variável %[1]s in" + "válido\x02Valor de variável inválido %[1]s" -var ru_RUIndex = []uint32{ // 308 elements +var ru_RUIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x00000056, 0x000000c1, 0x000000ec, 0x00000151, 0x00000172, 0x00000195, 0x0000023b, @@ -3175,7 +3193,8 @@ var ru_RUIndex = []uint32{ // 308 elements 0x00007e41, 0x00007ed3, 0x00007f4b, 0x00007f59, 0x00007f7d, 0x00007fa4, 0x00007ff3, 0x00008038, 0x00008038, 0x00008038, 0x00008038, 0x00008038, -} // Size: 1256 bytes + 0x00008038, 0x00008038, 0x00008038, 0x00008038, +} // Size: 1272 bytes const ru_RUData string = "" + // Size: 32824 bytes "\x02Установка или создание, запрос, удаление SQL Server\x02Просмотреть с" + @@ -3464,7 +3483,7 @@ const ru_RUData string = "" + // Size: 32824 bytes "идентификатор переменной %[1]s\x02Недопустимое значение переменной %[1]" + "s" -var zh_CNIndex = []uint32{ // 308 elements +var zh_CNIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x0000002b, 0x00000050, 0x00000065, 0x00000096, 0x000000ab, 0x000000b8, 0x000000fc, @@ -3552,7 +3571,8 @@ var zh_CNIndex = []uint32{ // 308 elements 0x00003805, 0x00003861, 0x000038ae, 0x000038b6, 0x000038c7, 0x000038dc, 0x000038f9, 0x00003910, 0x00003910, 0x00003910, 0x00003910, 0x00003910, -} // Size: 1256 bytes + 0x00003910, 0x00003910, 0x00003910, 0x00003910, +} // Size: 1272 bytes const zh_CNData string = "" + // Size: 14608 bytes "\x02安装/创建、查询、卸载 SQL Server\x02查看配置信息和连接字符串\x04\x02\x0a\x0a\x00\x0f\x02反馈" + @@ -3673,7 +3693,7 @@ const zh_CNData string = "" + // Size: 14608 bytes "[5]s,行 %#[6]v%[7]s\x02Msg %#[1]v,级别 %[2]d,状态 %[3]d,服务器 %[4]s,行 %#[5]v%[6" + "]s\x02密码:\x02(1 行受影响)\x02(%[1]d 行受影响)\x02变量标识符 %[1]s 无效\x02变量值 %[1]s 无效" -var zh_TWIndex = []uint32{ // 308 elements +var zh_TWIndex = []uint32{ // 312 elements // Entry 0 - 1F 0x00000000, 0x00000031, 0x00000053, 0x0000006e, 0x000000a1, 0x000000b8, 0x000000c2, 0x00000106, @@ -3761,7 +3781,8 @@ var zh_TWIndex = []uint32{ // 308 elements 0x00003853, 0x000038b2, 0x00003902, 0x0000390a, 0x00003924, 0x00003942, 0x00003961, 0x00003978, 0x00003978, 0x00003978, 0x00003978, 0x00003978, -} // Size: 1256 bytes + 0x00003978, 0x00003978, 0x00003978, 0x00003978, +} // Size: 1272 bytes const zh_TWData string = "" + // Size: 14712 bytes "\x02安裝/建立、查詢、解除安裝 SQL Server\x02檢視組態資訊和連接字串\x04\x02\x0a\x0a\x00\x15\x02意" + @@ -3880,4 +3901,4 @@ const zh_TWData string = "" + // Size: 14712 bytes "#[5]v%[6]s\x02密碼:\x02(1 個資料列受影響)\x02(%[1]d 個資料列受影響)\x02無效的變數識別碼 %[1]s" + "\x02變數值 %[1]s 無效" - // Total table size 235291 bytes (229KiB); checksum: AA9B2EAD + // Total table size 235846 bytes (230KiB); checksum: 422808F2 diff --git a/internal/translations/locales/de-DE/out.gotext.json b/internal/translations/locales/de-DE/out.gotext.json index 5e74cf30..014f2b89 100644 --- a/internal/translations/locales/de-DE/out.gotext.json +++ b/internal/translations/locales/de-DE/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/en-US/out.gotext.json b/internal/translations/locales/en-US/out.gotext.json index 21772c8d..01a63a85 100644 --- a/internal/translations/locales/en-US/out.gotext.json +++ b/internal/translations/locales/en-US/out.gotext.json @@ -2847,6 +2847,31 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ], + "fuzzy": true + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2905,6 +2930,13 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "Do not strip the \"mssql: \" prefix from error messages", + "translatorComment": "Copied from source.", + "fuzzy": true + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3661,6 +3693,40 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ], + "fuzzy": true + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ], + "fuzzy": true + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/es-ES/out.gotext.json b/internal/translations/locales/es-ES/out.gotext.json index 66b51962..3605e811 100644 --- a/internal/translations/locales/es-ES/out.gotext.json +++ b/internal/translations/locales/es-ES/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/fr-FR/out.gotext.json b/internal/translations/locales/fr-FR/out.gotext.json index d09d0a6d..1c571c9b 100644 --- a/internal/translations/locales/fr-FR/out.gotext.json +++ b/internal/translations/locales/fr-FR/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/it-IT/out.gotext.json b/internal/translations/locales/it-IT/out.gotext.json index b320dd5c..8c53c739 100644 --- a/internal/translations/locales/it-IT/out.gotext.json +++ b/internal/translations/locales/it-IT/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/ja-JP/out.gotext.json b/internal/translations/locales/ja-JP/out.gotext.json index 55cd0a6c..81570ef1 100644 --- a/internal/translations/locales/ja-JP/out.gotext.json +++ b/internal/translations/locales/ja-JP/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/ko-KR/out.gotext.json b/internal/translations/locales/ko-KR/out.gotext.json index c7bfe94a..bd40ea47 100644 --- a/internal/translations/locales/ko-KR/out.gotext.json +++ b/internal/translations/locales/ko-KR/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/pt-BR/out.gotext.json b/internal/translations/locales/pt-BR/out.gotext.json index 6ca60db9..3af8fb07 100644 --- a/internal/translations/locales/pt-BR/out.gotext.json +++ b/internal/translations/locales/pt-BR/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/ru-RU/out.gotext.json b/internal/translations/locales/ru-RU/out.gotext.json index e57c1ca7..3948ac18 100644 --- a/internal/translations/locales/ru-RU/out.gotext.json +++ b/internal/translations/locales/ru-RU/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/zh-CN/out.gotext.json b/internal/translations/locales/zh-CN/out.gotext.json index 145eb3ac..d72d3046 100644 --- a/internal/translations/locales/zh-CN/out.gotext.json +++ b/internal/translations/locales/zh-CN/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", diff --git a/internal/translations/locales/zh-TW/out.gotext.json b/internal/translations/locales/zh-TW/out.gotext.json index ee4e808c..98d3ded1 100644 --- a/internal/translations/locales/zh-TW/out.gotext.json +++ b/internal/translations/locales/zh-TW/out.gotext.json @@ -2841,6 +2841,29 @@ ], "fuzzy": true }, + { + "id": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "message": "Prints the output in ASCII table format. This option sets the sqlcmd scripting variable {SQLCMDFORMAT} to '{Ascii}'. The default is false", + "translation": "", + "placeholders": [ + { + "id": "SQLCMDFORMAT", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "sqlcmd.SQLCMDFORMAT" + }, + { + "id": "Ascii", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "\"ascii\"" + } + ] + }, { "id": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "message": "{_r0__1} Redirects error messages with severity \u003e= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", @@ -2899,6 +2922,11 @@ ], "fuzzy": true }, + { + "id": "Do not strip the \"mssql: \" prefix from error messages", + "message": "Do not strip the \"mssql: \" prefix from error messages", + "translation": "" + }, { "id": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", "message": "Specifies the number of rows to print between the column headings. Use -h-1 to specify that headers not be printed", @@ -3655,6 +3683,36 @@ ], "fuzzy": true }, + { + "id": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "message": "Kerberos credential cache type {CacheType} is not supported. Use a FILE: cache in KRB5CCNAME.", + "translation": "", + "placeholders": [ + { + "id": "CacheType", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "cacheType" + } + ] + }, + { + "id": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "message": "No Kerberos credentials found in {Path}. Run kinit to get a ticket in a FILE: cache, or set KRB5CCNAME to one.", + "translation": "", + "placeholders": [ + { + "id": "Path", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "path" + } + ] + }, { "id": "Server name override is not supported with the current authentication method", "message": "Server name override is not supported with the current authentication method", From b04f6ea0d4656dd2c9bd53d3ff884805be2dae08 Mon Sep 17 00:00:00 2001 From: Victor Luna Date: Sat, 31 Oct 2026 12:56:07 -0500 Subject: [PATCH 4/4] fix: check Fprintln result for errcheck --- pkg/sqlcmd/sqlcmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/sqlcmd/sqlcmd.go b/pkg/sqlcmd/sqlcmd.go index 16e49665..232894cb 100644 --- a/pkg/sqlcmd/sqlcmd.go +++ b/pkg/sqlcmd/sqlcmd.go @@ -274,7 +274,7 @@ func (s *Sqlcmd) ConnectDb(connect *ConnectSettings, nopw bool) error { if connect.UseTrustedConnection && !connect.sqlAuthentication() { if connstr, err = kerberosConnectionString(connstr); err != nil { if newConnection { - fmt.Fprintln(s.GetOutput(), err) + _, _ = fmt.Fprintln(s.GetOutput(), err) } return err }