Hello community, here is the log from the commit of package yast2-users for openSUSE:Factory checked in at 2016-05-10 09:26:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-users (Old) and /work/SRC/openSUSE:Factory/.yast2-users.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-users" Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-users/yast2-users.changes 2016-04-16 22:07:33.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-users.new/yast2-users.changes 2016-05-10 09:26:08.000000000 +0200 @@ -1,0 +2,15 @@ +Thu May 5 13:22:29 UTC 2016 - an...@suse.com + +- Make user import work even if passwd and shadow files are not + copied to /var/lib/YaST2 via "copy_to_system" (part of + fate#319624) +- 3.1.49 + +------------------------------------------------------------------- +Thu May 5 12:32:39 UTC 2016 - igonzalezs...@suse.com + +- Fix users import when entries for all non-system users are missing in + /etc/shadow (bsc#978648) +- 3.1.48 + +------------------------------------------------------------------- Old: ---- yast2-users-3.1.47.tar.bz2 New: ---- yast2-users-3.1.49.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-users.spec ++++++ --- /var/tmp/diff_new_pack.s30Lzc/_old 2016-05-10 09:26:09.000000000 +0200 +++ /var/tmp/diff_new_pack.s30Lzc/_new 2016-05-10 09:26:09.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-users -Version: 3.1.47 +Version: 3.1.49 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ yast2-users-3.1.47.tar.bz2 -> yast2-users-3.1.49.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/package/yast2-users.changes new/yast2-users-3.1.49/package/yast2-users.changes --- old/yast2-users-3.1.47/package/yast2-users.changes 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/package/yast2-users.changes 2016-05-05 17:34:04.000000000 +0200 @@ -1,4 +1,19 @@ ------------------------------------------------------------------- +Thu May 5 13:22:29 UTC 2016 - an...@suse.com + +- Make user import work even if passwd and shadow files are not + copied to /var/lib/YaST2 via "copy_to_system" (part of + fate#319624) +- 3.1.49 + +------------------------------------------------------------------- +Thu May 5 12:32:39 UTC 2016 - igonzalezs...@suse.com + +- Fix users import when entries for all non-system users are missing in + /etc/shadow (bsc#978648) +- 3.1.48 + +------------------------------------------------------------------- Thu Apr 7 08:49:13 UTC 2016 - igonzalezs...@suse.com - Does not set empty passwords fields in /etc/shadow during diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/package/yast2-users.spec new/yast2-users-3.1.49/package/yast2-users.spec --- old/yast2-users-3.1.47/package/yast2-users.spec 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/package/yast2-users.spec 2016-05-05 17:34:04.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-users -Version: 3.1.47 +Version: 3.1.49 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/src/Makefile.am new/yast2-users-3.1.49/src/Makefile.am --- old/yast2-users-3.1.47/src/Makefile.am 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/src/Makefile.am 2016-05-05 17:34:04.000000000 +0200 @@ -63,7 +63,8 @@ lib/users/local_password.rb \ lib/users/encryption_method.rb \ lib/users/proposal.rb \ - lib/users/encryption_proposal.rb + lib/users/encryption_proposal.rb \ + lib/users/users_database.rb scrconf_DATA = \ scrconf/uid.scr \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/src/lib/users/dialogs/inst_user_first.rb new/yast2-users-3.1.49/src/lib/users/dialogs/inst_user_first.rb --- old/yast2-users-3.1.47/src/lib/users/dialogs/inst_user_first.rb 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/src/lib/users/dialogs/inst_user_first.rb 2016-05-05 17:34:04.000000000 +0200 @@ -24,6 +24,7 @@ require "users/dialogs/users_to_import" require "users/ca_password_validator" require "users/local_password" +require "users/users_database" module Yast # Dialog for creation of local users during first stage of installation @@ -55,10 +56,12 @@ # names of imported users selected for writing @usernames_to_import = [] - # if importing users from different partition is possible - @import_available = UsersSimple.ImportAvailable + # Check if some users database was imported from a + # different partition (done during pre_install) + users_databases = Users::UsersDatabase.all + @import_available = users_databases.any? if @import_available - @importable_users = UsersSimple.GetImportedUsers("local") + @importable_users = importable_users(users_databases) @importable_usernames = @importable_users.keys if @importable_usernames.empty? @@ -389,6 +392,34 @@ return true end + # List of users from an imported users database. + # + # This method is kind of a wrapper around + # UserSimple.ReadUserData && UserSimple.GetImportedUsers. + # It receives a list of databases and tries to import users in order. If + # it's not possible to import users in the first database, it tries the + # the next and so on. + # + # Ideally this method would belong to UsersSimple... but that's Perl code. + # + # @param databases [Array<Users::UsersDatabase>] + # @return [Hash{String => Hash}] @see UsersSimple.GetImportedUsers + def importable_users(databases) + users = {} + databases.each do |database| + Dir.mktmpdir do |dir| + database.write_files(dir) + if UsersSimple.ReadUserData(dir) + # GetImportedUsers should not return nil, but better be safe + imported = UsersSimple.GetImportedUsers("local") + users = imported unless imported.nil? + break unless users.empty? + end + end + end + users + end + def import_users create_users = @usernames_to_import.map do |name| u = @importable_users.fetch(name, {}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/src/lib/users/users_database.rb new/yast2-users-3.1.49/src/lib/users/users_database.rb --- old/yast2-users-3.1.47/src/lib/users/users_database.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-users-3.1.49/src/lib/users/users_database.rb 2016-05-05 17:34:04.000000000 +0200 @@ -0,0 +1,85 @@ +# Copyright (c) 2016 SUSE LLC. +# All Rights Reserved. + +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 or 3 of the GNU General +# Public License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, contact SUSE LLC. + +# To contact SUSE about this file by physical or electronic mail, +# you may find current contact information at www.suse.com + +module Users + # Class that allows to memorize the user's database (/etc/passwd and + # associated files) of any partition. + # + # Used to implement the users importing functionality. + # + # It provides class methods to hold a list of databases (in case many + # partitions with /etc/passwd are found) + class UsersDatabase + attr_accessor :passwd + attr_accessor :shadow + attr_accessor :atime + + @all = [] + + # List of imported user databases, sorted by access time (the first element + # is the most recently accessed). + # + # @return [Array<UsersDatabase>] + def self.all + @all + end + + # Imports users data from a given root directory and stores it in .all + # + # @param root_dir [String] Path where the original "/" is mounted + def self.import(root_dir) + data = UsersDatabase.new + data.read_files(File.join(root_dir, "etc")) + return if data.passwd.nil? || data.passwd.empty? + + push(data) + end + + # Populates the object with information read from a directory + # + # @param dir [String] path to a directory containing passwd and shadow files + def read_files(dir) + passwd = File.join(dir, "passwd") + shadow = File.join(dir, "shadow") + return unless File.exist?(passwd) && File.exist?(shadow) + + self.passwd = IO.read(passwd) + self.shadow = IO.read(shadow) + self.atime = [File.atime(passwd), File.atime(shadow)].max + end + + # Writes passwd and shadow files to a directory + # + # @param dir [String] path of the target directory + def write_files(dir) + passwd = File.join(dir, "passwd") + shadow = File.join(dir, "shadow") + IO.write(passwd, self.passwd) + IO.write(shadow, self.shadow) + end + + protected + + # Adds a database to #all, honoring the expected order + def self.push(database) + @all << database + @all.sort_by!(&:atime) + @all.reverse! + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/src/modules/UsersSimple.pm new/yast2-users-3.1.49/src/modules/UsersSimple.pm --- old/yast2-users-3.1.47/src/modules/UsersSimple.pm 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/src/modules/UsersSimple.pm 2016-05-05 17:34:04.000000000 +0200 @@ -956,7 +956,7 @@ if (defined $imported_users{$type} && ref($imported_users{$type}) eq "HASH") { %ret = %{$imported_users{$type}}; - next if (!defined $imported_shadow{$type}); + return \%ret if (!defined $imported_shadow{$type}); # add the shadow data into each user map foreach my $username (keys %ret) { next if (!defined $imported_shadow{$type}{$username}); @@ -969,34 +969,6 @@ } ##------------------------------------ -# Check if importing user data from the system is available: -# if yes, go and read the data -BEGIN { $TYPEINFO{ImportAvailable} = ["function", "boolean"]; } -sub ImportAvailable { - - return $import_available if defined $import_available; - - my $self = shift; - my $tmp_dir = Directory->tmpdir()."/users"; - my $vardir = Directory->vardir(); - my $import_dir = $tmp_dir.$vardir."/imported/userdata/etc"; - - $import_available = ( - SCR->Execute (".target.mkdir", $tmp_dir) && - SystemFilesCopy->CopyFilesToSystem ($tmp_dir) && - FileUtils->Exists ($import_dir."/passwd") && - FileUtils->Exists ($import_dir."/shadow") && - $self->ReadUserData ($import_dir) - ); - y2milestone ("import available: $import_available"); - - # remove the directory with copied data after reading it - SCR->Execute (".target.bash", "/bin/rm -rf $tmp_dir"); - - return $import_available; -} - -##------------------------------------ # load cracklib image into the inst-sys BEGIN { $TYPEINFO{LoadCracklib} = ["function", "boolean"]; } sub LoadCracklib { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/test/fixtures/root2/etc/passwd new/yast2-users-3.1.49/test/fixtures/root2/etc/passwd --- old/yast2-users-3.1.47/test/fixtures/root2/etc/passwd 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-users-3.1.49/test/fixtures/root2/etc/passwd 2016-05-05 17:34:04.000000000 +0200 @@ -0,0 +1,19 @@ +a_user:x:1000:100:A test local user:/home/a_user:/bin/bash +root:x:0:0:root:/root:/bin/bash +bin:x:1:1:bin:/bin:/bin/bash +daemon:x:2:2:Daemon:/sbin:/bin/bash +lp:x:4:7:Printing daemon:/var/spool/lpd:/bin/bash +mail:x:8:12:Mailer daemon:/var/spool/clientmqueue:/bin/false +news:x:9:13:News system:/etc/news:/bin/bash +uucp:x:10:14:Unix-to-Unix CoPy system:/etc/uucp:/bin/bash +games:x:12:100:Games account:/var/games:/bin/bash +man:x:13:62:Manual pages viewer:/var/cache/man:/bin/bash +wwwrun:x:30:8:WWW daemon apache:/var/lib/wwwrun:/bin/false +ftp:x:40:49:FTP account:/srv/ftp:/bin/bash +nobody:x:65534:65533:nobody:/var/lib/nobody:/bin/bash +messagebus:x:499:499:User for D-Bus:/var/run/dbus:/bin/false +sshd:x:498:498:SSH daemon:/var/lib/sshd:/bin/false +polkitd:x:497:496:User for polkitd:/var/lib/polkit:/sbin/nologin +nscd:x:496:495:User for nscd:/run/nscd:/sbin/nologin +rpc:x:495:65534:user for rpcbind:/var/lib/empty:/sbin/nologin +openslp:x:494:2:openslp daemon:/var/lib/empty:/sbin/nologin diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/test/fixtures/root2/etc/shadow new/yast2-users-3.1.49/test/fixtures/root2/etc/shadow --- old/yast2-users-3.1.47/test/fixtures/root2/etc/shadow 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-users-3.1.49/test/fixtures/root2/etc/shadow 2016-05-05 17:34:04.000000000 +0200 @@ -0,0 +1,19 @@ +a_user:$6$pLaWhcXR$iiiiiilTEV9B.SBn.iITpknL6eg/n63am7rzp2fMsB8ap5cUWl3ZcnT7o5mTcrG85bz/NhaC1D/izwkJeL5gI.:16785:::::: +root:$6$pLaWhcXR$gn1LrOlTEV9B.SBn.iITpknL6eg/n63am7rzp2fMsB8ap5cUWl3ZcnT7o5mTcrG85bz/NhaC1D/izwkJeL5gI.:16899:::::: +bin:*:16765:::::: +daemon:*:16765:::::: +lp:*:16765:::::: +mail:*:16765:::::: +news:*:16765:::::: +uucp:*:16765:::::: +games:*:16765:::::: +man:*:16765:::::: +wwwrun:*:16765:::::: +ftp:*:16765:::::: +nobody:*:16765:::::: +messagebus:!:16765:::::: +sshd:!:16765:::::: +polkitd:!:16765:::::: +nscd:!:16765:::::: +rpc:!:16765:::::: +openslp:!:16765:::::: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/test/lib/users/users_database_test.rb new/yast2-users-3.1.49/test/lib/users/users_database_test.rb --- old/yast2-users-3.1.47/test/lib/users/users_database_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-users-3.1.49/test/lib/users/users_database_test.rb 2016-05-05 17:34:04.000000000 +0200 @@ -0,0 +1,89 @@ +#! /usr/bin/rspec +# Copyright (c) 2016 SUSE LLC. +# All Rights Reserved. + +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 or 3 of the GNU General +# Public License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, contact SUSE LLC. + +# To contact SUSE about this file by physical or electronic mail, +# you may find current contact information at www.suse.com + +require_relative "../../test_helper" +require "users/users_database" + +describe Users::UsersDatabase do + describe ".import" do + it "always stores databases sorted by access time" do + # Mock access time: files in root2 are more recent than files in root + allow(File).to receive(:atime) do |path| + path =~ /root2/ ? Time.now : Time.now - 1200 + end + + Users::UsersDatabase.all.clear + expect(Users::UsersDatabase.all).to be_empty + Users::UsersDatabase.import(FIXTURES_PATH.join("root")) + Users::UsersDatabase.import(FIXTURES_PATH.join("root2")) + databases = Users::UsersDatabase.all + expect(databases.size).to eq 2 + expect(databases.first.passwd).to start_with "a_user" + + Users::UsersDatabase.all.clear + expect(Users::UsersDatabase.all).to be_empty + Users::UsersDatabase.import(FIXTURES_PATH.join("root2")) + Users::UsersDatabase.import(FIXTURES_PATH.join("root")) + databases = Users::UsersDatabase.all + expect(databases.size).to eq 2 + expect(databases.first.passwd).to start_with "a_user" + end + + it "ignores wrong root directories" do + Users::UsersDatabase.all.clear + expect(Users::UsersDatabase.all).to be_empty + Users::UsersDatabase.import(FIXTURES_PATH.join("root/etc")) + Users::UsersDatabase.import("/nonexistent") + expect(Users::UsersDatabase.all).to be_empty + end + end + + describe "#read_files" do + before do + # Mock access time: passwd is more recent than shadow + allow(File).to receive(:atime) do |path| + path =~ /passwd$/ ? passwd_atime : passwd_atime - 1200 + end + end + + let(:passwd_atime) { Time.now } + + it "reads the content of the passwd file" do + subject.read_files(FIXTURES_PATH.join("root2/etc")) + expect(subject.passwd).to start_with "a_user" + end + + it "reads the content of the shadow file" do + subject.read_files(FIXTURES_PATH.join("root2/etc")) + expect(subject.shadow).to start_with "a_user" + end + + it "stores the most recent access time" do + subject.read_files(FIXTURES_PATH.join("root2/etc")) + expect(subject.atime).to eq passwd_atime + end + + it "does nothing if the files are not there" do + subject.read_files(FIXTURES_PATH.join("root2")) + expect(subject.passwd).to be_nil + expect(subject.shadow).to be_nil + expect(subject.atime).to be_nil + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/test/spec_helper.rb new/yast2-users-3.1.49/test/spec_helper.rb --- old/yast2-users-3.1.47/test/spec_helper.rb 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/test/spec_helper.rb 1970-01-01 01:00:00.000000000 +0100 @@ -1,40 +0,0 @@ -ENV["Y2DIR"] = File.expand_path("../../src", __FILE__) - -require "yast" -require "pathname" -require "yast/rspec" - -if ENV["COVERAGE"] - require "simplecov" - - # use coveralls for on-line code coverage reporting at Travis CI - if ENV["TRAVIS"] - require "coveralls" - - SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter - ] - end - - SimpleCov.start do - add_filter "/test/" - end -end - -# configure RSpec -RSpec.configure do |config| - config.mock_with :rspec do |c| - # https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/verifying-doubles/partial-doubles - c.verify_partial_doubles = true - end -end - -libdir = File.expand_path("../../src/lib", __FILE__) -$LOAD_PATH.unshift(libdir) - -# force loading all files to report proper code coverage -# Dir.chdir(libdir) { Dir["**/*.rb"].each { |f| require f } } - -TESTS_PATH = Pathname.new(File.dirname(__FILE__)) -FIXTURES_PATH = TESTS_PATH.join("fixtures") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/test/test_helper.rb new/yast2-users-3.1.49/test/test_helper.rb --- old/yast2-users-3.1.47/test/test_helper.rb 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/test/test_helper.rb 2016-05-05 17:34:04.000000000 +0200 @@ -21,6 +21,7 @@ ENV["Y2DIR"] = src_path require "yast" +require "pathname" require "yast/rspec" if ENV["COVERAGE"] @@ -41,3 +42,14 @@ ] end end + +# configure RSpec +RSpec.configure do |config| + config.mock_with :rspec do |c| + # https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/verifying-doubles/partial-doubles + c.verify_partial_doubles = true + end +end + +TESTS_PATH = Pathname.new(File.dirname(__FILE__)) +FIXTURES_PATH = TESTS_PATH.join("fixtures") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-users-3.1.47/test/users_finish_test.rb new/yast2-users-3.1.49/test/users_finish_test.rb --- old/yast2-users-3.1.47/test/users_finish_test.rb 2016-04-12 14:01:29.000000000 +0200 +++ new/yast2-users-3.1.49/test/users_finish_test.rb 2016-05-05 17:34:04.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env rspec -require_relative "spec_helper" +require_relative "test_helper" require "fileutils" require "yaml" require "users/clients/users_finish"