diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index 2557ae3db2..543f73d920 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -1832,6 +1832,22 @@ function check_acl($id_user, $id_group, $access, $onlyOneGroup = false) { return 0; } +/** + * Check the ACL of a list of groups. + * + * @param string $id_user to check the ACL + * @param Array $groups. All groups to check + * @param string $access. Profile to check + * + * @return bool True if at least one of this groups check the ACL + */ +function check_acl_one_of_groups($id_user, $groups, $access) { + foreach ($groups as $group) { + if (check_acl($id_user, $group, $access)) return true; + } + return false; +} + /** * Get the name of the database column of one access flag * diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index f4310418b3..0822bc3341 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -180,8 +180,6 @@ function agents_get_alerts_simple ($id_agent = false, $filter = '', $options = f } if (($id_agent !== false) && ($idGroup !== false)) { - $groups = users_get_groups($config["id_user"]); - if ($idGroup != 0) { //All group $subQuery = 'SELECT id_agente_modulo FROM tagente_modulo @@ -191,17 +189,6 @@ function agents_get_alerts_simple ($id_agent = false, $filter = '', $options = f $subQuery = 'SELECT id_agente_modulo FROM tagente_modulo WHERE delete_pending = 0'; } - - if ($strict_user) { - $where_tags = tags_get_acl_tags($config['id_user'], $groups, 'AR', 'module_condition', 'AND', 'tagente_modulo'); - // If there are any errors add imposible condition - if(in_array($where_tags, array(ERR_WRONG_PARAMETERS, ERR_ACL))) { - $subQuery .= ' AND 1 = 0'; - } - else { - $subQuery .= $where_tags; - } - } } else if ($id_agent === false || empty($id_agent)) { if ($allModules) @@ -256,7 +243,6 @@ function agents_get_alerts_simple ($id_agent = false, $filter = '', $options = f $limit_sql = " LIMIT $offset, $limit "; } $sql = sprintf("%s %s", $sql, $limit_sql); - $alerts = db_get_all_rows_sql($sql); break; case "postgresql": @@ -389,6 +375,7 @@ function agents_get_agents ($filter = false, $fields = false, if (empty ($filter['id_grupo'])) { $all_groups = true; $filter['id_grupo'] = $groups; + $filter['id_group'] = $groups; } elseif (! is_array ($filter['id_grupo'])) { $all_groups = false; @@ -397,6 +384,7 @@ function agents_get_agents ($filter = false, $fields = false, return false; } $filter['id_grupo'] = (array) $filter['id_grupo']; //Make an array + $filter['id_group'] = (array) $filter['id_grupo']; //Make an array } else { $all_groups = true; @@ -410,10 +398,12 @@ function agents_get_agents ($filter = false, $fields = false, if (count ($filter['id_grupo']) == 0) { return false; } + $filter['id_group'] = $filter['id_grupo']; } if (in_array (0, $filter['id_grupo'])) { unset ($filter['id_grupo']); + unset ($filter['id_group']); } if (!is_array ($fields)) { @@ -438,8 +428,22 @@ function agents_get_agents ($filter = false, $fields = false, if (empty($filter['id_agente'])) { unset($filter['id_agente']); } - - $where = db_format_array_where_clause_sql ($filter, 'AND', ''); + + // Group filter with secondary groups + $where_secondary = ''; + if (isset($filter['id_group']) && isset($filter['id_grupo'])) { + $where_secondary .= db_format_array_where_clause_sql (array( + 'tagent_secondary_group.id_group' => $filter['id_group'], + 'id_grupo' => $filter['id_grupo'] + ) , 'OR', ''); + unset($filter['id_group']); + unset($filter['id_grupo']); + } + // Add the group filter to + $where = db_format_array_where_clause_sql ($filter, 'AND', "(" . $where_secondary . ") AND "); + if ($where == '' && $where_secondary != '') { + $where = $where_secondary; + } $where_nogroup = db_format_array_where_clause_sql( $filter_nogroup, 'AND', ''); @@ -472,49 +476,18 @@ function agents_get_agents ($filter = false, $fields = false, $where, $where_nogroup, $status_sql, $search, $disabled, $search_custom); } $sql = sprintf('SELECT %s - FROM tagente + FROM tagente LEFT JOIN tagent_secondary_group ON tagent_secondary_group.id_agent=tagente.id_agente WHERE %s %s', implode(',',$fields), $where, $order); - - switch ($config["dbtype"]) { - case "mysql": - $limit_sql = ''; - if (isset($offset) && isset($limit)) { - $limit_sql = " LIMIT $offset, $limit "; - } - $sql = sprintf("%s %s", $sql, $limit_sql); - - if ($return) - return $sql; - else - $agents = db_get_all_rows_sql($sql); - break; - case "postgresql": - $limit_sql = ''; - if (isset($offset) && isset($limit)) { - $limit_sql = " OFFSET $offset LIMIT $limit "; - } - $sql = sprintf("%s %s", $sql, $limit_sql); - - if ($return) - return $sql; - else - $agents = db_get_all_rows_sql($sql); - - break; - case "oracle": - $set = array(); - if (isset($offset) && isset($limit)) { - $set['limit'] = $limit; - $set['offset'] = $offset; - } - - if ($return) - return $sql; - else - $agents = oracle_recode_query ($sql, $set, 'AND', false); - break; + + $limit_sql = ''; + if (isset($offset) && isset($limit)) { + $limit_sql = " LIMIT $offset, $limit "; } - + $sql = sprintf("%s %s", $sql, $limit_sql); + + if ($return) return $sql; + else $agents = db_get_all_rows_sql($sql); + return $agents; } @@ -1098,20 +1071,24 @@ function agents_get_modules ($id_agent = null, $details = false, $id_agent = safe_int ($id_agent, 1); } - $where = "( 1 = ( SELECT is_admin FROM tusuario WHERE id_user = '" . $config['id_user'] . "' ) - OR + OR tagente_modulo.id_agente IN ( SELECT id_agente - FROM tagente - WHERE id_grupo IN ( + FROM tagente tas LEFT JOIN tagent_secondary_group tasgs + ON tas.id_agente = tasgs.id_agent + WHERE (tas.id_grupo IN ( + " . implode(',', $id_userGroups) . " + ) OR + tasgs.id_group IN ( " . implode(',', $id_userGroups) . " ) + ) ) OR 0 IN ( SELECT id_grupo @@ -2678,4 +2655,26 @@ function agents_generate_name ($alias, $address = '') { return hash('sha256', $alias . '|' . $address . '|' . time() . '|' . sprintf('%04d', rand(0, 10000))); } +/** + * Returns all the groups related to an agent. It includes all secondary groups. + * + * @param int $id_agent + * @param int $id_group. By default it will search for it in dtabase + * + * @return Array with the main and secondary groups + */ +function agents_get_all_groups_agent ($id_agent, $group = false) { + // Get the group if is not defined + if ($group === false) $group = agents_get_group_agents($id_agent); + + $secondary_groups = enterprise_hook('agents_get_secondary_groups', array($id_agent)); + + // Return only an array with the group in open version + if ($secondary_groups == ENTERPRISE_NOT_HOOK) return array($group); + + // Add a list of groups + $secondary_groups['plain'][] = $group; + return $secondary_groups['plain']; +} + ?> diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php index b8c0c6834b..311f705c60 100644 --- a/pandora_console/include/functions_events.php +++ b/pandora_console/include/functions_events.php @@ -144,7 +144,7 @@ function events_get_events_grouped($sql_post, $offset = 0, db_process_sql ('SET group_concat_max_len = 9999999'); if ($total) { $sql = "SELECT COUNT(*) FROM (SELECT * - FROM $table te + FROM $table te LEFT JOIN tagent_secondary_group tasg ON te.id_grupo = tasg.id_group WHERE 1=1 " . $sql_post . " GROUP BY estado, evento, id_agente, id_agentmodule" . $groupby_extra . ") AS t"; } @@ -159,7 +159,7 @@ function events_get_events_grouped($sql_post, $offset = 0, (SELECT id_agente FROM $table WHERE id_evento = MAX(te.id_evento)) id_agente, (SELECT criticity FROM $table WHERE id_evento = MAX(te.id_evento)) AS criticity, (SELECT ack_utimestamp FROM $table WHERE id_evento = MAX(te.id_evento)) AS ack_utimestamp - FROM $table te + FROM $table te LEFT JOIN tagent_secondary_group tasg ON te.id_grupo = tasg.id_group WHERE 1=1 " . $sql_post . " GROUP BY estado, evento, id_agente, id_agentmodule" . $groupby_extra . " ORDER BY timestamp_rep " . $order . " LIMIT " . $offset . "," . $pagination; @@ -846,7 +846,7 @@ function events_print_event_table ($filter = "", $limit = 10, $width = 440, $ret case "mysql": case "postgresql": $sql = sprintf ("SELECT * - FROM tevento + FROM tevento LEFT JOIN tagent_secondary_group tasg ON tevento.id_agente = tasg.id_agent WHERE %s %s ORDER BY utimestamp DESC LIMIT %d", $agent_condition, $filter, $limit); break; @@ -913,9 +913,17 @@ function events_print_event_table ($filter = "", $limit = 10, $width = 440, $ret $table->headclass[5] = "datos3 f9"; $table->align[5] = "left"; $table->size[5] = "15%"; - + + $all_groups = array(); + if ($agent_id != 0) { + $all_groups = agents_get_all_groups_agent ($agent_id); + } + foreach ($result as $event) { - if (! check_acl ($config["id_user"], $event["id_grupo"], "ER")) { + // Copy all groups of the agent and append the event group + $check_events = $all_groups; + $check_events[] = $event["id_grupo"]; + if (! check_acl_one_of_groups ($config["id_user"], $check_events, "ER")) { continue; } @@ -3306,7 +3314,8 @@ function events_get_events_grouped_by_agent($sql_post, $offset = 0, $sql_post GROUP BY id_agente, event_type$groupby_extra ORDER BY id_agente ) AS t"; } else { - $sql = "select id_agente, count(*) as total$fields_extra from $table + $sql = "select id_agente, count(*) as total$fields_extra from $table te LEFT JOIN tagent_secondary_group tasg + ON te.id_grupo = tasg.id_group WHERE id_agente > 0 $sql_post GROUP BY id_agente$groupby_extra ORDER BY id_agente LIMIT $offset,$pagination"; } break; diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index 3462366c0d..3838b6db16 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -2624,30 +2624,28 @@ function truncate_negatives(&$element) { */ function graph_agent_status ($id_agent = false, $width = 300, $height = 200, $return = false, $show_not_init = false, $data_agents=false) { global $config; - - - $filter = array('disabled' => 0, 'id_grupo' => array_keys(users_get_groups(false, 'AR', false))); - - - if (!empty($id_agent)) { - $filter['id_agente'] = $id_agent; - } - - $fields = array('SUM(critical_count) AS Critical', - 'SUM(warning_count) AS Warning', - 'SUM(normal_count) AS Normal', - 'SUM(unknown_count) AS Unknown'); - - if ($show_not_init) { - $fields[] = 'SUM(notinit_count) "Not init"'; - } if ($data_agents == false) { - $data = db_get_row_filter('tagente', $filter, $fields); + $groups = implode(',', array_keys(users_get_groups(false, 'AR', false))); + $data = db_get_row_sql(sprintf('SELECT + SUM(critical_count) AS Critical, + SUM(warning_count) AS Warning, + SUM(normal_count) AS Normal, + SUM(unknown_count) AS Unknown + %s + FROM tagente ta LEFT JOIN tagent_secondary_group tasg + ON ta.id_agente = tasg.id_agent + WHERE + ta.disabled = 0 AND + (ta.id_grupo IN (%s) OR tasg.id_group IN (%s))', + $show_not_init ? ', SUM(notinit_count) "Not init"' : '', + $groups, + $groups + )); } else { $data = $data_agents; } - + if (empty($data)) { $data = array(); } @@ -3587,7 +3585,8 @@ function grafico_eventos_grupo ($width = 300, $height = 200, $url = "", $meta = //is required if both DISTINCT() and COUNT() are in the statement $sql = sprintf ('SELECT DISTINCT(id_agente) AS id_agente, COUNT(id_agente) AS count'.$field_extra.' - FROM '.$event_table.' + FROM '.$event_table.' te LEFT JOIN tagent_secondary_group tasg + ON te.id_grupo = tasg.id_group WHERE 1=1 %s %s GROUP BY id_agente'.$groupby_extra.' ORDER BY count DESC LIMIT 8', $url, $tags_condition); diff --git a/pandora_console/include/functions_tags.php b/pandora_console/include/functions_tags.php index 69863000e1..88a2d3702f 100644 --- a/pandora_console/include/functions_tags.php +++ b/pandora_console/include/functions_tags.php @@ -663,7 +663,6 @@ function tags_get_acl_tags($id_user, $id_group, $access = 'AR', elseif (!is_array($id_group)) { $id_group = array($id_group); } - $groups = $id_group; $acl_column = get_acl_column($access); if (empty($acl_column)) { @@ -740,15 +739,17 @@ function tags_get_acl_tags_module_condition($acltags, $modules_table = '') { %s INNER JOIN tagente tac ON tamc.id_agente = tac.id_agente - AND tac.id_grupo = %d', - $tag_join, $group_id); + LEFT JOIN tagent_secondary_group tasg + ON tasg.id_agent = tac.id_agente + WHERE (tac.id_grupo = %d OR tasg.id_group = %d)', + $tag_join, $group_id, $group_id); $sql_condition = sprintf('(%sid_agente_modulo IN (%s))', $modules_table, $agent_condition); $group_conditions[] = $sql_condition; $i++; } - + if (!empty($group_conditions)) $condition = implode(' OR ', $group_conditions); $condition = !empty($condition) ? "($condition)" : ''; @@ -858,7 +859,7 @@ function tags_get_acl_tags_event_condition($acltags, $meta = false, $force_group // Tags condition (The module has at least one of the restricted tags) $tags_condition = ''; if (empty($group_tags)) { - $tags_condition = "id_grupo = ".$group_id; + $tags_condition = "id_grupo = ".$group_id . " OR id_group = " . $group_id; } else { if (!is_array($group_tags)) { diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index b66304f40a..486e4c7b23 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -242,6 +242,7 @@ function groups_combine_acl($acl_group_a, $acl_group_b){ * @param boolean $returnAllColumns Flag to return all columns of groups. * @param array $id_groups The list of group to scan to bottom child. By default null. * @param string $keys_field The field of the group used in the array keys. By default ID + * @param bool $cache Set it to false to not use cache * * @return array A list of the groups the user has certain privileges. */ diff --git a/pandora_console/operation/agentes/alerts_status.php b/pandora_console/operation/agentes/alerts_status.php index 6667a73291..90c367bb64 100755 --- a/pandora_console/operation/agentes/alerts_status.php +++ b/pandora_console/operation/agentes/alerts_status.php @@ -123,8 +123,12 @@ if ($idAgent != 0) { if ($is_extra === ENTERPRISE_NOT_HOOK) { $is_extra = false; } - - if (!check_acl ($config["id_user"], $id_group, "AR") && !check_acl ($config["id_user"], $id_group, "AW") && !$is_extra) { + + // All groups is calculated in ver_agente.php. Avoid to calculate it again + if (!isset($all_groups)) { + $all_groups = agents_get_all_groups_agent ($idAgent, $id_group); + } + if (!check_acl_one_of_groups ($config["id_user"], $all_groups, "AR") && !check_acl_one_of_groups ($config["id_user"], $id_group, "AW") && !$is_extra) { db_pandora_audit("ACL Violation","Trying to access alert view"); require ("general/noaccess.php"); exit; @@ -158,6 +162,8 @@ else { users_get_groups($config["id_user"], $access, false)), false, 'lower', true)); $idGroup = $id_group; + // If there is no agent defined, it means that it cannot search for the secondary groups + $all_groups = array($id_group); $print_agent = true; @@ -170,7 +176,7 @@ else { } if ($alert_validate) { - if (check_acl ($config["id_user"], $id_group, "AW") || check_acl ($config["id_user"], $id_group, "LM") ) { + if (check_acl_one_of_groups ($config["id_user"], $all_groups, "AW") || check_acl_one_of_groups ($config["id_user"], $all_groups, "LM") ) { validateAlert(); } else { @@ -344,12 +350,14 @@ if (empty($id_groups)) { $whereAlertSimple .= ' AND (1 = 0) '; } else { - $whereAlertSimple .= ' AND id_agent_module IN ( + $whereAlertSimple .= sprintf (' AND id_agent_module IN ( SELECT tam.id_agente_modulo FROM tagente_modulo tam WHERE tam.id_agente IN (SELECT ta.id_agente - FROM tagente ta - WHERE ta.id_grupo IN (' . implode(',', $id_groups) . '))) '; + FROM tagente ta LEFT JOIN tagent_secondary_group tasg ON + ta.id_agente = tasg.id_agent + WHERE (ta.id_grupo IN (%s) OR tasg.id_group IN (%s)))) ', + implode(',', $id_groups), implode(',', $id_groups)); } diff --git a/pandora_console/operation/agentes/estado_generalagente.php b/pandora_console/operation/agentes/estado_generalagente.php index 8320845549..18aa3daafa 100755 --- a/pandora_console/operation/agentes/estado_generalagente.php +++ b/pandora_console/operation/agentes/estado_generalagente.php @@ -53,7 +53,7 @@ if ($is_extra === ENTERPRISE_NOT_HOOK) { $is_extra = false; } -if (! check_acl ($config["id_user"], $agent["id_grupo"], "AR") && ! check_acl ($config["id_user"], $agent["id_grupo"], "AW") && !$is_extra) { +if (! check_acl_one_of_groups ($config["id_user"], $all_groups, "AR") && ! check_acl_one_of_groups ($config["id_user"], $all_groups, "AW") && !$is_extra) { db_pandora_audit("ACL Violation", "Trying to access Agent General Information"); require_once ("general/noaccess.php"); @@ -482,16 +482,7 @@ if (!empty($network_interfaces)) { foreach ($network_interfaces as $interface_name => $interface) { if (!empty($interface['traffic'])) { - $permission = false; - - if ($strict_user) { - if (tags_check_acl_by_module($interface['traffic']['in'], $config['id_user'], 'RR') === true - && tags_check_acl_by_module($interface['traffic']['out'], $config['id_user'], 'RR') === true) - $permission = true; - } - else { - $permission = check_acl($config['id_user'], $agent["id_grupo"], "RR"); - } + $permission = check_acl_one_of_groups($config['id_user'], $all_groups, "RR"); if ($permission) { $params = array( @@ -648,7 +639,7 @@ $table->rowspan[1][0] = 0; $data[0][2] = '