From 9bdfa3d6cfb079a4ef706a8c4f93b83b0bc5dc75 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Tue, 19 Nov 2019 21:37:18 +0000 Subject: [PATCH] 93_DbRep: contrib 8.30.0 git-svn-id: https://svn.fhem.de/fhem/trunk@20543 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/93_DbRep.pm | 138 +++++++++++++++++++++------- 1 file changed, 106 insertions(+), 32 deletions(-) diff --git a/fhem/contrib/DS_Starter/93_DbRep.pm b/fhem/contrib/DS_Starter/93_DbRep.pm index 6d6ee78c2..0b9545e47 100644 --- a/fhem/contrib/DS_Starter/93_DbRep.pm +++ b/fhem/contrib/DS_Starter/93_DbRep.pm @@ -538,7 +538,7 @@ sub DbRep_Set($@) { (($hash->{ROLE} ne "Agent")?"fetchrows:history,current ":""). (($hash->{ROLE} ne "Agent")?"diffValue:display,writeToDB ":""). (($hash->{ROLE} ne "Agent")?"index:list_all,recreate_Search_Idx,drop_Search_Idx,recreate_Report_Idx,drop_Report_Idx ":""). - (($hash->{ROLE} ne "Agent" && $dbmodel !~ /SQLITE/)?"adminCredentials ":""). + (($dbmodel =~ /MYSQL/)?"adminCredentials ":""). (($hash->{ROLE} ne "Agent")?"insert ":""). (($hash->{ROLE} ne "Agent")?"reduceLog ":""). (($hash->{ROLE} ne "Agent")?"sqlCmd:textField-long ":""). @@ -964,7 +964,7 @@ sub DbRep_Get($@) { "svrinfo:noArg ". "blockinginfo:noArg ". "minTimestamp:noArg ". - (($hash->{ROLE} ne "Agent" && $dbmodel !~ /SQLITE/)?"storedCredentials:noArg ":""). + (($dbmodel =~ /MYSQL/)?"storedCredentials:noArg ":""). "dbValue:textField-long ". (($dbmodel eq "MYSQL")?"dbstatus:noArg ":""). (($dbmodel eq "MYSQL")?"tableinfo:noArg ":""). @@ -1184,7 +1184,6 @@ sub DbRep_Attr($$$$) { timestamp_end timeDiffToNow timeOlderThan - useAdminCredentials sqlResultFormat ); @@ -1594,19 +1593,19 @@ sub DbRep_getInitData($) { my $dbuser = $dbloghash->{dbuser}; my $dblogname = $dbloghash->{NAME}; my $dbmodel = $dbloghash->{MODEL}; + my $database = $hash->{DATABASE}; my $dbpassword = $attr{"sec$dblogname"}{secret}; my $mintsdef = "1970-01-01 01:00:00"; my $idxstate = ""; - my ($dbh,$sql,$err,$mints); + my ($dbh,$sth,$sql,$err,$mints); # Background-Startzeit my $bst = [gettimeofday]; - - eval { $dbh = DBI->connect("dbi:$dbconn", $dbuser, $dbpassword, { PrintError => 0, RaiseError => 1, AutoInactiveDestroy => 1 }); }; - if ($@) { - $err = encode_base64($@,""); - Log3 ($name, 2, "DbRep $name - $@"); - return "$name|''|''|$err"; + + ($err,$dbh) = DbRep_dbConnect($name,0); + if ($err) { + $err = encode_base64($err,""); + return "$name|''|''|$err"; } # SQL-Startzeit @@ -1641,6 +1640,34 @@ sub DbRep_getInitData($) { } } } + + # effektive Userrechte in MYSQL ermitteln + my ($grants,@uniq); + if($dbmodel =~ /MYSQL/) { + eval {$sth = $dbh->prepare("SHOW GRANTS FOR CURRENT_USER();"); $sth->execute();}; + if($@) { + Log3($name, 2, "DbRep $name - WARNING - user rights couldn't be determined: ".$@); + } else { + my $row = ""; + while (my @line = $sth->fetchrow_array()) { + foreach (@line) { + next if($_!~/(\s+ON \*\.\*\s+|\s+ON `$database`)/ ); + $row .= "," if($row); + $row .= (split(" ON ",(split("GRANT ",$_,2))[1],2))[0]; + } + } + $sth->finish; + my %seen = (); + my @g = split(/,(\s?)/,$row); + foreach (@g) { + next if(!$_ || $_=~/^\s+$/); + $seen{$_}++; + } + @uniq = keys %seen; + $grants = join(",",@uniq); + Log3 ($name, 4, "DbRep $name - all grants: $grants"); + } + } $dbh->disconnect; @@ -1649,6 +1676,7 @@ sub DbRep_getInitData($) { $mints = $mints?encode_base64($mints,""):encode_base64($mintsdef,""); $idxstate = encode_base64($idxstate,""); + $grants = encode_base64($grants,"") if($grants); # Background-Laufzeit ermitteln my $brt = tv_interval($bst); @@ -1657,7 +1685,7 @@ sub DbRep_getInitData($) { no warnings 'uninitialized'; Log3 ($name, 3, "DbRep $name - Initial data information retrieved successfully - total time used: ".sprintf("%.4f",$brt)." seconds"); -return "$name|$mints|$rt|0|$opt|$prop|$fret|$idxstate"; +return "$name|$mints|$rt|0|$opt|$prop|$fret|$idxstate|$grants"; } #################################################################################################### @@ -1676,6 +1704,7 @@ sub DbRep_getInitDataDone($) { my $prop = $a[5]; my $fret = \&{$a[6]} if($a[6]); my $idxstate = $a[7]?decode_base64($a[7]):""; + my $grants = $a[8]?decode_base64($a[8]):""; my $dbloghash = $defs{$hash->{HELPER}{DBLOGDEVICE}}; my $dbconn = $dbloghash->{dbconn}; @@ -1699,7 +1728,8 @@ sub DbRep_getInitDataDone($) { Log3 ($name, 3, "DbRep $name - Connectiontest to db $dbconn successful") if($hash->{LASTCMD} ne "minTimestamp"); - $hash->{HELPER}{MINTS} = $mints; + $hash->{HELPER}{MINTS} = $mints; + $hash->{HELPER}{GRANTS} = $grants if($grants); } delete($hash->{HELPER}{RUNNING_PID}); @@ -1739,7 +1769,7 @@ sub DbRep_dbConnect($$) { my $dbmodel = $defs{$defs{$name}->{HELPER}{DBLOGDEVICE}}->{MODEL}; my $dbpassword = $attr{"sec$dblogname"}{secret}; my $utf8 = defined($hash->{UTF8})?$hash->{UTF8}:0; - $uac = AttrVal($name, "useAdminCredentials", $uac); + $uac = $uac?$uac:AttrVal($name, "useAdminCredentials", 0); my ($dbh,$err); if($uac) { @@ -1748,8 +1778,9 @@ sub DbRep_dbConnect($$) { $dbuser = $admusername; $dbpassword = $admpassword; } else { - $err = encode_base64("Can't use admin credentials for database access, see logfile !",""); - return ($err,""); + $err = "Can't use admin credentials for database access, see logfile !"; + Log3 ($name, 2, "DbRep $name - ERROR - admin credentials are needed for database access, but can't use it"); + return $err; } } @@ -1761,7 +1792,7 @@ sub DbRep_dbConnect($$) { } ); }; if ($@) { - $err = encode_base64($@,""); + $err = $@; Log3 ($name, 2, "DbRep $name - ERROR: $@"); } @@ -1858,7 +1889,7 @@ sub DbRep_Main($$;$) { return; } - if ($opt =~ /index/) { + if ($opt =~ /index/) { if (exists($hash->{HELPER}{RUNNING_INDEX})) { Log3 ($name, 3, "DbRep $name - WARNING - old process $hash->{HELPER}{RUNNING_INDEX}{pid} will be killed now to start a new index operation"); BlockingKill($hash->{HELPER}{RUNNING_INDEX}); @@ -5963,7 +5994,10 @@ sub sqlCmd_DoParse($) { my $bst = [gettimeofday]; ($err,$dbh) = DbRep_dbConnect($name,0); - return "$name|''|$opt|$cmd|''|''|$err" if ($err); + if ($err) { + $err = encode_base64($err,""); + return "$name|''|$opt|$cmd|''|''|$err"; + } # only for this block because of warnings if details of readings are not set no warnings 'uninitialized'; @@ -6499,18 +6533,37 @@ sub DbRep_Index($) { my $dbuser = $dbloghash->{dbuser}; my $dblogname = $dbloghash->{NAME}; my $dbmodel = $dbloghash->{MODEL}; + my $grants = $hash->{HELPER}{GRANTS}; my $dbpassword = $attr{"sec$dblogname"}{secret}; my $utf8 = defined($hash->{UTF8})?$hash->{UTF8}:0; my ($dbh,$err,$sth,$rows,@six); my ($sqldel,$sqlcre,$sqlava,$sqlallidx,$ret) = ("","","","",""); + my $p = 0; Log3 ($name, 5, "DbRep $name -> Start DbRep_Index"); # Background-Startzeit my $bst = [gettimeofday]; - ($err,$dbh) = DbRep_dbConnect($name,0); - return "$name|''|''|$err" if ($err); + # Rechte Check MYSQL + if($cmdidx ne "list_all") { + if($dbmodel =~ /MYSQL/ && $grants && $grants ne "ALL PRIVILEGES") { + # Rechte INDEX und ALTER benötigt + my $i = index($grants,"INDEX"); + my $a = index($grants,"ALTER"); + if($i==-1 || $a==-1) { + $p = 1; + } + } elsif (!$grants) { + $p = 1; + } + } + + ($err,$dbh) = DbRep_dbConnect($name,$p); + if ($err) { + $err = encode_base64($err,""); + return "$name|''|''|$err"; + } my ($cmd,$idx) = split("_",$cmdidx,2); @@ -11512,6 +11565,15 @@ return;

