[pkg-nagios-changes] [Git][nagios-team/pkg-nagvis][upstream] New upstream version 1.9.17

Adam Cecile gitlab at salsa.debian.org
Tue Jan 21 08:00:13 GMT 2020



Adam Cecile pushed to branch upstream at Debian Nagios Maintainer Group / pkg-nagvis


Commits:
96dfc109 by Adam Cecile at 2020-01-20T15:57:28+01:00
New upstream version 1.9.17
- - - - -


25 changed files:

- ChangeLog
- docs/en_US/backend_mklivestatus.html
- docs/en_US/nagvis_config_format_description.html
- docs/en_US/worldmap.html
- etc/maps/demo-worldmap.cfg
- etc/nagvis.ini.php-sample
- share/frontend/nagvis-js/images/leaflet/layers-2x.png → share/frontend/nagvis-js/images/internal/leaflet/layers-2x.png
- share/frontend/nagvis-js/js/ElementHover.js
- share/frontend/nagvis-js/js/ElementLine.js
- share/frontend/nagvis-js/js/NagVisStatefulObject.js
- share/frontend/nagvis-js/js/ViewWorldmap.js
- share/server/core/classes/CoreLogonMultisite.php
- share/server/core/classes/CoreModMultisite.php
- share/server/core/classes/CorePDOHandler.php
- share/server/core/classes/GlobalBackendmkbi.php
- share/server/core/classes/GlobalBackendmklivestatus.php
- share/server/core/classes/GlobalMainCfg.php
- share/server/core/classes/ViewManageRoles.php
- share/server/core/classes/ViewManageUsers.php
- share/server/core/classes/ViewMapAddModify.php
- share/server/core/defines/global.php
- share/server/core/defines/matches.php
- share/server/core/mapcfg/default.php
- share/server/core/sources/geomap.php
- share/server/core/sources/worldmap.php


Changes:

