@@ -32,7 +32,7 @@ TPrivComparer = class(TComparer<TPrivObj>)
3232 TUserProblem = (upNone, upEmptyPassword, upInvalidPasswordLen, upSkipNameResolve, upUnknown);
3333
3434 TUser = class (TObject)
35- Username, Host, Password, Cipher, Issuer, Subject, DefaultRole: String;
35+ Username, Host, Password, Cipher, Issuer, Subject, DefaultRole, Plugin : String;
3636 MaxQueries, MaxUpdates, MaxConnections, MaxUserConnections, SSL: Integer;
3737 Problem: TUserProblem;
3838 IsRole: Boolean;
@@ -63,6 +63,8 @@ EInputError = class(Exception);
6363 TUserManagerForm = class (TExtForm)
6464 btnCancel: TSpeedButton;
6565 btnSave: TSpeedButton;
66+ comboPlugins: TComboBox;
67+ lblPlugin: TLabel;
6668 pnlBottom: TPanel;
6769 pnlLeft: TPanel;
6870 listUsers: TLazVirtualStringTree;
@@ -197,11 +199,14 @@ TUserManagerForm = class(TExtForm)
197199 FUsers: TUserList;
198200 FModified, FAdded: Boolean;
199201 FHasIsRole, FHasDefaultRole: Boolean;
202+ FHasPlugin: Boolean;
203+ FPlugins: TStringList;
200204 FCloneGrants: TStringList;
201205 FPrivObjects: TPrivObjList;
202206 FPrivsGlobal, FPrivsDb, FPrivsTable, FPrivsRoutine, FPrivsColumn: TStringList;
203207 FConnection: TDBConnection;
204208 FColorReadPriv, FColorWritePriv, FColorAdminPriv: TColor;
209+ FSQLPluginPrefix, FSQLPluginPassPrefix: String;
205210 procedure SetModified (Value : Boolean);
206211 property Modified: Boolean read FModified write SetModified;
207212 function GetPrivByNode (Node: PVirtualNode): TPrivObj;
@@ -296,7 +301,7 @@ procedure TUserManagerForm.FormShow(Sender: TObject);
296301 Version, i: Integer;
297302 Users: TDBQuery;
298303 U: TUser;
299- tmp, PasswordExpr, IsRoleExpr, DefaultRoleExpr: String;
304+ tmp, PasswordExpr, IsRoleExpr, DefaultRoleExpr, PluginExpr : String;
300305 SkipNameResolve,
301306 HasPassword, HasAuthString: Boolean;
302307 PasswordLengthMatters: Boolean;
@@ -328,6 +333,8 @@ procedure TUserManagerForm.FormShow(Sender: TObject);
328333 FPrivsRoutine := InitPrivList(' GRANT' );
329334 FPrivsColumn := InitPrivList(' INSERT,SELECT,UPDATE,REFERENCES' );
330335 PasswordLengthMatters := True;
336+ FSQLPluginPrefix := IfThen(FConnection.Parameters.IsMariaDB, ' VIA' , ' WITH' );
337+ FSQLPluginPassPrefix := IfThen(FConnection.Parameters.IsMariaDB, ' USING' , ' BY' );
331338
332339 if Version >= 40002 then begin
333340 FPrivsGlobal.Add(' REPLICATION CLIENT' );
@@ -419,6 +426,7 @@ procedure TUserManagerForm.FormShow(Sender: TObject);
419426 HasAuthString := UserTableColumns.IndexOf(' authentication_string' ) > -1 ;
420427 FHasIsRole := UserTableColumns.IndexOf(' is_role' ) > -1 ;
421428 FHasDefaultRole := UserTableColumns.IndexOf(' default_role' ) > -1 ;
429+ FHasPlugin := UserTableColumns.IndexOf(' plugin' ) > -1 ;
422430 if HasPassword and (not HasAuthString) then
423431 PasswordExpr := ' password'
424432 else if (not HasPassword) and HasAuthString then
@@ -430,14 +438,21 @@ procedure TUserManagerForm.FormShow(Sender: TObject);
430438 PasswordExpr := PasswordExpr + ' AS ' + FConnection.QuoteIdent(' password' );
431439 IsRoleExpr := IfThen(FHasIsRole, ' is_role' , FConnection.EscapeString(' N' )+' AS is_role' );
432440 DefaultRoleExpr := IfThen(FHasDefaultRole, ' default_role' , FConnection.EscapeString(' ' )+' AS default_role' );
441+ PluginExpr := IfThen(FHasPlugin, ' plugin' , FConnection.EscapeString(' ' )+' AS plugin' );
442+ if FConnection.SqlProvider.Has(qGetAuthPlugins) then
443+ FPlugins := FConnection.GetCol(FConnection.SqlProvider.GetSql(qGetAuthPlugins))
444+ else
445+ FPlugins := TStringList.Create;
446+ comboPlugins.Enabled := FHasPlugin;
433447
434448 Users := FConnection.GetResults(
435449 ' SELECT ' +
436450 FConnection.QuoteIdent(' user' ) + ' , ' +
437451 FConnection.QuoteIdent(' host' ) + ' , ' +
438452 PasswordExpr + ' , ' +
439453 IsRoleExpr + ' , ' +
440- DefaultRoleExpr + ' ' +
454+ DefaultRoleExpr + ' , ' +
455+ PluginExpr + ' ' +
441456 ' FROM ' +FConnection.QuoteIdent(' mysql' )+' .' +FConnection.QuoteIdent(' user' )
442457 );
443458 FUsers := TUserList.Create(True);
@@ -449,6 +464,7 @@ procedure TUserManagerForm.FormShow(Sender: TObject);
449464 U.Password := Users.Col(' password' );
450465 U.IsRole := UpperCase(Users.Col(' is_role' )) = ' Y' ;
451466 U.DefaultRole := Users.Col(' default_role' );
467+ U.Plugin := Users.Col(' plugin' );
452468 U.Problem := upNone;
453469 if U.IsUser then begin
454470 if Length(U.Password) = 0 then
@@ -630,26 +646,35 @@ procedure TUserManagerForm.listUsersFocusChanged(Sender: TBaseVirtualTree; Node:
630646 User := nil ;
631647 FPrivObjects.Clear;
632648 Caption := MainForm.actUserManager.Caption;
649+ // Credentials tab
633650 editUsername.Clear;
634651 editFromHost.Clear;
635652 editPassword.Clear;
636653 editPassword.TextHint := ' ' ;
637654 editRepeatPassword.Clear;
655+ comboPlugins.Items.Clear;
656+ comboPlugins.Items.Add(_(' None' ));
657+ comboPlugins.Items.AddStrings(FPlugins);
658+ comboPlugins.ItemIndex := 0 ;
638659 comboDefaultRole.Items.Clear;
639660 comboDefaultRole.Items.Add(_(' None' ));
640661 FUsers.GetRoleNames(comboDefaultRole.Items);
641662 comboDefaultRole.ItemIndex := 0 ;
663+ // Limitations tab
642664 spinMaxQueries.Value := 0 ;
643665 spinMaxUpdates.Value := 0 ;
644666 spinMaxConnections.Value := 0 ;
645667 spinMaxUserConnections.Value := 0 ;
668+ // SSL tab
646669 comboSSL.ItemIndex := 0 ;
647670 comboSSL.OnChange(Sender);
648671 editCipher.Clear;
649672 editIssuer.Clear;
650673 editSubject.Clear;
674+ // Page control
651675 tabPrivileges.Caption := _(' Privileges' );
652676 tabRoles.Caption := _(' Roles' );
677+
653678 // All possible quote chars, escaped for RegExpr. Todo: use in all relevant expressions.
654679 RxQuotes := ' [' +QuoteRegExprMetaChars(FConnection.QuoteChars + FConnection.StringQuoteChar)+' ]' ;
655680
@@ -663,6 +688,9 @@ procedure TUserManagerForm.listUsersFocusChanged(Sender: TBaseVirtualTree; Node:
663688 end ;
664689 editUsername.Text := User.Username;
665690 editFromHost.Text := User.Host;
691+ i := comboPlugins.Items.IndexOf(User.Plugin);
692+ if i > -1 then
693+ comboPlugins.ItemIndex := i;
666694 i := comboDefaultRole.Items.IndexOf(User.DefaultRole);
667695 if i > -1 then
668696 comboDefaultRole.ItemIndex := i;
@@ -1403,13 +1431,18 @@ procedure TUserManagerForm.btnSaveClick(Sender: TObject);
14031431 // Create added user
14041432 PasswordSet := False;
14051433 if FAdded and (FConnection.ServerVersionInt >= 50002 ) then begin
1406- Create := ' CREATE USER ' +UserHost;
1434+ Create := ' CREATE USER ' +UserHost+ ' ' ;
14071435 if editPassword.Modified then begin
1436+ // Insert authentication plugin with minor MariaDB/MySQL difference
1437+ if comboPlugins.ItemIndex > 0 then
1438+ Create := Create + ' IDENTIFIED ' + FSQLPluginPrefix + ' ' + comboPlugins.Text+' ' + FSQLPluginPassPrefix + ' '
1439+ else
1440+ Create := Create + ' IDENTIFIED BY ' ;
14081441 // Add "PASSWORD" clause when it's a hash already
14091442 if (Copy(editPassword.Text, 1 , 1 ) = ' *' ) and (Length(editPassword.Text) = 41 ) then
1410- Create := Create + ' IDENTIFIED BY PASSWORD ' +FConnection.EscapeString(editPassword.Text)
1443+ Create := Create + ' PASSWORD ' +FConnection.EscapeString(editPassword.Text)
14111444 else
1412- Create := Create + ' IDENTIFIED BY ' + FConnection.EscapeString(editPassword.Text);
1445+ Create := Create + FConnection.EscapeString(editPassword.Text);
14131446 end ;
14141447 FConnection.Query(Create);
14151448 FConnection.ShowWarnings;
@@ -1477,6 +1510,12 @@ procedure TUserManagerForm.btnSaveClick(Sender: TObject);
14771510
14781511 // General user options
14791512 if (P.DBObj.NodeType = lntNone) and FocusedUser.IsUser then begin
1513+ // Plugin
1514+ if comboPlugins.ItemIndex > 0 then begin
1515+ FConnection.Query(' ALTER USER ' + UserHost + ' IDENTIFIED ' + FSQLPluginPrefix + ' ' + comboPlugins.Text);
1516+ FConnection.ShowWarnings;
1517+ end ;
1518+
14801519 // SSL
14811520 case comboSSL.ItemIndex of
14821521 1 : RequireClause := ' SSL' ;
@@ -1574,6 +1613,7 @@ procedure TUserManagerForm.btnSaveClick(Sender: TObject);
15741613 FocusedUser.Host := editFromHost.Text;
15751614 if editPassword.Modified then
15761615 FocusedUser.Password := editPassword.Text;
1616+ FocusedUser.Plugin := IfThen(comboPlugins.ItemIndex=0 , ' ' , comboPlugins.Text);
15771617 FocusedUser.DefaultRole := IfThen(comboDefaultRole.ItemIndex=0 , ' ' , comboDefaultRole.Text);
15781618 FocusedUser.SSL := comboSSL.ItemIndex;
15791619 FocusedUser.Cipher := editCipher.Text;
@@ -1814,7 +1854,9 @@ procedure TUser.ParseSettings(GrantOrCreate: String; Priv: TPrivObj);
18141854 rx: TRegExpr;
18151855 RequireClause, WithClause: String;
18161856begin
1817- // REQUIRE SSL X509 ISSUER '456' SUBJECT '789' CIPHER '123' NONE
1857+ // CREATE USER ...
1858+ // mysql: IDENTIFIED WITH 'mysql_native_password' AS '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' REQUIRE SSL X509 ISSUER '456' SUBJECT '789' CIPHER '123' NONE
1859+ // mariadb: IDENTIFIED BY PASSWORD '23AE809DDACAF96A';
18181860 rx := TRegExpr.Create;
18191861 rx.ModifierI := True;
18201862 rx.Expression := ' \sREQUIRE\s+(.+)' ;
0 commit comments