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.
@@ -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
- krb5_kt_cursor cursor;
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
- kerror = krb5_kt_start_seq_get(
58
- ptr->ctx,
59
- ptr->keytab,
60
- &cursor
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
- while((kerror = krb5_kt_next_entry(ptr->ctx, ptr->keytab, &entry, &cursor)) == 0){
67
- krb5_unparse_name(ptr->ctx, entry.principal, &principal);
117
+ ea.cursor_active = 1;
68
118
 
69
- v_kt_entry = rb_class_new_instance(0, NULL, cKrb5KtEntry);
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+. If the
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, "krb5_unparse_name: %s", error_message(kerror));
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
- vno = 0;
275
- enctype = 0;
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
- krb5_kt_cursor cursor;
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(&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(context, keytab_name, MAX_KEYTAB_NAME_LEN);
584
+ kerror = krb5_kt_default_name(fa.ctx, keytab_name, MAX_KEYTAB_NAME_LEN);
397
585
 
398
586
  if(kerror){
399
- if(context)
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
- if(context)
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
- if(context)
432
- krb5_free_context(context);
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
- while((kerror = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){
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
- if(context)
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);
@@ -63,7 +63,8 @@ static VALUE rkrb5_kt_entry_inspect(VALUE self){
63
63
 
64
64
  rb_str_buf_cat2(v_str, "key=");
65
65
  rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@key")));
66
- rb_str_buf_cat2(v_str, " ");
66
+
67
+ rb_str_buf_cat2(v_str, ">");
67
68
 
68
69
  return v_str;
69
70
  }
@@ -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