+
  • versionNotes [hints | rel | <key>] - Shows realease informations and/or hints about the module. It contains only main release @@ -13659,6 +13726,13 @@ sub bdump {
  • timeout - set the timeout-value for Blocking-Call Routines in background in seconds (default 86400)

  • + +
  • useAdminCredentials + - If set, a before with "set <aame> adminCredentials" saved privileged user is used + for particular database operations.
    + (only valid if database type is MYSQL) +

  • +
  • userExitFn - provides an interface to execute user specific program code.
    To activate the interfaace at first you should implement the subroutine which will be @@ -13989,7 +14063,7 @@ sub bdump { - Speichert einen User / Passwort für den privilegierten bzw. administrativen Datenbankzugriff. Er wird bei Datenbankoperationen benötigt, die mit einem privilegierten User ausgeführt werden müssen. Siehe auch Attribut 'useAdminCredentials'.
    - (nicht bei Rolle Agent sowie Datenbank SQLite) + (nur gültig bei Datenbanktyp MYSQL)

  • @@ -15448,9 +15522,9 @@ return $ret;

  • storedCredentials - Listet die im Device gespeicherten User / Passworte für den Datenbankzugriff auf.
    - (nicht bei Rolle Agent sowie Datenbank SQLite) -
  • -

    + (nur gültig bei Datenbanktyp MYSQL) + +

  • svrinfo - allgemeine Datenbankserver-Informationen wie z.B. die DBMS-Version, Serveradresse und Port usw. Die Menge der Listenelemente ist vom Datenbanktyp abhängig. Mit dem Attribut "showSvrInfo" kann die Ergebnismenge eingeschränkt werden. @@ -16174,9 +16248,9 @@ sub bdump {
  • useAdminCredentials - - Wenn gesetzt, wird ein zuvor mit "set <Name> adminCredentials" gespeicherter User - für bestimmte Datenbankoperationen verwendet.
    - (nicht bei Rolle Agent sowie Datenbank SQLite) + - Wenn gesetzt, wird ein zuvor mit "set <Name> adminCredentials" gespeicherter + privilegierter User für bestimmte Datenbankoperationen verwendet.
    + (nur gültig für Datenbanktyp MYSQL)