Cacti / cacti

Cacti ™
http://www.cacti.net
GNU General Public License v2.0
1.65k stars 406 forks source link

Do not switch the trees of graphs #1131

Closed pautiina closed 6 years ago

pautiina commented 6 years ago

When I click on the graphs tree - it does not open. Problem started with commit 801d4e0b70a4708307d551cfeb62540cf9a781d5 Commit 7b4d33c880a0caa48fe09ff80cbe8ea7ef7939ea - dosn't have this problem.

netniV commented 6 years ago

Have you double checked that you have the correct rights setup against the user logged in with?

Users -> [user] -> General -> Rights to Tree View Users -> [user] -> Permissions -> View Graphs Users -> [user] -> Graphs -> Default Graph Policy Users -> [user] -> Graphs -> [desired graph] -> Effective Policy Users -> [user] -> Tree Perms -> Default Users -> [user] -> Tree Perms-> [desired tree] -> Effective Policy

Also check the groups that the user is part of, if any, to see whether they are allowing access etc.

At the very least, the user must have View Graph access plus be allowed on the Graph and the Graph Tree where the graph has been placed.

netniV commented 6 years ago

Also check that you aren't seeing issue #1083 where if you rely on groups to redirect you, there may be a group with an incorrect setting on the default page to switch to.

pautiina commented 6 years ago

I have full access to graphs, trees, plugin. 66 My trees: 67 68 69 When I click to Switch nothing happens On Preview Mode I look graphs, It's problem that trees not toogle

netniV commented 6 years ago

Are you sure that it does not look the same but changing ROUTERS to SWITCH? If you have no graphs actually at the root level, it will not show any and your first screen shot shows no graphs. Do you see the branches if you expand the tree at SWITCH ?

pautiina commented 6 years ago

The fact of the matter is that I do not see the subtrees when I click on general tree SWITCH

netniV commented 6 years ago

Do you see any of the other subtres? Is this just the SWITCH branch that is missing? I'll create a MySQL query to check a few things tomorrow if you haven't managed to find the issue.

pautiina commented 6 years ago

Any subtres not opened.

netniV commented 6 years ago

To debug this, we need to find information on whether you have access to the Tree, Branch, Device and Graph. When working through these sections, if you hit a true value, then assume you have access at that level.

Find the basics

For an example, we are going to look up testuser against test tree2. Each CHECK: section is performed.

Check the user defaults

We need the User's ID which can be found using the following query replacing <username> with the person who you are checking:

select id,username,policy_graphs,policy_graph_templates,policy_hosts,policy_trees
from user_auth 
where username = '<username>';

+----+--------------+---------------+------------------------+--------------+--------------+
| id | username     | policy_graphs | policy_graph_templates | policy_hosts | policy_trees |
+----+--------------+---------------+------------------------+--------------+--------------+
|  5 | <username>   |             1 |                      1 |            1 |            1 |
+----+--------------+---------------+------------------------+--------------+--------------+

For each of the policy columns, a value of 1 means the default is to allow the user and a value of 2 will by default deny the user. To that end, we search through the policies for the user, group, device and tree looking for a reason to deny if default is allow, or to allow if the default is deny.

Get the tree ID's

select id, name from graph_tree;

+----+---------------+
| id | name          |
+----+---------------+
|  1 | Test Tree1    |
|  2 | Test Tree2    |
|  3 | Test Tree3    |
+----+---------------+

Default permission check logic

For any of the following checks, if we have any rows then we have matches, so given this:

If at any point we return true, then that particular check passes.

CHECK: Permission to access tree - is_tree_allowed()

In order to check permissions, we need to

Explicit permissions with user default

select uap.user_id, item_id as tree_id, t.name as tree_name 
from user_auth_perms as uap 
left join graph_tree as t 
on t.id = uap.item_id  
where type = 2 and uap.user_id = <user_id>;

+---------+---------+------------+
| user_id | tree_id | tree_name  |
+---------+---------+------------+
|       5 |       2 | Test Tree2 |
+---------+---------+------------+

At this point, if we can pass the permission logic above using the policy_tree value, we move on to the next CHECK section.

