sys-admin 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|