sys-admin 1.3.1 → 1.4.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.
- data/CHANGES +16 -0
- data/MANIFEST +15 -14
- data/README +54 -38
- data/examples/groups.rb +3 -3
- data/examples/users.rb +21 -3
- data/{lib/sys/unix.c → ext/admin.c} +50 -60
- data/ext/admin.h +428 -0
- data/{extconf.rb → ext/extconf.rb} +4 -8
- data/test/tc_admin.rb +1 -1
- data/test/tc_unix.rb +5 -5
- data/test/{tc_win32.rb → tc_windows.rb} +68 -4
- metadata +9 -7
- data/lib/sys/unix.h +0 -411
- data/lib/sys/win32.orig +0 -403
data/CHANGES
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 1.4.0 - 20-Jan-2007
|
2
|
+
* Added the following methods: add_local_user, config_local_user,
|
3
|
+
delete_local_user, add_global_group, config_global_group, and
|
4
|
+
delete_global_group. MS Windows only at the moment.
|
5
|
+
* Added corresponding tests.
|
6
|
+
* Added much more inline documentation.
|
7
|
+
* Major refactoring of the get_lastlog_info helper function in admin.h. This
|
8
|
+
fixed a major bug in some flavors of Linux where the Admin.users method
|
9
|
+
could go into an infinite loop. It also fixed some minor bugs where console
|
10
|
+
and host values were sometimes filled with junk characters.
|
11
|
+
* Added the User#change attribute, and a check for the pw_change struct member
|
12
|
+
in the extconf.rb file.
|
13
|
+
* The User#expire attribute is now handled as a Time object instead of an
|
14
|
+
integer.
|
15
|
+
* Renamed tc_win32.rb to tc_windows.rb
|
16
|
+
|
1
17
|
== 1.3.1 - 29-Jun-2005
|
2
18
|
* Fixed a bug where the inability to read the lastlog file caused an error.
|
3
19
|
From now on that error is ignored, and the lastlog attributes of the User
|
data/MANIFEST
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
README
|
1
|
+
* install.rb
|
2
|
+
* sys-admin.gemspec
|
3
|
+
* CHANGES
|
4
|
+
* MANIFEST
|
5
|
+
* README
|
7
6
|
|
8
|
-
examples/groups.rb
|
9
|
-
examples/users.rb
|
7
|
+
* examples/groups.rb
|
8
|
+
* examples/users.rb
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
* ext/admin.c
|
11
|
+
* ext/admin.h
|
12
|
+
* ext/extconf.rb
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
test/
|
14
|
+
* lib/sys/win32.rb
|
15
|
+
|
16
|
+
* test/tc_admin.rb
|
17
|
+
* test/tc_unix.rb
|
18
|
+
* test/tc_windows.rb
|
data/README
CHANGED
@@ -3,18 +3,18 @@
|
|
3
3
|
Etc module.
|
4
4
|
|
5
5
|
== Installation
|
6
|
-
===
|
7
|
-
|
8
|
-
|
6
|
+
=== Windows
|
7
|
+
ruby tc_admin.rb # optional (in the 'test' directory)
|
8
|
+
ruby install.rb
|
9
9
|
|
10
10
|
=== Unix
|
11
|
-
ruby extconf.rb
|
12
|
-
|
13
|
-
ruby
|
14
|
-
|
11
|
+
ruby extconf.rb (in the 'ext' directory)
|
12
|
+
make
|
13
|
+
ruby tc_admin.rb # optional (in the 'test' directory)
|
14
|
+
make install
|
15
15
|
|
16
16
|
== Synopsis
|
17
|
-
require
|
17
|
+
require 'sys/admin'
|
18
18
|
include Sys
|
19
19
|
|
20
20
|
# Yields a User object for each user
|
@@ -47,7 +47,7 @@ Admin.get_user(name, host=localhost)
|
|
47
47
|
Admin.get_user(uid, host=localhost, local=true)
|
48
48
|
Returns a User object based on +name+ or +uid+.
|
49
49
|
|
50
|
-
|
50
|
+
Windows only: you may specify a host from which information is retrieved.
|
51
51
|
The default is the local machine. You may also specify whether to
|
52
52
|
retrieve a local or global account. The default is local.
|
53
53
|
|
@@ -55,7 +55,7 @@ Admin.get_group(name, host=localhost, local=true)
|
|
55
55
|
Admin.get_group(gid, host=localhost, local=true)
|
56
56
|
Returns a Group object based on +name+ or +uid+.
|
57
57
|
|
58
|
-
|
58
|
+
Windows only: you may specify a host from which information is retrieved.
|
59
59
|
The default is the local machine. You can retrieve either a global or
|
60
60
|
local group, depending on the value of the +local+ argument.
|
61
61
|
|
@@ -64,7 +64,7 @@ Admin.groups(host=localhost, local=true){ |group| ... }
|
|
64
64
|
In block form, yields a Group object for each user on the system. In
|
65
65
|
non-block form, returns an Array of Group objects.
|
66
66
|
|
67
|
-
|
67
|
+
Windows only: you may specify a host from which information is retrieved.
|
68
68
|
The default is the local machine. You can retrieve either a global or
|
69
69
|
local group, depending on the value of the +local+ argument.
|
70
70
|
|
@@ -73,13 +73,13 @@ Admin.users(host=localhost, local=true){ |user| ... }
|
|
73
73
|
In block form, yields a User object for each user on the system. In
|
74
74
|
non-block form, returns an Array of User objects.
|
75
75
|
|
76
|
-
|
76
|
+
Windows only: you may specify a host from which information is retrieved.
|
77
77
|
The default is the local machine. You can retrieve either a global or
|
78
78
|
local group, depending on the value of the +local+ argument.
|
79
79
|
|
80
80
|
== User class
|
81
|
-
=== User (
|
82
|
-
|
81
|
+
=== User (Windows)
|
82
|
+
The User class has the following attributes on MS Windows systems:
|
83
83
|
|
84
84
|
* account_type
|
85
85
|
* caption
|
@@ -99,7 +99,7 @@ Admin.users(host=localhost, local=true){ |user| ... }
|
|
99
99
|
* password_required?
|
100
100
|
|
101
101
|
=== User (Unix)
|
102
|
-
|
102
|
+
The User class has the following attributes on Unix systems:
|
103
103
|
|
104
104
|
* name
|
105
105
|
* passwd
|
@@ -112,11 +112,12 @@ Admin.users(host=localhost, local=true){ |user| ... }
|
|
112
112
|
* age
|
113
113
|
* class
|
114
114
|
* comment
|
115
|
+
* change
|
115
116
|
* expire
|
116
117
|
|
117
118
|
== Group Classes
|
118
|
-
=== Group (
|
119
|
-
|
119
|
+
=== Group (Windows)
|
120
|
+
The Group class has the following attributes on MS Windows systems:
|
120
121
|
|
121
122
|
* caption
|
122
123
|
* description
|
@@ -129,46 +130,61 @@ Admin.users(host=localhost, local=true){ |user| ... }
|
|
129
130
|
* local?
|
130
131
|
|
131
132
|
=== Group (Unix)
|
132
|
-
|
133
|
+
The Group class has the following attributes on Unix systems:
|
133
134
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
* name
|
136
|
+
* gid
|
137
|
+
* members
|
138
|
+
* passwd
|
138
139
|
|
139
140
|
== Error Classes
|
140
141
|
AdminError < StandardError
|
141
142
|
Raised if anything goes wrong with any of the above methods.
|
142
143
|
|
143
144
|
== Developer's Notes
|
144
|
-
===
|
145
|
-
|
146
|
-
|
147
|
-
|
145
|
+
=== MS Windows
|
146
|
+
The Windows version now uses a win32ole + WMI approach to getting
|
147
|
+
information. This means that the WMI service must be running on the
|
148
|
+
target machine in order to work (which it is, by default).
|
148
149
|
|
149
|
-
|
150
|
-
|
151
|
-
|
150
|
+
Note that, by default, local user and group information is retrieved
|
151
|
+
instead of global. You probably do NOT want to iterate over global users
|
152
|
+
or groups because there can be quite a few on your domain.
|
153
|
+
|
154
|
+
=== UNIX
|
155
|
+
The underlying implementation is similar to core Ruby's Etc implementation.
|
156
|
+
But, in addition to the different interface, I use the re-entrant version
|
157
|
+
of the appropriate functions when available.
|
152
158
|
|
153
159
|
== Future Plans
|
154
|
-
|
155
|
-
|
156
|
-
* Admin.
|
157
|
-
* Admin.
|
158
|
-
* Admin.
|
160
|
+
Add the following methods for UNIX:
|
161
|
+
|
162
|
+
* Admin.add_local_user
|
163
|
+
* Admin.config_local_user
|
164
|
+
* Admin.delete_local_user
|
165
|
+
* Admin.add_global_user
|
166
|
+
* Admin.config_global_user
|
167
|
+
* Admin.delete_global_user
|
168
|
+
|
169
|
+
* Admin.add_local_group
|
170
|
+
* Admin.config_local_group
|
171
|
+
* Admin.delete_local_group
|
172
|
+
* Admin.add_global_group
|
173
|
+
* Admin.config_global_group
|
174
|
+
* Admin.delete_global_group
|
159
175
|
|
160
176
|
== Known Bugs
|
161
|
-
None that I'm aware of.
|
177
|
+
None that I'm aware of. If you find any, please log them on the project
|
162
178
|
page at http://www.rubyforge.org/projects/sysutils.
|
163
179
|
|
164
180
|
== License
|
165
181
|
Ruby's
|
166
182
|
|
167
183
|
== Copyright
|
168
|
-
(C) 2005, Daniel J. Berger
|
184
|
+
(C) 2005-2007, Daniel J. Berger
|
169
185
|
All Rights Reserved
|
170
186
|
|
171
187
|
== Author
|
172
188
|
Daniel J. Berger
|
173
|
-
djberg96
|
174
|
-
IRC nickname: imperator/mok/rubyhacker1
|
189
|
+
djberg96 at nospam at gmail dot com
|
190
|
+
IRC nickname: imperator/mok/rubyhacker1 (freenode)
|
data/examples/groups.rb
CHANGED
@@ -10,8 +10,8 @@ if base == "examples" || base =~ /sys-admin.*/
|
|
10
10
|
require "ftools"
|
11
11
|
Dir.chdir("..") if base == "examples"
|
12
12
|
Dir.mkdir("sys") unless File.exists?("sys")
|
13
|
-
if
|
14
|
-
File.copy("lib/sys/
|
13
|
+
if RUBY_PLATFORM.match("mswin")
|
14
|
+
File.copy("lib/sys/admin.rb", "sys/admin.rb")
|
15
15
|
else
|
16
16
|
File.copy("admin.so","sys") if File.exists?("admin.so")
|
17
17
|
end
|
@@ -22,7 +22,7 @@ require "pp"
|
|
22
22
|
require "sys/admin"
|
23
23
|
include Sys
|
24
24
|
|
25
|
-
if
|
25
|
+
if PLATFORM.match("mswin")
|
26
26
|
pp Admin.get_group("guests")
|
27
27
|
pp Admin.get_group(513)
|
28
28
|
else
|
data/examples/users.rb
CHANGED
@@ -10,8 +10,8 @@ if base == "examples" || base =~ /sys-admin.*/
|
|
10
10
|
require "ftools"
|
11
11
|
Dir.chdir("..") if base == "examples"
|
12
12
|
Dir.mkdir("sys") unless File.exists?("sys")
|
13
|
-
if
|
14
|
-
File.copy("lib/sys/
|
13
|
+
if RUBY_PLATFORM.match("mswin")
|
14
|
+
File.copy("lib/sys/admin.rb", "sys/admin.rb")
|
15
15
|
else
|
16
16
|
File.copy("admin.so","sys") if File.exists?("admin.so")
|
17
17
|
end
|
@@ -22,6 +22,23 @@ require "pp"
|
|
22
22
|
require "sys/admin"
|
23
23
|
include Sys
|
24
24
|
|
25
|
+
user = User.new do |u|
|
26
|
+
u.name = "Foo"
|
27
|
+
u.description = "Test account"
|
28
|
+
u.password = "changeme"
|
29
|
+
#u.lockout = false
|
30
|
+
u.disabled = true
|
31
|
+
#u.password_required = true
|
32
|
+
end
|
33
|
+
|
34
|
+
Admin.delete_user(u.name) rescue nil
|
35
|
+
Admin.add_user(user)
|
36
|
+
|
37
|
+
#pp Admin.get_user("Foo")
|
38
|
+
|
39
|
+
#Admin.delete_user("Foo")
|
40
|
+
|
41
|
+
=begin
|
25
42
|
user = Admin.get_login
|
26
43
|
|
27
44
|
puts "User: #{user}"
|
@@ -32,4 +49,5 @@ Admin.users{ |u|
|
|
32
49
|
}
|
33
50
|
|
34
51
|
pp Admin.get_user(user)
|
35
|
-
pp Admin.get_user(501)
|
52
|
+
pp Admin.get_user(501)
|
53
|
+
=end
|
@@ -49,12 +49,12 @@ static VALUE group_init(VALUE self){
|
|
49
49
|
*/
|
50
50
|
static VALUE admin_get_login(VALUE klass){
|
51
51
|
char login[_POSIX_LOGIN_NAME_MAX];
|
52
|
-
VALUE
|
52
|
+
VALUE v_login = Qnil;
|
53
53
|
|
54
54
|
#ifdef HAVE_GETLOGIN_R
|
55
|
-
getlogin_r(login,sizeof(login));
|
55
|
+
getlogin_r(login, sizeof(login));
|
56
56
|
#elif HAVE_GETLOGIN
|
57
|
-
strcpy(login,getlogin());
|
57
|
+
strcpy(login, getlogin());
|
58
58
|
#endif
|
59
59
|
|
60
60
|
#ifdef HAVE_CUSERID
|
@@ -64,13 +64,13 @@ static VALUE admin_get_login(VALUE klass){
|
|
64
64
|
|
65
65
|
#ifdef HAVE_GETENV
|
66
66
|
if(!login)
|
67
|
-
strcpy(login,getenv("USER"));
|
67
|
+
strcpy(login, getenv("USER"));
|
68
68
|
#endif
|
69
69
|
|
70
70
|
if(login)
|
71
|
-
|
71
|
+
v_login = rb_str_new2(login);
|
72
72
|
|
73
|
-
return
|
73
|
+
return v_login;
|
74
74
|
}
|
75
75
|
|
76
76
|
/* call-seq:
|
@@ -80,17 +80,15 @@ static VALUE admin_get_login(VALUE klass){
|
|
80
80
|
* Returns a User object for the given +name+ or +uid+. Raises an AdminError
|
81
81
|
* if a user cannot be found for that name or user ID.
|
82
82
|
*/
|
83
|
-
static VALUE admin_get_user(VALUE klass, VALUE
|
84
|
-
VALUE
|
83
|
+
static VALUE admin_get_user(VALUE klass, VALUE v_value){
|
84
|
+
VALUE v_user;
|
85
85
|
|
86
|
-
if(FIXNUM_P(
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
rbUser = get_user_by_name(rbVal);
|
91
|
-
}
|
86
|
+
if(FIXNUM_P(v_value))
|
87
|
+
v_user = get_user_by_num(v_value);
|
88
|
+
else
|
89
|
+
v_user = get_user_by_name(v_value);
|
92
90
|
|
93
|
-
return
|
91
|
+
return v_user;
|
94
92
|
}
|
95
93
|
|
96
94
|
/* call-seq:
|
@@ -107,17 +105,15 @@ static VALUE admin_get_user(VALUE klass, VALUE rbVal){
|
|
107
105
|
* for only two types, I can live with it for the added convenience it
|
108
106
|
* provides.
|
109
107
|
*/
|
110
|
-
static VALUE admin_get_group(VALUE klass, VALUE
|
111
|
-
VALUE
|
108
|
+
static VALUE admin_get_group(VALUE klass, VALUE v_value){
|
109
|
+
VALUE v_group;
|
112
110
|
|
113
|
-
if(FIXNUM_P(
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
rbGroup = get_group_by_name(rbVal);
|
118
|
-
}
|
111
|
+
if(FIXNUM_P(v_value))
|
112
|
+
v_group = get_group_by_num(v_value);
|
113
|
+
else
|
114
|
+
v_group = get_group_by_name(v_value);
|
119
115
|
|
120
|
-
return
|
116
|
+
return v_group;
|
121
117
|
}
|
122
118
|
|
123
119
|
/* call-seq:
|
@@ -128,10 +124,10 @@ static VALUE admin_get_group(VALUE klass, VALUE rbVal){
|
|
128
124
|
* non-block form, returns an Array of Group objects.
|
129
125
|
*/
|
130
126
|
static VALUE admin_groups(VALUE klass){
|
131
|
-
VALUE
|
127
|
+
VALUE v_array = Qnil;
|
132
128
|
|
133
129
|
if(!rb_block_given_p())
|
134
|
-
|
130
|
+
v_array = rb_ary_new();
|
135
131
|
|
136
132
|
setgrent();
|
137
133
|
|
@@ -141,39 +137,34 @@ static VALUE admin_groups(VALUE klass){
|
|
141
137
|
#ifdef _GNU_SOURCE
|
142
138
|
struct group* grp_p;
|
143
139
|
while(!getgrent_r(&grp, buf, GROUP_BUF_SIZE, &grp_p)){
|
144
|
-
if(rb_block_given_p())
|
140
|
+
if(rb_block_given_p())
|
145
141
|
rb_yield(get_group(grp_p));
|
146
|
-
|
147
|
-
|
148
|
-
rb_ary_push(rbArray, get_group(grp_p));
|
149
|
-
}
|
142
|
+
else
|
143
|
+
rb_ary_push(v_array, get_group(grp_p));
|
150
144
|
}
|
151
145
|
#else
|
152
146
|
while(getgrent_r(&grp, buf, GROUP_BUF_SIZE) != NULL){
|
153
|
-
if(rb_block_given_p())
|
147
|
+
if(rb_block_given_p())
|
154
148
|
rb_yield(get_group(&grp));
|
155
|
-
|
156
|
-
|
157
|
-
rb_ary_push(rbArray, get_group(&grp));
|
158
|
-
}
|
149
|
+
else
|
150
|
+
rb_ary_push(v_array, get_group(&grp));
|
159
151
|
}
|
160
152
|
#endif
|
161
153
|
#elif HAVE_GETGRENT
|
162
154
|
struct group* grp;
|
163
155
|
while((grp = getgrent()) != NULL){
|
164
|
-
if(rb_block_given_p())
|
156
|
+
if(rb_block_given_p())
|
165
157
|
rb_yield(get_group(grp));
|
166
|
-
|
167
|
-
|
168
|
-
rb_ary_push(rbArray, get_group(grp));
|
169
|
-
}
|
158
|
+
else
|
159
|
+
rb_ary_push(v_array, get_group(grp));
|
170
160
|
}
|
171
161
|
#else
|
172
162
|
rb_raise(rb_eNotImpError, "groups method not supported on this platform");
|
173
163
|
#endif
|
174
164
|
|
175
165
|
endgrent();
|
176
|
-
|
166
|
+
|
167
|
+
return v_array;
|
177
168
|
}
|
178
169
|
|
179
170
|
/* call-seq:
|
@@ -184,10 +175,10 @@ static VALUE admin_groups(VALUE klass){
|
|
184
175
|
* non-block form, returns an Array of User objects.
|
185
176
|
*/
|
186
177
|
static VALUE admin_users(VALUE klass){
|
187
|
-
VALUE
|
178
|
+
VALUE v_array = Qnil;
|
188
179
|
|
189
180
|
if(!rb_block_given_p())
|
190
|
-
|
181
|
+
v_array = rb_ary_new();
|
191
182
|
|
192
183
|
setpwent();
|
193
184
|
|
@@ -198,40 +189,38 @@ static VALUE admin_users(VALUE klass){
|
|
198
189
|
#ifdef _GNU_SOURCE
|
199
190
|
struct passwd* pwd_p;
|
200
191
|
while(!getpwent_r(&pwd, buf, USER_BUF_SIZE, &pwd_p)){
|
201
|
-
if(rb_block_given_p())
|
192
|
+
if(rb_block_given_p())
|
202
193
|
rb_yield(get_user(pwd_p));
|
203
|
-
|
204
|
-
|
205
|
-
rb_ary_push(rbArray, get_user(pwd_p));
|
206
|
-
}
|
194
|
+
else
|
195
|
+
rb_ary_push(v_array, get_user(pwd_p));
|
207
196
|
}
|
208
197
|
#else
|
209
198
|
while(getpwent_r(&pwd, buf, USER_BUF_SIZE) != NULL){
|
210
|
-
if(rb_block_given_p())
|
199
|
+
if(rb_block_given_p())
|
211
200
|
rb_yield(get_user(&pwd));
|
212
|
-
|
213
|
-
|
214
|
-
rb_ary_push(rbArray, get_user(&pwd));
|
215
|
-
}
|
201
|
+
else
|
202
|
+
rb_ary_push(v_array, get_user(&pwd));
|
216
203
|
}
|
217
204
|
#endif
|
218
205
|
#elif HAVE_GETPWENT
|
219
206
|
struct passwd* pwd;
|
220
207
|
|
221
208
|
while((pwd = getpwent()) != NULL){
|
222
|
-
if(rb_block_given_p())
|
209
|
+
if(rb_block_given_p())
|
223
210
|
rb_yield(get_user(pwd));
|
224
|
-
|
225
|
-
|
226
|
-
rb_ary_push(rbArray, get_user(pwd));
|
227
|
-
}
|
211
|
+
else
|
212
|
+
rb_ary_push(v_array, get_user(pwd));
|
228
213
|
}
|
229
214
|
#else
|
230
215
|
rb_raise(rb_eNotImpError, "users method not supported on this platform");
|
231
216
|
#endif
|
232
217
|
|
233
218
|
endpwent();
|
234
|
-
|
219
|
+
|
220
|
+
if(rb_block_given_p())
|
221
|
+
return Qnil;
|
222
|
+
|
223
|
+
return v_array;
|
235
224
|
}
|
236
225
|
|
237
226
|
void Init_admin(){
|
@@ -268,6 +257,7 @@ void Init_admin(){
|
|
268
257
|
rb_define_attr(cUser, "class", 1, 1);
|
269
258
|
rb_define_attr(cUser, "comment", 1, 1);
|
270
259
|
rb_define_attr(cUser, "expire", 1, 1);
|
260
|
+
rb_define_attr(cUser, "change", 1, 1);
|
271
261
|
rb_define_attr(cUser, "login_time", 1, 0);
|
272
262
|
rb_define_attr(cUser, "login_device", 1, 0);
|
273
263
|
rb_define_attr(cUser, "login_host", 1, 0);
|