pam 1.5.2
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/COPYING +15 -0
- data/ChangeLog +68 -0
- data/LICENSE +510 -0
- data/MANIFEST +12 -0
- data/README +102 -0
- data/Rakefile +100 -0
- data/ext/extconf.rb +29 -0
- data/ext/pam.c +164 -0
- data/ext/pam.h +47 -0
- data/ext/pam_handle.c +685 -0
- data/test/check_conv.rb +54 -0
- data/test/check_get_item.rb +47 -0
- data/test/check_user.rb +114 -0
- metadata +58 -0
data/ext/pam_handle.c
ADDED
@@ -0,0 +1,685 @@
|
|
1
|
+
/* -*- C -*-
|
2
|
+
* $Id: pam_handle.c,v 1.2 2002/12/21 22:09:35 ttate Exp $
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "pam.h"
|
6
|
+
|
7
|
+
VALUE rb_cPAMHandle;
|
8
|
+
|
9
|
+
static int
|
10
|
+
rb_pam_inner_conv(int num_msg,
|
11
|
+
const struct pam_message **msg,
|
12
|
+
struct pam_response **resp,
|
13
|
+
void *appdata_ptr)
|
14
|
+
{
|
15
|
+
VALUE func = rb_ary_entry((VALUE)appdata_ptr,0);
|
16
|
+
VALUE data = rb_ary_entry((VALUE)appdata_ptr,1);
|
17
|
+
VALUE rmsg = Qnil;
|
18
|
+
VALUE rres = Qnil;
|
19
|
+
struct pam_response *reply = NULL;
|
20
|
+
int i;
|
21
|
+
|
22
|
+
rmsg = rb_ary_new();
|
23
|
+
for( i = 0; i < num_msg; i++ ){
|
24
|
+
VALUE m_msg;
|
25
|
+
VALUE m_style;
|
26
|
+
|
27
|
+
m_msg = msg[i]->msg ? rb_tainted_str_new2(msg[i]->msg) : Qnil;
|
28
|
+
m_style = INT2NUM(msg[i]->msg_style);
|
29
|
+
rb_ary_push(rmsg,
|
30
|
+
rb_struct_new(rb_sPAMMessage, m_style, m_msg, 0));
|
31
|
+
};
|
32
|
+
|
33
|
+
/* An exception will be raised. */
|
34
|
+
if( SYMBOL_P(func) ){
|
35
|
+
rres = rb_funcall(rb_mKernel, SYM2ID(func), 2, rmsg, data);
|
36
|
+
}
|
37
|
+
else{
|
38
|
+
rres = rb_funcall(func, rb_intern("call"), 2, rmsg, data);
|
39
|
+
};
|
40
|
+
|
41
|
+
if( TYPE(rres) != T_ARRAY ){
|
42
|
+
rb_raise(rb_eTypeError,"return type must be Array of PAM::Response");
|
43
|
+
};
|
44
|
+
|
45
|
+
/*
|
46
|
+
while( RARRAY(rres)->len < num_msg ){
|
47
|
+
rb_ary_push(rres,Qnil);
|
48
|
+
};
|
49
|
+
*/
|
50
|
+
|
51
|
+
reply = (struct pam_response *)malloc(sizeof(struct pam_response) * num_msg);
|
52
|
+
if( !reply ){
|
53
|
+
rb_raise(rb_eRuntimeError,"can't allocate the memory");
|
54
|
+
};
|
55
|
+
for( i = 0; i < num_msg; i++ ){
|
56
|
+
VALUE rrep = rb_ary_entry(rres,i);
|
57
|
+
if( rrep != Qnil ){
|
58
|
+
VALUE r_resp = rb_struct_getmember(rrep,rb_intern("resp"));
|
59
|
+
VALUE r_retcode = rb_struct_getmember(rrep,rb_intern("resp_retcode"));
|
60
|
+
|
61
|
+
reply[i].resp = ((r_resp != Qnil) ? strdup(STR2CSTR(r_resp)) : NULL);
|
62
|
+
reply[i].resp_retcode = ((r_retcode != Qnil) ? NUM2INT(r_retcode) : 0);
|
63
|
+
}
|
64
|
+
else{
|
65
|
+
reply[i].resp = NULL;
|
66
|
+
reply[i].resp_retcode = 0;
|
67
|
+
};
|
68
|
+
};
|
69
|
+
*resp = reply;
|
70
|
+
|
71
|
+
return PAM_SUCCESS;
|
72
|
+
};
|
73
|
+
|
74
|
+
#define CREATE_PAM_CONV(arg_conv,arg_data) { \
|
75
|
+
arg_conv = (struct pam_conv *)malloc(sizeof(struct pam_conv)); \
|
76
|
+
arg_conv->conv = rb_pam_inner_conv; \
|
77
|
+
arg_conv->appdata_ptr = (void*)arg_data; \
|
78
|
+
}
|
79
|
+
|
80
|
+
#define CREATE_PAM_CONV2(arg_conv,arg_proc,arg_data) { \
|
81
|
+
arg_conv = (struct pam_conv *)malloc(sizeof(struct pam_conv)); \
|
82
|
+
arg_conv->conv = rb_pam_inner_conv; \
|
83
|
+
arg_conv->appdata_ptr = (void*)rb_assoc_new(arg_proc,arg_data); \
|
84
|
+
}
|
85
|
+
|
86
|
+
static void
|
87
|
+
rb_pam_handle_free(struct rb_pam_struct *pam)
|
88
|
+
{
|
89
|
+
if( pam && pam->start ){
|
90
|
+
pam_end(pam->ptr,pam->status);
|
91
|
+
pam->start = 0;
|
92
|
+
if( pam->conv ){
|
93
|
+
free(pam->conv);
|
94
|
+
};
|
95
|
+
};
|
96
|
+
};
|
97
|
+
|
98
|
+
static void
|
99
|
+
rb_pam_handle_gc_mark(struct rb_pam_struct *pam)
|
100
|
+
{
|
101
|
+
if( pam && pam->start && pam->conv ){
|
102
|
+
rb_gc_mark((VALUE)(pam->conv->appdata_ptr));
|
103
|
+
};
|
104
|
+
};
|
105
|
+
|
106
|
+
VALUE
|
107
|
+
rb_pam_handle_new(pam_handle_t *pamh)
|
108
|
+
{
|
109
|
+
VALUE obj;
|
110
|
+
struct rb_pam_struct *pam;
|
111
|
+
|
112
|
+
obj = Data_Make_Struct(rb_cPAMHandle,struct rb_pam_struct,
|
113
|
+
rb_pam_handle_gc_mark,rb_pam_handle_free,pam);
|
114
|
+
pam->ptr = pamh;
|
115
|
+
pam->start = 0;
|
116
|
+
pam->status = PAM_SUCCESS;
|
117
|
+
pam->conv = NULL;
|
118
|
+
|
119
|
+
return obj;
|
120
|
+
};
|
121
|
+
|
122
|
+
VALUE
|
123
|
+
rb_pam_handle_s_allocate(VALUE klass)
|
124
|
+
{
|
125
|
+
VALUE obj;
|
126
|
+
struct rb_pam_struct *pam;
|
127
|
+
|
128
|
+
obj = Data_Make_Struct(rb_cPAMHandle, struct rb_pam_struct,
|
129
|
+
rb_pam_handle_gc_mark, rb_pam_handle_free, pam);
|
130
|
+
pam->ptr = 0;
|
131
|
+
pam->start = 0;
|
132
|
+
pam->status = 0;
|
133
|
+
pam->conv = NULL;
|
134
|
+
|
135
|
+
return obj;
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE
|
139
|
+
rb_pam_handle_initialize(int argc, VALUE argv[], VALUE self)
|
140
|
+
{
|
141
|
+
struct rb_pam_struct *pam;
|
142
|
+
pam_handle_t *pamh = NULL;
|
143
|
+
char *c_service = NULL;
|
144
|
+
char *c_user = NULL;
|
145
|
+
struct pam_conv *c_conv = NULL;
|
146
|
+
VALUE service, user, conv, data;
|
147
|
+
int status;
|
148
|
+
|
149
|
+
switch( rb_scan_args(argc, argv, "31", &service, &user, &conv, &data) ){
|
150
|
+
case 3:
|
151
|
+
c_service = STR2CSTR(service);
|
152
|
+
c_user = STR2CSTR(user);
|
153
|
+
CREATE_PAM_CONV2(c_conv,conv,Qnil);
|
154
|
+
break;
|
155
|
+
case 4:
|
156
|
+
c_service = STR2CSTR(service);
|
157
|
+
c_user = STR2CSTR(user);
|
158
|
+
CREATE_PAM_CONV2(c_conv,conv,data);
|
159
|
+
break;
|
160
|
+
default:
|
161
|
+
rb_bug("rb_pam_handle_s_start");
|
162
|
+
};
|
163
|
+
|
164
|
+
if( (status = pam_start(c_service, c_user, c_conv, &pamh)) == PAM_SUCCESS ){
|
165
|
+
Data_Get_Struct(self, struct rb_pam_struct, pam);
|
166
|
+
if( pam->ptr && pam->start ){
|
167
|
+
pam_end(pam->ptr, pam->status);
|
168
|
+
}
|
169
|
+
if( pam->conv ){
|
170
|
+
free(pam->conv);
|
171
|
+
}
|
172
|
+
pam->ptr = pamh;
|
173
|
+
pam->start = 1;
|
174
|
+
pam->status = status;
|
175
|
+
pam->conv = c_conv;
|
176
|
+
}
|
177
|
+
else{
|
178
|
+
rb_pam_raise(status, "pam_start");
|
179
|
+
};
|
180
|
+
|
181
|
+
if( rb_block_given_p() ){
|
182
|
+
rb_ensure(rb_yield,self,rb_pam_handle_end,self);
|
183
|
+
};
|
184
|
+
|
185
|
+
return Qnil;
|
186
|
+
};
|
187
|
+
|
188
|
+
VALUE
|
189
|
+
rb_pam_handle_s_start(int argc, VALUE argv[], VALUE klass)
|
190
|
+
{
|
191
|
+
VALUE obj;
|
192
|
+
|
193
|
+
obj = rb_pam_handle_s_allocate(klass);
|
194
|
+
rb_obj_call_init(obj, argc, argv);
|
195
|
+
|
196
|
+
return obj;
|
197
|
+
}
|
198
|
+
|
199
|
+
VALUE
|
200
|
+
rb_pam_handle_end(VALUE self)
|
201
|
+
{
|
202
|
+
struct rb_pam_struct *pam;
|
203
|
+
int c_retval;
|
204
|
+
VALUE retval;
|
205
|
+
|
206
|
+
Data_Get_Struct(self, struct rb_pam_struct, pam);
|
207
|
+
|
208
|
+
if( ! pam->start ){
|
209
|
+
rb_pam_raise(0, "pam hander is invalid");
|
210
|
+
};
|
211
|
+
pam->start = 0;
|
212
|
+
|
213
|
+
if( (pam->status = pam_end(pam->ptr,pam->status)) != PAM_SUCCESS ){
|
214
|
+
rb_pam_raise(pam->status, "pam_end");
|
215
|
+
};
|
216
|
+
|
217
|
+
if( pam->conv ){
|
218
|
+
free(pam->conv);
|
219
|
+
};
|
220
|
+
|
221
|
+
return Qnil;
|
222
|
+
};
|
223
|
+
|
224
|
+
VALUE
|
225
|
+
rb_pam_handle_conv(VALUE self, VALUE ary)
|
226
|
+
{
|
227
|
+
struct rb_pam_struct *pam;
|
228
|
+
struct pam_conv *conv;
|
229
|
+
struct pam_message **msg;
|
230
|
+
struct pam_response *resp;
|
231
|
+
int status, i, msg_len;
|
232
|
+
VALUE r;
|
233
|
+
|
234
|
+
Check_Type(ary, T_ARRAY);
|
235
|
+
Data_Get_Struct(self, struct rb_pam_struct, pam);
|
236
|
+
status = pam_get_item(pam->ptr, PAM_CONV, (void*)(&conv));
|
237
|
+
if( status != PAM_SUCCESS || !conv )
|
238
|
+
rb_pam_raise(status, "rb_pam_handle_conv");
|
239
|
+
|
240
|
+
msg_len = RARRAY(ary)->len;
|
241
|
+
msg = (struct pam_message **)ALLOCA_N(struct pam_message *, msg_len);
|
242
|
+
for( i=0; i<msg_len; i++ ){
|
243
|
+
VALUE elem = RARRAY(ary)->ptr[i];
|
244
|
+
VALUE m_style, m_msg;
|
245
|
+
m_style = rb_struct_getmember(elem, rb_intern("msg_style"));
|
246
|
+
m_msg = rb_struct_getmember(elem, rb_intern("msg"));
|
247
|
+
msg[i] = (struct pam_message *)ALLOCA_N(struct pam_message, 1);
|
248
|
+
msg[i]->msg_style = NUM2INT(m_style);
|
249
|
+
if( m_msg == Qnil ){
|
250
|
+
msg[i]->msg = NULL;
|
251
|
+
}
|
252
|
+
else{
|
253
|
+
msg[i]->msg = (char*)ALLOCA_N(char, RSTRING(m_msg)->len + 1);
|
254
|
+
strcpy((char*)(msg[i]->msg), STR2CSTR(m_msg));
|
255
|
+
};
|
256
|
+
};
|
257
|
+
|
258
|
+
resp = NULL;
|
259
|
+
status = (*(conv->conv))(msg_len, (const struct pam_message **)msg,
|
260
|
+
&resp, conv->appdata_ptr);
|
261
|
+
if( status != PAM_SUCCESS || !resp ){
|
262
|
+
rb_pam_raise(status, "conversation error");
|
263
|
+
};
|
264
|
+
|
265
|
+
/*
|
266
|
+
* note that 'resp' is allocated by the application and is
|
267
|
+
* correctly free()'d here
|
268
|
+
*/
|
269
|
+
r = rb_ary_new();
|
270
|
+
for( i=0; i<msg_len; i++ ){
|
271
|
+
VALUE elem;
|
272
|
+
VALUE r_resp;
|
273
|
+
VALUE r_retcode;
|
274
|
+
if( resp[i].resp ){
|
275
|
+
r_resp = rb_tainted_str_new2(resp[i].resp);
|
276
|
+
free(resp[i].resp);
|
277
|
+
}
|
278
|
+
else{
|
279
|
+
r_resp = Qnil;
|
280
|
+
};
|
281
|
+
r_retcode = INT2NUM(resp[i].resp_retcode);
|
282
|
+
elem = rb_struct_new(rb_sPAMResponse, r_resp, r_retcode, 0);
|
283
|
+
rb_ary_push(r, elem);
|
284
|
+
};
|
285
|
+
free(resp);
|
286
|
+
|
287
|
+
return r;
|
288
|
+
};
|
289
|
+
|
290
|
+
VALUE
|
291
|
+
rb_pam_handle_status(VALUE self)
|
292
|
+
{
|
293
|
+
struct rb_pam_struct *pam;
|
294
|
+
|
295
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
296
|
+
return INT2NUM(pam->status);
|
297
|
+
};
|
298
|
+
|
299
|
+
VALUE
|
300
|
+
rb_pam_handle_authenticate(int argc, VALUE argv[], VALUE self)
|
301
|
+
{
|
302
|
+
struct rb_pam_struct *pam;
|
303
|
+
int c_flag;
|
304
|
+
VALUE flag;
|
305
|
+
|
306
|
+
switch( rb_scan_args(argc, argv, "01", &flag) ){
|
307
|
+
case 0:
|
308
|
+
c_flag = 0;
|
309
|
+
break;
|
310
|
+
case 1:
|
311
|
+
if( flag == Qnil ){
|
312
|
+
c_flag = 0;
|
313
|
+
}
|
314
|
+
else{
|
315
|
+
c_flag = NUM2INT(flag);
|
316
|
+
};
|
317
|
+
break;
|
318
|
+
default:
|
319
|
+
rb_bug("rb_pam_handle_authenticate");
|
320
|
+
}
|
321
|
+
|
322
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
323
|
+
if( (pam->status = pam_authenticate(pam->ptr,c_flag)) != PAM_SUCCESS ){
|
324
|
+
rb_pam_raise(pam->status, "pam_authenticate");
|
325
|
+
};
|
326
|
+
|
327
|
+
return Qnil;
|
328
|
+
};
|
329
|
+
|
330
|
+
VALUE
|
331
|
+
rb_pam_handle_acct_mgmt(int argc, VALUE argv[], VALUE self)
|
332
|
+
{
|
333
|
+
struct rb_pam_struct *pam;
|
334
|
+
int c_flag;
|
335
|
+
VALUE flag;
|
336
|
+
|
337
|
+
switch( rb_scan_args(argc, argv, "01", &flag) ){
|
338
|
+
case 0:
|
339
|
+
c_flag = 0;
|
340
|
+
break;
|
341
|
+
case 1:
|
342
|
+
if( flag == Qnil ){
|
343
|
+
c_flag = 0;
|
344
|
+
}
|
345
|
+
else{
|
346
|
+
c_flag = NUM2INT(flag);
|
347
|
+
};
|
348
|
+
break;
|
349
|
+
default:
|
350
|
+
rb_bug("rb_pam_handle_acct_mgmt");
|
351
|
+
};
|
352
|
+
|
353
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
354
|
+
if( (pam->status = pam_acct_mgmt(pam->ptr,c_flag)) != PAM_SUCCESS ){
|
355
|
+
rb_pam_raise(pam->status, "pam_acct_mgmt");
|
356
|
+
};
|
357
|
+
|
358
|
+
return Qnil;
|
359
|
+
};
|
360
|
+
|
361
|
+
VALUE
|
362
|
+
rb_pam_handle_set_fail_delay(VALUE self, VALUE msec)
|
363
|
+
{
|
364
|
+
#ifdef HAVE_PAM_FAIL_DELAY
|
365
|
+
struct rb_pam_struct *pam;
|
366
|
+
int c_msec;
|
367
|
+
|
368
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
369
|
+
c_msec = NUM2INT(msec);
|
370
|
+
if( (pam->status = pam_fail_delay(pam->ptr,c_msec)) != PAM_SUCCESS ){
|
371
|
+
rb_pam_raise(pam->status, "pam_fail_delay");
|
372
|
+
};
|
373
|
+
#else
|
374
|
+
rb_notimplement();
|
375
|
+
#endif
|
376
|
+
|
377
|
+
return Qnil;
|
378
|
+
};
|
379
|
+
|
380
|
+
VALUE
|
381
|
+
rb_pam_handle_setcred(int argc, VALUE argv[], VALUE self)
|
382
|
+
{
|
383
|
+
#ifdef HAVE_PAM_SETCRED
|
384
|
+
struct rb_pam_struct *pam;
|
385
|
+
int c_flag;
|
386
|
+
VALUE flag;
|
387
|
+
|
388
|
+
switch( rb_scan_args(argc, argv, "01", &flag) ){
|
389
|
+
case 0:
|
390
|
+
c_flag = 0;
|
391
|
+
break;
|
392
|
+
case 1:
|
393
|
+
if( flag == Qnil ){
|
394
|
+
c_flag = 0;
|
395
|
+
}
|
396
|
+
else{
|
397
|
+
c_flag = NUM2INT(flag);
|
398
|
+
};
|
399
|
+
break;
|
400
|
+
default:
|
401
|
+
rb_bug("rb_pam_handle_setcred");
|
402
|
+
};
|
403
|
+
|
404
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
405
|
+
if( (pam->status = pam_setcred(pam->ptr,c_flag)) != PAM_SUCCESS ){
|
406
|
+
rb_pam_raise(pam->status,"pam_setcred");
|
407
|
+
};
|
408
|
+
#else
|
409
|
+
rb_notimplement();
|
410
|
+
#endif
|
411
|
+
|
412
|
+
return Qnil;
|
413
|
+
};
|
414
|
+
|
415
|
+
VALUE
|
416
|
+
rb_pam_handle_chauthtok(int argc, VALUE argv[], VALUE self)
|
417
|
+
{
|
418
|
+
#ifdef HAVE_PAM_CHAUTHTOK
|
419
|
+
struct rb_pam_struct *pam;
|
420
|
+
int c_flag;
|
421
|
+
VALUE flag;
|
422
|
+
|
423
|
+
switch( rb_scan_args(argc, argv, "01", &flag) ){
|
424
|
+
case 0:
|
425
|
+
c_flag = 0;
|
426
|
+
break;
|
427
|
+
case 1:
|
428
|
+
if( flag == Qnil ){
|
429
|
+
c_flag = 0;
|
430
|
+
}
|
431
|
+
else{
|
432
|
+
c_flag = NUM2INT(flag);
|
433
|
+
};
|
434
|
+
break;
|
435
|
+
default:
|
436
|
+
rb_bug("rb_pam_handle_chauthtok");
|
437
|
+
};
|
438
|
+
|
439
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
440
|
+
c_flag = NUM2INT(flag);
|
441
|
+
if( (pam->status = pam_chauthtok(pam->ptr,c_flag)) != PAM_SUCCESS ){
|
442
|
+
rb_pam_raise(pam->status, "pam_chauthtok");
|
443
|
+
};
|
444
|
+
#else
|
445
|
+
rb_notimplement();
|
446
|
+
#endif
|
447
|
+
|
448
|
+
return Qnil;
|
449
|
+
};
|
450
|
+
|
451
|
+
|
452
|
+
VALUE
|
453
|
+
rb_pam_handle_close_session(int argc, VALUE argv[], VALUE self)
|
454
|
+
{
|
455
|
+
#ifdef HAVE_PAM_CLOSE_SESSION
|
456
|
+
struct rb_pam_struct *pam;
|
457
|
+
int c_flag;
|
458
|
+
VALUE flag;
|
459
|
+
|
460
|
+
switch( rb_scan_args(argc, argv, "01", &flag) ){
|
461
|
+
case 0:
|
462
|
+
c_flag = 0;
|
463
|
+
break;
|
464
|
+
case 1:
|
465
|
+
if( flag == Qnil ){
|
466
|
+
c_flag = 0;
|
467
|
+
}
|
468
|
+
else{
|
469
|
+
c_flag = NUM2INT(flag);
|
470
|
+
};
|
471
|
+
break;
|
472
|
+
default:
|
473
|
+
rb_bug("rb_pam_handle_close_session");
|
474
|
+
};
|
475
|
+
|
476
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
477
|
+
if( (pam->status = pam_close_session(pam->ptr,c_flag)) != PAM_SUCCESS ){
|
478
|
+
rb_pam_raise(pam->status,"pam_close_session");
|
479
|
+
};
|
480
|
+
#else
|
481
|
+
rb_notimplement();
|
482
|
+
#endif
|
483
|
+
|
484
|
+
return Qnil;
|
485
|
+
};
|
486
|
+
|
487
|
+
static VALUE
|
488
|
+
rb_pam_handle_open_session_ensure(VALUE self)
|
489
|
+
{
|
490
|
+
return rb_pam_handle_close_session(0, 0, self);
|
491
|
+
};
|
492
|
+
|
493
|
+
VALUE
|
494
|
+
rb_pam_handle_open_session(int argc, VALUE argv[], VALUE self)
|
495
|
+
{
|
496
|
+
#ifdef HAVE_PAM_OPEN_SESSION
|
497
|
+
struct rb_pam_struct *pam;
|
498
|
+
int c_flag;
|
499
|
+
VALUE flag;
|
500
|
+
|
501
|
+
switch( rb_scan_args(argc, argv, "01", &flag) ){
|
502
|
+
case 0:
|
503
|
+
c_flag = 0;
|
504
|
+
break;
|
505
|
+
case 1:
|
506
|
+
if( flag == Qnil ){
|
507
|
+
c_flag = 0;
|
508
|
+
}
|
509
|
+
else{
|
510
|
+
c_flag = NUM2INT(flag);
|
511
|
+
};
|
512
|
+
break;
|
513
|
+
default:
|
514
|
+
rb_bug("rb_pam_handle_open_session");
|
515
|
+
};
|
516
|
+
|
517
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
518
|
+
if( (pam->status = pam_open_session(pam->ptr,c_flag)) != PAM_SUCCESS ){
|
519
|
+
rb_pam_raise(pam->status,"pam_open_session");
|
520
|
+
};
|
521
|
+
#else
|
522
|
+
rb_notimplement();
|
523
|
+
#endif
|
524
|
+
|
525
|
+
if( rb_block_given_p() ){
|
526
|
+
rb_ensure(rb_yield, self, rb_pam_handle_open_session_ensure, self);
|
527
|
+
};
|
528
|
+
|
529
|
+
return Qnil;
|
530
|
+
};
|
531
|
+
|
532
|
+
|
533
|
+
VALUE
|
534
|
+
rb_pam_handle_set_item(VALUE self, VALUE type, VALUE item)
|
535
|
+
{
|
536
|
+
struct rb_pam_struct *pam;
|
537
|
+
void *c_item;
|
538
|
+
int c_type;
|
539
|
+
|
540
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
541
|
+
c_type = NUM2INT(type);
|
542
|
+
switch( c_type ){
|
543
|
+
case PAM_SERVICE:
|
544
|
+
case PAM_USER:
|
545
|
+
case PAM_TTY:
|
546
|
+
case PAM_RHOST:
|
547
|
+
case PAM_RUSER:
|
548
|
+
case PAM_USER_PROMPT:
|
549
|
+
c_item = (void*)STR2CSTR(item);
|
550
|
+
break;
|
551
|
+
case PAM_CONV:
|
552
|
+
{
|
553
|
+
struct pam_conv *c_conv;
|
554
|
+
CREATE_PAM_CONV(c_conv,item);
|
555
|
+
free(pam->conv);
|
556
|
+
pam->conv = c_conv;
|
557
|
+
c_item = (void*)c_conv;
|
558
|
+
};
|
559
|
+
break;
|
560
|
+
default:
|
561
|
+
rb_raise(rb_eArgError,"unkown item type");
|
562
|
+
};
|
563
|
+
pam->status = pam_set_item(pam->ptr,c_type,c_item);
|
564
|
+
return INT2NUM(pam->status);
|
565
|
+
};
|
566
|
+
|
567
|
+
VALUE
|
568
|
+
rb_pam_handle_get_item(VALUE self, VALUE type)
|
569
|
+
{
|
570
|
+
struct rb_pam_struct *pam;
|
571
|
+
const void *c_item;
|
572
|
+
int c_type;
|
573
|
+
VALUE ret;
|
574
|
+
|
575
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
576
|
+
c_type = NUM2INT(type);
|
577
|
+
pam->status = pam_get_item(pam->ptr,c_type,&c_item);
|
578
|
+
|
579
|
+
if( !c_item ){
|
580
|
+
return Qnil;
|
581
|
+
};
|
582
|
+
|
583
|
+
switch( c_type ){
|
584
|
+
case PAM_SERVICE:
|
585
|
+
case PAM_USER:
|
586
|
+
case PAM_TTY:
|
587
|
+
case PAM_RHOST:
|
588
|
+
case PAM_RUSER:
|
589
|
+
case PAM_USER_PROMPT:
|
590
|
+
ret = rb_str_new2((char*)c_item);
|
591
|
+
break;
|
592
|
+
case PAM_CONV:
|
593
|
+
{
|
594
|
+
struct pam_conv *conv = (struct pam_conv *)c_item;
|
595
|
+
if( conv->conv == rb_pam_inner_conv ){
|
596
|
+
ret = (VALUE)(conv->appdata_ptr);
|
597
|
+
}
|
598
|
+
else{
|
599
|
+
ret = rb_assoc_new(INT2NUM((long)(conv->conv)),
|
600
|
+
INT2NUM((long)(conv->appdata_ptr)));
|
601
|
+
};
|
602
|
+
}
|
603
|
+
break;
|
604
|
+
default:
|
605
|
+
rb_raise(rb_eArgError,"unknown item type");
|
606
|
+
};
|
607
|
+
|
608
|
+
return ret;
|
609
|
+
};
|
610
|
+
|
611
|
+
VALUE
|
612
|
+
rb_pam_handle_strerror(VALUE self, VALUE errnum)
|
613
|
+
{
|
614
|
+
struct rb_pam_struct *pam;
|
615
|
+
const char *str;
|
616
|
+
|
617
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
618
|
+
pam->status = -1;
|
619
|
+
return( (str = pam_strerror(pam->ptr,NUM2INT(errnum))) ? rb_str_new2(str) : Qnil);
|
620
|
+
};
|
621
|
+
|
622
|
+
VALUE
|
623
|
+
rb_pam_handle_putenv(VALUE self, VALUE val)
|
624
|
+
{
|
625
|
+
#ifdef HAVE_PAM_PUTENV
|
626
|
+
struct rb_pam_struct *pam;
|
627
|
+
|
628
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
629
|
+
pam->status = -1;
|
630
|
+
return INT2NUM(pam_putenv(pam->ptr,STR2CSTR(val)));
|
631
|
+
#else
|
632
|
+
rb_notimplemented();
|
633
|
+
#endif
|
634
|
+
};
|
635
|
+
|
636
|
+
VALUE
|
637
|
+
rb_pam_handle_getenv(VALUE self, VALUE val)
|
638
|
+
{
|
639
|
+
#ifdef HAVE_PAM_GETENV
|
640
|
+
struct rb_pam_struct *pam;
|
641
|
+
const char *str;
|
642
|
+
|
643
|
+
Data_Get_Struct(self,struct rb_pam_struct,pam);
|
644
|
+
pam->status = -1;
|
645
|
+
return( (str = pam_getenv(pam->ptr,STR2CSTR(val))) ? rb_str_new2(str) : Qnil);
|
646
|
+
#else
|
647
|
+
rb_notimplemented();
|
648
|
+
#endif
|
649
|
+
};
|
650
|
+
|
651
|
+
void
|
652
|
+
Init_pam_handle()
|
653
|
+
{
|
654
|
+
rb_cPAMHandle = rb_define_class_under(rb_mPAM,"Handle",rb_cObject);
|
655
|
+
#if RUBY_VERSION_CODE < 170
|
656
|
+
rb_define_singleton_method(rb_cPAMHandle,"new",rb_pam_handle_s_start,-1);
|
657
|
+
#endif
|
658
|
+
rb_define_singleton_method(rb_cPAMHandle,"start",rb_pam_handle_s_start,-1);
|
659
|
+
#if RUBY_VERSION_CODE >= 173
|
660
|
+
rb_define_alloc_func(rb_cPAMHandle,rb_pam_handle_s_allocate);
|
661
|
+
#else
|
662
|
+
rb_define_singleton_method(rb_cPAMHandle,"allocate",rb_pam_handle_s_allocate,0);
|
663
|
+
#endif
|
664
|
+
|
665
|
+
#define rb_pamh_define_method(name,func,argc) \
|
666
|
+
rb_define_method(rb_cPAMHandle,name,func,argc)
|
667
|
+
rb_pamh_define_method("conv", rb_pam_handle_conv, 1);
|
668
|
+
rb_pamh_define_method("initialize", rb_pam_handle_initialize, -1);
|
669
|
+
rb_pamh_define_method("status",rb_pam_handle_status,0);
|
670
|
+
rb_pamh_define_method("end",rb_pam_handle_end,0);
|
671
|
+
rb_pamh_define_method("authenticate",rb_pam_handle_authenticate,-1);
|
672
|
+
rb_pamh_define_method("acct_mgmt",rb_pam_handle_acct_mgmt,-1);
|
673
|
+
rb_pamh_define_method("set_fail_delay",rb_pam_handle_set_fail_delay,1);
|
674
|
+
rb_pamh_define_method("setcred",rb_pam_handle_setcred,-1);
|
675
|
+
rb_pamh_define_method("chauthtok",rb_pam_handle_chauthtok,-1);
|
676
|
+
rb_pamh_define_method("open_session",rb_pam_handle_open_session,-1);
|
677
|
+
rb_pamh_define_method("close_session",rb_pam_handle_close_session,-1);
|
678
|
+
rb_pamh_define_method("set_item",rb_pam_handle_set_item,2);
|
679
|
+
rb_pamh_define_method("get_item",rb_pam_handle_get_item,1);
|
680
|
+
rb_pamh_define_method("strerror",rb_pam_handle_strerror,1);
|
681
|
+
rb_pamh_define_method("putenv",rb_pam_handle_putenv,1);
|
682
|
+
rb_pamh_define_method("getenv",rb_pam_handle_getenv,1);
|
683
|
+
#undef rb_pamh_define_method
|
684
|
+
|
685
|
+
};
|
data/test/check_conv.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# $Id: check_conv.rb,v 1.1.1.1 2002/11/06 08:04:49 ttate Exp $
|
3
|
+
|
4
|
+
require "pam"
|
5
|
+
|
6
|
+
def pam_conv(msgs, data)
|
7
|
+
ret = []
|
8
|
+
|
9
|
+
msgs.each{|msg|
|
10
|
+
case msg.msg_style
|
11
|
+
when PAM::PAM_PROMPT_ECHO_ON
|
12
|
+
printf(msg.msg)
|
13
|
+
if( str = $stdin.gets )
|
14
|
+
str.chomp!
|
15
|
+
end
|
16
|
+
ret.push(PAM::Response.new(str,0))
|
17
|
+
when PAM::PAM_PROMPT_ECHO_OFF
|
18
|
+
printf(msg.msg)
|
19
|
+
`stty -echo`
|
20
|
+
begin
|
21
|
+
if( str = $stdin.gets )
|
22
|
+
str.chomp!
|
23
|
+
end
|
24
|
+
ensure
|
25
|
+
`stty echo`
|
26
|
+
end
|
27
|
+
ret.push(PAM::Response.new(str, 0))
|
28
|
+
else
|
29
|
+
# unexpected, bug?
|
30
|
+
ret.push(PAM::Response.new(nil, 0))
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
ret
|
35
|
+
end
|
36
|
+
|
37
|
+
if( ARGV[0] && ARGV[1] )
|
38
|
+
service = ARGV[0]
|
39
|
+
user = ARGV[1]
|
40
|
+
else
|
41
|
+
print("usage:\n #{$0} <service> <user>\n")
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
conv = proc{|msg| pam_conv(msg)}
|
45
|
+
conv_data = user
|
46
|
+
|
47
|
+
# PAM.start("check_user", user, conv){|pam|
|
48
|
+
PAM.start(service, user, :pam_conv, conv_data){|pam|
|
49
|
+
msg = [PAM::Message.new(PAM::PAM_PROMPT_ECHO_ON, "login: "),
|
50
|
+
PAM::Message.new(PAM::PAM_PROMPT_ECHO_OFF, "passwd: ")]
|
51
|
+
p msg
|
52
|
+
rs = pam.conv(msg)
|
53
|
+
p rs
|
54
|
+
}
|