Using my example above, our default is to allow (1) but we have a match on tree_id 2 so we continue to check.

Explicit permission with group default

 select uag.id as group_id, uag.name as group_name, uag.policy_trees, uag.enabled 
from user_auth_group as uag 
inner join user_auth_group_members AS uagm 
on uag.id = uagm.group_id 
where uagm.user_id = <user_id>;
+----------+-----------------+--------------+---------+
| group_id | group_name      | policy_trees | enabled |
+----------+-----------------+--------------+---------+
|        2 | Test Tree       |            2 | on      |
|        3 | View Monitor    |            2 | on      |
|        4 | View Thresholds |            1 | on      |
+----------+-----------------+--------------+---------+

This list would normally only return those enabled, so if we have no enabled groups, then we don't have access to the tree in question.

For each enabled group we do have, we then retest the above trees to see if we pass authentication. Our example above shows the policy for trees is now to deny by default, unless explicitly allowed. So we would end up with the following:

Group 2 would return true Group 3 would return true Group 4 would return false

Note, that once a true value is found, we would pass the check. This does mean that you need to ensure you setting your groups all to the same allow/deny method or ensure that you do not have user-specific permissions. Where possible, ensure there are only group permissions.

Explicit permission with group level tree items

SELECT uagm.user_id, uag.id as group_id, uagp.type, uagp.item_id, uag.enabled                         
FROM user_auth_group AS uag
INNER JOIN user_auth_group_members AS uagm
ON uag.id = uagm.group_id
INNER JOIN user_auth_group_perms as uagp
ON uagp.group_id = uag.id where uagm.user_id = <user_id>;

+---------+----------+------+---------+---------+
| user_id | group_id | type | item_id | enabled |
+---------+----------+------+---------+---------+
|       5 |        2 |    2 |       1 | on      |
+---------+----------+------+---------+---------+

This list would normally only return those rows where item_id matches our <tree_id> and are enabled, so if we have no enabled tree items for our tree_id, then we don't have any matches.

For each enabled group (see previous section), we then test the trees returned to see if we pass authentication. For our example purposes, we do not have an item_id 2 (tree id 2) for group 2.

NOTE: There is a potential bug where the the type and group is not used in the filter, I will have to do further tests to work out if that matters

Explicitly fail

At this point, if no other check returns a true value, we return a false. This means we were unable to find a reason to allow access.

pautiina commented 6 years ago

Thanks for expanding the information for debug. My answers will be small :)

My account have allow policy for all:

mysql> select id,username,policy_graphs,policy_graph_templates,policy_hosts,policy_trees
    -> from user_auth
    -> where username = 'admin';
+----+----------+---------------+------------------------+--------------+--------------+
| id | username | policy_graphs | policy_graph_templates | policy_hosts | policy_trees |
+----+----------+---------------+------------------------+--------------+--------------+
|  1 | admin    |             1 |                      1 |            1 |            1 |
+----+----------+---------------+------------------------+--------------+--------------+
1 row in set (0.00 sec)

ID's for my trees

mysql> select id, name from graph_tree;
+----+----------------+
| id | name           |
+----+----------------+
|  1 | Default Tree   |
|  6 | SWITCH         |
|  5 | ROUTERS        |
|  4 | Servers        |
|  7 | Channels       |
|  8 | ADSL           |
|  9 | Clients graphs |
| 10 | UPS            |
| 12 | Dota Servers   |
+----+----------------+
9 rows in set (0.01 sec)

Nexy query return empty result:

mysql> select uap.user_id, item_id as tree_id, t.name as tree_name
    -> from user_auth_perms as uap
    -> left join graph_tree as t
    -> on t.id = uap.item_id
    -> where type = 2 and uap.user_id = 1;
Empty set (0.00 sec)

I try check that my User id have on user_auth_perms

mysql> SELECT * FROM `user_auth_perms` WHERE user_id = 1;
Empty set (0.00 sec)

And also get empty result. Policy for this user: Allow I dont use group on my Cacti and have full access for trees and other section. 70