=====================================
ChangeLog
=====================================
@@ -1,3 +1,61 @@
+1.9.17
+  * FIX: Fix PHP 5.3 incompatibility introduced with 1.9.16
+  * FIX: Fix IE 11 incompatibility on worldmaps in relation to lines
+	 which was introduced with 1.9.13
+  * FIX: Fix incompatibility with Check 1.6 auth cookies of users with special
+         characters in the user ID
+
+1.9.16
+Core:
+  * Add support for Encrypted livestatus. You can now configure "tcp-tls:[address]:[port]"
+    as socket address and control the TLS verification using the new backend specific
+    settings "verify_tls_peer" and "verify_tls_ca_path".
+
+
+1.9.15
+Core:
+  * FIX: "You are not permitted to access this page (ChangePassword/view/)" for users (issue #215)
+
+Frontend:
+  * FIX: Fix IE 11 incompatibility regression introduced with 1.9.13
+
+1.9.14
+Core:
+  * MKBI backend: Use "htmlcgi" URL/path for building links to the Checkmk GUI
+    (Aggregations used the base_url, which should not be used for user URLs)
+
+Worldmap:
+  * Consistent page reloads: center + zoom of the map kept in URL
+  * Memory and performance optimization: line rendering - clip long lines protruding out of viewport
+  * Memory and performance optimization: fix getMapObject SQL query (lng/lat rectangle)
+
+Frontend
+  * FIX: Fix creating users when mbstring extension is not available
+
+1.9.13
+Worldmap:
+  * Configurable OpenStreetMap tile server URL (worldmap_tiles_{url,attribution})
+  * OpenStreetMap tile colors can now be dimmed using the
+    worldmap_tiles_saturate configuration option so that larger colorful
+    backgrounds do not interfere with the map objects.
+  * Optional 2nd map layer (satellite imagery)
+  * FIX: Worldmap textbox visibility per zoom level
+  * FIX: The "clone object" functionality did sometimes break with an error
+  message like "Invalid argument supplied for foreach()"
+  (Thanks to Vojtech Pithart for taking the time to improve the NagVis worldmap!)
+
+1.9.12
+Core:
+  * FIX: Allow "*" character to be part of backend dbpass values
+  * Multisite Snapin: Reworked data export API to snapin. The new API is
+  compatible with Checkmk 1.6b2 and newer.
+
+Frontend
+  * FIX: Fixed incompatibility with PHP 7.2 (count(STRING)) when creating roles
+
+Geomap:
+  * Improved error handling of CSV lines with less than 4 fields
+
 1.9.11
 Frontend
   * FIX: Weathermap lines now respect the configured error colors
@@ -66,7 +124,7 @@ Core:
     (Configure this per object by adding the attribute hover_childs_sort=k).
 
 Frontend:
-  * On demand automaps: Hostgroup filter in header menu is now a searchable dropdown field 
+  * On demand automaps: Hostgroup filter in header menu is now a searchable dropdown field
   * FIX: Fixed moving textbox objects in IE
 
 1.9.3
@@ -89,7 +147,7 @@ Core:
 
 1.9.1
 Core:
-  * FIX: Fixed incompatibility with pecl-http (Cannot redeclare http_redirect()) 
+  * FIX: Fixed incompatibility with pecl-http (Cannot redeclare http_redirect())
   * FIX: Fixed duplicate global section in sample automaps after editing
 
 Frontend:
@@ -627,9 +685,9 @@ Automap:
 1.8b3
 Frontend:
   * Added option "zoom_scale_objects" to default section of global config to
-    allow users to control the scaling behaviour of zoomed objects. By 
-    default the whole maps is zoomed like in previous versions. But when 
-    zoom_scale_objects is set to 0, the map objects and labels are not 
+    allow users to control the scaling behaviour of zoomed objects. By
+    default the whole maps is zoomed like in previous versions. But when
+    zoom_scale_objects is set to 0, the map objects and labels are not
     resized, but only repositioned according to the given zoom factor.
   * FIX: Fixed broken NagVis Multisite sidebar dashlet
   * FIX: Fixed showing URLs as hover menus (hover_url option)
@@ -641,7 +699,7 @@ Frontend:
 
 Core:
   * Allowing ~ chars in URLs now (Thanks to Daniel Albers for the patch)
-  * FIX: Fixed rare occuring encoding problems of vars in several places 
+  * FIX: Fixed rare occuring encoding problems of vars in several places
   * FIX: Fixed PHP error with map objects linking to not existing maps
   * FIX: Trying to workaround broken processing of non UTF-8 pages in hover_urls
 
@@ -662,7 +720,7 @@ Core:
   * FIX: Fixed host alias attribute in livestatus backend
   * Dropped the merlinmy backend for the moment as it was not working for a
     time. Please provide a fixed one if you like to see this working again
-  * FIX: Fixed PHP errors when acknowleding host/service problems 
+  * FIX: Fixed PHP errors when acknowleding host/service problems
   * FIX: Fixed missing values alias, display_name, address values in hover templates
 
 Installer:
@@ -690,7 +748,7 @@ Core:
     filter on the map. In first instance it automatically gathers the list of
     objects to add on this map and positions them in a grid on the map. The
     user can then modify all the objects, for example change their options
-    like, positions and visualisation. 
+    like, positions and visualisation.
   * Changed default http_timeout from 10 to 2 seconds
   * Added new iconset std_area, which can be used to create maps which are
     visible from a greater distance
@@ -763,13 +821,13 @@ Geomap:
 Frontend:
   * FIX: Fixed "Undefined index" error when changing backend_id of maps
   * FIX: Fixed hiding of shapes during refresh (enable_refresh=1)
-  * Reverted change from 1.7.5 (Weathermap lines with byte/bit values in 
+  * Reverted change from 1.7.5 (Weathermap lines with byte/bit values in
     labels should print human) which broke the handling for some plugins
 
 1.7.7
 Core:
   * Implemented "on demand" maps. Maps which only need a basic configuration
-    of global parameters like automaps and geomaps can now be configured and 
+    of global parameters like automaps and geomaps can now be configured and
     created on demand by URL parameters. This mode is reached by simply
     calling the map URL without "show=" parameter and a bunch of parameters
     for the global section of the map instead.
@@ -920,7 +978,7 @@ Core
 Frontend
   * Added new map config option (global section) event_on_load to raise frontend events
     also on page loading
-  * Added new options event_repeat_interval and event_repeat_duration to 
+  * Added new options event_repeat_interval and event_repeat_duration to
     configured repeated frontend events
   * Added rotations to sidebar
   * Info page shows json_encode/json_decode capability of used PHP
@@ -1095,7 +1153,7 @@ Core
   * NagVis creates now "omdadmin" user in OMD environments when creating new auth.db files
   * Bugfix: Added missing default permissions for guest role (viewing demo maps)
   * Bugfix: Fixed version number format for stable versions like (1.6)
-    
+
 Frontend
   * Ajax call for redrawing map objects is not cacheable anymore (prevent strange
     hopping of icons after unlock -> edit -> lock in some cases.
@@ -1192,7 +1250,7 @@ Frontend
   * Bugfix: Don't hide dependent fiels where the master attribute is not available
   * Bugfix: Fixed map global section editing
   * Bugfix: IE8 fixing event registration (javascript errors on page loading)
-  * Updating map object information while having the hover menu open does not close 
+  * Updating map object information while having the hover menu open does not close
     open hover menus anymore
 
 1.6rc1


=====================================
docs/en_US/backend_mklivestatus.html
=====================================
@@ -26,7 +26,21 @@
         <tr>
             <td>socket</td>
             <td>unix:/usr/local/nagios/var/rw/live</td>
-            <td><p>The socket to connect to can be a local unix socket or a tcp socket. You have to define the type at the beginning of the string. Set "unix:" for unix sockets or "tcp:" for tcp sockets.</p> <p>In case of the unix socket you need to specify the path of the livestatus unix socket to connect to.</p> <p>When using a tcp socket you have to enter a host address and a tcp port using the following scheme: <host>:<port>. The host address can be an IP address or an FQDN.</p></td>
+            <td><p>The socket to connect to can be a local unix socket or a tcp
+            socket. You have to define the type at the beginning of the string.
+            Set "unix:" for unix sockets or "tcp:" for tcp
+            sockets.</p>
+
+            <p><font color="#f00">New in 1.9.16</font>:Since Checkmk 1.6.0 it is possible to encrypt the Livestatus
+            channel using TLS. To connnect to such a channel use "tcp-tls:".</p>
+
+            <p>In case of the unix socket you need to specify the
+            path of the livestatus unix socket to connect to.</p>
+
+            <p>When using a tcp socket you have to enter a host address and a
+            tcp port using the following scheme: <host>:<port>. The host address can
+            be an IP address or an FQDN.</p>
+            </td>
         </tr><tr>
             <td>timeout</td>
             <td>5</td>
@@ -35,6 +49,25 @@
                 This is just a fallback. To prevent timeouts when accessing remote sites you really should configure a statushost for the backend.
                 For details take a look at the general backend parameters documented in the <a href="nagvis_config_format_description.html#backend">backend section</a>
                 of the main configuration format description.</a></td>
+        </tr><tr>
+            <td>verify_tls_peer</td>
+            <td>1</td>
+            <td>
+                <font color="#f00">New in 1.9.16</font>: Only relevant when you connect to a Livestatus TLS encrypted socket.
+                This can be used to turn off the peer certificate verification. In case it is enabled, you will have to
+                set the <tt>verify_tls_ca_path</tt> option.
+            </td>
+        </tr><tr>
+            <td>verify_tls_ca_path</td>
+            <td></td>
+            <td>
+		<font color="#f00">New in 1.9.16</font>: Configure an absolute
+		path that points to a CA chain file which is then used to verify the
+		certificate of the Livestatus TLS server. You can, for example in Checkmk
+		sites, point it to the, "Trusted certificate authorities file of Checkmk
+		(/omd/sites/[site-id]/var/ssl/ca-certificates.crt) to use the same trust
+		configuration in NagVis and Checkmk.
+            </td>
         </tr>
         </table>
         <p>There are also some general parameters. You can read about them in <a href="nagvis_config_format_description.html#backend">main configuration format description</a>.</p>


=====================================
docs/en_US/nagvis_config_format_description.html
=====================================
@@ -101,6 +101,28 @@
 	  <td>http://geomap.nagvis.org/</td>
 	  <td>The server to use as source for the NagVis geomaps. Must implement the API which can be found <a href="http://pafciu17.dev.openstreetmap.org/">here</a></td>
         </tr>
+        
+        <tr>
+            <td>worldmap_tiles_url <font color="#ff0000">(new in 1.9.13)</font></td>
+            <td>https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png</td>
+            <td>Worldmap uses OpenStreetMap tiles as default map background. The URL specifies where to GET the PNG tile images from.</td>
+        </tr>
+        <tr>
+            <td>worldmap_tiles_attribution <font color="#ff0000">(new in 1.9.13)</font></td>
+            <td>© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a></td>
+            <td>Map tiles attribution text (shown in bottom right corner)</td>
+        </tr>
+        <tr>
+            <td>worldmap_satellite_tiles_url<br>
+                worldmap_satellite_tiles_attribution<br>
+                <font color="#ff0000">(new in 1.9.13)</font>
+            </td>
+            <td></td>
+            <td>Secondary map background tiles (satellite images) URL and attribution.
+                When used, the <a href="https://leafletjs.com/reference-1.5.0.html#control-layers">layers control</a>
+                appears on top right corner of the map.
+            </td>
+        </tr>
 
         <tr>
           <td>http_proxy <font color="#ff0000">(new in 1.6)</font></td>


=====================================
docs/en_US/worldmap.html
=====================================
@@ -22,12 +22,13 @@
         <h2>Prerequisites</h2>
         <p>There is no special software needed on the NagVis server, but there is one special requirement. To
         be able to use this feature, the browser opening NagVis worldmaps needs to be able to fetch the background
-        images (map tiles) from the internet. In most corporate environments this means that your client needs
+        images (map tiles) from the internet, or a local mirror, see below. In most corporate environments this means that your client needs
         to have a proxy server configured.</p>
-        <p>The worldmaps currently use the official tile servers of Open Street Map 
-        (<code>https://{s}.tile.openstreetmap.org/</code>). This is currently hardcoded, but might be made configurable
-        in the future.</p>
-        
+        <p>The worldmaps use the official tile servers of Open Street Map (<code>https://{s}.tile.openstreetmap.org/</code>) as a default.
+        Alternative tile server (local mirror) may be set in configuration, for example: <code>worldmap_tiles_url="http://my-tiles.local/{z}/{x}/{y}.png"</code> </p>
+
+        <p>The <a href="https://switch2osm.org/serving-tiles/">switch2osm guides</a> might help you to spin up your local OpenStreetMap mirror.</p>
+
         <h2>The first call</h2>
         <p>NagVis comes with a demo worldmap called "demo-worldmap". If your NagVis is configured correctly
         and your browser is able to fetch the background images from the tile server, you should see a map
@@ -37,7 +38,7 @@
 
         <p>This worldmap is defined using the map configuration file "demo-worldmap.cfg". The contents
         look like this:</p>
-        
+
         <pre>define global {
     alias=Demo: 4 Worldmap
     parent_map=demo-overview
@@ -48,6 +49,7 @@
     sources=worldmap
     worldmap_center=50.86837814203458,10.21728515625
     worldmap_zoom=6
+    worldmap_tiles_saturate=33
 }</pre>
 
         <p>Only the last three attributes are worldmap specific definitions, all of them are mandatory for
@@ -62,6 +64,8 @@
         <p>The <code>worldmap_zoom=6</code> specifies the initial zoom level to be used when rendering the worldmap.
         NagVis allows zoom levels from 2 to 18.</p>
 
+        <p>The <code>worldmap_tiles_saturate=33</code> dims the colors of default OpenStreetMap so that red motorways or
+        large green forests don't interfere with actual map objects. Possible values are 0 (no colors, grayscale) through 100 (full colors).</p>
 
         <h2>Create your own worldmap</h2>
 


=====================================
etc/maps/demo-worldmap.cfg
=====================================
@@ -6,6 +6,7 @@ define global {
     backend_id=demo
     worldmap_center=50.86837814203458,10.21728515625
     worldmap_zoom=6
+    worldmap_tiles_saturate=33
     iconset=std_geo
     icon_size=32
 }


=====================================
etc/nagvis.ini.php-sample
=====================================
@@ -71,6 +71,14 @@
 ; can be found on http://pafciu17.dev.openstreetmap.org/
 ;geomap_server="http://geomap.nagvis.org/"
 ;
+; Public or private mirror of OpenStreetMap tiles server
+;worldmap_tiles_url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
+;worldmap_tiles_attribution="© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>"
+;
+; Secondary "satellite" tiles server
+;worldmap_satellite_tiles_url=""
+;worldmap_satellite_tiles_attribution=""
+;
 ; In some cases NagVis needs to open connections to the internet. The cases are:
 ; - The new geomap needs access to openstreetmap webservices to be able to fetch
 ;   mapping information


=====================================
share/frontend/nagvis-js/images/leaflet/layers-2x.png → share/frontend/nagvis-js/images/internal/leaflet/layers-2x.png
=====================================


=====================================
share/frontend/nagvis-js/js/ElementHover.js
=====================================
@@ -716,7 +716,7 @@ var ElementHover = Element.extend({
         var regex = getRegEx('loopChild', "<!--\\sBEGIN\\sloop_child\\s-->(.+?)<!--\\sEND\\sloop_child\\s-->");
         if(this.template_html.search(regex) !== -1)
             this.template_html = this.template_html.replace(regex, '<!-- BEGIN loop_child -->'
-                                                                   + g_hover_template_childs[this.obj.hover_template]
+                                                                   + g_hover_template_childs[this.obj.conf.hover_template]
                                                                    + '<!-- END loop_child -->');
     
         // Search for images and append current timestamp to src (prevent caching of


=====================================
share/frontend/nagvis-js/js/ElementLine.js
=====================================
@@ -340,6 +340,16 @@ var ElementLine = Element.extend({
         var xEnd   = x[x.length - 1];
         var yEnd   = y[y.length - 1];
 
+        let adjustedPoints = this.cutLineBeyondViewport(xStart, yStart, xEnd, yEnd);
+        if (adjustedPoints === null) {
+            return; // Line won't be visible -> this.parts left empty -> no rendering
+        }
+
+        xStart = adjustedPoints[0];
+        yStart = adjustedPoints[1];
+        xEnd = adjustedPoints[2];
+        yEnd = adjustedPoints[3];
+
         var width = addZoomFactor(this.obj.conf.line_width);
         if (width <= 0)
             width = 1; // minimal width for lines
@@ -422,6 +432,10 @@ var ElementLine = Element.extend({
     },
 
     renderLine: function() {
+        if (this.parts.length === 0) {
+            return;
+        }
+
         var allX = [], allY = [];
         for (var i = 0, len = this.parts.length; i < len; i++) {
             allX = allX.concat(this.parts[i][2]);
@@ -948,6 +962,147 @@ var ElementLine = Element.extend({
             ]);
         }
         return parsed;
-    }
+    },
+
+    /*
+     * There is a rectangle: viewport (current Leaflet map shown) + 10% on each side.
+     * This function cuts the lines protruding beyond the rectangle.
+     * Shortened lines prevent renderLine() from generating many vast <canvas> (10000-ish pixels) which eventually lead 
+     * to memory exhaustion or crash the browser 
+     * 
+     * Returns:
+     *  either: [xA, yA, xB, yB] - original or adjusted line A/B coordinates,
+     *  or: null - line out of a rectangle, don't render
+     */
+     
+    cutLineBeyondViewport: function(xA, yA, xB, yB) {
+        if (!g_map)
+            return([xA, yA, xB, yB]); // no viewport - no clipping
+
+        let viewport_size = g_map.getSize();
+        const xMax = viewport_size.x; // 1920
+        const yMax = viewport_size.y; // 1080
+        const xTolerance = xMax * 0.1; // 192 (10%)
+        const yTolerance = yMax * 0.1; // 108 (10%)
+        
+        // Cohen-Sutherland algorithm 
+        
+        // region codes 
+        const INSIDE = 0; // 0000 
+        const LEFT = 1;   // 0001 
+        const RIGHT = 2;  // 0010 
+        const BOTTOM = 4; // 0100 
+        const TOP = 8;    // 1000 
+
+        // boundaries
+        const x_min = -xTolerance;
+        const x_max = xMax + xTolerance;
+        const y_min = -yTolerance;
+        const y_max = yMax + yTolerance;
+
+        // Function to compute region code
+        let regionCode = function (x, y) 
+        { 
+            let code = INSIDE; 
+        
+            if (x < x_min)       // to the left of rectangle 
+                code |= LEFT; 
+            else if (x > x_max)  // to the right of rectangle 
+                code |= RIGHT; 
+            if (y < y_min)       // below the rectangle 
+                code |= BOTTOM; 
+            else if (y > y_max)  // above the rectangle 
+                code |= TOP; 
+        
+            return code; 
+        } 
+
+        let cohenSutherlandClip = function (x1, y1, x2, y2) {
+            let code1 = regionCode(x1, y1); 
+            let code2 = regionCode(x2, y2); 
+
+            let accept = false; 
+
+            while (true) 
+            { 
+                if ((code1 == 0) && (code2 == 0)) 
+                { 
+                    // If both endpoints lie within rectangle 
+                    accept = true; 
+                    break; 
+                } 
+                else if (code1 & code2) 
+                { 
+                    // If both endpoints are outside rectangle, 
+                    // in same region 
+                    break; 
+                } 
+                else
+                { 
+                    // Some segment of line lies within the 
+                    // rectangle 
+                    let code_out; 
+                    let x, y; 
+
+                    // At least one endpoint is outside the  
+                    // rectangle, pick it. 
+                    if (code1 != 0) 
+                        code_out = code1; 
+                    else
+                        code_out = code2; 
+
+                    // Find intersection point; 
+                    // using formulas y = y1 + slope * (x - x1), 
+                    // x = x1 + (1 / slope) * (y - y1) 
+                    if (code_out & TOP) 
+                    { 
+                        // point is above the clip rectangle 
+                        x = x1 + (x2 - x1) * (y_max - y1) / (y2 - y1); 
+                        y = y_max; 
+                    } 
+                    else if (code_out & BOTTOM) 
+                    { 
+                        // point is below the rectangle 
+                        x = x1 + (x2 - x1) * (y_min - y1) / (y2 - y1); 
+                        y = y_min; 
+                    } 
+                    else if (code_out & RIGHT) 
+                    { 
+                        // point is to the right of rectangle 
+                        y = y1 + (y2 - y1) * (x_max - x1) / (x2 - x1); 
+                        x = x_max; 
+                    } 
+                    else if (code_out & LEFT) 
+                    { 
+                        // point is to the left of rectangle 
+                        y = y1 + (y2 - y1) * (x_min - x1) / (x2 - x1); 
+                        x = x_min; 
+                    } 
+
+                    // Now intersection point x,y is found 
+                    // We replace point outside rectangle 
+                    // by intersection point 
+                    if (code_out == code1) 
+                    { 
+                        x1 = x; 
+                        y1 = y; 
+                        code1 = regionCode(x1, y1); 
+                    } 
+                    else
+                    { 
+                        x2 = x; 
+                        y2 = y; 
+                        code2 = regionCode(x2, y2); 
+                    } 
+                } 
+            } 
+            if (accept) 
+                return([x1, y1, x2, y2]);
+            else
+                return null;
+        }
+
+        return cohenSutherlandClip(xA, yA, xB, yB);
+    },
 
 });


=====================================
share/frontend/nagvis-js/js/NagVisStatefulObject.js
=====================================
@@ -436,20 +436,33 @@ var NagVisStatefulObject = NagVisObject.extend({
 
         var sColor = oStates[this.conf.summary_state].color;
 
+        // Use these classes (icon-flashing-<state>) in your custom css to customise flashing icons
+        // e.g. icon-flashing-critical, icondiv-flashing-critical
+        // Note you may need to use '!important' to override the inline default
+        // 
+        var sFlashingClass = 'icon-flashing-' + this.conf.summary_state.toLowerCase();
+        var sFlashingDivClass = 'icondiv-flashing-' + this.conf.summary_state.toLowerCase();
+
         this.bIsFlashing = show;
         if(show) {
             oObjIcon.style.border  = "5px solid " + sColor;
+            oObjIcon.classList.add(sFlashingClass);
             oObjIconDiv.style.top  = (this.parseCoord(this.conf.y, 'y') - 5) + 'px';
             oObjIconDiv.style.left = (this.parseCoord(this.conf.x, 'x') - 5) + 'px';
+            oObjIconDiv.classList.add(sFlashingDivClass);
         } else {
             oObjIcon.style.border  = "none";
+            oObjIcon.classList.remove(sFlashingClass);
             oObjIconDiv.style.top  = this.parseCoord(this.conf.y, 'y') + 'px';
             oObjIconDiv.style.left = this.parseCoord(this.conf.x, 'x') + 'px';
+            oObjIconDiv.classList.remove(sFlashingDivClass);
         }
 
-        sColor      = null;
-        oObjIconDiv = null;
-        oObjIcon    = null;
-    },
+        sColor            = null;
+        sFlashingClass    = null;
+        sFlashingDivClass = null;
+        oObjIconDiv       = null;
+        oObjIcon          = null;
+    }
 
 });


=====================================
share/frontend/nagvis-js/js/ViewWorldmap.js
=====================================
@@ -55,16 +55,41 @@ var ViewWorldmap = ViewMap.extend({
 
     initWorldmap: function() {
         L.Icon.Default.imagePath = oGeneralProperties.path_base+'/frontend/nagvis-js/images/leaflet';
+        var layers = {
+            "map": L.tileLayer(oGeneralProperties.worldmap_tiles_url, {
+                attribution: oGeneralProperties.worldmap_tiles_attribution,
+                noWrap: true, // don't repeat the world on horizontal axis
+                detectRetina: true, // look nice on high resolution screens
+                maxZoom: 20,
+            }),
+        }
+        if(oGeneralProperties.worldmap_satellite_tiles_url) {
+            layers.satellite = L.tileLayer(oGeneralProperties.worldmap_satellite_tiles_url, {
+                attribution: oGeneralProperties.worldmap_satellite_tiles_attribution,
+                noWrap: true, // don't repeat the world on horizontal axis
+                detectRetina: true, // look nice on high resolution screens
+                maxZoom: 20,
+            })
+        }
+
         g_map = L.map('map', {
             markerZoomAnimation: false,
             maxBounds: [ [-85,-180.0], [85,180.0] ],
-            minZoom: 2
-        }).setView(getViewParam('worldmap_center').split(','), parseInt(getViewParam('worldmap_zoom')));
-        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
-            attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
-            noWrap: true, // don't repeat the world on horizontal axe
-            detectRetina: true, // look nice on high resolution screens
-        }).addTo(g_map);
+            minZoom: 2,
+            layers: [layers.map]
+        })
+
+        let restored_coordinates = window.location.hash.substr(1).split('/');
+        if (restored_coordinates.length === 3) {
+            // place the map view according to location hash (#lat/lon/zoom) - consistent page reloads
+            g_map.setView([restored_coordinates[1], restored_coordinates[0]], restored_coordinates[2]);
+        } else {
+            // or default (map-defined) view
+            g_map.setView(getViewParam('worldmap_center').split(','), parseInt(getViewParam('worldmap_zoom')));
+        }
+
+        if (layers.satellite)
+            L.control.layers(layers).addTo(g_map);
 
         g_map_objects = L.layerGroup().addTo(g_map);
 
@@ -80,6 +105,12 @@ var ViewWorldmap = ViewMap.extend({
         if (typeof checkHideMenu !== "undefined")
             g_map.on('mousedown', checkHideMenu);
         g_map.on('mousedown', context_handle_global_mousedown);
+
+        // dim the colors of map background so that red motorways don't distract
+        let saturate_percentage = getViewParam('worldmap_tiles_saturate');
+        let ltp = document.getElementsByClassName('leaflet-tile-pane');
+        if (ltp && saturate_percentage !== '')
+            ltp[0].style.filter = "saturate("+saturate_percentage+"%)";
     },
 
     handleMoveStart: function(lEvent) {
@@ -94,6 +125,10 @@ var ViewWorldmap = ViewMap.extend({
         setViewParam('worldmap_zoom', g_map.getZoom());
 
         this.render(); // re-render the whole map
+
+        // Put the new map view coords into URL (location) - consistent reloads
+        new_center = g_map.getCenter();
+        window.location.hash = new_center.lng + "/" + new_center.lat + "/" + g_map.getZoom();
     },
 
     saveView: function() {


=====================================
share/server/core/classes/CoreLogonMultisite.php
=====================================
@@ -79,7 +79,11 @@ class CoreLogonMultisite extends CoreLogonModule {
             throw new Exception();
         }
 
-        list($username, $issueTime, $cookieHash) = explode(':', $_COOKIE[$cookieName], 3);
+        // Checkmk 1.6+ may add double quotes round the value in some cases
+        // (e.g. when @ signs are found in the value)
+        $cookieValue = trim($_COOKIE[$cookieName], '"');
+
+        list($username, $issueTime, $cookieHash) = explode(':', $cookieValue, 3);
 
         if($this->authFile == 'htpasswd')
             $users = $this->loadAuthFile($this->htpasswdPath);


=====================================
share/server/core/classes/CoreModMultisite.php
=====================================
@@ -39,15 +39,25 @@ class CoreModMultisite extends CoreModule {
         if(!$this->offersAction($this->sAction))
             return '';
 
+        $maps = array();
+
         switch($this->sAction) {
             case 'getMaps':
                 if (cfg('global', 'multisite_snapin_layout') == 'tree') {
-                    return $this->renderTree();
+                    $maps = array(
+                        "type" => "tree",
+                        "maps" => $this->renderTree(),
+                    );
                 } else {
-                    return $this->renderTable();
+                    $maps = array(
+                        "type" => "table",
+                        "maps" => $this->renderTable(),
+                    );
                 }
             break;
         }
+
+        return json_encode($maps);
     }
 
     private function renderTree() {
@@ -55,102 +65,38 @@ class CoreModMultisite extends CoreModule {
         $childs = array();
         foreach ($this->getMapsCached() as $map) {
             if($map['parent_map'] === '')
-                $maps[$map['name']] = $map;
+                $maps[$map['name']] = $this->getMapForMultisite($map);
             else {
                 if(!isset($childs[$map['parent_map']]))
                     $childs[$map['parent_map']] = Array();
-                $childs[$map['parent_map']][$map['name']] = $map;
-            }
-        }
-
-        $s = '<ul>'.$this->renderTreeNodes($maps, $childs).'</ul>';
-
-        // FIXME: check_mk/tree_state.py?tree=nagvis holen
-        // evaluieren
-        // alles was auf off steht per toggle_foldable_container schließen
-        return $s.$this->renderFootnotelinks();
-    }
-
-    private function renderTreeNodes($maps, $childs) {
-        $s = '';
-        foreach($maps AS $map) {
-            // this copies the foldable_container code provided in Check_MK htmllib
-            // assume always open by default
-            $s .= '<li>';
-            $map_url = cfg('paths', 'htmlbase').'/index.php?mod=Map&act=view&show='.$map['name'];
-            if(isset($childs[$map['name']])) {
-                $act = 'onclick="toggle_foldable_container(\'nagvis\', \''.$map['name'].'\')" '
-                     . 'onmouseover="this.style.cursor=\'pointer\';" '
-                     . 'onmouseout="this.style.cursor=\'auto\';"';
-
-                $s .= '<img align=absbottom class="treeangle" id="treeimg.nagvis.'.$map['name'].'" '
-                    . 'src="images/tree_90.png" '.$act.' />';
-                $s .= '<a href="'.$map_url.'" target="main"><b class="treeangle title" class=treeangle>';
-                $s .= $map['alias'];
-                $s .= '</b></a><br>';
-                $s .= '<ul class="treeangle open" style="padding-left:0;" id="tree.nagvis.'.$map['name'].'">';
-                $s .= $this->renderTreeNodes($childs[$map['name']], $childs);
-                $s .= '</ul>';
-            } else {
-                $s .= '<a target="main" href="'.$map_url.'">'.$map['alias'].'</a>';
+                $childs[$map['parent_map']][$map['name']] = $this->getMapForMultisite($map);
             }
-            $s .= '</li>';
         }
-        return $s;
+        return array(
+            "maps" => $maps,
+            "childs" => $childs,
+        );
     }
 
     private function renderTable() {
-        $code = '<table class="allhosts"><tbody>';
+        $maps = array();
         foreach ($this->getMapsCached() as $map) {
-            switch($map['summary_state']) {
-                case 'OK':
-                case 'UP':
-                    $state = '0';
-                    break;
-                case 'WARNING':
-                    $state = '1';
-                    break;
-                case 'CRITICAL':
-                case 'DOWN':
-                case 'UNREACHABLE':
-                    $state = '2';
-                    break;
-                default:
-                    $state = '3';
-                    break;
-            }
-
-            $title = $map['summary_state'];
-
-            if ($map['summary_in_downtime']) {
-                $state .= ' stated';
-                $title .= ' (Downtime)';
-            }
-            elseif ($map['summary_problem_has_been_acknowledged']) {
-                $state .= ' statea';
-                $title .= ' (Acknowledged)';
-            }
-
-            if ($map['summary_stale']) {
-                $state .= ' stale';
-                $title .= ' (Stale)';
-            }
-
-            $code .= '<tr><td>';
-            $code .= '<div class="statebullet state'.$state.'" title="'.$title.'"> </div>';
-            $code .= '<a href="'.cfg('paths', 'htmlbase').'/index.php?mod=Map&act=view&show='.$map['name'].'" ';
-            $code .= 'class="link" target="main">'.$map['alias'].'</a>';
-            $code .= '</td></tr>';
+            $maps[] = $this->getMapForMultisite($map);
         }
-        $code .= '</tbody></table>';
-        return $code.$this->renderFootnotelinks();
+        return $maps;
     }
 
-    private function renderFootnoteLinks() {
-        $url = cfg('paths', 'htmlbase');
-        return "<div class=footnotelink>"
-              ."<a onfocus=\"if (this.blur) this.blur();\" target=\"main\" class=\"link\" href=\"".$url."/\">EDIT</a>"
-              ."</div>";
+    private function getMapForMultisite($map) {
+        return array(
+            "name" => $map["name"],
+            "title" => $map['summary_state'],
+            "alias" => $map['alias'],
+            "url" => cfg('paths', 'htmlbase').'/index.php?mod=Map&act=view&show='.$map['name'],
+            "summary_state" => $map["summary_state"],
+            "summary_in_downtime" => $map['summary_in_downtime'],
+            "summary_problem_has_been_acknowledged" => $map['summary_problem_has_been_acknowledged'],
+            "summary_stale" => $map['summary_stale'],
+        );
     }
 
     // Wraps the getMaps() function by applying a short livetime cache based


=====================================
share/server/core/classes/CorePDOHandler.php
=====================================
@@ -63,6 +63,7 @@ class CorePDOHandler {
                         .'WHERE users2roles."userId" = :id',
                     '-perm-rename-map' => 'UPDATE perms SET obj=:new_name '.
                         ' WHERE "mod"=\'Map\' AND obj=:old_name',
+                    '-perm-change-act' => 'UPDATE perms SET act=:new_act WHERE mod=:mod and act=:old_act',
 
                     '-role-add' => 'INSERT INTO roles (name) VALUES (:name)',
                     '-role-add-with-id' => 'INSERT INTO roles ("roleId", name) VALUES (:roleId, :name)',
@@ -128,6 +129,10 @@ class CorePDOHandler {
                 ),
 
                 'updates' => array(
+                    '1091500' => array(
+                        array('-perm-change-act', array('mod' => 'ChangePassword', 'old_act' => 'change', 'new_act' => '*'))
+                    ),
+
                     '1080600' => array(
                         array('-perm-add', array('mod' => 'Url', 'act' => 'view', 'obj' => '*')),
                         array('-create-pop-roles-perms-3', array(
@@ -261,6 +266,7 @@ class CorePDOHandler {
         }
         $drv_data = self::$DRIVERS[$driver];
         $dsn = "$driver:".$drv_data['build_dsn']($params);
+        $this->dsn = $dsn;
 
         try {
             $this->DB = new PDO($dsn, $username, $password, array(
@@ -270,12 +276,12 @@ class CorePDOHandler {
             ));
         } catch(PDOException $e) {
             error_log('Could not initialize a database connection: '.$e->getMessage());
+            $this->lastErrorInfo = $e->getMessage();
             return false;
-    	}
+        }
         if($this->DB === false || $this->DB === null)
             return false;
 
-        $this->dsn = $dsn;
         $this->driver = $driver;
         $this->data = $drv_data;
         $this->updating = false;
@@ -286,6 +292,7 @@ class CorePDOHandler {
                 $res = $this->DB->exec($q);
                 if($res === false) {
                     $this->DB = null;
+                    $this->lastErrorInfo = "Initial DB query ($q) failed";
                     return false;
                 }
             }
@@ -356,7 +363,7 @@ class CorePDOHandler {
         if (isset($this->lastErrorInfo))
             return $this->lastErrorInfo;
         else
-            return $this->DB->errorInfo();
+            return $this->DB ? $this->DB->errorInfo() : '';
     }
 
     public function errorString() {
@@ -460,7 +467,7 @@ class CorePDOHandler {
         try {
             ksort(self::$DRIVERS['_common']['updates']);
             foreach (self::$DRIVERS['_common']['updates'] as $ver => $queries) {
-                if (intval($ver) <= $dbVersion)
+                if (intval($ver) < $dbVersion)
                     continue;
 
                 if (!$this->inTrans) {
@@ -583,7 +590,7 @@ class CorePDOHandler {
         $this->queryFatal('-perm-add', array('mod' => 'User', 'act' => 'setOption', 'obj' => '*'));
 
         // Access controll: Change own password
-        $this->queryFatal('-perm-add', array('mod' => 'ChangePassword', 'act' => 'change', 'obj' => '*'));
+        $this->queryFatal('-perm-add', array('mod' => 'ChangePassword', 'act' => '*', 'obj' => '*'));
 
         // Access controll: View maps via multisite
         $this->queryFatal('-perm-add', array('mod' => 'Multisite', 'act' => 'getMaps', 'obj' => '*'));
@@ -618,7 +625,7 @@ class CorePDOHandler {
 
         // Access control: View URLs e.g. in rotation pools
         $this->queryFatal('-perm-add', array('mod' => 'Url', 'act' => 'view', 'obj' => '*'));
-        
+
         // Assign the new permission to the managers, users, guests
         $this->queryFatal('-create-pop-roles-perms-3', array(
             'r1' => 'Managers', 'r2' => 'Users (read-only)', 'r3' => 'Guests',


=====================================
share/server/core/classes/GlobalBackendmkbi.php
=====================================
@@ -127,7 +127,8 @@ class GlobalBackendmkbi implements GlobalBackendInterface {
     }
 
     private function aggrUrl($name) {
-        return $this->baseUrl.'view.py?view_name=aggr_single&aggr_name='.$name.'&po_aggr_expand=1';
+        $html_cgi = cfg('backend_'.$this->backendId, 'htmlcgi');
+        return $html_cgi.'/view.py?view_name=aggr_single&aggr_name='.$name.'&po_aggr_expand=1';
     }
 
     /**


=====================================
share/server/core/classes/GlobalBackendmklivestatus.php
=====================================
@@ -37,6 +37,7 @@
 class GlobalBackendmklivestatus implements GlobalBackendInterface {
     private $backendId = '';
 
+    private $CONNECT_ERR = "";
     private $CONNECT_EXC = null;
     private $SOCKET = null;
     private $socketType = '';
@@ -52,6 +53,19 @@ class GlobalBackendmklivestatus implements GlobalBackendInterface {
           'default'   => 'unix:/usr/local/nagios/var/rw/live',
           'match'     => MATCH_SOCKET,
         ),
+        'verify_tls_peer' => Array(
+          'must'       => 0,
+          'editable'   => 1,
+          'default'    => 1,
+          'match'      => MATCH_BOOLEAN,
+          'field_type' => 'boolean',
+        ),
+        'verify_tls_ca_path' => Array(
+          'must'      => 0,
+          'editable'  => 1,
+          'default'   => '',
+          'match'     => MATCH_STRING_PATH,
+        ),
         'timeout' => Array(
           'must'      => 1,
           'editable'  => 1,
@@ -118,7 +132,7 @@ class GlobalBackendmklivestatus implements GlobalBackendInterface {
         if($type === 'unix') {
             $this->socketType = $type;
             $this->socketPath = $address;
-        } elseif($type === 'tcp') {
+        } elseif($type === 'tcp' || $type === 'tcp-tls') {
             $this->socketType = $type;
 
             // Extract address and port
@@ -126,6 +140,7 @@ class GlobalBackendmklivestatus implements GlobalBackendInterface {
 
             $this->socketAddress = $address;
             $this->socketPort = $port;
+
         } else {
             throw new BackendConnectionProblem(
               l('Unknown socket type given in backend [BACKENDID]',
@@ -170,31 +185,77 @@ class GlobalBackendmklivestatus implements GlobalBackendInterface {
         if($this->CONNECT_EXC != null)
             throw $this->CONNECT_EXC;
 
+        set_error_handler(array($this, 'connectErrorHandler'), E_WARNING | E_NOTICE);
+
         // Connect to the socket
         // don't want to see the connection error messages - want to handle the
         // errors later with an own error message
         // FIXME: Maybe use pfsockopen in the future to use persistent connections
         if($this->socketType === 'unix') {
-            $oldLevel = error_reporting(0);
             $this->SOCKET = fsockopen('unix://'.$this->socketPath, NULL, $errno, $errstr, (float) cfg('backend_'.$this->backendId, 'timeout'));
-            error_reporting($oldLevel);
+
+        } elseif($this->socketType === 'tcp-tls') {
+            if (cfg('backend_'.$this->backendId, 'verify_tls_peer') == true) {
+                $ssl_options = Array(
+                    'verify_peer' => true,
+                    'verify_peer_name' => false,
+                    'verify_depth' => 1,
+                );
+
+            $ca_path = cfg('backend_'.$this->backendId, 'verify_tls_ca_path');
+            if ($ca_path)
+                $ssl_options['cafile'] = $ca_path;
+                $context = stream_context_create(Array(
+                    'ssl' => $ssl_options
+                ));
+            } else {
+                $context = stream_context_create(Array(
+                    'ssl' => Array(
+                        'verify_peer' => false,
+                        'verify_peer_name' => false
+                    )
+                ));
+            }
+
+            $this->SOCKET= stream_socket_client(
+                "tls://" . $this->socketAddress . ":" . $this->socketPort, $errno, $errstr,
+                (float) cfg('backend_'.$this->backendId, 'timeout'), STREAM_CLIENT_CONNECT,
+                $context);
+
         } elseif($this->socketType === 'tcp') {
-            $oldLevel = error_reporting(0);
-            $this->SOCKET = fsockopen($this->socketAddress, $this->socketPort, $errno, $errstr, (float) cfg('backend_'.$this->backendId, 'timeout'));
-            error_reporting($oldLevel);
+            $this->SOCKET = fsockopen($this->socketAddress, $this->socketPort, $errno, $errstr,
+                                        (float) cfg('backend_'.$this->backendId, 'timeout'));
         }
 
+        restore_error_handler();
+
         if(!$this->SOCKET) {
+            if ($errno === 0)
+                $error_msg = $this->CONNECT_ERR;
+            else
+                $error_msg = $errstr;
+
             $this->SOCKET = null;
             $this->CONNECT_EXC = new BackendConnectionProblem(
                                      l('Unable to connect to the [SOCKET] in backend [BACKENDID]: [MSG]',
                                                Array('BACKENDID' => $this->backendId,
                                                      'SOCKET'    => $this->socketPath,
-                                                     'MSG'       => $errstr)));
+                                                     'MSG'       => $error_msg)));
             throw $this->CONNECT_EXC;
         }
     }
 
+    /**
+     * Catch PHP errors occured during connect
+     */
+    public function connectErrorHandler($errno, $errstr) {
+    	if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
+            return false; // use default error handler
+    	}
+    	$this->CONNECT_ERR .= $errstr . "\n";
+    	return true;
+    }
+
     /*private function verifyLivestatusVersion() {
         $result = $this->queryLivestatusSingleColumn("GET status\nColumns: livestatus_version\n");
         $result[0] = '1.1.7rc1';


=====================================
share/server/core/classes/GlobalMainCfg.php
=====================================
@@ -154,6 +154,27 @@ class GlobalMainCfg {
                     'match'   => MATCH_STRING_URL,
                 ),
 
+                'worldmap_tiles_url' => array(
+                    'must'    => 0,
+                    'default' => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
+                    'match'   => MATCH_STRING_URL,
+                ),
+                'worldmap_tiles_attribution' => array(
+                    'must'    => 0,
+                    'default' => '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
+                    'match'   => MATCH_ALL
+                ),
+                'worldmap_satellite_tiles_url' => array(
+                    'must'    => 0,
+                    'default' => '',
+                    'match'   => MATCH_STRING_URL,
+                ),
+                'worldmap_satellite_tiles_attribution' => array(
+                    'must'    => 0,
+                    'default' => '',
+                    'match'   => MATCH_ALL
+                ),
+
                 'http_proxy' => array(
                     'must'    => 0,
                     'default' => null,
@@ -655,7 +676,7 @@ class GlobalMainCfg {
                     'must'       => 0,
                     'editable'   => 1,
                     'default'    => '0',
-                    'match'      => MATCH_BOOLEAN, 
+                    'match'      => MATCH_BOOLEAN,
                     'field_type' => 'boolean',
                 ),
                 'line_weather_colors' => Array(
@@ -2184,6 +2205,11 @@ class GlobalMainCfg {
           'internal_title'     => $this->getValue('internal', 'title'),
           'header_show_states' => intval($this->getValue('defaults', 'header_show_states')),
           'zoom_scale_objects' => intval($this->getValue('defaults', 'zoom_scale_objects')),
+          'worldmap_tiles_url' => $this->getValue('global', 'worldmap_tiles_url'),
+          'worldmap_tiles_attribution' => $this->getValue('global', 'worldmap_tiles_attribution'),
+          'worldmap_satellite_tiles_url' => $this->getValue('global', 'worldmap_satellite_tiles_url'),
+          'worldmap_satellite_tiles_attribution' => $this->getValue('global', 'worldmap_satellite_tiles_attribution'),
+          // Add custom action configuration
         );
 
         // Add custom action configuration


=====================================
share/server/core/classes/ViewManageRoles.php
=====================================
@@ -35,7 +35,7 @@ class ViewManageRoles {
                 if (!$name)
                     throw new FieldInputError('name', l('Please specify a name'));
 
-                if (count($name) > AUTH_MAX_ROLENAME_LENGTH)
+                if (strlen($name) > AUTH_MAX_ROLENAME_LENGTH)
                     throw new FieldInputError('name', l('This name is too long'));
 
                 if (!preg_match(MATCH_ROLE_NAME, $name))


=====================================
share/server/core/classes/ViewManageUsers.php
=====================================
@@ -35,7 +35,7 @@ class ViewManageUsers {
                 if (!$name)
                     throw new FieldInputError('name', l('Please specify a name.'));
 
-                if (mb_strlen($name) > AUTH_MAX_USERNAME_LENGTH)
+                if (strlen($name) > AUTH_MAX_USERNAME_LENGTH)
                     throw new FieldInputError('name', l('This name is too long.'));
 
                 if (!preg_match(MATCH_USER_NAME, $name))
@@ -49,7 +49,7 @@ class ViewManageUsers {
                 if (!$password1)
                     throw new FieldInputError('password1', l('Please specify a password.'));
 
-                if (mb_strlen($password1) > AUTH_MAX_PASSWORD_LENGTH)
+                if (strlen($password1) > AUTH_MAX_PASSWORD_LENGTH)
                     throw new FieldInputError('password1', l('This password is too long.'));
 
                 $password2 = post('password2');
@@ -254,7 +254,7 @@ class ViewManageUsers {
                 if (!$password1)
                     throw new FieldInputError('password1', l('Please specify a password.'));
 
-                if (mb_strlen($password1) > AUTH_MAX_PASSWORD_LENGTH)
+                if (strlen($password1) > AUTH_MAX_PASSWORD_LENGTH)
                     throw new FieldInputError('password1', l('This password is too long.'));
 
                 $password2 = post('password2');


=====================================
share/server/core/classes/ViewMapAddModify.php
=====================================
@@ -50,7 +50,7 @@ class ViewMapAddModify {
         );
         $attrDefs = $this->MAPCFG->getValidObjectType($this->object_type);
         foreach ($_REQUEST as $attr => $val) {
-            // $_REQUEST might contain cookie infos. Skipt them.
+            // $_REQUEST might contain cookie infos. Skip them.
             if (isset($_COOKIE[$attr]))
                 continue;
             if (substr($attr, 0, 7) == 'toggle_' || substr($attr, 0, 1) == '_' || isset($exclude[$attr]))


=====================================
share/server/core/defines/global.php
=====================================
@@ -23,7 +23,7 @@
  *****************************************************************************/
  
 // NagVis Version
-define('CONST_VERSION', '1.9.11');
+define('CONST_VERSION', '1.9.17');
 
 // Set PHP error handling to standard level
 // Different levels for php versions below 5.1 because PHP 5.1 reports


=====================================
share/server/core/defines/matches.php
=====================================
@@ -21,7 +21,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *****************************************************************************/
- 
+
 /**
  * @author	Lars Michelsen <lm at larsmichelsen.com>
  */
@@ -30,14 +30,14 @@ define('MATCH_NOT_EMPTY', '/^.+$/');
 define('MATCH_REGEX', '/^.*$/i');
 
 // These regex allow unicode matching
-define('MATCH_STRING', '/^[0-9a-zа-яё\p{L}\s:+[\]()_.,\-?!#@=\/\\\]+$/iu');
-define('MATCH_STRING_EMPTY', '/^[0-9a-zа-яё\p{L}\s:+[\]()_.,\-?!#@=\/\\\]*$/iu');
-define('MATCH_STRING_NO_SPACE', '/^[0-9a-zа-яё\p{L}:+[\]()_.,\-?!#@=\/\\\]+$/iu');
-define('MATCH_STRING_NO_SPACE_EMPTY', '/^[0-9a-zа-яё\p{L}:+[\]()_.,\-?!#@=\/\\\]*$/iu');
+define('MATCH_STRING', '/^[0-9a-zа-яё\p{L}\s:+[\]()_.,\-\*?!#@=\/\\\]+$/iu');
+define('MATCH_STRING_EMPTY', '/^[0-9a-zа-яё\p{L}\s:+[\]()_.,\-\*?!#@=\/\\\\*]*$/iu');
+define('MATCH_STRING_NO_SPACE', '/^[0-9a-zа-яё\p{L}:+[\]()_.,\-\*?!#@=\/\\\\*]+$/iu');
+define('MATCH_STRING_NO_SPACE_EMPTY', '/^[0-9a-zа-яё\p{L}:+[\]()_.,\-\*?!#@=\/\\\]*$/iu');
 define('MATCH_CONDITION', '/^[0-9a-zа-яё\p{L}\s_\-~=]*$/iu');
 
 define('MATCH_STRING_PATH', '/^[0-9a-z\s_.\-\/\\\]+$/i');
-define('MATCH_STRING_URL', '/^[0-9a-z\s:;|+[\]()=%?&_,.\-#@=\/\\\~]+$/i');
+define('MATCH_STRING_URL', '/^[0-9a-z\s:;|+[\]()=%?&_,.\-#@=\/\\\~\{\}]+$/i');
 define('MATCH_STRING_URL_EMPTY', '/^[0-9a-z\s:;|+[\]()=%?&_,.\-#@=\/\\\~]*$/i');
 define('MATCH_GADGET_OPT', '/^[0-9a-z\s:+[\]()_.,\-&?!#@=\/\\\%]+$/i');
 define('MATCH_STRING_STYLE', '/^[0-9a-z:;\-+%#(),.]*$/i');
@@ -114,7 +114,7 @@ define('MATCH_ORDER', '/^(?:asc|desc)$/');
 define('MATCH_TEXTBOX_WIDTH', '/^([0-9]+|auto)$/');
 define('MATCH_TEXTBOX_HEIGHT', '/^([0-9]+|auto)$/');
 define('MATCH_WEATHER_COLORS', '/^(?:[0-9]{1,4}(\.[0-9]{1,2})?:#[0-9a-f]{6},?)+$/');
-define('MATCH_SOCKET', '/^(unix:[a-zA-Z0-9\-_.\/]+|tcp:[a-zA-Z0-9.-]+:[0-9]{1,5})$/');
+define('MATCH_SOCKET', '/^(unix:[a-zA-Z0-9\-_.\/]+|tcp(-tls)?:[a-zA-Z0-9.-]+:[0-9]{1,5})$/');
 
 define('MATCH_WUI_ADDMODIFY_DO', '/^(add|modify)$/');
 ?>


=====================================
share/server/core/mapcfg/default.php
=====================================
@@ -110,11 +110,13 @@ function listZoomFactors() {
 
 function getObjectNames($type, $MAPCFG, $objId, $attrs) {
     global $_BACKEND;
+    $backendIds = false;
     if (isset($attrs['backend_id']) && $attrs['backend_id'] != '') {
         $backendIds = $attrs['backend_id'];
     } elseif ($objId !== null) {
         $backendIds = $MAPCFG->getValue($objId, 'backend_id');
-    } else {
+    }
+    if (!$backendIds) {
         $backendIds = $MAPCFG->getValue(0, 'backend_id');
     }
 


=====================================
share/server/core/sources/geomap.php
=====================================
@@ -20,11 +20,18 @@ function geomap_read_csv($p) {
     if(!file_exists($f))
         throw new GeomapError(l('Location source file "[F]" does not exist.', Array('F' => $f)));
 
+    $i = 0;
     foreach(file($f) AS $line) {
+        $i++;
+
         // skip lines beginning with any of the usual comment characters
         if(preg_match('/^[;#\/]/',$line))
             continue;
         $parts = explode(';', $line);
+        if (count($parts) < 4)
+            throw new GeomapError(l('Invalid source file line found: Line "[NR]" in "[F]" '
+                                   .'has less than 4 fields', Array('NR' => $i, 'F' => $f)));
+
         $locations[] = array(
             'name'  => $parts[0],
             'alias' => $parts[1],


=====================================
share/server/core/sources/worldmap.php
=====================================
@@ -32,6 +32,11 @@ $configVars = array(
         'default'   => 6,
         'match'     => MATCH_WORLDMAP_ZOOM,
     ),
+    'worldmap_tiles_saturate' => array(
+        'must'      => false,
+        'default'   => '',
+        'match'     => MATCH_INTEGER_EMPTY,
+    ),
 
     /*** OBJECT OPTIONS ***/
     'min_zoom' => array(
@@ -53,6 +58,7 @@ $configVarMap = array(
         'worldmap' => array(
             'worldmap_center' => null,
             'worldmap_zoom'   => null,
+            'worldmap_tiles_saturate'   => null,
         ),
     ),
 );
@@ -153,18 +159,12 @@ function worldmap_get_objects_by_bounds($sw_lng, $sw_lat, $ne_lng, $ne_lat) {
     global $DB;
     worldmap_init_db();
 
+    if ($sw_lat > $ne_lat) swap($sw_lat, $ne_lat);
+    if ($sw_lng > $ne_lng) swap($sw_lng, $ne_lng);
+        
     $q = 'SELECT lat, lng, lat2, lng2, object FROM objects WHERE'
-        .'((:sw_lat < :ne_lat AND lat BETWEEN :sw_lat AND :ne_lat)'
-        .' OR (:ne_lat < :sw_lat AND lat BETWEEN :ne_lat AND :sw_lat)'
-        .'AND '
-        .'(:sw_lng < :ne_lng AND lng BETWEEN :sw_lng AND :ne_lng)'
-        .' OR (:ne_lng < :sw_lng AND lng BETWEEN :ne_lng AND :sw_lng))'
-        .'OR '
-        .'((:sw_lat < :ne_lat AND lat2 BETWEEN :sw_lat AND :ne_lat)'
-        .' OR (:ne_lat < :sw_lat AND lat2 BETWEEN :ne_lat AND :sw_lat)'
-        .'AND '
-        .'(:sw_lng < :ne_lng AND lng2 BETWEEN :sw_lng AND :ne_lng)'
-        .' OR (:ne_lng < :sw_lng AND lng2 BETWEEN :ne_lng AND :sw_lng))';
+        .'(lat BETWEEN :sw_lat AND :ne_lat AND lng BETWEEN :sw_lng AND :ne_lng)'
+        .'OR (lat2 BETWEEN :sw_lat AND :ne_lat AND lng2 BETWEEN :sw_lng AND :ne_lng)';
 
     $RES = $DB->query($q, array('sw_lng' => $sw_lng, 'sw_lat' => $sw_lat, 'ne_lng' => $ne_lng, 'ne_lat' => $ne_lat));
     $objects = array();
@@ -204,6 +204,18 @@ function worldmap_get_objects_by_bounds($sw_lng, $sw_lat, $ne_lng, $ne_lat) {
     return $objects;
 }
 
+function worldmap_get_object_by_id($id) {
+    global $DB;
+    worldmap_init_db();
+
+    $q = 'SELECT object FROM objects WHERE object_id = :id LIMIT 1';
+
+    $RES = $DB->query($q, array('id' => $id));
+    if ($data = $RES->fetch()) {
+        return json_decode($data['object'], true);
+    }
+}
+
 // Worldmap internal helper function to add an object to the worldmap
 function worldmap_db_update_object($obj_id, $lat, $lng, $obj,
                                    $lat2 = null, $lng2 = null, $insert = true) {
@@ -324,25 +336,34 @@ function add_obj_worldmap($MAPCFG, $map_name, &$map_config, $obj_id) {
 
 function process_worldmap($MAPCFG, $map_name, &$map_config) {
     $bbox = val($_GET, 'bbox', null);
-    if ($bbox === null)
-        return false; // do nothing
+    $clone_id = val($_GET, 'clone_id', null);
 
-    $params = $MAPCFG->getSourceParams();
-    $zoom = (int)$params['worldmap_zoom'];
+    if ($bbox !== null)
+    {
+        $params = $MAPCFG->getSourceParams();
+        $zoom = (int)$params['worldmap_zoom'];
 
-    list($sw_lng, $sw_lat, $ne_lng, $ne_lat) = explode(',', $bbox);
-    foreach (worldmap_get_objects_by_bounds($sw_lng, $sw_lat, $ne_lng, $ne_lat) as $object_id => $obj) {
-        // Now, when the object has a maximum / minimum zoom configured,
-        // hide it depending on the zoom
-        $min_zoom = isset($obj['min_zoom']) ? (int)$obj['min_zoom'] : $MAPCFG->getDefaultValue('host', 'min_zoom');
-        $max_zoom = isset($obj['max_zoom']) ? (int)$obj['max_zoom'] : $MAPCFG->getDefaultValue('host', 'max_zoom');
+        list($sw_lng, $sw_lat, $ne_lng, $ne_lat) = explode(',', $bbox);
+        foreach (worldmap_get_objects_by_bounds($sw_lng, $sw_lat, $ne_lng, $ne_lat) as $object_id => $obj) {
+            // Now, when the object has a maximum / minimum zoom configured,
+            // hide it depending on the zoom
+            $min_zoom = isset($obj['min_zoom']) ? (int)$obj['min_zoom'] : $MAPCFG->getDefaultValue('host', 'min_zoom');
+            $max_zoom = isset($obj['max_zoom']) ? (int)$obj['max_zoom'] : $MAPCFG->getDefaultValue('host', 'max_zoom');
 
-        if ($min_zoom < $max_zoom && ($zoom < $min_zoom || $zoom > $max_zoom))
-            continue;
+            if ($min_zoom <= $max_zoom && ($zoom < $min_zoom || $zoom > $max_zoom))
+                continue;
 
-        $map_config[$object_id] = $obj;
+            $map_config[$object_id] = $obj;
+        }
+        return true;
+    }
+    elseif ($clone_id !== null)
+    {
+        $map_config[$clone_id] = worldmap_get_object_by_id($clone_id);
+        return true;
     }
-    return true;
+
+    return false;
 }
 
 function changed_worldmap($MAPCFG, $compare_time) {
@@ -350,4 +371,10 @@ function changed_worldmap($MAPCFG, $compare_time) {
     return !file_exists($db_path) || filemtime($db_path) > $compare_time;
 }
 
+function swap(&$x, &$y) {
+    $tmp=$x;
+    $x=$y;
+    $y=$tmp;
+}
+
 ?>



View it on GitLab: https://salsa.debian.org/nagios-team/pkg-nagvis/commit/96dfc109eb9aa036c29cd911afa815c7c215628e

-- 
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-nagvis/commit/96dfc109eb9aa036c29cd911afa815c7c215628e
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20200121/94825803/attachment-0001.html>


More information about the pkg-nagios-changes mailing list