sys-admin 1.5.6 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/sys/admin.h DELETED
@@ -1,515 +0,0 @@
1
- #include <limits.h>
2
- #include <stdlib.h>
3
- #include <stdio.h>
4
- #include <unistd.h>
5
- #include <pwd.h>
6
- #include <grp.h>
7
- #include <fcntl.h>
8
- #include <errno.h>
9
- #include <string.h>
10
-
11
- #define SYS_ADMIN_VERSION "1.5.6"
12
-
13
- #if defined(__MACH__) || defined(__APPLE__)
14
- #define __BSD__
15
- #endif
16
-
17
- #if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
18
- #define __BSD__
19
- #endif
20
-
21
- #if defined(HAVE_USERSEC_H)
22
- #include <usersec.h>
23
- #else
24
- #if defined(HAVE_UTMPX_H) && defined(HAVE_GETLASTLOGX)
25
- #include <utmpx.h>
26
- #else
27
- #ifdef HAVE_LASTLOG_H
28
- #include <lastlog.h>
29
- #else
30
- #include <utmp.h>
31
- #endif
32
- #endif
33
- #endif
34
-
35
- #ifndef _POSIX_LOGIN_NAME_MAX
36
- #define _POSIX_LOGIN_NAME_MAX 9
37
- #endif
38
-
39
- // BSD platforms are problematic with explicit inclusion of unistd.h
40
- #if defined(__BSD__)
41
- #define USER_BUF_SIZE 1024
42
- #else
43
- #ifdef _SC_GETPW_R_SIZE_MAX
44
- #define USER_BUF_SIZE (sysconf(_SC_GETPW_R_SIZE_MAX))
45
- #else
46
- #define USER_BUF_SIZE 1024
47
- #endif
48
- #endif
49
-
50
- // BSD platforms are problematic with explicit inclusion of unistd.h
51
- #if defined(__BSD__)
52
- #define GROUP_BUF_SIZE 7296
53
- #else
54
- #ifdef _SC_GETGR_R_SIZE_MAX
55
- #define GROUP_BUF_SIZE (sysconf(_SC_GETGR_R_SIZE_MAX))
56
- #else
57
- #define GROUP_BUF_SIZE 7296
58
- #endif
59
- #endif
60
-
61
- #ifndef _PATH_LASTLOG
62
- #define _PATH_LASTLOG "/var/adm/lastlog"
63
- #endif
64
-
65
- /* Function prototypes */
66
- static VALUE admin_users_cleanup();
67
- static VALUE admin_groups_cleanup();
68
- static VALUE get_user(struct passwd* p);
69
- static VALUE get_group(struct group* g);
70
- int get_lastlog_info(struct passwd* p, VALUE v_value);
71
-
72
- VALUE cUser, cGroup, cAdminError;
73
-
74
- /*
75
- * :no-doc:
76
- *
77
- * Helper function that returns a User object based on user ID.
78
- */
79
- static VALUE get_user_by_num(VALUE v_uid){
80
- volatile VALUE v_user;
81
- uid_t uid = NUM2INT(v_uid);
82
-
83
- #ifdef HAVE_GETPWUID_R
84
- char buf[USER_BUF_SIZE];
85
- struct passwd pwd;
86
- struct passwd* pwdbuf;
87
-
88
- if(getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwdbuf) != 0)
89
- rb_raise(cAdminError, "%s", strerror(errno));
90
-
91
- if(!pwdbuf)
92
- rb_raise(cAdminError, "no user found for %i:", uid);
93
-
94
- v_user = get_user(pwdbuf);
95
- #elif HAVE_GETPWUID
96
- struct passwd* pwd;
97
- if( (pwd = getpwuid(uid)) == NULL)
98
- rb_raise(cAdminError, "no user found for: %i", uid);
99
-
100
- v_user = get_user(pwd);
101
- #else
102
- rb_raise(rb_eNotImpError, "getting user by user ID not supported");
103
- #endif
104
-
105
- return v_user;
106
- }
107
-
108
- /*
109
- * :no-doc:
110
- *
111
- * Helper function that returns a User object based on name.
112
- */
113
- static VALUE get_user_by_name(VALUE v_name){
114
- volatile VALUE v_user;
115
- SafeStringValue(v_name);
116
-
117
- #ifdef HAVE_GETPWNAM_R
118
- char buf[USER_BUF_SIZE];
119
- struct passwd pwd;
120
- struct passwd* pwdbuf;
121
-
122
- if(getpwnam_r(RSTRING_PTR(v_name), &pwd, buf, sizeof(buf), &pwdbuf) != 0)
123
- rb_raise(cAdminError, "%s", strerror(errno));
124
-
125
- if(!pwdbuf)
126
- rb_raise(cAdminError, "no user found for %s", StringValuePtr(v_name));
127
-
128
- v_user = get_user(pwdbuf);
129
- #elif HAVE_GETPWNAM
130
- struct passwd* pwd;
131
- if( (pwd = getpwnam(RSTRING(v_name)->ptr)) == NULL)
132
- rb_raise(cAdminError, "no user found for %s", StringValuePtr(v_name));
133
-
134
- v_user = get_user(pwd);
135
- #else
136
- rb_raise(rb_eNotImpError, "getting user by name not supported");
137
- #endif
138
-
139
- return v_user;
140
- }
141
-
142
- /*
143
- * :no-doc:
144
- *
145
- * Helper function that returns a Group object based on group ID.
146
- */
147
- static VALUE get_group_by_num(VALUE v_gid){
148
- volatile VALUE v_group;
149
- gid_t gid = NUM2INT(v_gid);
150
-
151
- #ifdef HAVE_GETGRGID_R
152
- char buf[GROUP_BUF_SIZE];
153
- struct group grp;
154
- struct group* grpbuf;
155
-
156
- if(getgrgid_r(gid, &grp, buf, sizeof(buf), &grpbuf) != 0)
157
- rb_raise(cAdminError, "getgrgid_r() failed: %s", strerror(errno));
158
-
159
- if(!grpbuf)
160
- rb_raise(cAdminError, "no group found for group ID: %i", gid);
161
-
162
- v_group = get_group(grpbuf);
163
- #elif HAVE_GETGRGID
164
- struct group* grp;
165
- if( (grp = getgrgid(gid)) == NULL)
166
- rb_raise(cAdminError, "no group found for group ID: %i", gid);
167
-
168
- v_group = get_group(grp);
169
- #else
170
- rb_raise(rb_eNotImpError, "getting group by group ID not supported");
171
- #endif
172
-
173
- return v_group;
174
- }
175
-
176
- /*
177
- * :no-doc:
178
- *
179
- * Helper function that returns a Group object based on group name.
180
- */
181
- static VALUE get_group_by_name(VALUE v_name){
182
- volatile VALUE v_group = Qnil;
183
- SafeStringValue(v_name);
184
- #ifdef HAVE_GETGRNAM_R
185
- char buf[GROUP_BUF_SIZE];
186
- struct group grp;
187
- struct group* grpbuf;
188
-
189
- if(getgrnam_r(RSTRING_PTR(v_name), &grp, buf, sizeof(buf), &grpbuf) != 0)
190
- rb_raise(cAdminError, "%s", strerror(errno));
191
-
192
- if(!grpbuf)
193
- rb_raise(cAdminError, "no group found for: %s", StringValuePtr(v_name));
194
-
195
- v_group = get_group(grpbuf);
196
- #elif HAVE_GETGRNAM
197
- struct group* grp
198
- if((grp = getgrnam(RSTRING(v_name)->ptr)) == NULL)
199
- rb_raise(cAdminError, "no group found for: %s", StringValuePtr(v_name));
200
-
201
- v_group = get_group(grp);
202
- #else
203
- rb_raise(rb_eNotImpError, "get_group is not supported on this platform");
204
- #endif
205
-
206
- return v_group;
207
- }
208
-
209
- /*
210
- * :no-doc:
211
- *
212
- * Helper function that turns a struct passwd into a User object.
213
- */
214
- static VALUE get_user(struct passwd* pwd){
215
- VALUE v_user = rb_funcall(cUser, rb_intern("new"), 0, 0);
216
-
217
- rb_iv_set(v_user, "@name", rb_str_new2(pwd->pw_name));
218
- rb_iv_set(v_user, "@uid", INT2FIX(pwd->pw_uid));
219
- rb_iv_set(v_user, "@gid", INT2FIX(pwd->pw_gid));
220
- rb_iv_set(v_user, "@dir", rb_str_new2(pwd->pw_dir));
221
- rb_iv_set(v_user, "@shell", rb_str_new2(pwd->pw_shell));
222
-
223
- #ifdef HAVE_ST_PW_PASSWD
224
- rb_iv_set(v_user, "@passwd", rb_str_new2(pwd->pw_passwd));
225
- #endif
226
-
227
- /* TODO: Fix this, or just set it to nil */
228
- #ifdef HAVE_ST_PW_AGE
229
- rb_iv_set(v_user, "@age", INT2FIX(pwd->pw_age));
230
- #endif
231
-
232
- #ifdef HAVE_ST_PW_COMMENT
233
- rb_iv_set(v_user, "@comment", rb_str_new2(pwd->pw_comment));
234
- #endif
235
-
236
- #ifdef HAVE_ST_PW_GECOS
237
- rb_iv_set(v_user, "@gecos", rb_str_new2(pwd->pw_gecos));
238
- #endif
239
-
240
- #ifdef HAVE_ST_PW_QUOTA
241
- rb_iv_set(v_user, "@quota", INT2FIX(pwd->pw_quota));
242
- #endif
243
-
244
- #ifdef HAVE_ST_PW_CLASS
245
- rb_iv_set(v_user, "@access_class", rb_str_new2(pwd->pw_class));
246
- #endif
247
-
248
- #ifdef HAVE_ST_PW_EXPIRE
249
- rb_iv_set(v_user, "@expire", rb_time_new(pwd->pw_expire, 0));
250
- #endif
251
-
252
- #ifdef HAVE_ST_PW_CHANGE
253
- rb_iv_set(v_user, "@change", rb_time_new(pwd->pw_change, 0));
254
- #endif
255
-
256
- #if defined(HAVE_LASTLOG_H) || defined(HAVE_UTMP_H) || defined(HAVE_USERSEC_H)
257
- get_lastlog_info(pwd, v_user);
258
- #endif
259
-
260
- return v_user;
261
- }
262
-
263
- /*
264
- * :no-doc:
265
- *
266
- * Helper function that turns a User object into a struct passwd.
267
- */
268
- void get_user_from_value(VALUE v_user, struct passwd* pwd){
269
-
270
- VALUE v_name = rb_iv_get(v_user, "@name");
271
- VALUE v_uid = rb_iv_get(v_user, "@uid");
272
- VALUE v_gid = rb_iv_get(v_user, "@gid");
273
- VALUE v_dir = rb_iv_get(v_user, "@dir");
274
- VALUE v_shell = rb_iv_get(v_user, "@shell");
275
-
276
- if(NIL_P(v_name))
277
- rb_raise(cAdminError, "user name cannot be nil");
278
-
279
- if(!NIL_P(v_uid))
280
- pwd->pw_uid = NUM2INT(v_uid);
281
-
282
- if(!NIL_P(v_gid))
283
- pwd->pw_gid = NUM2INT(v_gid);
284
-
285
- if(!NIL_P(v_dir)){
286
- SafeStringValue(v_dir);
287
- pwd->pw_dir = StringValuePtr(v_dir);
288
- }
289
-
290
- if(!NIL_P(v_shell)){
291
- SafeStringValue(v_shell);
292
- pwd->pw_shell = StringValuePtr(v_shell);
293
- }
294
-
295
- #ifdef HAVE_ST_PW_PASSWD
296
- VALUE v_passwd = rb_iv_get(v_user, "@passwd");
297
- if(!NIL_P(v_passwd)){
298
- SafeStringValue(v_passwd);
299
- pwd->pw_passwd = StringValuePtr(v_passwd);
300
- }
301
- #endif
302
-
303
- /* TODO: Fix this or just set it to nil */
304
- #ifdef HAVE_ST_PW_AGE
305
- VALUE v_age = rb_iv_get(v_user, "@age");
306
- if(!NIL_P(v_age))
307
- pwd->pw_age = (char*)NUM2INT(v_age);
308
- #endif
309
-
310
- #ifdef HAVE_ST_PW_COMMENT
311
- VALUE v_comment = rb_iv_get(v_user, "@comment");
312
- if(!NIL_P(v_comment)){
313
- SafeStringValue(v_comment);
314
- pwd->pw_comment = StringValuePtr(v_comment);
315
- }
316
- #endif
317
-
318
- #ifdef HAVE_ST_PW_GECOS
319
- VALUE v_gecos = rb_iv_get(v_user, "@gecos");
320
- if(!NIL_P(v_gecos)){
321
- SafeStringValue(v_gecos);
322
- pwd->pw_gecos = StringValuePtr(v_gecos);
323
- }
324
- #endif
325
-
326
- #ifdef HAVE_ST_PW_QUOTA
327
- VALUE v_quota = rb_iv_get(v_user, "@quota");
328
- if(!NIL_P(v_quota))
329
- pwd->pw_quota = NUM2INT(v_quota);
330
- #endif
331
-
332
- #ifdef HAVE_ST_PW_CLASS
333
- VALUE v_class = rb_iv_get(v_user, "@access_class");
334
- if(!NIL_P(v_class)){
335
- SafeStringValue(v_class);
336
- pwd->pw_class = StringValuePtr(v_class);
337
- }
338
- #endif
339
-
340
- #ifdef HAVE_ST_PW_EXPIRE
341
- VALUE v_expire = rb_iv_get(v_user, "@expire");
342
- v_expire = rb_funcall(v_expire, rb_intern("to_i"), 0, 0);
343
- if(!NIL_P(v_expire))
344
- pwd->pw_expire = NUM2ULONG(v_expire);
345
- #endif
346
-
347
- #ifdef HAVE_ST_PW_CHANGE
348
- VALUE v_change = rb_iv_get(v_user, "@change");
349
- v_change = rb_funcall(v_change, rb_intern("to_i"), 0, 0);
350
- if(!NIL_P(v_change))
351
- pwd->pw_change = NUM2ULONG(v_change);
352
- #endif
353
-
354
- }
355
-
356
- /*
357
- * :no-doc:
358
- *
359
- * Helper function that turns a struct grp into a Group object.
360
- */
361
- static VALUE get_group(struct group* g){
362
- VALUE v_group = rb_funcall(cGroup,rb_intern("new"),0,0);
363
- VALUE v_array = rb_ary_new();
364
- char **my_gr_mem = g->gr_mem;
365
-
366
- /* Return the members as an Array of Strings */
367
- while(*my_gr_mem){
368
- rb_ary_push(v_array, rb_str_new2(*my_gr_mem));
369
- my_gr_mem++;
370
- }
371
-
372
- rb_iv_set(v_group, "@name", rb_str_new2(g->gr_name));
373
- rb_iv_set(v_group, "@gid", INT2FIX(g->gr_gid));
374
- rb_iv_set(v_group, "@members", v_array);
375
- #ifdef HAVE_ST_GR_PASSWD
376
- rb_iv_set(v_group, "@passwd", rb_str_new2(g->gr_passwd));
377
- #endif
378
-
379
- return v_group;
380
- }
381
-
382
- /*
383
- * :no-doc:
384
- *
385
- * Helper function that turns a Group object into a struct group.
386
- */
387
- void get_group_from_value(VALUE v_group, struct group* grp){
388
- char** members = malloc(sizeof(char*));
389
- VALUE v_name = rb_iv_get(v_group, "@name");
390
- VALUE v_gid = rb_iv_get(v_group, "@gid");
391
- VALUE v_mem = rb_iv_get(v_group, "@members");
392
- VALUE v_passwd = rb_iv_get(v_group, "@passwd");
393
- int i = 0;
394
-
395
- if(NIL_P(v_name))
396
- rb_raise(cAdminError, "group name must be set");
397
-
398
- SafeStringValue(v_name);
399
- grp->gr_name = StringValuePtr(v_name);
400
-
401
- if(!NIL_P(v_gid))
402
- grp->gr_gid = NUM2INT(v_gid);
403
-
404
- if(!NIL_P(v_mem)){
405
- VALUE v_value;
406
- while((v_value = rb_ary_shift(v_mem)) != Qnil){
407
- members[i] = StringValuePtr(v_value);
408
- i++;
409
- }
410
- members[i] = '\0';
411
- grp->gr_mem = members;
412
- }
413
-
414
- #ifdef HAVE_ST_GR_PASSWD
415
- if(!NIL_P(v_passwd)){
416
- SafeStringValue(v_passwd);
417
- grp->gr_passwd = StringValuePtr(v_passwd);
418
- }
419
- #endif
420
-
421
- free(members);
422
- }
423
-
424
- /*
425
- * :no-doc:
426
- *
427
- * Helper function that gets lastlog information for the User object.
428
- *--
429
- * Note that even if the platform supports lastlog information, it can
430
- * still be empty or nil.
431
- */
432
- int get_lastlog_info(struct passwd* pwd, VALUE v_user){
433
- #ifdef HAVE_USERSEC_H
434
- char *lasthost;
435
- int lasttime;
436
- char *lasttty;
437
-
438
- if (setuserdb(S_READ) == -1) {
439
- return -1;
440
- }
441
-
442
- if (getuserattr(pwd->pw_name, S_LASTTIME, &lasttime, SEC_INT) == -1
443
- || getuserattr(pwd->pw_name, S_LASTTTY, &lasttty, SEC_CHAR) == -1
444
- || getuserattr(pwd->pw_name, S_LASTHOST, &lasthost, SEC_CHAR) == -1) {
445
- enduserdb();
446
- return -1;
447
- }
448
-
449
- rb_iv_set(v_user, "@login_time", rb_time_new(lasttime, 0));
450
- rb_iv_set(v_user, "@login_device", rb_str_new2(lasttty));
451
- rb_iv_set(v_user, "@login_host", rb_str_new2(lasthost));
452
- enduserdb();
453
- #else
454
- #ifdef HAVE_GETLASTLOGX
455
- struct lastlogx log;
456
-
457
- if(getlastlogx(pwd->pw_uid, &log)){
458
- rb_iv_set(v_user, "@login_time", rb_time_new(log.ll_tv.tv_sec, log.ll_tv.tv_usec));
459
- rb_iv_set(v_user, "@login_device", rb_str_new2(log.ll_line));
460
- rb_iv_set(v_user, "@login_host", rb_str_new2(log.ll_host));
461
- }
462
- #else
463
- int fd;
464
- ssize_t bytes_read;
465
- struct lastlog log;
466
- int ll_size = sizeof(struct lastlog);
467
-
468
- /* The lastlog information is not necessarily readable by all users, so
469
- * ignore open() errors if they occur.
470
- */
471
- if((fd = open(_PATH_LASTLOG, O_RDONLY)) == -1)
472
- return -1;
473
-
474
- if((bytes_read = pread(fd, &log, ll_size, pwd->pw_uid * ll_size)) < 0){
475
- close(fd);
476
- rb_raise(cAdminError, "%s", strerror(errno));
477
- }
478
-
479
- close(fd);
480
-
481
- if(bytes_read > 0){
482
- #ifdef HAVE_ST_LL_TIME
483
- if(log.ll_time != 0)
484
- rb_iv_set(v_user, "@login_time", rb_time_new(log.ll_time, 0));
485
- #endif
486
- rb_iv_set(v_user, "@login_device", rb_str_new2(log.ll_line));
487
- rb_iv_set(v_user, "@login_host", rb_str_new2(log.ll_host));
488
- }
489
- #endif
490
- #endif
491
-
492
- return 0;
493
- }
494
-
495
- /*
496
- * :no-doc:
497
- *
498
- * This function is used for an rb_ensure() call where we need to make sure
499
- * that endpwent() is called in the block form of Admin.groups.
500
- */
501
- static VALUE admin_groups_cleanup(){
502
- endgrent();
503
- return Qnil;
504
- }
505
-
506
- /*
507
- * :no-doc:
508
- *
509
- * This function is used for an rb_ensure() call where we need to make sure
510
- * that endpwent() is called in the block form of Admin.users.
511
- */
512
- static VALUE admin_users_cleanup(){
513
- endpwent();
514
- return Qnil;
515
- }