Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: support password reuse policy #39162

Merged
merged 109 commits into from
Dec 2, 2022
Merged
Changes from 1 commit
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
7d7c24f
Support Password Reuse Policy
keeplearning20221 Nov 12, 2022
5cb28df
modified: errno/errcode.go
keeplearning20221 Nov 12, 2022
724c6d8
drop user support
bob34007 Nov 14, 2022
fc719ca
modified: executor/simple.go
keeplearning20221 Nov 15, 2022
4ce6866
modified: infoschema_cluster_table_test.go
keeplearning20221 Nov 15, 2022
20ebf62
Support Password Reuse Policy
keeplearning20221 Nov 12, 2022
34140ab
modified: errno/errcode.go
keeplearning20221 Nov 12, 2022
5a7dd17
drop user support
bob34007 Nov 14, 2022
d169f11
modified: executor/simple.go
keeplearning20221 Nov 15, 2022
af730b5
modified: infoschema_cluster_table_test.go
keeplearning20221 Nov 15, 2022
a988ee6
modified: executor/simple.go
keeplearning20221 Nov 15, 2022
da04920
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 15, 2022
69d01a4
modified: executor/infoschema_cluster_table_test.go
keeplearning20221 Nov 15, 2022
bf1d0cd
modified: executor/simple_test.go
keeplearning20221 Nov 15, 2022
d3961d6
modified: errors.toml
keeplearning20221 Nov 15, 2022
f15de2f
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 16, 2022
bcc4937
modified: simple.go
keeplearning20221 Nov 16, 2022
ba1a3b7
modified: ../sessionctx/variable/sysvar.go
keeplearning20221 Nov 16, 2022
d50099a
modified: simple.go
keeplearning20221 Nov 16, 2022
49b3946
modified: simple.go
keeplearning20221 Nov 17, 2022
3db40d5
modified: simple.go
keeplearning20221 Nov 17, 2022
a2b1525
add alter multi user fail test
bob34007 Nov 17, 2022
1387ad0
modified: simple_test.go
bob34007 Nov 17, 2022
00f6566
password reuse resolve conflicts
keeplearning20221 Nov 18, 2022
f8a5825
modified: session/bootstrap.go
keeplearning20221 Nov 18, 2022
86da639
modified: server/http_handler_serial_test.go
keeplearning20221 Nov 18, 2022
d0b70af
modified: executor/simple.go
keeplearning20221 Nov 22, 2022
6611473
modified: simple.go
keeplearning20221 Nov 22, 2022
e482177
modified: executor/simple.go
keeplearning20221 Nov 22, 2022
3093520
modified: executor/simple.go
keeplearning20221 Nov 22, 2022
7631916
modified: simple.go
keeplearning20221 Nov 22, 2022
5868d96
Merge https://github.com/pingcap/tidb into enhance_passwd
keeplearning20221 Nov 22, 2022
81bf030
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 22, 2022
8223492
modified: simple.go
keeplearning20221 Nov 22, 2022
2b29b75
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 22, 2022
180c405
modified: show.go
keeplearning20221 Nov 23, 2022
99cab07
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 23, 2022
fdbd8c9
modified: grant_test.go
keeplearning20221 Nov 23, 2022
a502b3b
password reuse resolve conflicts
keeplearning20221 Nov 25, 2022
1a1ee7b
modified: ../sessionctx/variable/tidb_vars.go
keeplearning20221 Nov 25, 2022
fc64ce4
Update executor/simple.go
keeplearning20221 Nov 25, 2022
d1a7668
Update executor/simple.go
keeplearning20221 Nov 25, 2022
c0a1bde
Apply suggestions from code review
keeplearning20221 Nov 25, 2022
e3c4b3e
modified: simple.go
keeplearning20221 Nov 25, 2022
5248a31
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 25, 2022
409f85d
modified: simple.go
keeplearning20221 Nov 25, 2022
5253b65
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 25, 2022
43249a8
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 25, 2022
1210a05
Apply suggestions from code review
keeplearning20221 Nov 26, 2022
ed64326
Update session/bootstrap.go
keeplearning20221 Nov 26, 2022
af5679c
modified: executor/simple.go
keeplearning20221 Nov 26, 2022
969d4b1
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 26, 2022
d1facde
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 26, 2022
6a469c2
password reuse resolve conflicts
keeplearning20221 Nov 28, 2022
ff9830c
session isolation level changed to read committed
keeplearning20221 Nov 28, 2022
2a10631
modified: simple.go
keeplearning20221 Nov 28, 2022
c7d6ece
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 28, 2022
2cf8050
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 28, 2022
f70601f
modified: simple.go
keeplearning20221 Nov 28, 2022
831e04d
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 28, 2022
98d58b3
modified: executor/simple.go
keeplearning20221 Nov 28, 2022
cca0b6e
modified: executor/simple.go
keeplearning20221 Nov 28, 2022
403e8b5
modified: simple.go
keeplearning20221 Nov 29, 2022
1152787
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 29, 2022
5010061
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 29, 2022
5b13f49
Merge branch 'master' into enhance_passwd
hawkingrei Nov 29, 2022
8ad2ac0
modified: executor/simple_test.go
keeplearning20221 Nov 29, 2022
335a3f3
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 29, 2022
2785512
modified: simple_test.go
bob34007 Nov 29, 2022
f8119a7
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 29, 2022
a145b53
Apply suggestions from code review
keeplearning20221 Nov 30, 2022
3530297
Modified according to the comment
keeplearning20221 Nov 30, 2022
f007aa6
modified: Makefile
keeplearning20221 Nov 30, 2022
d732cbf
modified: Makefile
keeplearning20221 Nov 30, 2022
7a5a2ed
modified: Makefile
keeplearning20221 Nov 30, 2022
314b1cf
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
08c6e12
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
bc61ad7
modified: Makefile
keeplearning20221 Nov 30, 2022
53d539d
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 30, 2022
6549253
modified: Makefile
keeplearning20221 Nov 30, 2022
f717cdb
Merge branch 'master' into enhance_passwd
hawkingrei Nov 30, 2022
1b82662
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
22f278f
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
61f0e43
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
1f6fb52
modified: executor/simple.go
keeplearning20221 Nov 30, 2022
9221e7c
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 30, 2022
9324762
modified: executor/simple.go
keeplearning20221 Nov 30, 2022
66c9a4c
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
b97e2a0
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
beddf8d
resolve conflicts
keeplearning20221 Nov 30, 2022
7984eac
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Nov 30, 2022
4279e90
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
2196883
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
c23cbd0
Merge branch 'master' into enhance_passwd
keeplearning20221 Nov 30, 2022
92d7de2
Merge branch 'master' into enhance_passwd
keeplearning20221 Dec 1, 2022
85325a4
Merge https://github.com/pingcap/tidb into enhance_passwd
keeplearning20221 Dec 1, 2022
3d105f2
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Dec 1, 2022
8fae3f5
Merge branch 'master' into enhance_passwd
keeplearning20221 Dec 1, 2022
8e2936c
Merge branch 'master' into enhance_passwd
keeplearning20221 Dec 1, 2022
419c317
Merge https://github.com/pingcap/tidb into enhance_passwd
keeplearning20221 Dec 1, 2022
77a8dee
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Dec 1, 2022
bf5161c
Merge https://github.com/pingcap/tidb into enhance_passwd
keeplearning20221 Dec 1, 2022
b2b1c98
Merge branch 'master' into enhance_passwd
keeplearning20221 Dec 1, 2022
e8c99a5
Apply suggestions from code review
keeplearning20221 Dec 2, 2022
2e0755b
modified: executor/simple.go
keeplearning20221 Dec 2, 2022
fe71bff
Merge branch 'enhance_passwd' of https://github.com/bob34007/tidb int…
keeplearning20221 Dec 2, 2022
caf6063
modified: executor/simple.go
keeplearning20221 Dec 2, 2022
6f10ebf
resolve conflicts
keeplearning20221 Dec 2, 2022
53eac1e
modified: executor/showtest/show_test.go
keeplearning20221 Dec 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
modified: executor/simple.go
	modified:   executor/simple_test.go
	modified:   session/bootstrap.go
