diff --git a/cmd/sqlcmd/sqlcmd.go b/cmd/sqlcmd/sqlcmd.go index b11c5d04..064312b8 100644 --- a/cmd/sqlcmd/sqlcmd.go +++ b/cmd/sqlcmd/sqlcmd.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" + mssql "github.com/microsoft/go-mssqldb" "github.com/microsoft/go-mssqldb/azuread" "github.com/microsoft/go-sqlcmd/internal/localizer" "github.com/microsoft/go-sqlcmd/pkg/console" @@ -70,7 +71,9 @@ type SQLCmdArguments struct { RemoveControlCharacters *int EchoInput bool QueryTimeout int - EnableColumnEnryption bool + EnableColumnEncryption bool + ChangePassword string + ChangePasswordAndExit string // Keep Help at the end of the list Help bool } @@ -423,7 +426,9 @@ func setFlags(rootCmd *cobra.Command, args *SQLCmdArguments) { _ = rootCmd.Flags().IntP(removeControlCharacters, "k", 0, localizer.Sprintf("%s Remove control characters from output. Pass 1 to substitute a space per character, 2 for a space per consecutive characters", "-k [1|2]")) rootCmd.Flags().BoolVarP(&args.EchoInput, "echo-input", "e", false, localizer.Sprintf("Echo input")) rootCmd.Flags().IntVarP(&args.QueryTimeout, "query-timeout", "t", 0, "Query timeout") - rootCmd.Flags().BoolVarP(&args.EnableColumnEnryption, "enable-column-encryption", "g", false, localizer.Sprintf("Enable column encryption")) + rootCmd.Flags().BoolVarP(&args.EnableColumnEncryption, "enable-column-encryption", "g", false, localizer.Sprintf("Enable column encryption")) + rootCmd.Flags().StringVarP(&args.ChangePassword, "change-password", "z", "", localizer.Sprintf("New password")) + rootCmd.Flags().StringVarP(&args.ChangePasswordAndExit, "change-password-exit", "Z", "", localizer.Sprintf("New password and exit")) } func setScriptVariable(v string) string { @@ -682,11 +687,17 @@ func setConnect(connect *sqlcmd.ConnectSettings, args *SQLCmdArguments, vars *sq connect.ExitOnError = args.ExitOnError connect.ErrorSeverityLevel = args.ErrorSeverityLevel connect.DedicatedAdminConnection = args.DedicatedAdminConnection - connect.EnableColumnEnryption = args.EnableColumnEnryption + connect.EnableColumnEncryption = args.EnableColumnEncryption + if len(args.ChangePassword) > 0 { + connect.ChangePassword = args.ChangePassword + } + if len(args.ChangePasswordAndExit) > 0 { + connect.ChangePassword = args.ChangePasswordAndExit + } } func isConsoleInitializationRequired(connect *sqlcmd.ConnectSettings, args *SQLCmdArguments) bool { - iactive := args.InputFile == nil && args.Query == "" + iactive := args.InputFile == nil && args.Query == "" && len(args.ChangePasswordAndExit) == 0 return iactive || connect.RequiresPassword() } @@ -749,8 +760,23 @@ func run(vars *sqlcmd.Variables, args *SQLCmdArguments) (int, error) { // connect using no overrides err = s.ConnectDb(nil, line == nil) if err != nil { - s.WriteError(s.GetError(), err) - return 1, err + switch e := err.(type) { + // 18488 == password must be changed on connection + case mssql.Error: + if e.Number == 18488 && line != nil && len(args.Password) == 0 && len(args.ChangePassword) == 0 && len(args.ChangePasswordAndExit) == 0 { + b, _ := line.ReadPassword(localizer.Sprintf("Enter new password:")) + s.Connect.ChangePassword = string(b) + err = s.ConnectDb(nil, true) + } + } + if err != nil { + s.WriteError(s.GetError(), err) + return 1, err + } + } + + if len(args.ChangePasswordAndExit) > 0 { + return 0, nil } script := vars.StartupScriptFile() diff --git a/cmd/sqlcmd/sqlcmd_test.go b/cmd/sqlcmd/sqlcmd_test.go index df5c6cad..057926ac 100644 --- a/cmd/sqlcmd/sqlcmd_test.go +++ b/cmd/sqlcmd/sqlcmd_test.go @@ -96,8 +96,8 @@ func TestValidCommandLineToArgsConversion(t *testing.T) { {[]string{"-i", `"comma,text.sql"`}, func(args SQLCmdArguments) bool { return args.InputFile[0] == "comma,text.sql" }}, - {[]string{"-k", "-X", "-r"}, func(args SQLCmdArguments) bool { - return args.warnOnBlockedCmd() && !args.useEnvVars() && args.getControlCharacterBehavior() == sqlcmd.ControlRemove && *args.ErrorsToStderr == 0 + {[]string{"-k", "-X", "-r", "-z", "something"}, func(args SQLCmdArguments) bool { + return args.warnOnBlockedCmd() && !args.useEnvVars() && args.getControlCharacterBehavior() == sqlcmd.ControlRemove && *args.ErrorsToStderr == 0 && args.ChangePassword == "something" }}, } diff --git a/internal/translations/catalog.go b/internal/translations/catalog.go index f6112c0d..252042cd 100644 --- a/internal/translations/catalog.go +++ b/internal/translations/catalog.go @@ -165,6 +165,7 @@ var messageKeyToIndex = map[string]int{ "Endpoint name must be provided. Provide endpoint name with %s flag": 117, "Endpoint name to view details of": 138, "Endpoint required to add context. Endpoint '%v' does not exist. Use %s flag": 59, + "Enter new password:": 296, "Executes a query when sqlcmd starts and then immediately exits sqlcmd. Multiple-semicolon-delimited queries can be executed": 240, "Executes a query when sqlcmd starts, but does not exit sqlcmd when the query has finished running. Multiple-semicolon-delimited queries can be executed": 239, "Explicitly set the container hostname, it defaults to the container ID": 174, @@ -200,30 +201,33 @@ var messageKeyToIndex = map[string]int{ "List all the endpoints in your sqlconfig file": 136, "List all the users in your sqlconfig file": 143, "List connection strings for all client drivers": 103, - "List tags": 215, - "Minimum number of numeric characters": 168, - "Minimum number of special characters": 167, - "Minimum number of upper characters": 169, - "Modify sqlconfig files using subcommands like \"%s\"": 7, - "Msg %#v, Level %d, State %d, Server %s, Line %#v%s": 284, - "Msg %#v, Level %d, State %d, Server %s, Procedure %s, Line %#v%s": 283, - "Name of context to delete": 110, - "Name of context to set as current context": 151, - "Name of endpoint this context will use": 54, - "Name of endpoint to delete": 116, - "Name of user this context will use": 55, - "Name of user to delete": 122, - "No context exists with the name: \"%v\"": 155, - "No current context": 20, - "No endpoints to uninstall": 50, - "Now ready for client connections on port %d": 191, - "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 ": 180, - "Pass in the %s %s": 89, + "List tags": 215, + "Minimum number of numeric characters": 168, + "Minimum number of special characters": 167, + "Minimum number of upper characters": 169, + "Modify sqlconfig files using subcommands like \"%s\"": 7, + "Msg %#v, Level %d, State %d, Server %s, Line %#v%s": 284, + "Msg %#v, Level %d, State %d, Server %s, Procedure %s, Line %#v%s": 283, + "Name of context to delete": 110, + "Name of context to set as current context": 151, + "Name of endpoint this context will use": 54, + "Name of endpoint to delete": 116, + "Name of user this context will use": 55, + "Name of user to delete": 122, + "New password": 294, + "New password and exit": 295, + "No context exists with the name: \"%v\"": 155, + "No current context": 20, + "No endpoints to uninstall": 50, + "Now ready for client connections on port %d": 191, + "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 ": 180, + "Pass in the %s %s": 89, "Pass in the flag %s to override this safety check for user (non-system) databases": 48, "Password": 259, - "Password encryption method (%s) in sqlconfig file": 85, + "Password encryption method (%s) in sqlconfig file": 85, + "Password:": 298, "Port (next available port from 1433 upwards used by default)": 177, "Press Ctrl+C to exit this process...": 219, "Print version information and exit": 233, @@ -294,7 +298,7 @@ var messageKeyToIndex = map[string]int{ "This option sets the sqlcmd scripting variable %s. The workstation name is listed in the hostname column of the sys.sysprocesses catalog view and can be returned using the stored procedure sp_who. If this option is not specified, the default is the current computer name. This name can be used to identify different sqlcmd sessions": 247, "This option sets the sqlcmd scripting variable %s. This parameter specifies the initial database. The default is your login's default-database property. If the database does not exist, an error message is generated and sqlcmd exits": 235, "This switch is used by the client to request an encrypted connection": 249, - "Timeout expired": 294, + "Timeout expired": 297, "To override the check, use %s": 40, "To remove: %s": 153, "To run a query": 66, @@ -345,7 +349,7 @@ var messageKeyToIndex = map[string]int{ "sqlcmd: Install/Create/Query SQL Server, Azure SQL, and Tools\n\nFeedback:\n %s": 2, } -var de_DEIndex = []uint32{ // 296 elements +var de_DEIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x0000003c, 0x0000007e, 0x000000d8, 0x00000113, 0x0000012b, 0x0000013f, 0x0000018a, @@ -430,7 +434,8 @@ var de_DEIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00004975, 0x00004975, 0x00004975, 0x00004975, 0x00004975, 0x00004975, 0x00004975, 0x00004975, -} // Size: 1208 bytes + 0x00004975, 0x00004975, 0x00004975, 0x00004975, +} // Size: 1224 bytes const de_DEData string = "" + // Size: 18805 bytes "\x02SQL Server installieren/erstellen, abfragen, deinstallieren\x02Konfi" + @@ -707,7 +712,7 @@ const de_DEData string = "" + // Size: 18805 bytes "#[5]v%[6]s\x02Ungültiger Variablenbezeichner %[1]s\x02Ungültiger Variabl" + "enwert %[1]s" -var en_USIndex = []uint32{ // 296 elements +var en_USIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x0000002c, 0x00000062, 0x000000b3, 0x000000ec, 0x00000104, 0x00000117, 0x0000014c, @@ -791,10 +796,11 @@ var en_USIndex = []uint32{ // 296 elements 0x000039d1, 0x00003a16, 0x00003a38, 0x00003a55, // Entry 120 - 13F 0x00003ad3, 0x00003c12, 0x00003c89, 0x00003cc3, - 0x00003d45, 0x00003d50, 0x00003d69, 0x00003d79, -} // Size: 1208 bytes + 0x00003d45, 0x00003d50, 0x00003d69, 0x00003d76, + 0x00003d8c, 0x00003da0, 0x00003db0, 0x00003dba, +} // Size: 1224 bytes -const en_USData string = "" + // Size: 15737 bytes +const en_USData string = "" + // Size: 15802 bytes "\x02Install/Create, Query, Uninstall SQL Server\x02View configuration in" + "formation and connection strings\x02sqlcmd: Install/Create/Query SQL Ser" + "ver, Azure SQL, and Tools\x0a\x0aFeedback:\x0a %[1]s\x02help for backwa" + @@ -1028,9 +1034,10 @@ const en_USData string = "" + // Size: 15737 bytes "\x02%[1]s List servers. Pass %[2]s to omit 'Servers:' output.\x02%[1]s R" + "emove control characters from output. Pass 1 to substitute a space per c" + "haracter, 2 for a space per consecutive characters\x02Echo input\x02Enab" + - "le column encryption\x02Timeout expired" + "le column encryption\x02New password\x02New password and exit\x02Enter n" + + "ew password:\x02Timeout expired\x02Password:" -var es_ESIndex = []uint32{ // 296 elements +var es_ESIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x00000032, 0x00000081, 0x000000de, 0x0000012e, 0x0000014f, 0x00000169, 0x000001c1, @@ -1115,7 +1122,8 @@ var es_ESIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x0000497f, 0x0000497f, 0x0000497f, 0x0000497f, 0x0000497f, 0x0000497f, 0x0000497f, 0x0000497f, -} // Size: 1208 bytes + 0x0000497f, 0x0000497f, 0x0000497f, 0x0000497f, +} // Size: 1224 bytes const es_ESData string = "" + // Size: 18815 bytes "\x02Instalar/Crear, Consultar, Desinstalar SQL Server\x02Visualización d" + @@ -1393,7 +1401,7 @@ const es_ESData string = "" + // Size: 18815 bytes " Estado %[3]d, Servidor %[4]s, Línea %#[5]v%[6]s\x02Identificador de var" + "iable %[1]s no válido\x02Valor de variable %[1]s no válido" -var fr_FRIndex = []uint32{ // 296 elements +var fr_FRIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x00000037, 0x0000007f, 0x000000da, 0x0000011e, 0x0000013b, 0x00000154, 0x000001a6, @@ -1478,7 +1486,8 @@ var fr_FRIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00004c6a, 0x00004c6a, 0x00004c6a, 0x00004c6a, 0x00004c6a, 0x00004c6a, 0x00004c6a, 0x00004c6a, -} // Size: 1208 bytes + 0x00004c6a, 0x00004c6a, 0x00004c6a, 0x00004c6a, +} // Size: 1224 bytes const fr_FRData string = "" + // Size: 19562 bytes "\x02Installer/créer, interroger, désinstaller SQL Server\x02Afficher les" + @@ -1765,7 +1774,7 @@ const fr_FRData string = "" + // Size: 19562 bytes "6]s\x02Identifiant de variable invalide %[1]s\x02Valeur de variable inva" + "lide %[1]s" -var it_ITIndex = []uint32{ // 296 elements +var it_ITIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x0000003c, 0x00000088, 0x000000e9, 0x00000140, 0x0000015d, 0x00000174, 0x000001b3, @@ -1850,7 +1859,8 @@ var it_ITIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00004757, 0x00004757, 0x00004757, 0x00004757, 0x00004757, 0x00004757, 0x00004757, 0x00004757, -} // Size: 1208 bytes + 0x00004757, 0x00004757, 0x00004757, 0x00004757, +} // Size: 1224 bytes const it_ITData string = "" + // Size: 18263 bytes "\x02Installare/creare, eseguire query, disinstallare SQL Server\x02Visua" + @@ -2122,7 +2132,7 @@ const it_ITData string = "" + // Size: 18263 bytes "dentificatore della variabile %[1]s non valido\x02Valore della variabile" + " %[1]s non valido" -var ja_JPIndex = []uint32{ // 296 elements +var ja_JPIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x0000004f, 0x00000077, 0x000000f3, 0x0000012e, 0x0000014e, 0x00000161, 0x000001a2, @@ -2207,7 +2217,8 @@ var ja_JPIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00005929, 0x00005929, 0x00005929, 0x00005929, 0x00005929, 0x00005929, 0x00005929, 0x00005929, -} // Size: 1208 bytes + 0x00005929, 0x00005929, 0x00005929, 0x00005929, +} // Size: 1224 bytes const ja_JPData string = "" + // Size: 22825 bytes "\x02インストール/作成、クエリ、SQL Server のアンインストール\x02構成情報と接続文字列の表示\x02sqlcmd: SQL S" + @@ -2363,7 +2374,7 @@ const ja_JPData string = "" + // Size: 22825 bytes "ロシージャ %[5]s、行 %#[6]v%[7]s\x02メッセージ %#[1]v、レベル %[2]d、状態 %[3]d、サーバー %[4]" + "s、行 %#[5]v%[6]s\x02変数識別子 %[1]s が無効です\x02変数値の %[1]s が無効です" -var ko_KRIndex = []uint32{ // 296 elements +var ko_KRIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x00000029, 0x00000053, 0x000000a8, 0x000000f4, 0x0000010c, 0x0000011a, 0x0000015d, @@ -2448,7 +2459,8 @@ var ko_KRIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x0000494e, 0x0000494e, 0x0000494e, 0x0000494e, 0x0000494e, 0x0000494e, 0x0000494e, 0x0000494e, -} // Size: 1208 bytes + 0x0000494e, 0x0000494e, 0x0000494e, 0x0000494e, +} // Size: 1224 bytes const ko_KRData string = "" + // Size: 18766 bytes "\x02SQL Server 설치/생성, 쿼리, 제거\x02구성 정보 및 연결 문자열 보기\x02sqlcmd: SQL Server," + @@ -2596,7 +2608,7 @@ const ko_KRData string = "" + // Size: 18766 bytes "#[1]v, 수준 %[2]d, 상태 %[3]d, 서버 %[4]s, 줄 %#[5]v%[6]s\x02잘못된 변수 식별자 %[1]s" + "\x02잘못된 변수 값 %[1]s" -var pt_BRIndex = []uint32{ // 296 elements +var pt_BRIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x00000034, 0x00000071, 0x000000d0, 0x00000126, 0x00000146, 0x00000161, 0x000001b0, @@ -2681,7 +2693,8 @@ var pt_BRIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00004675, 0x00004675, 0x00004675, 0x00004675, 0x00004675, 0x00004675, 0x00004675, 0x00004675, -} // Size: 1208 bytes + 0x00004675, 0x00004675, 0x00004675, 0x00004675, +} // Size: 1224 bytes const pt_BRData string = "" + // Size: 18037 bytes "\x02Instalar/Criar, Consultar, Desinstalar o SQL Server\x02Exibir inform" + @@ -2947,7 +2960,7 @@ const pt_BRData string = "" + // Size: 18037 bytes "a %#[5]v%[6]s\x02Identificador de variável %[1]s inválido\x02Valor de va" + "riável inválido %[1]s" -var ru_RUIndex = []uint32{ // 296 elements +var ru_RUIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x00000056, 0x000000c1, 0x00000156, 0x000001bb, 0x000001dc, 0x000001ff, 0x000002a5, @@ -3032,7 +3045,8 @@ var ru_RUIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00007901, 0x00007901, 0x00007901, 0x00007901, 0x00007901, 0x00007901, 0x00007901, 0x00007901, -} // Size: 1208 bytes + 0x00007901, 0x00007901, 0x00007901, 0x00007901, +} // Size: 1224 bytes const ru_RUData string = "" + // Size: 30977 bytes "\x02Установка или создание, запрос, удаление SQL Server\x02Просмотреть с" + @@ -3304,7 +3318,7 @@ const ru_RUData string = "" + // Size: 30977 bytes "ие %[3]d, сервер %[4]s, строка %#[5]v%[6]s\x02Недопустимый идентификато" + "р переменной %[1]s\x02Недопустимое значение переменной %[1]s" -var zh_CNIndex = []uint32{ // 296 elements +var zh_CNIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x0000002b, 0x00000050, 0x0000009f, 0x000000d0, 0x000000e5, 0x000000f2, 0x00000136, @@ -3389,7 +3403,8 @@ var zh_CNIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x000035d2, 0x000035d2, 0x000035d2, 0x000035d2, 0x000035d2, 0x000035d2, 0x000035d2, 0x000035d2, -} // Size: 1208 bytes + 0x000035d2, 0x000035d2, 0x000035d2, 0x000035d2, +} // Size: 1224 bytes const zh_CNData string = "" + // Size: 13778 bytes "\x02安装/创建、查询、卸载 SQL Server\x02查看配置信息和连接字符串\x02sqlcmd: 安装/创建/查询 SQL Serve" + @@ -3504,7 +3519,7 @@ const zh_CNData string = "" + // Size: 13778 bytes "s,过程 %[5]s,行 %#[6]v%[7]s\x02Msg %#[1]v,级别 %[2]d,状态 %[3]d,服务器 %[4]s,行 %#[" + "5]v%[6]s\x02变量标识符 %[1]s 无效\x02变量值 %[1]s 无效" -var zh_TWIndex = []uint32{ // 296 elements +var zh_TWIndex = []uint32{ // 300 elements // Entry 0 - 1F 0x00000000, 0x00000031, 0x00000053, 0x000000a8, 0x000000db, 0x000000f2, 0x000000fc, 0x00000140, @@ -3589,7 +3604,8 @@ var zh_TWIndex = []uint32{ // 296 elements // Entry 120 - 13F 0x00003624, 0x00003624, 0x00003624, 0x00003624, 0x00003624, 0x00003624, 0x00003624, 0x00003624, -} // Size: 1208 bytes + 0x00003624, 0x00003624, 0x00003624, 0x00003624, +} // Size: 1224 bytes const zh_TWData string = "" + // Size: 13860 bytes "\x02安裝/建立、查詢、解除安裝 SQL Server\x02檢視組態資訊和連接字串\x02sqlcmd: 安裝/建立/查詢 SQL Serv" + @@ -3701,4 +3717,4 @@ const zh_TWData string = "" + // Size: 13860 bytes "]s、程序 %[5]s、行 %#[6]v%[7]s\x02訊息 %#[1]v、層級 %[2]d、狀態 %[3]d、伺服器 %[4]s、行 %#[" + "5]v%[6]s\x02無效的變數識別碼 %[1]s\x02變數值 %[1]s 無效" - // Total table size 222713 bytes (217KiB); checksum: 4532551A + // Total table size 222954 bytes (217KiB); checksum: 9AF0EDE6 diff --git a/internal/translations/locales/de-DE/out.gotext.json b/internal/translations/locales/de-DE/out.gotext.json index 8ffdc991..1a47f649 100644 --- a/internal/translations/locales/de-DE/out.gotext.json +++ b/internal/translations/locales/de-DE/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/en-US/out.gotext.json b/internal/translations/locales/en-US/out.gotext.json index 0778d399..d4eacd60 100644 --- a/internal/translations/locales/en-US/out.gotext.json +++ b/internal/translations/locales/en-US/out.gotext.json @@ -3016,6 +3016,20 @@ "translatorComment": "Copied from source.", "fuzzy": true }, + { + "id": "New password", + "message": "New password", + "translation": "New password", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "New password and exit", + "translatorComment": "Copied from source.", + "fuzzy": true + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3257,6 +3271,13 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "Enter new password:", + "translatorComment": "Copied from source.", + "fuzzy": true + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3549,6 +3570,13 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "Password:", + "translatorComment": "Copied from source.", + "fuzzy": true + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/es-ES/out.gotext.json b/internal/translations/locales/es-ES/out.gotext.json index f666e669..f20ebd83 100644 --- a/internal/translations/locales/es-ES/out.gotext.json +++ b/internal/translations/locales/es-ES/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/fr-FR/out.gotext.json b/internal/translations/locales/fr-FR/out.gotext.json index 0aff911e..073086b4 100644 --- a/internal/translations/locales/fr-FR/out.gotext.json +++ b/internal/translations/locales/fr-FR/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/it-IT/out.gotext.json b/internal/translations/locales/it-IT/out.gotext.json index b5c24b31..120c6ffa 100644 --- a/internal/translations/locales/it-IT/out.gotext.json +++ b/internal/translations/locales/it-IT/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/ja-JP/out.gotext.json b/internal/translations/locales/ja-JP/out.gotext.json index 5919bc39..e68150c5 100644 --- a/internal/translations/locales/ja-JP/out.gotext.json +++ b/internal/translations/locales/ja-JP/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/ko-KR/out.gotext.json b/internal/translations/locales/ko-KR/out.gotext.json index d55158f5..896dca98 100644 --- a/internal/translations/locales/ko-KR/out.gotext.json +++ b/internal/translations/locales/ko-KR/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/pt-BR/out.gotext.json b/internal/translations/locales/pt-BR/out.gotext.json index cb5ef973..220f2e17 100644 --- a/internal/translations/locales/pt-BR/out.gotext.json +++ b/internal/translations/locales/pt-BR/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/ru-RU/out.gotext.json b/internal/translations/locales/ru-RU/out.gotext.json index 4ac9c239..cb9a47f1 100644 --- a/internal/translations/locales/ru-RU/out.gotext.json +++ b/internal/translations/locales/ru-RU/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/zh-CN/out.gotext.json b/internal/translations/locales/zh-CN/out.gotext.json index 858dc6d0..d81a352e 100644 --- a/internal/translations/locales/zh-CN/out.gotext.json +++ b/internal/translations/locales/zh-CN/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/internal/translations/locales/zh-TW/out.gotext.json b/internal/translations/locales/zh-TW/out.gotext.json index 0f823d46..6e8f2e22 100644 --- a/internal/translations/locales/zh-TW/out.gotext.json +++ b/internal/translations/locales/zh-TW/out.gotext.json @@ -3002,6 +3002,16 @@ "message": "Enable column encryption", "translation": "" }, + { + "id": "New password", + "message": "New password", + "translation": "" + }, + { + "id": "New password and exit", + "message": "New password and exit", + "translation": "" + }, { "id": "Sets the sqlcmd scripting variable {V}", "message": "Sets the sqlcmd scripting variable {V}", @@ -3243,6 +3253,11 @@ ], "fuzzy": true }, + { + "id": "Enter new password:", + "message": "Enter new password:", + "translation": "" + }, { "id": "Sqlcmd: Error:", "message": "Sqlcmd: Error:", @@ -3533,6 +3548,11 @@ ], "fuzzy": true }, + { + "id": "Password:", + "message": "Password:", + "translation": "" + }, { "id": "Invalid variable identifier {Name}", "message": "Invalid variable identifier {Name}", diff --git a/pkg/sqlcmd/connect.go b/pkg/sqlcmd/connect.go index 26fd3ad7..1295c900 100644 --- a/pkg/sqlcmd/connect.go +++ b/pkg/sqlcmd/connect.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/microsoft/go-mssqldb/azuread" + "github.com/microsoft/go-mssqldb/msdsn" ) // ConnectSettings specifies the settings for SQL connections and queries @@ -54,7 +55,9 @@ type ConnectSettings struct { // DedicatedAdminConnection forces the connection to occur over tcp on the dedicated admin port. Requires Browser service access DedicatedAdminConnection bool // EnableColumnEncryption enables support for transparent column encryption - EnableColumnEnryption bool + EnableColumnEncryption bool + // ChangePassword is the new password for the user to set during login + ChangePassword string } func (c ConnectSettings) authenticationMethod() string { @@ -113,7 +116,7 @@ func (connect ConnectSettings) ConnectionString() (connectionString string, err return "", &InvalidServerName } serverName = pipeParts[0] - query.Add("pipe", pipeParts[2]) + query.Add(msdsn.Pipe, pipeParts[2]) } if port > 0 { connectionURL.Host = fmt.Sprintf("%s:%d", serverName, port) @@ -121,42 +124,45 @@ func (connect ConnectSettings) ConnectionString() (connectionString string, err connectionURL.Host = serverName } if connect.Database != "" { - query.Add("database", connect.Database) + query.Add(msdsn.Database, connect.Database) } if connect.TrustServerCertificate { - query.Add("trustservercertificate", "true") + query.Add(msdsn.TrustServerCertificate, "true") } if connect.ApplicationIntent != "" && connect.ApplicationIntent != "default" { - query.Add("applicationintent", connect.ApplicationIntent) + query.Add(msdsn.ApplicationIntent, connect.ApplicationIntent) } if connect.LoginTimeoutSeconds > 0 { - query.Add("dial timeout", fmt.Sprint(connect.LoginTimeoutSeconds)) + query.Add(msdsn.DialTimeout, fmt.Sprint(connect.LoginTimeoutSeconds)) } if connect.PacketSize > 0 { - query.Add("packet size", fmt.Sprint(connect.PacketSize)) + query.Add(msdsn.PacketSize, fmt.Sprint(connect.PacketSize)) } if connect.WorkstationName != "" { - query.Add("workstation id", connect.WorkstationName) + query.Add(msdsn.WorkstationID, connect.WorkstationName) } if connect.Encrypt != "" && connect.Encrypt != "default" { - query.Add("encrypt", connect.Encrypt) + query.Add(msdsn.Encrypt, connect.Encrypt) } if connect.LogLevel > 0 { - query.Add("log", fmt.Sprint(connect.LogLevel)) + query.Add(msdsn.LogParam, fmt.Sprint(connect.LogLevel)) } if protocol != "" { - query.Add("protocol", protocol) + query.Add(msdsn.Protocol, protocol) } if connect.ApplicationName != "" { - query.Add(`app name`, connect.ApplicationName) + query.Add(msdsn.AppName, connect.ApplicationName) } if connect.DedicatedAdminConnection { - query.Set("protocol", "admin") + query.Set(msdsn.Protocol, "admin") } - if connect.EnableColumnEnryption { + if connect.EnableColumnEncryption { query.Set("columnencryption", "true") } + if connect.ChangePassword != "" { + query.Set(msdsn.ChangePassword, connect.ChangePassword) + } connectionURL.RawQuery = query.Encode() return connectionURL.String(), nil } diff --git a/pkg/sqlcmd/sqlcmd.go b/pkg/sqlcmd/sqlcmd.go index 4dd5f21c..a4e37c07 100644 --- a/pkg/sqlcmd/sqlcmd.go +++ b/pkg/sqlcmd/sqlcmd.go @@ -26,6 +26,7 @@ import ( _ "github.com/microsoft/go-mssqldb/aecmk/localcert" "github.com/microsoft/go-mssqldb/msdsn" "github.com/microsoft/go-sqlcmd/internal/color" + "github.com/microsoft/go-sqlcmd/internal/localizer" "golang.org/x/text/encoding/unicode" "golang.org/x/text/transform" ) @@ -312,7 +313,7 @@ func (s *Sqlcmd) promptPassword() (string, error) { if s.lineIo == nil { return "", nil } - pwd, err := s.lineIo.ReadPassword("Password:") + pwd, err := s.lineIo.ReadPassword(localizer.Sprintf("Password:")) if err != nil { return "", err }