etcutils 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'etcutils/etcutils.so'
3
+ require 'etcutils/version'
4
+ EU = EtcUtils
@@ -0,0 +1,3 @@
1
+ module EtcUtils
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,141 @@
1
+ EU Tests
2
+ ======
3
+
4
+ Trying to clearly define what should be expected and where it is tested.
5
+
6
+
7
+ test_eu_next_uid_next_gid
8
+ next_uid
9
+ next_gid
10
+ next_uid()
11
+ next_gid()
12
+ next_uid=
13
+ next_gid=
14
+
15
+ test_etc_utils
16
+ me
17
+ getlogin
18
+ has_passwd?
19
+ has_shadow?
20
+ has_group?
21
+ has_gshadow?
22
+ setXXent
23
+ endXXent
24
+ getpwent
25
+ getgrent
26
+ find_pwd
27
+ setpwent
28
+ endpwent
29
+
30
+ test_eu_sgetpwent
31
+ sgetpwent
32
+ find_pwd.to_entry = sgetpwent.to_entry
33
+ most field changes are allowed
34
+ - gecos, directory, passwd, shell
35
+ new entry with available UID/GID
36
+ new entry with unavailable/conflicting UID/GID
37
+ nil username should raise exception
38
+
39
+
40
+ test_eu_locking
41
+ lckpwdf
42
+ ulckpwdf
43
+ lock
44
+ unlock
45
+ locked?
46
+ - root/locking
47
+ lock = locked?
48
+ unlock != locked?
49
+ block locking
50
+ lock exception handling
51
+ - user/locking
52
+ lock exception raised
53
+
54
+
55
+ root/etc_utils.rb
56
+ |- root/shadow_tests
57
+ module tests
58
+ getspent
59
+ find_spwd
60
+ setspent
61
+ endspent
62
+ sgetspent
63
+ getspnam
64
+ fgetspent
65
+ putspent
66
+ putspent_raises for file/type
67
+ class tests
68
+ get
69
+ each
70
+ find
71
+ parse
72
+ set
73
+ end
74
+
75
+ |- root/gshadow_tests
76
+ module tests
77
+ getsgent
78
+ find_sgrp
79
+ setsgent
80
+ endsgent
81
+ sgetsgent
82
+ getsgnam
83
+ fgetsgent
84
+ putsgent
85
+ putspent_raises for file/type
86
+ class tests
87
+ get
88
+ each
89
+ find
90
+ parse
91
+ set
92
+ end
93
+ members
94
+ admins
95
+
96
+ test_passwd_class
97
+ module tests
98
+ getpwent
99
+ find_pwd
100
+ setpwent
101
+ endpwent
102
+ sgetpwent
103
+ getpwnam
104
+ fgetpwent
105
+ putpwent
106
+ putspent_raises for file/type
107
+ class tests
108
+ get
109
+ each
110
+ find
111
+ parse
112
+ set
113
+ end
114
+
115
+
116
+ test_group_class
117
+ module tests
118
+ getgrent
119
+ find_grp
120
+ setgrent
121
+ endgrent
122
+ sgetgrent
123
+ getgrnam
124
+ fgetgrent
125
+ putgrent
126
+ putspent_raises for file/type
127
+ class tests
128
+ get
129
+ each
130
+ find
131
+ parse
132
+ set
133
+ end
134
+ members
135
+
136
+
137
+ ## TODO
138
+
139
+ DRYIFY root/etc_utils.rb
140
+
141
+ Should raise rb_eSystemCallError if system calls fail
@@ -0,0 +1,8 @@
1
+ $:.unshift File.dirname(__FILE__) + "/../lib"
2
+
3
+ require 'test/unit'
4
+ require 'etcutils'
5
+
6
+ $eu_user = EtcUtils.me.uid.zero? ? "root" : "user"
7
+
8
+ class Test::Unit::TestCase; include EtcUtils; end
@@ -0,0 +1,5 @@
1
+ require 'root/shadow_tests'
2
+
3
+ if EU.read_gshadow?
4
+ require 'root/gshadow_tests'
5
+ end
@@ -0,0 +1,153 @@
1
+ # This needs to be mentioned during install, but it's just going to
2
+ # fail a majority of the time until 14.04.
3
+ #
4
+ # def test_nsswitch_conf_gshadow
5
+ # assert_block "\n#{'*' * 75}
6
+ # nsswitch.conf may be misconfigured. Consider adding the below to /etc/nsswitch.conf.
7
+ # gshadow:\tfiles
8
+ # See 'http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=699089' for more.\n" do
9
+ # setsgent
10
+ # !!getsgent
11
+ # end
12
+ # end
13
+
14
+ class GShadowTest < Test::Unit::TestCase
15
+
16
+ ##
17
+ # Module Specific Methods
18
+ #
19
+
20
+ def test_set_end_ent
21
+ assert_nothing_raised do
22
+ EU.setsgent
23
+ end
24
+
25
+ assert_nothing_raised do
26
+ EU.endsgent
27
+ end
28
+ end
29
+
30
+ def test_find
31
+ assert_nil EtcUtils.find_sgrp("testuser"), "EU.find_sgrp should return nil if user does not exist"
32
+ assert_equal("root", EtcUtils.find_sgrp("root").name, "EU.find_sgrp(str) should return user if it exists")
33
+ assert_equal("root", EtcUtils.find_sgrp(0).name, "EU.find_sgrp(int) should return user if it exists")
34
+ assert_nothing_raised do
35
+ EU.setsgent
36
+ end
37
+ assert_equal(getsgnam('root').name, getsgent.name, "EU.getsgnam('root') and EU.getsgent should return the same user")
38
+ end
39
+
40
+ def test_shadow_vs_passwd
41
+ assert_equal(find_sgrp('root').name, find_grp('root').name, "EU.find_sgrp and EU.find_grp should return the same user")
42
+ end
43
+
44
+ def test_sgetsgent
45
+ assert sgetsgent(find_sgrp('root').to_entry).name.eql? "root"
46
+ end
47
+
48
+ def test_getsgent_while
49
+ assert_nothing_raised do
50
+ EtcUtils.setsgent
51
+ while ( ent = EtcUtils.getsgent ); nil; end
52
+ end
53
+ end
54
+
55
+ def test_fgetsgent_and_putsgent
56
+ tmp_fn = "/tmp/_fgetsgent_test"
57
+ assert_nothing_raised do
58
+ fh = File.open('/etc/gshadow', 'r')
59
+ File.open(tmp_fn, File::RDWR|File::CREAT, 0600) { |tmp_fh|
60
+ while ( ent = EtcUtils.fgetsgent(fh) )
61
+ EU.putsgent(ent, tmp_fh)
62
+ end
63
+ }
64
+ fh.close
65
+ end
66
+ assert File.exists?(tmp_fn), "EU.fgetsgent(fh) should write to fh"
67
+ assert FileUtils.compare_file("/etc/gshadow", tmp_fn) == true,
68
+ "DIFF FAILED: /etc/gshadow <=> #{tmp_fn}\n" << `diff /etc/gshadow #{tmp_fn}`
69
+ ensure
70
+ FileUtils.remove_file(tmp_fn);
71
+ end
72
+
73
+ def test_putsgent_raises
74
+ FileUtils.touch "/tmp/_gshadow"
75
+
76
+ assert_raise IOError do
77
+ f = File.open("/tmp/_gshadow", 'r')
78
+ u = EU.find_sgrp('root')
79
+ u.fputs f
80
+ end
81
+ ensure
82
+ FileUtils.remove_file("/tmp/_gshadow");
83
+ end
84
+
85
+ ##
86
+ # EU::GShadow class methods
87
+ #
88
+ def test_class_set_end_ent
89
+ assert_nothing_raised do
90
+ EU::GShadow.set
91
+ end
92
+
93
+ assert_nothing_raised do
94
+ EU::GShadow.end
95
+ end
96
+ end
97
+
98
+ def test_class_get
99
+ assert_not_nil EU::GShadow.get
100
+ end
101
+
102
+ def test_class_each
103
+ assert_nothing_raised do
104
+ EU::GShadow.each do |e|
105
+ assert e.name
106
+ end
107
+ end
108
+ end
109
+
110
+ def test_class_find
111
+ assert_equal "root", EU::GShadow.find('root').name
112
+ end
113
+
114
+ def test_class_parse
115
+ assert_nothing_raised do
116
+ EtcUtils::GShadow.parse("root:x:0:")
117
+ end
118
+ end
119
+
120
+ def test_class_parse_members
121
+ assert_nothing_raised do
122
+ assert_equal Array, EtcUtils::GShadow.parse("root:*::").members.class
123
+ end
124
+
125
+ assert_equal "user", EtcUtils::GShadow.parse("root:*:admin:user").members.first
126
+ end
127
+
128
+ def test_class_parse_admins
129
+ assert_nothing_raised do
130
+ assert_equal Array, EtcUtils::GShadow.parse("root:*::").admins.class
131
+ end
132
+
133
+ assert_equal "admin", EtcUtils::GShadow.parse("root:*:admin:user").admins.first
134
+ end
135
+
136
+ ##
137
+ # EU::GShadow instance methods
138
+ #
139
+ def test_init
140
+ assert_equal EU::GShadow, EU::GShadow.new.class
141
+ end
142
+
143
+ def test_instance_methods
144
+ e = EU::GShadow.find('root')
145
+ assert_equal 'root', e.name
146
+ assert_not_nil e.passwd
147
+ assert_equal 'root', EU::GShadow.parse(e.to_entry).name
148
+ assert_equal String, e.to_entry.class
149
+ assert_equal Array, e.members.class
150
+ assert_equal Array, e.admins.class
151
+ assert e.respond_to?(:fputs)
152
+ end
153
+ end
@@ -0,0 +1,23 @@
1
+ class RootLockingTest < EULockingTest
2
+ def test_locking
3
+ assert_equal(lock, locked?)
4
+ assert_not_equal(unlock, locked?)
5
+ end
6
+
7
+ def test_locking_block
8
+ assert_block "Couldn't run a block inside of lock()" do
9
+ lock { assert locked? }
10
+ !locked?
11
+ end
12
+ end
13
+
14
+ def test_locked_after_exception
15
+ assert_block "Files remained locked when an exception is raised inside of lock()" do
16
+ begin
17
+ lock { raise "foobar" }
18
+ rescue
19
+ !locked?
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,161 @@
1
+ class ShadowTest < Test::Unit::TestCase
2
+ require 'stringio'
3
+ ##
4
+ # Module Specific Methods
5
+ #
6
+
7
+ def test_set_end_ent
8
+ assert_nothing_raised do
9
+ EU.setspent
10
+ end
11
+
12
+ assert_nothing_raised do
13
+ EU.endspent
14
+ end
15
+ end
16
+
17
+ def test_find
18
+ assert_nil EtcUtils.find_spwd("testuser"), "EU.find_spwd should return nil if user does not exist"
19
+ assert_equal("root", EtcUtils.find_spwd("root").name, "EU.find_spwd(str) should return user if it exists")
20
+ assert_equal("root", EtcUtils.find_spwd(0).name, "EU.find_spwd(int) should return user if it exists")
21
+ assert_nothing_raised do
22
+ EU.setspent
23
+ end
24
+ assert_equal(getspnam('root').name, getspent.name, "EU.getspent and EU.find_spwd(0) should return the same user")
25
+ end
26
+
27
+ def test_shadow_vs_passwd
28
+ assert_equal(find_spwd('root').name, find_pwd('root').name, "EU.find_spwd and EU.find_pwd should return the same user")
29
+ end
30
+
31
+ def test_sgetspent
32
+ assert EU.sgetspent(EU.find_spwd('root').to_entry).name.eql? "root"
33
+ end
34
+
35
+ def test_getspent_while
36
+ assert_nothing_raised do
37
+ EtcUtils.setspent
38
+ while ( ent = EtcUtils.getspent ); nil; end
39
+ end
40
+ end
41
+
42
+ def test_fgetspent_and_putspent
43
+ tmp_fn = "/tmp/_fgetsgent_test"
44
+ assert_nothing_raised do
45
+ fh = File.open('/etc/shadow', 'r')
46
+ File.open(tmp_fn, File::RDWR|File::CREAT, 0600) { |tmp_fh|
47
+ while ( ent = EtcUtils.fgetspent(fh) )
48
+ EU.putspent(ent, tmp_fh)
49
+ end
50
+ }
51
+ fh.close
52
+ end
53
+ assert File.exists?(tmp_fn), "EU.fgetspent(fh) should write to fh"
54
+ assert FileUtils.compare_file("/etc/shadow", tmp_fn) == true,
55
+ "DIFF FAILED: /etc/shadow <=> #{tmp_fn}\n" << `diff /etc/shadow #{tmp_fn}`
56
+ ensure
57
+ FileUtils.remove_file(tmp_fn);
58
+ end
59
+
60
+ def test_putspent_raises
61
+ FileUtils.touch "/tmp/_shadow"
62
+
63
+ assert_raise IOError do
64
+ f = File.open("/tmp/_shadow", 'r')
65
+ u = EU.find_spwd('root')
66
+ u.fputs f
67
+ end
68
+ ensure
69
+ FileUtils.remove_file("/tmp/_shadow");
70
+ end
71
+
72
+ ##
73
+ # EU::Shadow class methods
74
+ #
75
+ def test_class_set_end_ent
76
+ assert_nothing_raised do
77
+ EU::Shadow.set
78
+ end
79
+
80
+ assert_nothing_raised do
81
+ EU::Shadow.end
82
+ end
83
+ end
84
+
85
+ def test_class_get
86
+ assert_not_nil EU::Shadow.get
87
+ end
88
+
89
+ def test_class_each
90
+ assert_nothing_raised do
91
+ EU::Shadow.each do |e|
92
+ assert e.name
93
+ end
94
+ end
95
+ end
96
+
97
+ def test_class_find
98
+ assert_equal "root", EU::Shadow.find('root').name
99
+ end
100
+
101
+ def test_class_parse
102
+ assert_nothing_raised do
103
+ EtcUtils::Shadow.parse("root:!:16122:0:99999:7:::")
104
+ end
105
+ end
106
+
107
+ ##
108
+ # EU::Shadow instance methods
109
+ #
110
+ def test_init
111
+ assert_equal EU::Shadow, EU::Shadow.new.class
112
+ end
113
+
114
+ def test_instance_methods
115
+ e = EU::Shadow.find('root')
116
+ assert_equal 'root', e.name
117
+ assert_not_nil e.passwd
118
+ assert_not_nil e.last_pw_change
119
+ assert e.respond_to?(:fputs)
120
+ assert_equal 'root', EU::Shadow.parse(e.to_entry).name
121
+ assert_equal String, e.to_entry.class
122
+ end
123
+
124
+ # rb_define_method(rb_cShadow, "passwd=", user_set_pw_change, 1);
125
+ # rb_define_method(rb_cShadow, "last_pw_change_date", user_get_pw_change, 0);
126
+ # rb_define_method(rb_cShadow, "expire_date", user_get_expire, 0);
127
+ # rb_define_method(rb_cShadow, "expire_date=", user_set_expire, 1);
128
+ def test_last_pwchange
129
+ e = EU::Shadow.find('root')
130
+ lstchg = e.last_pw_change
131
+ e.passwd = "!#{e.passwd}"
132
+ assert_not_equal e.last_pw_change, lstchg
133
+ end
134
+
135
+ def test_expire
136
+ e = EU::Shadow.find('root')
137
+ assert_not_nil e.expire = 500
138
+ assert_equal Time.at(500 * 86400), e.expire_date
139
+ n = Time.now
140
+ assert_not_nil e.expire = n
141
+ assert_equal n.to_i / 86400, e.expire
142
+ end
143
+
144
+ def test_expire_warning
145
+ e = EU::Shadow.find('root')
146
+ assert_equal capture_stderr{ e.expire = 0 }.gsub(/.+warning:\s+|\n/,''), "Setting EtcUtils::Shadow#expire to 0 should not be used as it is interpreted as either an account with no expiration, or as an expiration of Jan 1, 1970."
147
+ assert_equal 0, e.expire
148
+ end
149
+
150
+ def capture_stderr
151
+ # The output stream must be an IO-like object. In this case we capture it in
152
+ # an in-memory IO object so we can return the string value. You can assign any
153
+ # IO object here.
154
+ previous_stderr, $stderr = $stderr, StringIO.new
155
+ yield
156
+ $stderr.string
157
+ ensure
158
+ # Restore the previous value of stderr (typically equal to STDERR).
159
+ $stderr = previous_stderr
160
+ end
161
+ end