mysql>  select uag.id as group_id, uag.name as group_name, uag.policy_trees, uag.enabled
    -> from user_auth_group as uag
    -> inner join user_auth_group_members AS uagm
    -> on uag.id = uagm.group_id
    -> where uagm.user_id = 1;
Empty set (0.67 sec)
mysql> SELECT uagm.user_id, uag.id as group_id, uagp.type, uagp.item_id, uag.enabled
    -> INNER JOIN user_auth_group_perms as uagp
FROM user_auth_group AS uag
    -> INNER JOIN user_auth_group_members AS uagm
    -> ON uag.id = uagm.group_id
    -> INNER JOIN user_auth_group_perms as uagp
    -> ON uagp.group_id = uag.id where uagm.user_id = 1;
Empty set (2.64 sec)

If I understood you correctly, then everything should be fine, but something is wrong.

Previously, everything was fine. I'll try part by part to check the commit, which stopped working

pautiina commented 6 years ago

I look for code and try to get resuly for this query:

SELECT gti.graph_tree_id AS tree_id, gti.id, gti.title, gti.host_id, gti.site_id,
            gti.local_graph_id, gti.host_grouping_type, h.description AS hostname, s.name AS sitename
            FROM graph_tree_items AS gti
            INNER JOIN graph_tree AS gt
            ON gt.id = gti.graph_tree_id
            LEFT JOIN host AS h
            ON h.id = gti.host_id
            LEFT JOIN sites AS s
            ON gti.site_id=s.id
            WHERE gti.local_graph_id=0 AND gti.parent= 0 AND gti.graph_tree_id= 6 
            ORDER BY gti.position

But have error: ERROR 1054 (42S22): Unknown column 'gti.site_id' in 'field list'

The structure of the table is graph_tree_items

CREATE TABLE `graph_tree_items` (
  `id` bigint(20) UNSIGNED NOT NULL,
  `parent` bigint(20) UNSIGNED DEFAULT NULL,
  `position` int(10) UNSIGNED DEFAULT NULL,
  `graph_tree_id` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
  `local_graph_id` mediumint(8) UNSIGNED NOT NULL DEFAULT '0',
  `title` varchar(255) DEFAULT NULL,
  `host_id` mediumint(8) UNSIGNED NOT NULL DEFAULT '0',
  `host_grouping_type` tinyint(3) UNSIGNED NOT NULL DEFAULT '1',
  `sort_children_type` tinyint(3) UNSIGNED NOT NULL DEFAULT '1'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

and look that I dont have filed site_id, graph_regex maybe and other fields

I think that I skipped file install/upgrades/./1_1_4.php on upgrade maybe and other files but don't know why? Maybe you are know how I can automatic check my database for all field and keys ?

smiles1969 commented 6 years ago

You need to run the database upgrade utility in cli directory.

It's good practice to do this whenever you do a git pull. Not every commit has changes to the database, but it doesn't hurt to run it anyway. If you pay attention to what's changing in the pull, you can watch for updates to cacti.sql, if you see that file change, you absolutely need to run the upgrade utility, or you will run into this type of issue.

cd (cacti-path)/cli php upgrade_database.php --forcever (whatever version you are running before the upgrade)

you are missing fields in that table because you didn't upgrade the database when there were changes.

The current database structure of the github release you are running can always be referenced by looking at cacti.sql. Here is what it is currently:

CREATE TABLE graph_tree_items ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, parent bigint(20) unsigned DEFAULT NULL, position int(10) unsigned DEFAULT NULL, graph_tree_id smallint(5) unsigned NOT NULL DEFAULT '0', local_graph_id mediumint(8) unsigned NOT NULL DEFAULT '0', title varchar(255) DEFAULT NULL, host_id mediumint(8) unsigned NOT NULL DEFAULT '0', site_id int unsigned DEFAULT '0', host_grouping_type tinyint(3) unsigned NOT NULL DEFAULT '1', sort_children_type tinyint(3) unsigned NOT NULL DEFAULT '1', graph_regex varchar(60) DEFAULT '', host_regex varchar(60) DEFAULT '', PRIMARY KEY (id), KEY graph_tree_id (graph_tree_id), KEY host_id (host_id), KEY site_id (site_id), KEY local_graph_id (local_graph_id), KEY parent_position(parent, position) ) ENGINE=InnoDB;

