rkerberos 0.2.1 → 0.2.3
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.
- checksums.yaml +4 -4
- data/CHANGES.md +28 -8
- data/MANIFEST.md +24 -16
- data/Rakefile +4 -1
- data/ext/rkerberos/ccache.c +98 -1
- data/ext/rkerberos/config.c +10 -7
- data/ext/rkerberos/context.c +6 -0
- data/ext/rkerberos/extconf.rb +16 -3
- data/ext/rkerberos/kadm5.c +97 -45
- data/ext/rkerberos/keytab.c +247 -106
- data/ext/rkerberos/keytab_entry.c +2 -1
- data/ext/rkerberos/principal.c +28 -0
- data/ext/rkerberos/rkerberos.c +91 -13
- data/rkerberos.gemspec +1 -1
- data/spec/config_spec.rb +29 -7
- data/spec/context_spec.rb +6 -7
- data/spec/credentials_cache_spec.rb +79 -12
- data/spec/kadm5_spec.rb +57 -16
- data/spec/krb5_keytab_spec.rb +200 -4
- data/spec/krb5_spec.rb +81 -9
- data/spec/policy_spec.rb +8 -7
- data/spec/principal_spec.rb +18 -0
- data/spec/spec_helper.rb +34 -0
- metadata +3 -2
data/ext/rkerberos/keytab.c
CHANGED
|
@@ -7,7 +7,7 @@ VALUE cKrb5Keytab, cKrb5KeytabException;
|
|
|
7
7
|
void rkrb5_keytab_typed_free(void *ptr) {
|
|
8
8
|
if (!ptr) return;
|
|
9
9
|
RUBY_KRB5_KEYTAB *kt = (RUBY_KRB5_KEYTAB *)ptr;
|
|
10
|
-
if (kt->keytab)
|
|
10
|
+
if (kt->keytab && kt->ctx)
|
|
11
11
|
krb5_kt_close(kt->ctx, kt->keytab);
|
|
12
12
|
if (kt->ctx)
|
|
13
13
|
krb5_free_cred_contents(kt->ctx, &kt->creds);
|
|
@@ -35,6 +35,61 @@ VALUE rkrb5_keytab_allocate(VALUE klass){
|
|
|
35
35
|
|
|
36
36
|
// Allocation function for the Kerberos::Krb5::Keytab class.
|
|
37
37
|
|
|
38
|
+
// Struct for rb_ensure in each()
|
|
39
|
+
typedef struct {
|
|
40
|
+
krb5_context ctx;
|
|
41
|
+
krb5_keytab keytab;
|
|
42
|
+
krb5_kt_cursor cursor;
|
|
43
|
+
int cursor_active;
|
|
44
|
+
} keytab_each_arg;
|
|
45
|
+
|
|
46
|
+
static VALUE rkrb5_keytab_each_body(VALUE arg){
|
|
47
|
+
keytab_each_arg* ea = (keytab_each_arg*)arg;
|
|
48
|
+
krb5_keytab_entry entry;
|
|
49
|
+
krb5_error_code kerror;
|
|
50
|
+
char* principal;
|
|
51
|
+
VALUE v_kt_entry;
|
|
52
|
+
|
|
53
|
+
while((kerror = krb5_kt_next_entry(ea->ctx, ea->keytab, &entry, &ea->cursor)) == 0){
|
|
54
|
+
kerror = krb5_unparse_name(ea->ctx, entry.principal, &principal);
|
|
55
|
+
|
|
56
|
+
if(kerror){
|
|
57
|
+
krb5_kt_free_entry(ea->ctx, &entry);
|
|
58
|
+
rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
v_kt_entry = rb_class_new_instance(0, NULL, cKrb5KtEntry);
|
|
62
|
+
|
|
63
|
+
rb_iv_set(v_kt_entry, "@principal", rb_str_new2(principal));
|
|
64
|
+
rb_iv_set(v_kt_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
|
65
|
+
rb_iv_set(v_kt_entry, "@vno", INT2FIX(entry.vno));
|
|
66
|
+
rb_iv_set(v_kt_entry, "@key", INT2FIX(entry.key.enctype));
|
|
67
|
+
|
|
68
|
+
krb5_free_unparsed_name(ea->ctx, principal);
|
|
69
|
+
krb5_kt_free_entry(ea->ctx, &entry);
|
|
70
|
+
|
|
71
|
+
rb_yield(v_kt_entry);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ea->cursor_active = 0;
|
|
75
|
+
|
|
76
|
+
kerror = krb5_kt_end_seq_get(ea->ctx, ea->keytab, &ea->cursor);
|
|
77
|
+
|
|
78
|
+
if(kerror)
|
|
79
|
+
rb_raise(cKrb5Exception, "krb5_kt_end_seq_get: %s", error_message(kerror));
|
|
80
|
+
|
|
81
|
+
return Qnil;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static VALUE rkrb5_keytab_each_ensure(VALUE arg){
|
|
85
|
+
keytab_each_arg* ea = (keytab_each_arg*)arg;
|
|
86
|
+
|
|
87
|
+
if(ea->cursor_active)
|
|
88
|
+
krb5_kt_end_seq_get(ea->ctx, ea->keytab, &ea->cursor);
|
|
89
|
+
|
|
90
|
+
return Qnil;
|
|
91
|
+
}
|
|
92
|
+
|
|
38
93
|
/*
|
|
39
94
|
* call-seq:
|
|
40
95
|
*
|
|
@@ -46,48 +101,22 @@ VALUE rkrb5_keytab_allocate(VALUE klass){
|
|
|
46
101
|
*/
|
|
47
102
|
static VALUE rkrb5_keytab_each(VALUE self){
|
|
48
103
|
RUBY_KRB5_KEYTAB* ptr;
|
|
49
|
-
VALUE v_kt_entry;
|
|
50
104
|
krb5_error_code kerror;
|
|
51
|
-
|
|
52
|
-
krb5_keytab_entry entry;
|
|
53
|
-
char* principal;
|
|
105
|
+
keytab_each_arg ea;
|
|
54
106
|
|
|
55
107
|
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
56
108
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
);
|
|
109
|
+
ea.ctx = ptr->ctx;
|
|
110
|
+
ea.keytab = ptr->keytab;
|
|
111
|
+
|
|
112
|
+
kerror = krb5_kt_start_seq_get(ea.ctx, ea.keytab, &ea.cursor);
|
|
62
113
|
|
|
63
114
|
if(kerror)
|
|
64
115
|
rb_raise(cKrb5Exception, "krb5_kt_start_seq_get: %s", error_message(kerror));
|
|
65
116
|
|
|
66
|
-
|
|
67
|
-
krb5_unparse_name(ptr->ctx, entry.principal, &principal);
|
|
117
|
+
ea.cursor_active = 1;
|
|
68
118
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
rb_iv_set(v_kt_entry, "@principal", rb_str_new2(principal));
|
|
72
|
-
rb_iv_set(v_kt_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
|
73
|
-
rb_iv_set(v_kt_entry, "@vno", INT2FIX(entry.vno));
|
|
74
|
-
rb_iv_set(v_kt_entry, "@key", INT2FIX(entry.key.enctype));
|
|
75
|
-
|
|
76
|
-
rb_yield(v_kt_entry);
|
|
77
|
-
|
|
78
|
-
free(principal);
|
|
79
|
-
|
|
80
|
-
krb5_kt_free_entry(ptr->ctx, &entry);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
kerror = krb5_kt_end_seq_get(
|
|
84
|
-
ptr->ctx,
|
|
85
|
-
ptr->keytab,
|
|
86
|
-
&cursor
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
if(kerror)
|
|
90
|
-
rb_raise(cKrb5Exception, "krb5_kt_end_seq_get: %s", error_message(kerror));
|
|
119
|
+
rb_ensure(rkrb5_keytab_each_body, (VALUE)&ea, rkrb5_keytab_each_ensure, (VALUE)&ea);
|
|
91
120
|
|
|
92
121
|
return self;
|
|
93
122
|
}
|
|
@@ -130,6 +159,11 @@ static VALUE rkrb5_keytab_close(VALUE self){
|
|
|
130
159
|
|
|
131
160
|
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
132
161
|
|
|
162
|
+
if(ptr->keytab && ptr->ctx){
|
|
163
|
+
krb5_kt_close(ptr->ctx, ptr->keytab);
|
|
164
|
+
ptr->keytab = NULL;
|
|
165
|
+
}
|
|
166
|
+
|
|
133
167
|
if(ptr->ctx)
|
|
134
168
|
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
135
169
|
|
|
@@ -241,8 +275,8 @@ static VALUE rkrb5_keytab_add_entry(int argc, VALUE* argv, VALUE self){
|
|
|
241
275
|
* call-seq:
|
|
242
276
|
* keytab.get_entry(principal, vno = 0, encoding_type = nil)
|
|
243
277
|
*
|
|
244
|
-
* Searches the keytab by +principal+, +vno+ and +encoding_type+.
|
|
245
|
-
* +vno+ is zero (the default), then the first entry that matches +principal+
|
|
278
|
+
* Searches the keytab by +principal+, +vno+ (version number) and +encoding_type+.
|
|
279
|
+
* If the +vno+ is zero (the default), then the first entry that matches +principal+
|
|
246
280
|
* is returned.
|
|
247
281
|
*
|
|
248
282
|
* Returns a Kerberos::Krb5::KeytabEntry object if the entry is found.
|
|
@@ -269,10 +303,17 @@ static VALUE rkrb5_keytab_get_entry(int argc, VALUE* argv, VALUE self){
|
|
|
269
303
|
kerror = krb5_parse_name(ptr->ctx, name, &principal);
|
|
270
304
|
|
|
271
305
|
if(kerror)
|
|
272
|
-
rb_raise(cKrb5Exception, "
|
|
306
|
+
rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));
|
|
307
|
+
|
|
308
|
+
if(NIL_P(v_vno))
|
|
309
|
+
vno = 0;
|
|
310
|
+
else
|
|
311
|
+
vno = NUM2INT(v_vno);
|
|
273
312
|
|
|
274
|
-
|
|
275
|
-
|
|
313
|
+
if(NIL_P(v_enctype))
|
|
314
|
+
enctype = 0;
|
|
315
|
+
else
|
|
316
|
+
enctype = NUM2INT(v_enctype);
|
|
276
317
|
|
|
277
318
|
kerror = krb5_kt_get_entry(
|
|
278
319
|
ptr->ctx,
|
|
@@ -283,6 +324,8 @@ static VALUE rkrb5_keytab_get_entry(int argc, VALUE* argv, VALUE self){
|
|
|
283
324
|
&entry
|
|
284
325
|
);
|
|
285
326
|
|
|
327
|
+
krb5_free_principal(ptr->ctx, principal);
|
|
328
|
+
|
|
286
329
|
if(kerror)
|
|
287
330
|
rb_raise(cKrb5Exception, "krb5_kt_get_entry: %s", error_message(kerror));
|
|
288
331
|
|
|
@@ -298,6 +341,93 @@ static VALUE rkrb5_keytab_get_entry(int argc, VALUE* argv, VALUE self){
|
|
|
298
341
|
return v_entry;
|
|
299
342
|
}
|
|
300
343
|
|
|
344
|
+
/*
|
|
345
|
+
* call-seq:
|
|
346
|
+
* keytab.keytab_name
|
|
347
|
+
*
|
|
348
|
+
* Return the name associated with the open keytab. This returns the canonical
|
|
349
|
+
* type:residual string used internally by the library. It will usually be the
|
|
350
|
+
* same as the +name+ method, but could be different.
|
|
351
|
+
*/
|
|
352
|
+
static VALUE rkrb5_keytab_get_name(VALUE self){
|
|
353
|
+
RUBY_KRB5_KEYTAB* ptr;
|
|
354
|
+
krb5_error_code kerror;
|
|
355
|
+
char name[MAX_KEYTAB_NAME_LEN];
|
|
356
|
+
|
|
357
|
+
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
358
|
+
|
|
359
|
+
if(!ptr->ctx)
|
|
360
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
361
|
+
|
|
362
|
+
kerror = krb5_kt_get_name(ptr->ctx, ptr->keytab, name, MAX_KEYTAB_NAME_LEN);
|
|
363
|
+
|
|
364
|
+
if(kerror)
|
|
365
|
+
rb_raise(cKrb5Exception, "krb5_kt_get_name: %s", error_message(kerror));
|
|
366
|
+
|
|
367
|
+
return rb_str_new2(name);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/*
|
|
371
|
+
* call-seq:
|
|
372
|
+
* keytab.keytab_type
|
|
373
|
+
*
|
|
374
|
+
* Return the keytab type portion, e.g. "FILE". Raises an error if nil.
|
|
375
|
+
*/
|
|
376
|
+
static VALUE rkrb5_keytab_get_type(VALUE self){
|
|
377
|
+
RUBY_KRB5_KEYTAB* ptr;
|
|
378
|
+
const char *type;
|
|
379
|
+
|
|
380
|
+
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
381
|
+
|
|
382
|
+
if(!ptr->ctx)
|
|
383
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
384
|
+
|
|
385
|
+
type = krb5_kt_get_type(ptr->ctx, ptr->keytab);
|
|
386
|
+
|
|
387
|
+
if(!type)
|
|
388
|
+
rb_raise(cKrb5Exception, "krb5_kt_get_type returned NULL");
|
|
389
|
+
|
|
390
|
+
return rb_str_new2(type);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/*
|
|
394
|
+
* call-seq:
|
|
395
|
+
* keytab.dup -> new_keytab
|
|
396
|
+
*
|
|
397
|
+
* Duplicate the keytab object so that both handles may be closed
|
|
398
|
+
* independently. Underlying data is shared by the krb5 library; the
|
|
399
|
+
* new Ruby object receives a fresh context.
|
|
400
|
+
*/
|
|
401
|
+
static VALUE rkrb5_keytab_dup(VALUE self){
|
|
402
|
+
RUBY_KRB5_KEYTAB *ptr, *newptr;
|
|
403
|
+
krb5_error_code kerror;
|
|
404
|
+
VALUE newobj;
|
|
405
|
+
|
|
406
|
+
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
407
|
+
|
|
408
|
+
if(!ptr->ctx)
|
|
409
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
410
|
+
|
|
411
|
+
newobj = rkrb5_keytab_allocate(CLASS_OF(self));
|
|
412
|
+
TypedData_Get_Struct(newobj, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, newptr);
|
|
413
|
+
|
|
414
|
+
kerror = krb5_init_context(&newptr->ctx);
|
|
415
|
+
if(kerror){
|
|
416
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
kerror = krb5_kt_dup(newptr->ctx, ptr->keytab, &newptr->keytab);
|
|
420
|
+
if(kerror){
|
|
421
|
+
krb5_free_context(newptr->ctx);
|
|
422
|
+
newptr->ctx = NULL;
|
|
423
|
+
rb_raise(cKrb5Exception, "krb5_kt_dup: %s", error_message(kerror));
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
rb_iv_set(newobj, "@name", rb_iv_get(self, "@name"));
|
|
427
|
+
|
|
428
|
+
return newobj;
|
|
429
|
+
}
|
|
430
|
+
|
|
301
431
|
/*
|
|
302
432
|
* call-seq:
|
|
303
433
|
* Kerberos::Krb5::Keytab.new(name = nil)
|
|
@@ -362,6 +492,67 @@ static VALUE rkrb5_keytab_initialize(int argc, VALUE* argv, VALUE self){
|
|
|
362
492
|
|
|
363
493
|
// Singleton Methods
|
|
364
494
|
|
|
495
|
+
// Struct for rb_ensure in foreach()
|
|
496
|
+
typedef struct {
|
|
497
|
+
krb5_context ctx;
|
|
498
|
+
krb5_keytab keytab;
|
|
499
|
+
krb5_kt_cursor cursor;
|
|
500
|
+
int cursor_active;
|
|
501
|
+
} keytab_foreach_arg;
|
|
502
|
+
|
|
503
|
+
static VALUE rkrb5_s_keytab_foreach_body(VALUE arg){
|
|
504
|
+
keytab_foreach_arg* fa = (keytab_foreach_arg*)arg;
|
|
505
|
+
krb5_keytab_entry entry;
|
|
506
|
+
krb5_error_code kerror;
|
|
507
|
+
char* principal;
|
|
508
|
+
VALUE v_kt_entry;
|
|
509
|
+
|
|
510
|
+
while((kerror = krb5_kt_next_entry(fa->ctx, fa->keytab, &entry, &fa->cursor)) == 0){
|
|
511
|
+
kerror = krb5_unparse_name(fa->ctx, entry.principal, &principal);
|
|
512
|
+
|
|
513
|
+
if(kerror){
|
|
514
|
+
krb5_kt_free_entry(fa->ctx, &entry);
|
|
515
|
+
rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
v_kt_entry = rb_class_new_instance(0, NULL, cKrb5KtEntry);
|
|
519
|
+
|
|
520
|
+
rb_iv_set(v_kt_entry, "@principal", rb_str_new2(principal));
|
|
521
|
+
rb_iv_set(v_kt_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
|
522
|
+
rb_iv_set(v_kt_entry, "@vno", INT2FIX(entry.vno));
|
|
523
|
+
rb_iv_set(v_kt_entry, "@key", INT2FIX(entry.key.enctype));
|
|
524
|
+
|
|
525
|
+
krb5_free_unparsed_name(fa->ctx, principal);
|
|
526
|
+
krb5_kt_free_entry(fa->ctx, &entry);
|
|
527
|
+
|
|
528
|
+
rb_yield(v_kt_entry);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
fa->cursor_active = 0;
|
|
532
|
+
|
|
533
|
+
kerror = krb5_kt_end_seq_get(fa->ctx, fa->keytab, &fa->cursor);
|
|
534
|
+
|
|
535
|
+
if(kerror)
|
|
536
|
+
rb_raise(cKrb5Exception, "krb5_kt_end_seq_get: %s", error_message(kerror));
|
|
537
|
+
|
|
538
|
+
return Qnil;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
static VALUE rkrb5_s_keytab_foreach_ensure(VALUE arg){
|
|
542
|
+
keytab_foreach_arg* fa = (keytab_foreach_arg*)arg;
|
|
543
|
+
|
|
544
|
+
if(fa->cursor_active)
|
|
545
|
+
krb5_kt_end_seq_get(fa->ctx, fa->keytab, &fa->cursor);
|
|
546
|
+
|
|
547
|
+
if(fa->keytab)
|
|
548
|
+
krb5_kt_close(fa->ctx, fa->keytab);
|
|
549
|
+
|
|
550
|
+
if(fa->ctx)
|
|
551
|
+
krb5_free_context(fa->ctx);
|
|
552
|
+
|
|
553
|
+
return Qnil;
|
|
554
|
+
}
|
|
555
|
+
|
|
365
556
|
/*
|
|
366
557
|
* call-seq:
|
|
367
558
|
* Kerberos::Krb5::Keytab.foreach(keytab = nil){ |entry|
|
|
@@ -374,31 +565,26 @@ static VALUE rkrb5_keytab_initialize(int argc, VALUE* argv, VALUE self){
|
|
|
374
565
|
* If no +keytab+ is provided, then the default keytab is used.
|
|
375
566
|
*/
|
|
376
567
|
static VALUE rkrb5_s_keytab_foreach(int argc, VALUE* argv, VALUE klass){
|
|
377
|
-
VALUE v_kt_entry;
|
|
378
568
|
VALUE v_keytab_name;
|
|
379
569
|
krb5_error_code kerror;
|
|
380
|
-
|
|
381
|
-
krb5_keytab keytab;
|
|
382
|
-
krb5_keytab_entry entry;
|
|
383
|
-
krb5_context context;
|
|
384
|
-
char* principal;
|
|
570
|
+
keytab_foreach_arg fa;
|
|
385
571
|
char keytab_name[MAX_KEYTAB_NAME_LEN];
|
|
386
572
|
|
|
573
|
+
memset(&fa, 0, sizeof(fa));
|
|
574
|
+
|
|
387
575
|
rb_scan_args(argc, argv, "01", &v_keytab_name);
|
|
388
576
|
|
|
389
|
-
kerror = krb5_init_context(&
|
|
577
|
+
kerror = krb5_init_context(&fa.ctx);
|
|
390
578
|
|
|
391
579
|
if(kerror)
|
|
392
580
|
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
|
393
581
|
|
|
394
582
|
// Use the default keytab name if one isn't provided.
|
|
395
583
|
if(NIL_P(v_keytab_name)){
|
|
396
|
-
kerror = krb5_kt_default_name(
|
|
584
|
+
kerror = krb5_kt_default_name(fa.ctx, keytab_name, MAX_KEYTAB_NAME_LEN);
|
|
397
585
|
|
|
398
586
|
if(kerror){
|
|
399
|
-
|
|
400
|
-
krb5_free_context(context);
|
|
401
|
-
|
|
587
|
+
krb5_free_context(fa.ctx);
|
|
402
588
|
rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
|
|
403
589
|
}
|
|
404
590
|
}
|
|
@@ -408,73 +594,24 @@ static VALUE rkrb5_s_keytab_foreach(int argc, VALUE* argv, VALUE klass){
|
|
|
408
594
|
keytab_name[MAX_KEYTAB_NAME_LEN - 1] = '\0';
|
|
409
595
|
}
|
|
410
596
|
|
|
411
|
-
kerror = krb5_kt_resolve(
|
|
412
|
-
context,
|
|
413
|
-
keytab_name,
|
|
414
|
-
&keytab
|
|
415
|
-
);
|
|
597
|
+
kerror = krb5_kt_resolve(fa.ctx, keytab_name, &fa.keytab);
|
|
416
598
|
|
|
417
599
|
if(kerror){
|
|
418
|
-
|
|
419
|
-
krb5_free_context(context);
|
|
420
|
-
|
|
600
|
+
krb5_free_context(fa.ctx);
|
|
421
601
|
rb_raise(cKrb5Exception, "krb5_kt_resolve: %s", error_message(kerror));
|
|
422
602
|
}
|
|
423
603
|
|
|
424
|
-
kerror = krb5_kt_start_seq_get(
|
|
425
|
-
context,
|
|
426
|
-
keytab,
|
|
427
|
-
&cursor
|
|
428
|
-
);
|
|
604
|
+
kerror = krb5_kt_start_seq_get(fa.ctx, fa.keytab, &fa.cursor);
|
|
429
605
|
|
|
430
606
|
if(kerror){
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if(keytab)
|
|
435
|
-
krb5_kt_close(context, keytab);
|
|
436
|
-
|
|
607
|
+
krb5_kt_close(fa.ctx, fa.keytab);
|
|
608
|
+
krb5_free_context(fa.ctx);
|
|
437
609
|
rb_raise(cKrb5Exception, "krb5_kt_start_seq_get: %s", error_message(kerror));
|
|
438
610
|
}
|
|
439
611
|
|
|
440
|
-
|
|
441
|
-
krb5_unparse_name(context, entry.principal, &principal);
|
|
442
|
-
|
|
443
|
-
v_kt_entry = rb_class_new_instance(0, NULL, cKrb5KtEntry);
|
|
444
|
-
|
|
445
|
-
rb_iv_set(v_kt_entry, "@principal", rb_str_new2(principal));
|
|
446
|
-
rb_iv_set(v_kt_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
|
447
|
-
rb_iv_set(v_kt_entry, "@vno", INT2FIX(entry.vno));
|
|
448
|
-
rb_iv_set(v_kt_entry, "@key", INT2FIX(entry.key.enctype));
|
|
449
|
-
|
|
450
|
-
rb_yield(v_kt_entry);
|
|
451
|
-
|
|
452
|
-
free(principal);
|
|
453
|
-
|
|
454
|
-
krb5_kt_free_entry(context, &entry);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
kerror = krb5_kt_end_seq_get(
|
|
458
|
-
context,
|
|
459
|
-
keytab,
|
|
460
|
-
&cursor
|
|
461
|
-
);
|
|
462
|
-
|
|
463
|
-
if(kerror){
|
|
464
|
-
if(context)
|
|
465
|
-
krb5_free_context(context);
|
|
466
|
-
|
|
467
|
-
if(keytab)
|
|
468
|
-
krb5_kt_close(context, keytab);
|
|
469
|
-
|
|
470
|
-
rb_raise(cKrb5Exception, "krb5_kt_end_seq_get: %s", error_message(kerror));
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
if(keytab)
|
|
474
|
-
krb5_kt_close(context, keytab);
|
|
612
|
+
fa.cursor_active = 1;
|
|
475
613
|
|
|
476
|
-
|
|
477
|
-
krb5_free_context(context);
|
|
614
|
+
rb_ensure(rkrb5_s_keytab_foreach_body, (VALUE)&fa, rkrb5_s_keytab_foreach_ensure, (VALUE)&fa);
|
|
478
615
|
|
|
479
616
|
return Qnil;
|
|
480
617
|
}
|
|
@@ -504,6 +641,10 @@ void Init_keytab(void){
|
|
|
504
641
|
rb_define_method(cKrb5Keytab, "close", rkrb5_keytab_close, 0);
|
|
505
642
|
rb_define_method(cKrb5Keytab, "each", rkrb5_keytab_each, 0);
|
|
506
643
|
rb_define_method(cKrb5Keytab, "get_entry", rkrb5_keytab_get_entry, -1);
|
|
644
|
+
rb_define_method(cKrb5Keytab, "keytab_name", rkrb5_keytab_get_name, 0);
|
|
645
|
+
rb_define_method(cKrb5Keytab, "keytab_type", rkrb5_keytab_get_type, 0);
|
|
646
|
+
rb_define_method(cKrb5Keytab, "dup", rkrb5_keytab_dup, 0);
|
|
647
|
+
rb_define_alias(cKrb5Keytab, "clone", "dup");
|
|
507
648
|
|
|
508
649
|
// TODO: Move these into Kadm5 and/or figure out how to set the vno properly.
|
|
509
650
|
// rb_define_method(cKrb5Keytab, "add_entry", rkrb5_keytab_add_entry, -1);
|
data/ext/rkerberos/principal.c
CHANGED
|
@@ -49,22 +49,30 @@ static VALUE rkrb5_princ_allocate(VALUE klass){
|
|
|
49
49
|
static VALUE rkrb5_princ_initialize(VALUE self, VALUE v_name){
|
|
50
50
|
RUBY_KRB5_PRINC* ptr;
|
|
51
51
|
krb5_error_code kerror;
|
|
52
|
+
|
|
52
53
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
54
|
+
|
|
53
55
|
kerror = krb5_init_context(&ptr->ctx);
|
|
56
|
+
|
|
54
57
|
if(kerror)
|
|
55
58
|
rb_raise(cKrb5Exception, "krb5_init_context failed: %s", error_message(kerror));
|
|
59
|
+
|
|
56
60
|
if(NIL_P(v_name)){
|
|
57
61
|
rb_iv_set(self, "@principal", Qnil);
|
|
58
62
|
}
|
|
59
63
|
else{
|
|
60
64
|
char* name;
|
|
61
65
|
Check_Type(v_name, T_STRING);
|
|
66
|
+
|
|
62
67
|
name = StringValueCStr(v_name);
|
|
63
68
|
kerror = krb5_parse_name(ptr->ctx, name, &ptr->principal);
|
|
69
|
+
|
|
64
70
|
if(kerror)
|
|
65
71
|
rb_raise(cKrb5Exception, "krb5_parse_name failed: %s", error_message(kerror));
|
|
72
|
+
|
|
66
73
|
rb_iv_set(self, "@principal", v_name);
|
|
67
74
|
}
|
|
75
|
+
|
|
68
76
|
rb_iv_set(self, "@attributes", Qnil);
|
|
69
77
|
rb_iv_set(self, "@aux_attributes", Qnil);
|
|
70
78
|
rb_iv_set(self, "@expire_time", Qnil);
|
|
@@ -79,8 +87,10 @@ static VALUE rkrb5_princ_initialize(VALUE self, VALUE v_name){
|
|
|
79
87
|
rb_iv_set(self, "@password_expiration", Qnil);
|
|
80
88
|
rb_iv_set(self, "@policy", Qnil);
|
|
81
89
|
rb_iv_set(self, "@kvno", Qnil);
|
|
90
|
+
|
|
82
91
|
if(rb_block_given_p())
|
|
83
92
|
rb_yield(self);
|
|
93
|
+
|
|
84
94
|
return self;
|
|
85
95
|
}
|
|
86
96
|
|
|
@@ -92,7 +102,12 @@ static VALUE rkrb5_princ_initialize(VALUE self, VALUE v_name){
|
|
|
92
102
|
*/
|
|
93
103
|
static VALUE rkrb5_princ_get_realm(VALUE self){
|
|
94
104
|
RUBY_KRB5_PRINC* ptr;
|
|
105
|
+
|
|
95
106
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
107
|
+
|
|
108
|
+
if(!ptr->principal)
|
|
109
|
+
rb_raise(cKrb5Exception, "no principal has been established");
|
|
110
|
+
|
|
96
111
|
return rb_str_new2(krb5_princ_realm(ptr->ctx, ptr->principal)->data);
|
|
97
112
|
}
|
|
98
113
|
|
|
@@ -104,9 +119,16 @@ static VALUE rkrb5_princ_get_realm(VALUE self){
|
|
|
104
119
|
*/
|
|
105
120
|
static VALUE rkrb5_princ_set_realm(VALUE self, VALUE v_realm){
|
|
106
121
|
RUBY_KRB5_PRINC* ptr;
|
|
122
|
+
|
|
107
123
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
124
|
+
|
|
125
|
+
if(!ptr->principal)
|
|
126
|
+
rb_raise(cKrb5Exception, "no principal has been established");
|
|
127
|
+
|
|
108
128
|
Check_Type(v_realm, T_STRING);
|
|
129
|
+
|
|
109
130
|
krb5_set_principal_realm(ptr->ctx, ptr->principal, StringValueCStr(v_realm));
|
|
131
|
+
|
|
110
132
|
return v_realm;
|
|
111
133
|
}
|
|
112
134
|
|
|
@@ -120,10 +142,16 @@ static VALUE rkrb5_princ_equal(VALUE self, VALUE v_other){
|
|
|
120
142
|
RUBY_KRB5_PRINC* ptr1;
|
|
121
143
|
RUBY_KRB5_PRINC* ptr2;
|
|
122
144
|
VALUE v_bool = Qfalse;
|
|
145
|
+
|
|
123
146
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr1);
|
|
124
147
|
TypedData_Get_Struct(v_other, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr2);
|
|
148
|
+
|
|
149
|
+
if(!ptr1->principal || !ptr2->principal)
|
|
150
|
+
return Qfalse;
|
|
151
|
+
|
|
125
152
|
if(krb5_principal_compare(ptr1->ctx, ptr1->principal, ptr2->principal))
|
|
126
153
|
v_bool = Qtrue;
|
|
154
|
+
|
|
127
155
|
return v_bool;
|
|
128
156
|
}
|
|
129
157
|
|