Skip to content

Commit

Permalink
Adding a locked superuser account for the event scheduler, and a new …
Browse files Browse the repository at this point in the history
…utility function to create locked superuser accounts
  • Loading branch information
fulghum committed Jan 3, 2025
1 parent 394a5bc commit e4a10fd
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
23 changes: 23 additions & 0 deletions eventscheduler/event_scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/analyzer"
"github.com/dolthub/go-mysql-server/sql/mysql_db"
)

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

// eventSchedulerSuperUserName is the name of the superuser that
const eventSchedulerSuperUserName = "event_scheduler"

var _ sql.EventScheduler = (*EventScheduler)(nil)

// EventScheduler is responsible for SQL events execution.
Expand Down Expand Up @@ -69,10 +73,20 @@ func InitEventScheduler(
ctxGetterFunc: getSqlCtxFunc,
}

// Ensure the event_scheduler superuser exists so that the event scheduler can read
// events from all databases.
initializeEventSchedulerSuperUser(a.Catalog.MySQLDb)

// If the EventSchedulerStatus is ON, then load enabled
// events and start executing events on schedule.
if es.status == SchedulerOn {
ctx, commit, err := getSqlCtxFunc()
ctx.Session.SetClient(sql.Client{
User: eventSchedulerSuperUserName,
Address: "localhost",
Capabilities: 0,
})

if err != nil {
return nil, err
}
Expand All @@ -89,6 +103,15 @@ func InitEventScheduler(
return es, nil
}

// initializeEventSchedulerSuperUser ensures the event_scheduler superuser exists (as a locked
// account that cannot be directly used to log in) so that the event scheduler can read events
// from all databases.
func initializeEventSchedulerSuperUser(mySQLDb *mysql_db.MySQLDb) {
ed := mySQLDb.Editor()
defer ed.Close()
mySQLDb.AddLockedSuperUser(ed, eventSchedulerSuperUserName, "localhost", "")
}

// Close closes the EventScheduler.
func (es *EventScheduler) Close() {
if es == nil {
Expand Down
26 changes: 26 additions & 0 deletions sql/mysql_db/mysql_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,32 @@ func (db *MySQLDb) AddSuperUser(ed *Editor, username string, host string, passwo
}
}

// AddLockedSuperUser adds a new superuser with the specified |username|, |host|, and |password|
// and sets the account to be locked so that it cannot be used to log in.
func (db *MySQLDb) AddLockedSuperUser(ed *Editor, username string, host string, password string) {
user := db.GetUser(ed, username, host, false)

// If the user doesn't exist yet, create it and lock it
if user == nil {
db.AddSuperUser(ed, username, host, password)
user = db.GetUser(ed, username, host, false)
if user == nil {
panic("unable to load newly created superuser: " + username)
}

// Lock the account to prevent it being used to log in
user.Locked = true
ed.PutUser(user)
}

// If the user exists, but isn't a superuser or locked, fix it
if user.IsSuperUser == false || user.Locked == false {
user.IsSuperUser = true
user.Locked = true
ed.PutUser(user)
}
}

// GetUser returns a user matching the given user and host if it exists. Due to the slight difference between users and
// roles, roleSearch changes whether the search matches against user or role rules.
func (db *MySQLDb) GetUser(fetcher UserFetcher, user string, host string, roleSearch bool) *User {
Expand Down

0 comments on commit e4a10fd

Please sign in to comment.