pautiina commented 6 years ago

@smiles1969 thanks for cli command. And future need will be check all fields in tables :( @netniV thank you very much for help

It's only my bug, because I'm using the develop branch and the update functions were not always performed. Now all works.

netniV commented 6 years ago

Thanks @smiles1969 I'll have to remember that cli parameter. Normally, when you upgrade Cacti, it runs the upgrade of the database for you (at least it did for me). Does your cacti DB user have that access? If so, I'm not sure why the upgrade would have been missed unless i'm mistaken.

pautiina commented 6 years ago

My cacti DB user have access and I also do not know why it happened. I think this was due to the fact that I'm updating from the development branch, and not from table branch. The main thing is that we sorted it out and found the problem, otherwise I would have to check half the code :)

netniV commented 6 years ago

No, it's not to do with the branch you take. Both the update_database.php and the index.php (in the /instal/ folder) run through the known version array (defined in global_constants.php) and check for a matching file in /install/upgrades/.php (replacing full stops with underscores). If an upgrade function matching the version if that is found after including the file, it is run.

I did some checks tonight using both cacti_compare_version() and compare_version() functions. i'm not sure why there is a cacti_compare_version() used by one system and the base compare_version() used by the other. Both appear to give the same result, except that alpha/beta/charlie test versions (eg, 1.1.28d) can be compared with cacti_compare_version() that may not work with compare_version(). Still, they should probably both be using the same comparison function or one day it may cause an issue of inconsistency.

The CLI puts any database update failures out to the screen. Does the website upgrade notify you have had a database update failure? Not sure at the moment, but if not that might be an area of improvement too. @cigamit may know better than me.

cigamit commented 6 years ago

You all are doing great work keeping the core solid. Thanks for all your efforts.

dsclassen commented 6 years ago

I am also having problems with my DB not getting updated properly.

A manual inspection of my graph_tree_items table vs the one in cacti.sql indicates that I'm missing several new columns. So i attempted to manually update the DB.

php upgrade_database.php --debug --forcever=1.1.4

Upgrading to 1.1.5 no actions Upgrading to 1.1.6 Upgrading to 1.1.7 Upgrading to 1.1.8 Upgrading to 1.1.9 no actions Upgrading to 1.1.10 no actions Upgrading to 1.1.11 Upgrading to 1.1.12 no actions Upgrading to 1.1.13 no actions Upgrading to 1.1.14 Upgrading to 1.1.15 no actions Upgrading to 1.1.16 no actions Upgrading to 1.1.17 Upgrading to 1.1.18 no actions Upgrading to 1.1.19 no actions Upgrading to 1.1.20 Upgrading to 1.1.21 no actions Upgrading to 1.1.22 no actions Upgrading to 1.1.23 no actions Upgrading to 1.1.24 no actions Upgrading to 1.1.25 no actions Upgrading to 1.1.26 Upgrading to 1.1.27 no actions Upgrading to 1.1.28 Upgrading to 1.1.29 no actions Upgrading to 1.1.30 no actions

However, the graph_tree_items table was not updated and is still missing: site_id graph_regex host_regex

I'll continue to investigate.

dsclassen commented 6 years ago

OK. I fixed it. I just had to go back one more version to 1.1.2

php upgrade_database.php --debug --forcever=1.1.1

Now the graph_tree_items is fixed and my Graph Trees are displaying. Yay!

majed17 commented 4 years ago

I switched to https on a source compiled cacti 1.2.8 and everything went great, then i tried the same action on Fedora 31, but tree mode displays nothing! cacti i also added a dns a record for the server.. and the whole tree only shows if i access from ip ..

what to check?

cigamit commented 4 years ago

@majed17

  1. You are posting on a closed bug from 2018 that has nothing to do with your issue. Please don't do that.

  2. Looks more like you are just hitting this bug that was fixed for 1.2.9 already https://github.com/Cacti/cacti/issues/3142