diff --git a/share/linters/.rubocop.yml b/share/linters/.rubocop.yml index 50de0856b7..4583475405 100644 --- a/share/linters/.rubocop.yml +++ b/share/linters/.rubocop.yml @@ -501,11 +501,9 @@ AllCops: - src/onedb/fsck/pool_control.rb - src/onedb/fsck/marketplace.rb - src/onedb/fsck/template.rb - - src/onedb/fsck/group.rb - src/onedb/fsck/host.rb - src/onedb/fsck/vm.rb - src/onedb/fsck/marketplaceapp.rb - - src/onedb/fsck/user.rb - src/onedb/fsck.rb - src/onedb/patches/ip4_ip6_static.rb - src/onedb/patches/history_times.rb diff --git a/src/onedb/fsck/group.rb b/src/onedb/fsck/group.rb index 3ffe6178c7..ecee4d8af8 100644 --- a/src/onedb/fsck/group.rb +++ b/src/onedb/fsck/group.rb @@ -1,47 +1,54 @@ - +# Group module module OneDBFsck + + # Check groups users def check_group @fixes_group = groups_fix = {} + group = @data_user[:group] - group = @data_user[:group] - - @db.fetch("SELECT oid,body from group_pool") do |row| + @db.fetch('SELECT oid,body from group_pool') do |row| gid = row[:oid] - doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks} + doc = Nokogiri::XML(row[:body], nil, NOKOGIRI_ENCODING) do |c| + c.default_xml.noblanks + end - users_elem = doc.root.at_xpath("USERS") - users_elem.remove if !users_elem.nil? + users_elem = doc.root.at_xpath('USERS') + users_new_elem = doc.create_element('USERS') + error = false - users_new_elem = doc.create_element("USERS") + users_elem.remove unless users_elem.nil? doc.root.add_child(users_new_elem) - error_found = false - group[gid].each do |id| id_elem = users_elem.at_xpath("ID[.=#{id}]") + id_e = doc.create_element('ID') if id_elem.nil? - log_error("User #{id} is missing from Group #{gid} users id list", !db_version[:is_slave]) - error_found = true + log_error("User #{id} is missing from Group #{gid}" \ + 'users id list', + !db_version[:is_slave]) + error = true else id_elem.remove end - users_new_elem.add_child(doc.create_element("ID")).content = id.to_s + users_new_elem.add_child(id_e).content = id.to_s end - users_elem.xpath("ID").each do |id_elem| - log_error("User #{id_elem.text} is in Group #{gid} users id list, but it should not", !db_version[:is_slave]) - error_found = true + users_elem.xpath('ID').each do |id| + id = id.text + error = true + + log_error("User #{id} is in Group #{gid} users id list, " \ + 'but it should not', + !db_version[:is_slave]) end - - if error_found - groups_fix[row[:oid]] = doc.root.to_s - end + groups_fix[gid] = doc.root.to_s if error end end + # Fix groups information def fix_group groups_fix = @fixes_group @@ -52,7 +59,8 @@ module OneDBFsck end end elsif !groups_fix.empty? - log_msg("^ Group errors need to be fixed in the master OpenNebula") + log_msg('^ Group errors need to be fixed in the master OpenNebula') end end + end diff --git a/src/onedb/fsck/user.rb b/src/onedb/fsck/user.rb index ba12b11c14..217be7599d 100644 --- a/src/onedb/fsck/user.rb +++ b/src/onedb/fsck/user.rb @@ -1,98 +1,184 @@ - +# User module module OneDBFsck - def check_user - @data_user = { group: {} } - group = @data_user[:group] - @db.fetch("SELECT oid FROM group_pool") do |row| + # Check users groups + def check_user + @data_user = { :group => {} } + @fixes_user = users_fix = {} + group = @data_user[:group] + name_seen = {} + + @db.fetch('SELECT oid FROM group_pool') do |row| group[row[:oid]] = [] end - @fixes_user = users_fix = {} + @db.fetch('SELECT oid,body,gid,name FROM user_pool') do |row| + doc = Nokogiri::XML(row[:body], nil, NOKOGIRI_ENCODING) do |c| + c.default_xml.noblanks + end - name_seen = {} - @db.fetch("SELECT oid,body,gid,name FROM user_pool") do |row| - doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks} - - gid = doc.root.at_xpath('GID').text.to_i + gid = doc.root.at_xpath('GID').text.to_i auth_driver = doc.root.at_xpath('AUTH_DRIVER').text - user_gid = gid - user_gids = Set.new + user_gid = gid + user_gids = Set.new + exists = check_group_exists(doc, group, row[:oid], gid) - if group[gid].nil? - log_error("User #{row[:oid]} has primary group #{gid}, but it does not exist", !db_version[:is_slave]) - - user_gid = 1 - - doc.root.xpath('GID').each do |e| - e.content = "1" - end - - doc.root.xpath('GNAME').each do |e| - e.content = "users" - end - - doc.root.xpath("GROUPS").each { |e| - e.xpath("ID[.=#{gid}]").each{|x| x.remove} - - e.add_child(doc.create_element("ID")).content = user_gid.to_s - } - - users_fix[row[:oid]] = {:body => doc.root.to_s, :gid => user_gid} + if !exists.nil? + gid = exists[0] + user_gid = gid + users_fix[row[:oid]] = exists[1] end - doc.root.xpath("GROUPS/ID").each { |e| + doc.root.xpath('GROUPS/ID').each do |e| user_gids.add e.text.to_i - } - - if !user_gids.include?(user_gid) - log_error("User #{row[:oid]} does not have his primary group #{user_gid} in the list of secondary groups", !db_version[:is_slave]) - - doc.root.xpath("GROUPS").each { |e| - e.add_child(doc.create_element("ID")).content = user_gid.to_s - } - - user_gids.add user_gid.to_i - - users_fix[row[:oid]] = {:body => doc.root.to_s, :gid => user_gid} end - user_gids.each do |secondary_gid| - if group[secondary_gid].nil? - log_error("User #{row[:oid]} has secondary group #{secondary_gid}, but it does not exist", !db_version[:is_slave]) + primary = check_primary_group(doc, row[:oid], user_gids, user_gid) - doc.root.xpath("GROUPS").each { |e| - e.xpath("ID[.=#{secondary_gid}]").each{|x| x.remove} - } + if !primary.nil? + user_gids = primary[0] + users_fix[row[:oid]] = primary[1] + end - users_fix[row[:oid]] = {:body => doc.root.to_s, :gid => user_gid} - else - group[secondary_gid] << row[:oid] - end + secondary = check_secondary_group(doc, + group, + row[:oid], + user_gids, + user_gid, + users_fix) + + if !secondary.nil? + users_fix = secondary[0] + group = secondary[1] end if gid != row[:gid] - log_error( - "User #{row[:oid]} is in group #{gid}, but the DB "<< - "table has GID column #{row[:gid]}", !db_version[:is_slave]) + log_error("User #{row[:oid]} is in group #{gid}, but the DB " \ + "table has GID column #{row[:gid]}", + !db_version[:is_slave]) - users_fix[row[:oid]] = {:body => doc.root.to_s, :gid => user_gid} + users_fix[row[:oid]] = { :body => doc.root.to_s, + :gid => user_gid } end - if auth_driver == 'ldap' - if ! name_seen[row[:name].downcase] - name_seen[row[:name].downcase] = [row[:oid] , row[:name]] - else - log_error( - "User id:#{row[:oid]} has conficting name #{row[:name]}, "<< - "another user id:#{name_seen[row[:name].downcase][0]} "<< - "with name #{name_seen[row[:name].downcase][1] } is present", - repaired=false) - end - end + ldap = check_ldap(row[:oid], row[:name], auth_driver, name_seen) + + name_seen = ldap unless ldap.nil? end end + # Check that group exists + # + # @param doc [Document] Document with user information + # @param group [Array] Array with groups information + # @param uid [Integer] User ID + # @param gid [Integer] Group ID + # + # @return [Object] Object with new body and gid + def check_group_exists(doc, group, uid, gid) + return unless group[gid].nil? + + log_error("User #{uid} has primary group #{gid}, but it does not exist", + !db_version[:is_slave]) + + user_gid = 1 + + doc.root.xpath('GID').each do |e| + e.content = '1' + end + + doc.root.xpath('GNAME').each do |e| + e.content = 'users' + end + + doc.root.xpath('GROUPS').each do |e| + e.xpath("ID[.=#{gid}]").each {|x| x.remove } + + e.add_child(doc.create_element('ID')).content = user_gid.to_s + end + + [user_gid, { :body => doc.root.to_s, :gid => user_gid }] + end + + # Check user primary group + # + # @param doc [Document] Document with user information + # @param uid [Integer] User ID + # @param gids [Array] User group IDs + # @param gid [Integer] User group ID + # + # @param [Array] User group IDs, object with new body and gid + def check_primary_group(doc, uid, gids, gid) + return if gids.include?(gid) + + log_error("User #{uid} does not have his primary group #{gid} in the " \ + 'list of secondary groups', !db_version[:is_slave]) + + doc.root.xpath('GROUPS').each do |e| + e.add_child(doc.create_element('ID')).content = gid.to_s + end + + gids.add gid.to_i + + [gids, { :body => doc.root.to_s, :gid => gid }] + end + + # Check user secondary group + # + # @param doc [Document] Document with user information + # @param group [Array] Array with groups information + # @param uid [Integer] User ID + # @param gids [Array] User group IDs + # @param gid [Integer] User group ID + # @param users_fix [Integer] Array with fixes for users + # + # @param [Array] Users fixes and groups + # rubocop:disable Metrics/ParameterLists + def check_secondary_group(doc, group, uid, gids, gid, users_fix) + # rubocop:enable Metrics/ParameterLists + gids.each do |secondary_gid| + if group[secondary_gid].nil? + log_error("User #{uid} has secondary group " \ + "#{secondary_gid}, but it does not exist", + !db_version[:is_slave]) + + doc.root.xpath('GROUPS').each do |e| + e.xpath("ID[.=#{secondary_gid}]").each {|x| x.remove } + end + + users_fix[uid] = { :body => doc.root.to_s, :gid => gid } + else + group[secondary_gid] << uid + end + end + + [users_fix, group] + end + + # Check ldap user + # + # @param uid [Integer] User ID + # @param name [String] User name + # @param auth_driver [String] Authentication driver + # @param name_seen [Array] Array with user names + # + # @return [Array] Array with user names + def check_ldap(uid, name, auth_driver, name_seen) + return if auth_driver != 'ldap' + + if !name_seen[name.downcase] + name_seen[name.downcase] = [uid, name] + else + log_error("User id:#{uid} has conficting name #{name}, " \ + "another user id:#{name_seen[name.downcase][0]} " \ + "with name #{name_seen[name.downcase][1]} is present", + false) + end + + name_seen + end + + # Fix users def fix_user users_fix = @fixes_user @@ -101,11 +187,13 @@ module OneDBFsck users_fix.each do |id, user| @db[:user_pool].where(:oid => id).update( :body => user[:body], - :gid => user[:gid]) + :gid => user[:gid] + ) end end elsif !users_fix.empty? - log_msg("^ User errors need to be fixed in the master OpenNebula") + log_msg('^ User errors need to be fixed in the master OpenNebula') end end + end