kerberos 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +11 -0
- data/bin/example.rb +55 -0
- data/ext/admin.h +517 -0
- data/ext/extconf.rb +12 -0
- data/ext/krb5.h +3011 -0
- data/ext/ruby_kerberos.c +362 -0
- data/ext/ruby_kerberos.h +25 -0
- data/lib/kerberos.rb +18 -0
- metadata +52 -0
data/ext/ruby_kerberos.c
ADDED
@@ -0,0 +1,362 @@
|
|
1
|
+
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "krb5.h"
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <strings.h>
|
6
|
+
#include "admin.h"
|
7
|
+
#include "ruby_kerberos.h"
|
8
|
+
|
9
|
+
static VALUE mKerberos;
|
10
|
+
static VALUE cKrb5;
|
11
|
+
static VALUE cKadm5;
|
12
|
+
int kadm5_error_number = 0;
|
13
|
+
int krb5_error_number = 0;
|
14
|
+
void *kadm5_handle = NULL;
|
15
|
+
|
16
|
+
static VALUE Kadm5_errstr(VALUE self);
|
17
|
+
int Kadm55_register_error(int error);
|
18
|
+
static VALUE Kadm5_init_with_password(VALUE self,VALUE _auser,VALUE _apass);
|
19
|
+
static VALUE Kadm5_create_principal(VALUE self, VALUE _user, VALUE _pass, VALUE options);
|
20
|
+
static VALUE Kadm5_delete_principal(VALUE self, VALUE _auser);
|
21
|
+
|
22
|
+
static VALUE Krb5_errstr(VALUE self);
|
23
|
+
int Krb5_register_error(int error);
|
24
|
+
static VALUE Krb5_change_password(VALUE self, VALUE _user, VALUE _pass, VALUE _newpass);
|
25
|
+
static VALUE Krb5_get_init_creds_password(VALUE self, VALUE _user, VALUE _pass);
|
26
|
+
|
27
|
+
|
28
|
+
int Krb5_register_error(int error) {
|
29
|
+
krb5_error_number = error;
|
30
|
+
return 0;
|
31
|
+
}
|
32
|
+
|
33
|
+
int Kadm5_register_error(int error) {
|
34
|
+
kadm5_error_number = error;
|
35
|
+
return 0;
|
36
|
+
}
|
37
|
+
|
38
|
+
/* returns the last error message generated or nil */
|
39
|
+
static VALUE Kadm5_errstr(VALUE self) {
|
40
|
+
char error[255];
|
41
|
+
if (kadm5_error_number == 0) {
|
42
|
+
return Qnil;
|
43
|
+
}
|
44
|
+
strncpy(error,error_message(kadm5_error_number), sizeof(error));
|
45
|
+
error[sizeof(error) - 1] = '\0';
|
46
|
+
VALUE kerror = rb_str_new2(error);
|
47
|
+
return kerror;
|
48
|
+
}
|
49
|
+
|
50
|
+
/* returns the last error message generated or nil */
|
51
|
+
static VALUE Krb5_errstr(VALUE self) {
|
52
|
+
char error[255];
|
53
|
+
if (kadm5_error_number == 0) {
|
54
|
+
return Qnil;
|
55
|
+
}
|
56
|
+
strncpy(error,error_message(krb5_error_number), sizeof(error));
|
57
|
+
error[sizeof(error) - 1] = '\0';
|
58
|
+
VALUE kerror = rb_str_new2(error);
|
59
|
+
return kerror;
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
/*
|
64
|
+
Initializes a connection to the kdc using an administrative user. This method must be called before any other Kadm5 methods.
|
65
|
+
Returns true on success, false on falure. The reason for a failure can be found in Kadm5.errstr
|
66
|
+
*p1 = username
|
67
|
+
*p2 = password
|
68
|
+
*/
|
69
|
+
static VALUE Kadm5_init_with_password(VALUE self, VALUE _auser, VALUE _apass) {
|
70
|
+
Check_Type(_auser,T_STRING);
|
71
|
+
Check_Type(_apass,T_STRING);
|
72
|
+
char * auser = STR2CSTR(_auser);
|
73
|
+
char * apass = STR2CSTR(_apass);
|
74
|
+
kadm5_ret_t rc;
|
75
|
+
|
76
|
+
rc = kadm5_init_with_password(auser, apass, KADM5_ADMIN_SERVICE, NULL, KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, &kadm5_handle);
|
77
|
+
if (rc) {
|
78
|
+
Kadm5_register_error(rc);
|
79
|
+
return Qfalse;
|
80
|
+
}
|
81
|
+
return Qtrue;
|
82
|
+
}
|
83
|
+
|
84
|
+
/*
|
85
|
+
Create a kerberos principal.
|
86
|
+
*p1 = username
|
87
|
+
*p2 = password
|
88
|
+
*p3 = options hash
|
89
|
+
|
90
|
+
Options hash can contain any of the following keys:
|
91
|
+
*kvno
|
92
|
+
*attributes
|
93
|
+
*max_renewable_life
|
94
|
+
*pw_expiration
|
95
|
+
*max_life
|
96
|
+
*princ_expire_time
|
97
|
+
*policy
|
98
|
+
|
99
|
+
attributes is a bitmask of the above KRB5_KDB_* constants.
|
100
|
+
*/
|
101
|
+
static VALUE Kadm5_create_principal(VALUE self, VALUE _user, VALUE _pass, VALUE options) {
|
102
|
+
Check_Type(options,T_HASH);
|
103
|
+
Check_Type(_user,T_STRING);
|
104
|
+
Check_Type(_pass,T_STRING);
|
105
|
+
char * user = STR2CSTR(_user);
|
106
|
+
char * pass = STR2CSTR(_pass);
|
107
|
+
|
108
|
+
VALUE hval;
|
109
|
+
long mask =0;
|
110
|
+
krb5_error_code krbret;
|
111
|
+
kadm5_ret_t rc;
|
112
|
+
krb5_context ctx;
|
113
|
+
kadm5_principal_ent_rec princ;
|
114
|
+
|
115
|
+
memset(&princ, 0, sizeof(princ));
|
116
|
+
if ((krbret = krb5_init_context(&ctx))) {
|
117
|
+
Kadm5_register_error(krbret);
|
118
|
+
return Qfalse;
|
119
|
+
}
|
120
|
+
|
121
|
+
if ((krbret = krb5_parse_name(ctx, user, &princ.principal))) {
|
122
|
+
krb5_free_context(ctx);
|
123
|
+
Kadm5_register_error(krbret);
|
124
|
+
return Qfalse;
|
125
|
+
}
|
126
|
+
|
127
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_KVNO), &hval)) {
|
128
|
+
Check_Type(hval,T_FIXNUM);
|
129
|
+
mask |= KADM5_KVNO;
|
130
|
+
princ.kvno = FIX2LONG(hval);
|
131
|
+
}
|
132
|
+
|
133
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_ATTRIBUTES), &hval)) {
|
134
|
+
Check_Type(hval,T_FIXNUM);
|
135
|
+
princ.attributes = FIX2LONG(hval);
|
136
|
+
mask |= KADM5_ATTRIBUTES;
|
137
|
+
}
|
138
|
+
|
139
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_MAX_RLIFE), &hval)) {
|
140
|
+
Check_Type(hval,T_FIXNUM);
|
141
|
+
mask |= KADM5_MAX_RLIFE;
|
142
|
+
princ.max_renewable_life = FIX2LONG(hval);
|
143
|
+
}
|
144
|
+
|
145
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_PW_EXPIRATION), &hval)) {
|
146
|
+
Check_Type(hval,T_FIXNUM);
|
147
|
+
mask |= KADM5_PW_EXPIRATION;
|
148
|
+
princ.pw_expiration = FIX2LONG(hval);
|
149
|
+
}
|
150
|
+
|
151
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_PRINC_EXPIRE_TIME), &hval)) {
|
152
|
+
Check_Type(hval,T_FIXNUM);
|
153
|
+
mask |= KADM5_PRINC_EXPIRE_TIME;
|
154
|
+
princ.princ_expire_time = FIX2LONG(hval);
|
155
|
+
}
|
156
|
+
|
157
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_MAX_LIFE), &hval)) {
|
158
|
+
Check_Type(hval,T_FIXNUM);
|
159
|
+
mask |= KADM5_MAX_LIFE;
|
160
|
+
princ.max_life = FIX2LONG(hval);
|
161
|
+
}
|
162
|
+
|
163
|
+
if (st_lookup(RHASH(options)->tbl, rb_str_new2(OP_POLICY), &hval)) {
|
164
|
+
Check_Type(hval,T_STRING);
|
165
|
+
mask |= KADM5_POLICY;
|
166
|
+
princ.policy = RSTRING(hval)->ptr;
|
167
|
+
}
|
168
|
+
|
169
|
+
|
170
|
+
mask |= KADM5_PRINCIPAL;
|
171
|
+
rc = kadm5_create_principal(kadm5_handle, &princ, mask, pass);
|
172
|
+
if (rc) {
|
173
|
+
krb5_free_principal(ctx, princ.principal);
|
174
|
+
krb5_free_context(ctx);
|
175
|
+
Kadm5_register_error(rc);
|
176
|
+
return Qfalse;
|
177
|
+
}
|
178
|
+
|
179
|
+
krb5_free_principal(ctx, princ.principal);
|
180
|
+
krb5_free_context(ctx);
|
181
|
+
return Qtrue;
|
182
|
+
|
183
|
+
}
|
184
|
+
|
185
|
+
|
186
|
+
/*
|
187
|
+
Deletes a principal from the kerberos database. Takes the username to delete as it's sole argument.
|
188
|
+
Returns true on success, false on failure.
|
189
|
+
*/
|
190
|
+
static VALUE Kadm5_delete_principal(VALUE self, VALUE _user) {
|
191
|
+
Check_Type(_user,T_STRING);
|
192
|
+
char * user = STR2CSTR(_user);
|
193
|
+
|
194
|
+
krb5_error_code krbret;
|
195
|
+
kadm5_ret_t rc;
|
196
|
+
krb5_context ctx;
|
197
|
+
krb5_principal princ;
|
198
|
+
|
199
|
+
if ((krbret = krb5_init_context(&ctx))) {
|
200
|
+
Kadm5_register_error(krbret);
|
201
|
+
return Qfalse;
|
202
|
+
}
|
203
|
+
if ((krbret = krb5_parse_name(ctx, user, &princ))) {
|
204
|
+
krb5_free_context(ctx);
|
205
|
+
Kadm5_register_error(krbret);
|
206
|
+
return Qfalse;
|
207
|
+
}
|
208
|
+
|
209
|
+
rc = kadm5_delete_principal(kadm5_handle, princ);
|
210
|
+
if (rc) {
|
211
|
+
krb5_free_principal(ctx, princ);
|
212
|
+
krb5_free_context(ctx);
|
213
|
+
Kadm5_register_error(rc);
|
214
|
+
return Qfalse;
|
215
|
+
}
|
216
|
+
|
217
|
+
krb5_free_principal(ctx, princ);
|
218
|
+
krb5_free_context(ctx);
|
219
|
+
return Qtrue;
|
220
|
+
|
221
|
+
}
|
222
|
+
|
223
|
+
/*
|
224
|
+
Change password of an existing user. Returns true on success, false on failure.
|
225
|
+
*p1=username
|
226
|
+
*p2=current password
|
227
|
+
*p3=new password
|
228
|
+
*/
|
229
|
+
static VALUE Krb5_change_password(VALUE self, VALUE _user, VALUE _pass, VALUE _newpass) {
|
230
|
+
Check_Type(_user,T_STRING);
|
231
|
+
Check_Type(_pass,T_STRING);
|
232
|
+
Check_Type(_newpass,T_STRING);
|
233
|
+
char * user = STR2CSTR(_user);
|
234
|
+
char * pass = STR2CSTR(_pass);
|
235
|
+
char * newpass = STR2CSTR(_newpass);
|
236
|
+
|
237
|
+
krb5_error_code krbret;
|
238
|
+
krb5_context ctx;
|
239
|
+
krb5_creds creds;
|
240
|
+
krb5_principal princ;
|
241
|
+
int pw_result;
|
242
|
+
krb5_data pw_res_string, res_string;
|
243
|
+
|
244
|
+
if ((krbret = krb5_init_context(&ctx))) {
|
245
|
+
Krb5_register_error(krbret);
|
246
|
+
return Qfalse;
|
247
|
+
}
|
248
|
+
|
249
|
+
if ((krbret = krb5_parse_name(ctx, user, &princ))) {
|
250
|
+
krb5_free_context(ctx);
|
251
|
+
Krb5_register_error(krbret);
|
252
|
+
return Qfalse;
|
253
|
+
}
|
254
|
+
|
255
|
+
if ((krbret = krb5_get_init_creds_password( ctx, &creds, princ, pass, NULL, NULL, 0, KADM5_CHANGEPW_SERVICE, NULL))) {
|
256
|
+
krb5_free_principal(ctx, princ);
|
257
|
+
krb5_free_context(ctx);
|
258
|
+
Krb5_register_error(krbret);
|
259
|
+
return Qfalse;
|
260
|
+
}
|
261
|
+
|
262
|
+
krbret = krb5_change_password(ctx, &creds, newpass, &pw_result, &pw_res_string, &res_string );
|
263
|
+
if (pw_result) {
|
264
|
+
krb5_free_cred_contents(ctx, &creds);
|
265
|
+
krb5_free_principal(ctx, princ);
|
266
|
+
krb5_free_context(ctx);
|
267
|
+
Krb5_register_error(pw_result);
|
268
|
+
return Qfalse;
|
269
|
+
}
|
270
|
+
|
271
|
+
krb5_free_cred_contents(ctx, &creds);
|
272
|
+
krb5_free_principal(ctx, princ);
|
273
|
+
krb5_free_context(ctx);
|
274
|
+
return Qtrue;
|
275
|
+
|
276
|
+
}
|
277
|
+
|
278
|
+
/*
|
279
|
+
Kerberos user authentication. Returns true on success, false on failure.
|
280
|
+
*p1=username
|
281
|
+
*p2=password
|
282
|
+
*/
|
283
|
+
static VALUE Krb5_get_init_creds_password(VALUE self, VALUE _user, VALUE _pass) {
|
284
|
+
Check_Type(_user,T_STRING);
|
285
|
+
Check_Type(_pass,T_STRING);
|
286
|
+
char * user = STR2CSTR(_user);
|
287
|
+
char * pass = STR2CSTR(_pass);
|
288
|
+
|
289
|
+
krb5_error_code krbret;
|
290
|
+
krb5_context ctx;
|
291
|
+
krb5_creds creds;
|
292
|
+
krb5_principal princ;
|
293
|
+
|
294
|
+
if ((krbret = krb5_init_context(&ctx))) {
|
295
|
+
Krb5_register_error(krbret);
|
296
|
+
return Qfalse;
|
297
|
+
}
|
298
|
+
|
299
|
+
memset(&creds, 0, sizeof(krb5_creds));
|
300
|
+
if ((krbret = krb5_parse_name(ctx, user, &princ))) {
|
301
|
+
krb5_free_context(ctx);
|
302
|
+
Krb5_register_error(krbret);
|
303
|
+
return Qfalse;
|
304
|
+
}
|
305
|
+
|
306
|
+
if ((krbret = krb5_get_init_creds_password( ctx, &creds, princ, pass, 0, NULL, 0, NULL, NULL))) {
|
307
|
+
krb5_free_context(ctx);
|
308
|
+
krb5_free_principal(ctx, princ);
|
309
|
+
Krb5_register_error(krbret);
|
310
|
+
return Qfalse;
|
311
|
+
}
|
312
|
+
|
313
|
+
krb5_free_cred_contents(ctx, &creds);
|
314
|
+
krb5_free_principal(ctx, princ);
|
315
|
+
krb5_free_context(ctx);
|
316
|
+
|
317
|
+
return Qtrue;
|
318
|
+
}
|
319
|
+
|
320
|
+
VALUE Krb5_init(VALUE self)
|
321
|
+
{
|
322
|
+
return self;
|
323
|
+
}
|
324
|
+
|
325
|
+
VALUE Kadm5_init(VALUE self)
|
326
|
+
{
|
327
|
+
return self;
|
328
|
+
}
|
329
|
+
|
330
|
+
void Init_ruby_kerberos() {
|
331
|
+
mKerberos = rb_define_module("Kerberos");
|
332
|
+
|
333
|
+
cKadm5 = rb_define_class_under(mKerberos,"Kadm5", rb_cObject);
|
334
|
+
rb_define_method(cKadm5, "initialize", Kadm5_init,0);
|
335
|
+
rb_define_method(cKadm5, "errstr", Kadm5_errstr,0);
|
336
|
+
rb_define_method(cKadm5, "init_with_password", Kadm5_init_with_password,2);
|
337
|
+
rb_define_method(cKadm5, "create_principal", Kadm5_create_principal,3);
|
338
|
+
rb_define_method(cKadm5, "delete_principal", Kadm5_delete_principal,1);
|
339
|
+
|
340
|
+
/* Principal primary attributes */
|
341
|
+
rb_define_const(cKadm5,"KRB5_KDB_PWCHANGE_SERVICE",INT2NUM(KRB5_KDB_PWCHANGE_SERVICE));
|
342
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_POSTDATED",INT2NUM(KRB5_KDB_DISALLOW_POSTDATED));
|
343
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_FORWARDABLE",INT2NUM(KRB5_KDB_DISALLOW_FORWARDABLE));
|
344
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_TGT_BASED",INT2NUM(KRB5_KDB_DISALLOW_TGT_BASED));
|
345
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_RENEWABLE",INT2NUM(KRB5_KDB_DISALLOW_RENEWABLE));
|
346
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_PROXIABLE",INT2NUM(KRB5_KDB_DISALLOW_PROXIABLE));
|
347
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_DUP_SKEY",INT2NUM(KRB5_KDB_DISALLOW_DUP_SKEY));
|
348
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_ALL_TIX",INT2NUM(KRB5_KDB_DISALLOW_ALL_TIX));
|
349
|
+
rb_define_const(cKadm5,"KRB5_KDB_REQUIRES_PRE_AUTH",INT2NUM(KRB5_KDB_REQUIRES_PRE_AUTH));
|
350
|
+
rb_define_const(cKadm5,"KRB5_KDB_REQUIRES_HW_AUTH",INT2NUM(KRB5_KDB_REQUIRES_HW_AUTH));
|
351
|
+
rb_define_const(cKadm5,"KRB5_KDB_DISALLOW_SVR",INT2NUM(KRB5_KDB_DISALLOW_SVR));
|
352
|
+
rb_define_const(cKadm5,"KRB5_KDB_REQUIRES_PWCHANGE",INT2NUM(KRB5_KDB_REQUIRES_PWCHANGE));
|
353
|
+
rb_define_const(cKadm5,"KRB5_KDB_SUPPORT_DESMD5",INT2NUM(KRB5_KDB_SUPPORT_DESMD5));
|
354
|
+
rb_define_const(cKadm5,"KRB5_KDB_NEW_PRINC",INT2NUM(KRB5_KDB_NEW_PRINC));
|
355
|
+
|
356
|
+
cKrb5 = rb_define_class_under(mKerberos,"Krb5", rb_cObject);
|
357
|
+
rb_define_method(cKrb5, "initialize", Krb5_init,0);
|
358
|
+
rb_define_method(cKrb5, "errstr", Krb5_errstr,0);
|
359
|
+
rb_define_method(cKrb5, "get_init_creds_password", Krb5_get_init_creds_password,2);
|
360
|
+
rb_define_method(cKrb5, "change_password", Krb5_change_password,3);
|
361
|
+
}
|
362
|
+
|
data/ext/ruby_kerberos.h
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#define OP_PRINCIPAL "principal"
|
2
|
+
#define OP_PRINC_EXPIRE_TIME "princ_expire_time"
|
3
|
+
#define OP_PW_EXPIRATION "pw_expiration"
|
4
|
+
#define OP_LAST_PW_CHANGE "last_pwd_change"
|
5
|
+
#define OP_ATTRIBUTES "attributes"
|
6
|
+
#define OP_MAX_LIFE "max_life"
|
7
|
+
#define OP_MOD_TIME "mod_time"
|
8
|
+
#define OP_MOD_NAME "mod_name"
|
9
|
+
#define OP_KVNO "kvno"
|
10
|
+
#define OP_MKVNO "mkvno"
|
11
|
+
#define OP_AUX_ATTRIBUTES "aux_attributes"
|
12
|
+
#define OP_POLICY "policy"
|
13
|
+
#define OP_CLEARPOLICY "clearpolicy"
|
14
|
+
#define OP_RANDKEY "randkey"
|
15
|
+
#define OP_MAX_RLIFE "max_renewable_life"
|
16
|
+
#define OP_LAST_SUCCESS "last_success"
|
17
|
+
#define OP_LAST_FAILED "last_failed"
|
18
|
+
#define OP_FAIL_AUTH_COUNT "fail_auth_count"
|
19
|
+
|
20
|
+
#define OP_PW_MAX_LIFE "pw_max_life"
|
21
|
+
#define OP_PW_MIN_LIFE "pw_min_life"
|
22
|
+
#define OP_PW_MIN_LENGTH "pw_min_length"
|
23
|
+
#define OP_PW_MIN_CLASSES "pw_min_classes"
|
24
|
+
#define OP_PW_HISTORY_NUM "pw_history_num"
|
25
|
+
#define OP_REF_COUNT "pw_refcnt"
|
data/lib/kerberos.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require 'ruby_kerberos'
|
4
|
+
|
5
|
+
# Ruby C extension for basic Kerberos functions. Tested on Linux/Freebsd with Kerberos 5-1.4.3 and 5-1.5.1.
|
6
|
+
module Kerberos
|
7
|
+
|
8
|
+
# Krb5 contains the kerberos end user functionality, such as user authentication and password changes.
|
9
|
+
class Krb5
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
# Kadm5 contains the administrative functions, such as adding/deleting/modifying principals.
|
14
|
+
class Kadm5
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: kerberos
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.2"
|
7
|
+
date: 2006-09-22 00:00:00 -07:00
|
8
|
+
summary: Kerberos binding for ruby
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: chris@paymentonline.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: kerberos
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Chris Ochs
|
30
|
+
files:
|
31
|
+
- README
|
32
|
+
- lib/kerberos.rb
|
33
|
+
- bin/example.rb
|
34
|
+
- ext/extconf.rb
|
35
|
+
- ext/ruby_kerberos.c
|
36
|
+
- ext/ruby_kerberos.h
|
37
|
+
- ext/admin.h
|
38
|
+
- ext/krb5.h
|
39
|
+
test_files: []
|
40
|
+
|
41
|
+
rdoc_options: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
executables: []
|
46
|
+
|
47
|
+
extensions:
|
48
|
+
- ext/extconf.rb
|
49
|
+
requirements: []
|
50
|
+
|
51
|
+
dependencies: []
|
52
|
+
|