keeplearning20221 committed Nov 15, 2022

Verified

This commit was signed with the committer’s verified signature. The key has expired.
renovate-bot Mend Renovate
commit fc719ca1e74f952a3942db39d8f333ed28eac642
165 changes: 102 additions & 63 deletions executor/simple.go
Original file line number Diff line number Diff line change
@@ -801,8 +801,20 @@ func (e *SimpleExec) executeRollback(s *ast.RollbackStmt) error {
return nil
}

func whetherSavePasswordHistory(PasswordHistory, PasswordReuseInterval int64) bool {
if PasswordHistory >= 0 || PasswordReuseInterval >= 0 || variable.PasswordHistory.Load() > 0 || variable.PasswordReuseInterval.Load() > 0 {
func whetherSavePasswordHistory(passwdlockinfo *passwordLockInfo) bool {
var passwdSaveNum int64
if passwdlockinfo.passwordHistory == notSpecified {
passwdSaveNum = variable.PasswordHistory.Load()
} else {
passwdSaveNum = passwdlockinfo.passwordHistory
}
var passwdSaveTime int64
if passwdlockinfo.passwordReuseInterval == notSpecified {
passwdSaveTime = variable.PasswordReuseInterval.Load()
} else {
passwdSaveTime = passwdlockinfo.passwordReuseInterval
}
if passwdSaveTime > 0 || passwdSaveNum > 0 {
return true
}
return false
@@ -901,7 +913,7 @@ func (e *SimpleExec) executeCreateUser(ctx context.Context, s *ast.CreateUserStm
sql := new(strings.Builder)
sqlPasswordHistory := new(strings.Builder)
passwordInit := true
savePasswdHistory := whetherSavePasswordHistory(passwdlockinfo.passwordHistory, passwdlockinfo.passwordReuseInterval)
savePasswdHistory := whetherSavePasswordHistory(passwdlockinfo)
sqlTemplate := "INSERT INTO %n.%n (Host, User, authentication_string, plugin, user_attributes, Account_locked, Token_issuer "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this sqlTemplate, just insert passwordHistory and passwordReuseInterval directly. If not specified, you can insert 'nil'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

valueTemplate := "(%?, %?, %?, %?, %?, %?, %?"
if passwdlockinfo.passwordReuseInterval != notSpecified {
@@ -1073,33 +1085,51 @@ func getUserPasswordLimit(ctx context.Context, sctx sessionctx.Context, name str
return res, nil
}

func deleteAddHistoricalData(ctx context.Context, sctx sessionctx.Context, name string, host string, maxnum int64, passwordReuse *passwordReuseInfo, pwd string) error {
if passwordReuse.passwordHistory <= 0 && passwordReuse.passwordReuseInterval <= 0 {
return nil
func getSystemTime(ctx context.Context, sctx sessionctx.Context, passwordReuse *passwordReuseInfo) string {
nowTime := time.Now().In(sctx.GetSessionVars().TimeZone)
nowTimeS := nowTime.Unix()
beforeTimeS := nowTimeS - passwordReuse.passwordReuseInterval*24*60*60
if beforeTimeS < 0 {
beforeTimeS = 0
}
return time.Unix(beforeTimeS, 0).Format("2006-01-02 15:04:05.999999999")
}

if passwordReuse.passwordReuseInterval > math.MaxInt32 {
//never times out
func deleteAddHistoricalData(ctx context.Context, sctx sessionctx.Context, name string, host string, maxDelRows int64, passwordReuse *passwordReuseInfo, pwd string) error {
if passwordReuse.passwordHistory <= 0 && passwordReuse.passwordReuseInterval <= 0 {
return nil
}

exec := sctx.(sqlexec.RestrictedSQLExecutor)
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnPrivilege)
nowTime := time.Now().In(sctx.GetSessionVars().TimeZone)
nowTimeS := nowTime.Unix()
beforeTimeS := nowTimeS - passwordReuse.passwordReuseInterval*24*60*60
if beforeTimeS < 0 {
beforeTimeS = 0
if (passwordReuse.passwordReuseInterval > math.MaxInt32) || maxDelRows == 0 {
//never times out or no row need delete
_, _, err := exec.ExecRestrictedSQL(ctx, nil, `INSERT INTO %n.%n (Host, User, Password) VALUES (%?, %?, %?) `, mysql.SystemDB, mysql.PasswordHistoryTable, strings.ToLower(host), name, pwd)
if err != nil {
return err
}
return nil
}
beforeDate := time.Unix(beforeTimeS, 0).Format("2006-01-02 15:04:05.999999999")
//Deletion must satisfy 1. Exceed the prohibition time 2. Exceed the maximum number of saved records
deleteTemplate := `DELETE from %n.%n WHERE User= %? AND Host= %? AND Password_timestamp < %? order by Password_timestamp ASC LIMIT `
deleteTemplate = deleteTemplate + strconv.FormatInt(maxnum, 10)
_, _, err := exec.ExecRestrictedSQL(ctx, nil, deleteTemplate, mysql.SystemDB, mysql.PasswordHistoryTable,
name, strings.ToLower(host), beforeDate)
if err != nil {
return err
if passwordReuse.passwordReuseInterval == 0 {
deleteTemplate := `DELETE from %n.%n WHERE User= %? AND Host= %? order by Password_timestamp ASC LIMIT `
keeplearning20221 marked this conversation as resolved.
Show resolved Hide resolved
deleteTemplate = deleteTemplate + strconv.FormatInt(maxDelRows, 10)
_, _, err := exec.ExecRestrictedSQL(ctx, nil, deleteTemplate, mysql.SystemDB, mysql.PasswordHistoryTable,
name, strings.ToLower(host))
if err != nil {
return err
}
} else {
beforeDate := getSystemTime(ctx, sctx, passwordReuse)
//Deletion must satisfy 1. Exceed the prohibition time 2. Exceed the maximum number of saved records
keeplearning20221 marked this conversation as resolved.
Show resolved Hide resolved
deleteTemplate := `DELETE from %n.%n WHERE User= %? AND Host= %? AND Password_timestamp < %? order by Password_timestamp ASC LIMIT `
deleteTemplate = deleteTemplate + strconv.FormatInt(maxDelRows, 10)
_, _, err := exec.ExecRestrictedSQL(ctx, nil, deleteTemplate, mysql.SystemDB, mysql.PasswordHistoryTable,
name, strings.ToLower(host), beforeDate)
if err != nil {
return err
}
}
_, _, err = exec.ExecRestrictedSQL(ctx, nil, `INSERT INTO %n.%n (Host, User, Password) VALUES (%?, %?, %?) `, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)
_, _, err := exec.ExecRestrictedSQL(ctx, nil, `INSERT INTO %n.%n (Host, User, Password) VALUES (%?, %?, %?) `, mysql.SystemDB, mysql.PasswordHistoryTable, strings.ToLower(host), name, pwd)
if err != nil {
return err
keeplearning20221 marked this conversation as resolved.
Show resolved Hide resolved
}
@@ -1116,52 +1146,60 @@ func passwordVerification(ctx context.Context, sctx sessionctx.Context, name str
if err != nil {
return false, err, 0
}
if int64(len(rows)) <= passwordReuse.passwordHistory {
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT count(*) FROM %n.%n WHERE User= %? AND Host= %? AND Password != %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)
if err != nil {
return false, err, 0
}
if len(rows) == 0 {
return true, nil, 0
}
return false, nil, 0
}
canDeleteNum := int64(len(rows)) - passwordReuse.passwordHistory
if passwordReuse.passwordReuseInterval > math.MaxInt32 {
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT count(*) FROM %n.%n WHERE User= %? AND Host= %? AND Password != %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)
if err != nil {
return false, err, 0
}
if len(rows) == 0 {
return true, nil, 0
}
return false, nil, 0
if len(rows) != 1 {
return false, errors.New("User and Host Classification is not unique,Please confirm the mysql.password_history table structure"), 0
}
nowTime := time.Now().In(sctx.GetSessionVars().TimeZone)
nowTimeS := nowTime.Unix()
beforeTimeS := nowTimeS - passwordReuse.passwordReuseInterval*24*60*60
if beforeTimeS < 0 {
beforeTimeS = 0
passwordNum := rows[0].GetInt64(0)
canDeleteNum := passwordNum - passwordReuse.passwordHistory + 1
if canDeleteNum < 0 {
canDeleteNum = 0
}
beforeDate := time.Unix(beforeTimeS, 0).Format("2006-01-02 15:04:05.999999999")
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT count(*) FROM %n.%n WHERE User=%? AND Host=%? AND Password != %? AND Password_timestamp >= "%?";`, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd, beforeDate)
if err != nil {
return false, err, 0
if passwordReuse.passwordHistory > 0 {
if passwordNum <= passwordReuse.passwordHistory {
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT count(*) FROM %n.%n WHERE User= %? AND Host= %? AND Password = %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)
if err != nil {
return false, err, 0
}
if rows[0].GetInt64(0) == 0 {
return true, nil, canDeleteNum
}
return false, nil, 0
} else {
// more password limit check
checkRows := `SELECT count(*) FROM (SELECT Password FROM %n.%n WHERE User=%? AND Host=%? ORDER BY Password_timestamp DESC LIMIT `
checkRows = checkRows + strconv.FormatInt(passwordReuse.passwordHistory, 10)
checkRows = checkRows + ` ) as t where t.Password = %? `
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, checkRows, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)
if err != nil {
return false, err, 0
}
if rows[0].GetInt64(0) != 0 {
return false, nil, 0
}
}
}
if len(rows) == 0 {
// Not enough passwords in the time range
checkRows := `SELECT count(*) FROM (SELECT Password FROM %n.%n WHERE User=%? AND Host=%? ORDER BY Password_timestamp DESC LIMIT `
checkRows = checkRows + strconv.FormatInt(passwordReuse.passwordHistory, 10)
checkRows = checkRows + ` ) as as t where t.Password != %? `
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, checkRows, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)

if passwordReuse.passwordReuseInterval > 0 {
//There are too many retention days, and it is impossible to time out in one's lifetime
if passwordReuse.passwordReuseInterval > math.MaxInt32 {
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT count(*) FROM %n.%n WHERE User= %? AND Host= %? AND Password = %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd)
if err != nil {
return false, err, 0
}
if rows[0].GetInt64(0) == 0 {
return true, nil, 0
}
return false, nil, 0
}

beforeDate := getSystemTime(ctx, sctx, passwordReuse)
rows, _, err = exec.ExecRestrictedSQL(ctx, nil, `SELECT count(*) FROM %n.%n WHERE User=%? AND Host=%? AND Password = %? AND Password_timestamp >= %?;`, mysql.SystemDB, mysql.PasswordHistoryTable, name, strings.ToLower(host), pwd, beforeDate)
if err != nil {
return false, err, 0
}
if len(rows) == 0 {
if rows[0].GetInt64(0) == 0 {
return true, nil, canDeleteNum
}

}
return false, nil, canDeleteNum
}
@@ -1342,17 +1380,18 @@ func (e *SimpleExec) executeAlterUser(ctx context.Context, s *ast.AlterUserStmt)
fields = append(fields, alterField{"account_locked=%?", passwdlockinfo.lockAccount})
}
if passwdlockinfo.passwordHistoryFlag {

if passwdlockinfo.passwordHistory == notSpecified {
fields = append(fields, alterField{"Password_reuse_history=%?", "NULL"})
fields = append(fields, alterField{"Password_reuse_history = NULL ", ""})
} else {
fields = append(fields, alterField{"Password_reuse_history=%?", strconv.FormatInt(passwdlockinfo.passwordHistory, 10)})
fields = append(fields, alterField{"Password_reuse_history = %?", strconv.FormatInt(passwdlockinfo.passwordHistory, 10)})
}
}
if passwdlockinfo.passwordReuseIntervalFlag {
if passwdlockinfo.passwordReuseInterval == notSpecified {
fields = append(fields, alterField{"Password_reuse_time=%?", "NULL"})
fields = append(fields, alterField{"Password_reuse_time = NULL ", ""})
} else {
fields = append(fields, alterField{"Password_reuse_time=%?", strconv.FormatInt(passwdlockinfo.passwordReuseInterval, 10)})
fields = append(fields, alterField{"Password_reuse_time = %? ", strconv.FormatInt(passwdlockinfo.passwordReuseInterval, 10)})
}
}

98 changes: 98 additions & 0 deletions executor/simple_test.go
Original file line number Diff line number Diff line change
@@ -122,3 +122,101 @@ func TestUserAttributes(t *testing.T) {
testkit.Rows("root % <nil>", "testuser % {\"comment\": \"1234\"}", "testuser1 % {\"age\": 20, \"name\": \"Tom\"}", "testuser2 % <nil>"))
tk.MustGetErrCode(`SELECT user, host, user_attributes FROM mysql.user ORDER BY user`, mysql.ErrTableaccessDenied)
}

func TestUserReuseInfo(t *testing.T) {
store, _ := testkit.CreateMockStoreAndDomain(t)
hawkingrei marked this conversation as resolved.
Show resolved Hide resolved
rootTK := testkit.NewTestKit(t, store)
rootTK.MustExec(`CREATE USER testReuse`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`<nil> <nil>`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 5`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 <nil>`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 0`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`0 <nil>`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY DEFAULT`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`<nil> <nil>`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 65536`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 <nil>`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL 5 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 5`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL 0 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 0`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL DEFAULT`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 <nil>`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD REUSE INTERVAL 65536 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`65535 65535`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 6 PASSWORD REUSE INTERVAL 6 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`6 6`))
rootTK.MustExec(`ALTER USER testReuse PASSWORD HISTORY 6 PASSWORD HISTORY 7 `)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`7 6`))

rootTK.MustExec(`drop USER testReuse`)
rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 5`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 <nil>`))
rootTK.MustExec(`drop USER testReuse`)
rootTK.MustExec(`CREATE USER testReuse PASSWORD REUSE INTERVAL 5 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`<nil> 5`))
rootTK.MustExec(`drop USER testReuse`)
rootTK.MustExec(`CREATE USER testReuse PASSWORD REUSE INTERVAL 5 DAY PASSWORD REUSE INTERVAL 6 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`<nil> 6`))
rootTK.MustExec(`drop USER testReuse`)
rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 6 DAY`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 6`))
rootTK.MustExec(`drop USER testReuse`)
rootTK.MustExec(`CREATE USER testReuse PASSWORD REUSE INTERVAL 6 DAY PASSWORD HISTORY 5`)
rootTK.MustQuery(`SELECT Password_reuse_history,Password_reuse_time FROM mysql.user WHERE user = 'testReuse'`).Check(testkit.Rows(`5 6`))

}

func TestUserReuseFunction(t *testing.T) {
store, _ := testkit.CreateMockStoreAndDomain(t)
hawkingrei marked this conversation as resolved.
Show resolved Hide resolved
rootTK := testkit.NewTestKit(t, store)
rootTK.MustExec(`CREATE USER testReuse identified by 'test'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`))
rootTK.MustExec(`set global password_history = 1;`)
rootTK.MustExec(`alter USER testReuse identified by 'test'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`))
rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`))
rootTK.MustExec(`alter USER testReuse identified by 'test1'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`))
rootTK.MustExec(`DROP USER testReuse`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`))

rootTK.MustExec(`set global password_history = 0;`)
rootTK.MustExec(`set global password_reuse_interval = 1;`)
rootTK.MustExec(`CREATE USER testReuse identified by 'test'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`))
rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638)
rootTK.MustExec(`alter USER testReuse identified by 'test1'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`2`))
rootTK.MustExec(`alter USER testReuse identified by 'test2'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`3`))
rootTK.MustExec(`alter USER testReuse identified by 'test3'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`))
rootTK.MustExec(`update mysql.password_history set Password_timestamp = date_sub(Password_timestamp,interval '1 0:0:1' DAY_SECOND)`)
rootTK.MustExec(`alter USER testReuse identified by 'test'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`))
rootTK.MustExec(`drop USER testReuse `)

rootTK.MustExec(`set global password_reuse_interval = 0;`)
// nil is not stored
rootTK.MustExec(`CREATE USER testReuse PASSWORD HISTORY 5 PASSWORD REUSE INTERVAL 6 DAY`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`0`))
rootTK.MustExec(`drop USER testReuse `)

rootTK.MustExec(`CREATE USER testReuse identified by 'test' PASSWORD HISTORY 5`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`1`))
rootTK.MustExec(`alter USER testReuse identified by 'test1'`)
rootTK.MustExec(`alter USER testReuse identified by 'test2'`)
rootTK.MustExec(`alter USER testReuse identified by 'test3'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`4`))
rootTK.MustGetErrCode(`alter USER testReuse identified by 'test'`, 3638)
rootTK.MustExec(`alter USER testReuse identified by 'test4'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`))
rootTK.MustExec(`alter USER testReuse identified by 'test5'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`))
rootTK.MustGetErrCode(`alter USER testReuse identified by 'test1'`, 3638)
rootTK.MustExec(`alter USER testReuse identified by 'test'`)
rootTK.MustQuery(`SELECT count(*) FROM mysql.password_history WHERE user = 'testReuse'`).Check(testkit.Rows(`5`))
rootTK.MustExec(`drop USER testReuse`)
}
10 changes: 8 additions & 2 deletions session/bootstrap.go
Original file line number Diff line number Diff line change
@@ -2104,6 +2104,8 @@ func doDDLWorks(s Session) {
mustExecute(s, "CREATE DATABASE IF NOT EXISTS %n", mysql.SystemDB)
// Create user table.
mustExecute(s, CreateUserTable)
// Create password history
mustExecute(s, CreatePasswordHistory)
// Create privilege tables.
mustExecute(s, CreateGlobalPrivTable)
mustExecute(s, CreateDBPrivTable)
@@ -2187,10 +2189,14 @@ func doDMLWorks(s Session) {
if err != nil {
logutil.BgLogger().Fatal("failed to read current user. unable to secure bootstrap.", zap.Error(err))
}
mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user VALUES
mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user (Host,User,authentication_string,plugin,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Process_priv,Grant_priv,References_priv,Alter_priv,Show_db_priv,
Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Index_priv,Create_user_priv,Event_priv,Repl_slave_priv,Repl_client_priv,Trigger_priv,Create_role_priv,Drop_role_priv,Account_locked,
Shutdown_priv,Reload_priv,FILE_priv,Config_priv,Create_Tablespace_Priv,User_attributes,Token_issuer) VALUES
("localhost", "root", %?, "auth_socket", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y", null, "")`, u.Username)
} else {
mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user VALUES
mustExecute(s, `INSERT HIGH_PRIORITY INTO mysql.user (Host,User,authentication_string,plugin,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Process_priv,Grant_priv,References_priv,Alter_priv,Show_db_priv,
Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Index_priv,Create_user_priv,Event_priv,Repl_slave_priv,Repl_client_priv,Trigger_priv,Create_role_priv,Drop_role_priv,Account_locked,
Shutdown_priv,Reload_priv,FILE_priv,Config_priv,Create_Tablespace_Priv,User_attributes,Token_issuer) VALUES
("%", "root", "", "mysql_native_password", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y", null, "")`)
}