Skip to content

Commit 57e5666

Browse files
committed
Adding a locked superuser account for the event scheduler, and a new utility function to create locked superuser accounts
1 parent 090873b commit 57e5666

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

eventscheduler/event_scheduler.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/dolthub/go-mysql-server/sql"
2222
"github.com/dolthub/go-mysql-server/sql/analyzer"
23+
"github.com/dolthub/go-mysql-server/sql/mysql_db"
2324
)
2425

2526
// ErrEventSchedulerDisabled is returned when user tries to set `event_scheduler_notifier` global system variable to ON or OFF
@@ -41,6 +42,10 @@ const (
4142
SchedulerDisabled SchedulerStatus = "DISABLED"
4243
)
4344

45+
// eventSchedulerSuperUserName is the name of the locked superuser that the event scheduler
46+
// creates and uses to ensure it has access to read events from all databases.
47+
const eventSchedulerSuperUserName = "event_scheduler"
48+
4449
var _ sql.EventScheduler = (*EventScheduler)(nil)
4550

4651
// EventScheduler is responsible for SQL events execution.
@@ -69,10 +74,20 @@ func InitEventScheduler(
6974
ctxGetterFunc: getSqlCtxFunc,
7075
}
7176

77+
// Ensure the event_scheduler superuser exists so that the event scheduler can read
78+
// events from all databases.
79+
initializeEventSchedulerSuperUser(a.Catalog.MySQLDb)
80+
7281
// If the EventSchedulerStatus is ON, then load enabled
7382
// events and start executing events on schedule.
7483
if es.status == SchedulerOn {
7584
ctx, commit, err := getSqlCtxFunc()
85+
ctx.Session.SetClient(sql.Client{
86+
User: eventSchedulerSuperUserName,
87+
Address: "localhost",
88+
Capabilities: 0,
89+
})
90+
7691
if err != nil {
7792
return nil, err
7893
}
@@ -89,6 +104,25 @@ func InitEventScheduler(
89104
return es, nil
90105
}
91106

107+
// initializeEventSchedulerSuperUser ensures the event_scheduler superuser exists (as a locked
108+
// account that cannot be directly used to log in) so that the event scheduler can read events
109+
// from all databases.
110+
func initializeEventSchedulerSuperUser(mySQLDb *mysql_db.MySQLDb) {
111+
// TODO: Creating a superuser for the event_scheduler causes the mysqldb to be marked as
112+
// enabled, which enables privileges checking for all resources. We want privileges
113+
// enabled only when running in a sql-server context, but currently creating any
114+
// engine starts up the event system, so we reset the mysqldb enabled status after
115+
// we create the event scheduler super user. To clean this up, we can look into
116+
// moving the event system initialization, or possibly just switch to enabling the
117+
// privilege system as part of server startup.
118+
wasEnabled := mySQLDb.Enabled()
119+
defer mySQLDb.SetEnabled(wasEnabled)
120+
121+
ed := mySQLDb.Editor()
122+
defer ed.Close()
123+
mySQLDb.AddLockedSuperUser(ed, eventSchedulerSuperUserName, "localhost", "")
124+
}
125+
92126
// Close closes the EventScheduler.
93127
func (es *EventScheduler) Close() {
94128
if es == nil {

sql/mysql_db/mysql_db.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ func (db *MySQLDb) AddRootAccount() {
522522
// the server is restarted, this superuser account will not be present.
523523
func (db *MySQLDb) AddEphemeralSuperUser(ed *Editor, username string, host string, password string) {
524524
db.SetEnabled(true)
525+
525526
if len(password) > 0 {
526527
hash := sha1.New()
527528
hash.Write([]byte(password))
@@ -545,6 +546,7 @@ func (db *MySQLDb) AddEphemeralSuperUser(ed *Editor, username string, host strin
545546
func (db *MySQLDb) AddSuperUser(ed *Editor, username string, host string, password string) {
546547
//TODO: remove this function and the called function
547548
db.SetEnabled(true)
549+
548550
if len(password) > 0 {
549551
hash := sha1.New()
550552
hash.Write([]byte(password))
@@ -563,6 +565,32 @@ func (db *MySQLDb) AddSuperUser(ed *Editor, username string, host string, passwo
563565
}
564566
}
565567

568+
// AddLockedSuperUser adds a new superuser with the specified |username|, |host|, and |password|
569+
// and sets the account to be locked so that it cannot be used to log in.
570+
func (db *MySQLDb) AddLockedSuperUser(ed *Editor, username string, host string, password string) {
571+
user := db.GetUser(ed, username, host, false)
572+
573+
// If the user doesn't exist yet, create it and lock it
574+
if user == nil {
575+
db.AddSuperUser(ed, username, host, password)
576+
user = db.GetUser(ed, username, host, false)
577+
if user == nil {
578+
panic("unable to load newly created superuser: " + username)
579+
}
580+
581+
// Lock the account to prevent it being used to log in
582+
user.Locked = true
583+
ed.PutUser(user)
584+
}
585+
586+
// If the user exists, but isn't a superuser or locked, fix it
587+
if user.IsSuperUser == false || user.Locked == false {
588+
user.IsSuperUser = true
589+
user.Locked = true
590+
ed.PutUser(user)
591+
}
592+
}
593+
566594
// GetUser returns a user matching the given user and host if it exists. Due to the slight difference between users and
567595
// roles, roleSearch changes whether the search matches against user or role rules.
568596
func (db *MySQLDb) GetUser(fetcher UserFetcher, user string, host string, roleSearch bool) *User {

0 commit comments

Comments
 (0)