rkerberos 0.2.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d95bc44b05fe9b2d7d50af063944d2464a39e2387c6af3c9b8dbefd68025e94
4
- data.tar.gz: 8dcdcec07fcdd598065fc7e826dda60b66a683c0cfb500aaa594fdbe5b5c3326
3
+ metadata.gz: 10c43a653634532f7c52f8156f9ea2c9b5646d9bdff60866f8dde301c1abe5e7
4
+ data.tar.gz: 99021863b149758d3231938481736878027ad99ef8b4056d3d994e0b0a8dbffb
5
5
  SHA512:
6
- metadata.gz: ee3844d89f82e24b9447f67538e40f9af8d4df630c3e3da757e0ce8c3d54b1ba1d3a57d48db0c2ed4001a687dd1ccfbcb2e3c5ef6eb120b5eed5802964a47f74
7
- data.tar.gz: 93003f70201a17ecbc3f158cf4fa997657ee1d25b1c28d3e3019207f3b3664d880db4d3297a8a542d54343ad4fe2f38afa607b028ea161d6bbb50a1a526f4e63
6
+ metadata.gz: c74926903cdbbcafe0e756189b0e5b53308fc30f4808d090d8091e92941c28f9c7e4629f61c9fb30df130990574bec809f42cfccee9d75d9b697e27e5654889f
7
+ data.tar.gz: 798be63f34c776a54d1ea54556edc36d965ac0149b7a04414f37b16db3439f8ea1dc8ae7d0f64a0c826c3f80d7cdea0818f5c519a2a77bac0495fa3cb4a44317
data/CHANGES.md CHANGED
@@ -1,4 +1,17 @@
1
- = 0.2.1 - 1-Mar-2026
1
+ # 0.2.2 - 3-Mar-2026
2
+ * Added custom .dup methods for CredentialsCache and Keytab.
3
+ * Added the keytab_name and keytab_type methods to Keytab.
4
+ * Added the cache_name, cache_type and principal methods to CredentialsCache.
5
+ * The Keytab#get_entry method now properly honors the vno and encoding type arguments.
6
+ * Fixed the max_life and max_rlife attributes in Config.
7
+ * Fixed the get_privileges method in Kadm5.
8
+ * Fixed the change_password method in Kadm5 and added specs for it. Previously it would
9
+ generally always return true because it wasn't considering KDC failures, only raw
10
+ function failures.
11
+ * Heaps of memory leak fixes. Get it? Heaps? Right, I'll see myself out.
12
+ * Converted the CHANGES and MANIFEST files to markdown.
13
+
14
+ # 0.2.1 - 1-Mar-2026
2
15
  * Added the verify_init_creds and an authenticate! methods.
3
16
  * The Context constructor now accepts optional :secure and/or :profile arguments
4
17
  for different types of contexts.
@@ -10,37 +23,37 @@
10
23
  * The rake-compiler gem is now a development dependency, not a runtime
11
24
  dependency (thanks Ondřej Gajdušek).
12
25
 
13
- = 0.2.0 - 14-Feb-2026
26
+ # 0.2.0 - 14-Feb-2026
14
27
  * Added Docker and Podman support for running tests in isolated environments with Kerberos and OpenLDAP services.
15
28
  * Updated documentation with modern testing and development workflows, including container-based instructions.
16
29
  * Improved compatibility for Ruby 3.4 and later.
17
30
  * Enhanced build and test automation using docker-compose and podman-compose.
18
31
  * Various bug fixes, code cleanups, and test improvements.
19
32
 
20
- = 0.1.5 - 17-Oct-2016
33
+ # 0.1.5 - 17-Oct-2016
21
34
  * Fix build error on Ruby 2.0.0/2.1 with CFLAGS concatenation
22
35
 
23
- = 0.1.4 - 14-Oct-2016
36
+ # 0.1.4 - 14-Oct-2016
24
37
  * Implement db_args functionality in kadmin (fixes #8)
25
38
  * Fix a double-free error when setting the realm for a principal
26
39
  * Fix an error in policy creation that would sometimes cause a communication failure
27
40
  * Set C99 as the C Standard and fix all compiler warnings at this level
28
41
 
29
- = 0.1.3 - 07-Sep-2013
42
+ # 0.1.3 - 07-Sep-2013
30
43
  * Add optional 'service' argument to get_init_creds_password (fixes #3)
31
44
  * Artistic License 2.0 text now included (fixes #2)
32
45
 
33
- = 0.1.2 - 24-Jun-2013
46
+ # 0.1.2 - 24-Jun-2013
34
47
  * Fix kadm5clnt build issue on EL6
35
48
  * Remove admin_keytab references for krb5 1.11
36
49
  * Add Gemfile
37
50
  * Replace deprecated Config with RbConfig (Ruby 2)
38
51
 
39
- = 0.1.1 - 08-May-2013
52
+ # 0.1.1 - 08-May-2013
40
53
  * Add credential cache argument to get_init_creds_keytab
41
54
  * Fixed invalid VALUE declarations affecting non-gcc compilers
42
55
  * Add OS X install instructions
43
56
 
44
- = 0.1.0 - 28-Apr-2011
57
+ # 0.1.0 - 28-Apr-2011
45
58
  * Initial release. This is effectively a re-release of my own custom branch
46
59
  of the krb5-auth library, with some minor changes.
data/MANIFEST.md CHANGED
@@ -1,16 +1,24 @@
1
- CHANGES.md
2
- rkerberos.gemspec
3
- MANIFEST.md
4
- Rakefile
5
- README
6
- ext/ccache.c
7
- ext/context.c
8
- ext/extconf.rb
9
- ext/kadm5.c
10
- ext/keytab.c
11
- ext/keytab_entry.c
12
- ext/rkerberos.c
13
- ext/rkerberos.h
14
- ext/policy.c
15
- ext/principal.c
16
- test/test_krb5.rb
1
+ * CHANGES.md
2
+ * rkerberos.gemspec
3
+ * MANIFEST.md
4
+ * Rakefile
5
+ * README
6
+ * ext/ccache.c
7
+ * ext/context.c
8
+ * ext/extconf.rb
9
+ * ext/kadm5.c
10
+ * ext/keytab.c
11
+ * ext/keytab_entry.c
12
+ * ext/rkerberos.c
13
+ * ext/rkerberos.h
14
+ * ext/policy.c
15
+ * ext/principal.c
16
+ * spec/config_spec.rb
17
+ * spec/context_spec.rb
18
+ * spec/credentials_spec.rb
19
+ * spec/kadm5_spec.rb
20
+ * spec/keytab_entry_spec.rb
21
+ * spec/krb5_keytab_spec.rb
22
+ * spec/krb5_spec.rb
23
+ * spec/policy_spec.rb
24
+ * spec/principal_spec.rb
data/Rakefile CHANGED
@@ -100,7 +100,10 @@ namespace :spec do
100
100
 
101
101
  FileUtils.rm_rf('Gemfile.lock')
102
102
  begin
103
- sh "#{compose} build --no-cache rkerberos-test" unless fast
103
+ unless fast
104
+ sh "#{compose} build --no-cache kerberos-kdc"
105
+ sh "#{compose} build --no-cache rkerberos-test"
106
+ end
104
107
  sh "#{compose} run --rm rkerberos-test"
105
108
  ensure
106
109
  # redirect stderr so missing-container messages don't appear
@@ -157,6 +157,40 @@ static VALUE rkrb5_ccache_default_name(VALUE self){
157
157
  return rb_str_new2(krb5_cc_default_name(ptr->ctx));
158
158
  }
159
159
 
160
+ // Wrapper for krb5_cc_get_name; returns the actual ccache name.
161
+ static VALUE rkrb5_ccache_get_name(VALUE self){
162
+ RUBY_KRB5_CCACHE* ptr;
163
+ const char *name;
164
+
165
+ TypedData_Get_Struct(self, RUBY_KRB5_CCACHE, &rkrb5_ccache_data_type, ptr);
166
+
167
+ if(!ptr->ctx)
168
+ rb_raise(cKrb5Exception, "no context has been established");
169
+
170
+ name = krb5_cc_get_name(ptr->ctx, ptr->ccache);
171
+ if(!name)
172
+ rb_raise(cKrb5Exception, "krb5_cc_get_name returned NULL");
173
+
174
+ return rb_str_new2(name);
175
+ }
176
+
177
+ // Wrapper for krb5_cc_get_type; returns the cache type string.
178
+ static VALUE rkrb5_ccache_get_type(VALUE self){
179
+ RUBY_KRB5_CCACHE* ptr;
180
+ const char *type;
181
+
182
+ TypedData_Get_Struct(self, RUBY_KRB5_CCACHE, &rkrb5_ccache_data_type, ptr);
183
+
184
+ if(!ptr->ctx)
185
+ rb_raise(cKrb5Exception, "no context has been established");
186
+
187
+ type = krb5_cc_get_type(ptr->ctx, ptr->ccache);
188
+ if(!type)
189
+ rb_raise(cKrb5Exception, "krb5_cc_get_type returned NULL");
190
+
191
+ return rb_str_new2(type);
192
+ }
193
+
160
194
  /*
161
195
  * call-seq:
162
196
  * ccache.primary_principal
@@ -173,6 +207,11 @@ static VALUE rkrb5_ccache_primary_principal(VALUE self){
173
207
  if(!ptr->ctx)
174
208
  rb_raise(cKrb5Exception, "no context has been established");
175
209
 
210
+ if(ptr->principal){
211
+ krb5_free_principal(ptr->ctx, ptr->principal);
212
+ ptr->principal = NULL;
213
+ }
214
+
176
215
  kerror = krb5_cc_get_principal(ptr->ctx, ptr->ccache, &ptr->principal);
177
216
 
178
217
  if(kerror)
@@ -183,7 +222,15 @@ static VALUE rkrb5_ccache_primary_principal(VALUE self){
183
222
  if(kerror)
184
223
  rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
185
224
 
186
- return rb_str_new2(name);
225
+ VALUE v_name = rb_str_new2(name);
226
+ krb5_free_unparsed_name(ptr->ctx, name);
227
+
228
+ return v_name;
229
+ }
230
+
231
+ // Simple wrapper around krb5_cc_get_principal returning a principal name string.
232
+ static VALUE rkrb5_ccache_principal(VALUE self){
233
+ return rkrb5_ccache_primary_principal(self);
187
234
  }
188
235
 
189
236
  /*
@@ -237,6 +284,47 @@ static VALUE rkrb5_ccache_destroy(VALUE self){
237
284
  return v_bool;
238
285
  }
239
286
 
287
+ // Duplicate the credentials cache object.
288
+ // call-seq:
289
+ // ccache.dup -> new_ccache
290
+ //
291
+ // Returns a new Kerberos::Krb5::CredentialsCache that references the
292
+ // same underlying cache data. The new object has its own krb5 context so
293
+ // that closing one cache does not affect the other.
294
+ static VALUE rkrb5_ccache_dup(VALUE self){
295
+ RUBY_KRB5_CCACHE *ptr, *newptr;
296
+ krb5_error_code kerror;
297
+ VALUE newobj;
298
+
299
+ TypedData_Get_Struct(self, RUBY_KRB5_CCACHE, &rkrb5_ccache_data_type, ptr);
300
+
301
+ if(!ptr->ctx)
302
+ rb_raise(cKrb5Exception, "no context has been established");
303
+
304
+ // allocate new ruby object and struct
305
+ newobj = rkrb5_ccache_allocate(CLASS_OF(self));
306
+ TypedData_Get_Struct(newobj, RUBY_KRB5_CCACHE, &rkrb5_ccache_data_type, newptr);
307
+
308
+ // initialize a fresh context for the duplicate
309
+ kerror = krb5_init_context(&newptr->ctx);
310
+ if(kerror){
311
+ rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
312
+ }
313
+
314
+ // perform ccache duplication using the new context
315
+ kerror = krb5_cc_dup(newptr->ctx, ptr->ccache, &newptr->ccache);
316
+ if(kerror){
317
+ krb5_free_context(newptr->ctx);
318
+ newptr->ctx = NULL;
319
+ rb_raise(cKrb5Exception, "krb5_cc_dup: %s", error_message(kerror));
320
+ }
321
+
322
+ // principal is not copied; let callers query primary_principal on each
323
+ newptr->principal = NULL;
324
+
325
+ return newobj;
326
+ }
327
+
240
328
  void Init_ccache(void){
241
329
  /* The Kerberos::Krb5::CredentialsCache class encapsulates a Kerberos credentials cache. */
242
330
  cKrb5CCache = rb_define_class_under(cKrb5, "CredentialsCache", rb_cObject);
@@ -250,8 +338,13 @@ void Init_ccache(void){
250
338
  // Instance Methods
251
339
  rb_define_method(cKrb5CCache, "close", rkrb5_ccache_close, 0);
252
340
  rb_define_method(cKrb5CCache, "default_name", rkrb5_ccache_default_name, 0);
341
+ rb_define_method(cKrb5CCache, "cache_name", rkrb5_ccache_get_name, 0);
342
+ rb_define_method(cKrb5CCache, "cache_type", rkrb5_ccache_get_type, 0);
253
343
  rb_define_method(cKrb5CCache, "destroy", rkrb5_ccache_destroy, 0);
254
344
  rb_define_method(cKrb5CCache, "primary_principal", rkrb5_ccache_primary_principal, 0);
345
+ rb_define_method(cKrb5CCache, "principal", rkrb5_ccache_principal, 0);
346
+ rb_define_method(cKrb5CCache, "dup", rkrb5_ccache_dup, 0);
347
+ rb_define_alias(cKrb5CCache, "clone", "dup");
255
348
 
256
349
  // Aliases
257
350
  rb_define_alias(cKrb5CCache, "delete", "destroy");
@@ -263,12 +263,12 @@ static VALUE rkadm5_config_inspect(VALUE self){
263
263
  rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@mkey_from_kbd")));
264
264
  rb_str_buf_cat2(v_str, " ");
265
265
 
266
- rb_str_buf_cat2(v_str, "maxlife=");
267
- rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@maxlife")));
266
+ rb_str_buf_cat2(v_str, "max_life=");
267
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@max_life")));
268
268
  rb_str_buf_cat2(v_str, " ");
269
269
 
270
- rb_str_buf_cat2(v_str, "maxrlife=");
271
- rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@maxrlife")));
270
+ rb_str_buf_cat2(v_str, "max_rlife=");
271
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@max_rlife")));
272
272
  rb_str_buf_cat2(v_str, " ");
273
273
 
274
274
  rb_str_buf_cat2(v_str, "num_keysalts=");
@@ -8,6 +8,7 @@ VALUE cKadm5PrincipalNotFoundException;
8
8
 
9
9
  // Prototype
10
10
  static VALUE rkadm5_close(VALUE);
11
+ static void free_tl_data(krb5_tl_data *);
11
12
  char** parse_db_args(VALUE v_db_args);
12
13
  void add_db_args(kadm5_principal_ent_rec*, char**);
13
14
  void add_tl_data(krb5_int16 *, krb5_tl_data **,
@@ -18,6 +19,8 @@ void add_tl_data(krb5_int16 *, krb5_tl_data **,
18
19
  static void rkadm5_typed_free(void *ptr) {
19
20
  if (!ptr) return;
20
21
  RUBY_KADM5 *k = (RUBY_KADM5 *)ptr;
22
+ if (k->handle)
23
+ kadm5_destroy(k->handle);
21
24
  if (k->princ)
22
25
  krb5_free_principal(k->ctx, k->princ);
23
26
  if (k->ctx)
@@ -72,6 +75,7 @@ static VALUE rkadm5_initialize(VALUE self, VALUE v_opts){
72
75
  char* pass = NULL;
73
76
  char* keytab = NULL;
74
77
  char* service = NULL;
78
+ char default_keytab_name[MAX_KEYTAB_NAME_LEN];
75
79
  krb5_error_code kerror;
76
80
 
77
81
  TypedData_Get_Struct(self, RUBY_KADM5, &rkadm5_data_type, ptr);
@@ -126,14 +130,12 @@ static VALUE rkadm5_initialize(VALUE self, VALUE v_opts){
126
130
  // The docs say I can use NULL to get the default, but reality appears to be otherwise.
127
131
  if(RTEST(v_keytab)){
128
132
  if(TYPE(v_keytab) == T_TRUE){
129
- char default_name[MAX_KEYTAB_NAME_LEN];
130
-
131
- kerror = krb5_kt_default_name(ptr->ctx, default_name, MAX_KEYTAB_NAME_LEN);
133
+ kerror = krb5_kt_default_name(ptr->ctx, default_keytab_name, MAX_KEYTAB_NAME_LEN);
132
134
 
133
135
  if(kerror)
134
136
  rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
135
137
 
136
- keytab = default_name;
138
+ keytab = default_keytab_name;
137
139
  }
138
140
  else{
139
141
  Check_Type(v_keytab, T_STRING);
@@ -206,6 +208,11 @@ static VALUE rkadm5_set_password(VALUE self, VALUE v_user, VALUE v_pass){
206
208
  if(!ptr->ctx)
207
209
  rb_raise(cKadm5Exception, "no context has been established");
208
210
 
211
+ if(ptr->princ){
212
+ krb5_free_principal(ptr->ctx, ptr->princ);
213
+ ptr->princ = NULL;
214
+ }
215
+
209
216
  kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
210
217
 
211
218
  if(kerror)
@@ -239,6 +246,11 @@ static VALUE rkadm5_set_pwexpire(VALUE self, VALUE v_user, VALUE v_pwexpire){
239
246
  if(!ptr->ctx)
240
247
  rb_raise(cKadm5Exception, "no context has been established");
241
248
 
249
+ if(ptr->princ){
250
+ krb5_free_principal(ptr->ctx, ptr->princ);
251
+ ptr->princ = NULL;
252
+ }
253
+
242
254
  kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
243
255
 
244
256
  if(kerror)
@@ -258,6 +270,8 @@ static VALUE rkadm5_set_pwexpire(VALUE self, VALUE v_user, VALUE v_pwexpire){
258
270
  ent.pw_expiration=pwexpire;
259
271
  kerror = kadm5_modify_principal(ptr->handle, &ent, KADM5_PW_EXPIRATION);
260
272
 
273
+ kadm5_free_principal_ent(ptr->handle, &ent);
274
+
261
275
  if(kerror)
262
276
  rb_raise(cKadm5Exception, "kadm5_set_pwexpire: %s", error_message(kerror));
263
277
 
@@ -307,15 +321,21 @@ static VALUE rkadm5_create_principal(int argc, VALUE* argv, VALUE self){
307
321
 
308
322
  kerror = krb5_parse_name(ptr->ctx, user, &princ.principal);
309
323
 
310
- if(kerror)
324
+ if(kerror){
325
+ free_tl_data(princ.tl_data);
311
326
  rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
327
+ }
312
328
 
313
329
  kerror = kadm5_create_principal(ptr->handle, &princ, mask, pass);
314
330
 
315
- if(kerror)
331
+ if(kerror){
332
+ krb5_free_principal(ptr->ctx, princ.principal);
333
+ free_tl_data(princ.tl_data);
316
334
  rb_raise(cKadm5Exception, "kadm5_create_principal: %s", error_message(kerror));
335
+ }
317
336
 
318
337
  krb5_free_principal(ptr->ctx, princ.principal);
338
+ free_tl_data(princ.tl_data);
319
339
 
320
340
  return self;
321
341
  }
@@ -337,6 +357,11 @@ static VALUE rkadm5_delete_principal(VALUE self, VALUE v_user){
337
357
  if(!ptr->ctx)
338
358
  rb_raise(cKadm5Exception, "no context has been established");
339
359
 
360
+ if(ptr->princ){
361
+ krb5_free_principal(ptr->ctx, ptr->princ);
362
+ ptr->princ = NULL;
363
+ }
364
+
340
365
  kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
341
366
 
342
367
  if(kerror)
@@ -364,15 +389,15 @@ static VALUE rkadm5_close(VALUE self){
364
389
  RUBY_KADM5* ptr;
365
390
  TypedData_Get_Struct(self, RUBY_KADM5, &rkadm5_data_type, ptr);
366
391
 
392
+ if(ptr->handle)
393
+ kadm5_destroy(ptr->handle);
394
+
367
395
  if(ptr->princ)
368
396
  krb5_free_principal(ptr->ctx, ptr->princ);
369
397
 
370
398
  if(ptr->ctx)
371
399
  krb5_free_context(ptr->ctx);
372
400
 
373
- if(ptr->handle)
374
- kadm5_destroy(ptr->handle);
375
-
376
401
  free(ptr->db_args);
377
402
 
378
403
  ptr->db_args = NULL;
@@ -405,10 +430,10 @@ static VALUE create_principal_from_entry(VALUE v_name, RUBY_KADM5* ptr, kadm5_pr
405
430
  if(ent->last_failed)
406
431
  rb_iv_set(v_principal, "@last_failed", rb_time_new(ent->last_failed, 0));
407
432
 
408
- if(ent->last_failed)
433
+ if(ent->last_pwd_change)
409
434
  rb_iv_set(v_principal, "@last_password_change", rb_time_new(ent->last_pwd_change, 0));
410
435
 
411
- if(ent->last_failed)
436
+ if(ent->last_success)
412
437
  rb_iv_set(v_principal, "@last_success", rb_time_new(ent->last_success, 0));
413
438
 
414
439
  rb_iv_set(v_principal, "@max_life", LONG2FIX(ent->max_life));
@@ -425,6 +450,7 @@ static VALUE create_principal_from_entry(VALUE v_name, RUBY_KADM5* ptr, kadm5_pr
425
450
  rb_raise(cKadm5Exception, "krb5_unparse_name: %s", error_message(kerror));
426
451
 
427
452
  rb_iv_set(v_principal, "@mod_name", rb_str_new2(mod_name));
453
+ krb5_free_unparsed_name(ptr->ctx, mod_name);
428
454
  }
429
455
 
430
456
  if(ent->pw_expiration)
@@ -464,6 +490,11 @@ static VALUE rkadm5_find_principal(VALUE self, VALUE v_user){
464
490
  if(!ptr->ctx)
465
491
  rb_raise(cKadm5Exception, "no context has been established");
466
492
 
493
+ if(ptr->princ){
494
+ krb5_free_principal(ptr->ctx, ptr->princ);
495
+ ptr->princ = NULL;
496
+ }
497
+
467
498
  kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
468
499
 
469
500
  if(kerror)
@@ -487,6 +518,7 @@ static VALUE rkadm5_find_principal(VALUE self, VALUE v_user){
487
518
  }
488
519
  else{
489
520
  v_principal = create_principal_from_entry(v_user, ptr, &ent);
521
+ kadm5_free_principal_ent(ptr->handle, &ent);
490
522
  }
491
523
 
492
524
  return v_principal;
@@ -520,6 +552,11 @@ static VALUE rkadm5_get_principal(VALUE self, VALUE v_user){
520
552
  if(!ptr->ctx)
521
553
  rb_raise(cKadm5Exception, "no context has been established");
522
554
 
555
+ if(ptr->princ){
556
+ krb5_free_principal(ptr->ctx, ptr->princ);
557
+ ptr->princ = NULL;
558
+ }
559
+
523
560
  kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
524
561
 
525
562
  if(kerror)
@@ -543,6 +580,8 @@ static VALUE rkadm5_get_principal(VALUE self, VALUE v_user){
543
580
 
544
581
  v_principal = create_principal_from_entry(v_user, ptr, &ent);
545
582
 
583
+ kadm5_free_principal_ent(ptr->handle, &ent);
584
+
546
585
  return v_principal;
547
586
  }
548
587
 
@@ -609,7 +648,7 @@ static VALUE rkadm5_create_policy(VALUE self, VALUE v_policy){
609
648
 
610
649
  if(RTEST(v_history_num)){
611
650
  mask |= KADM5_PW_HISTORY_NUM;
612
- ent.pw_max_life = NUM2LONG(v_history_num);
651
+ ent.pw_history_num = NUM2LONG(v_history_num);
613
652
  }
614
653
 
615
654
  kerror = kadm5_create_policy(ptr->handle, &ent, mask);
@@ -694,6 +733,8 @@ static VALUE rkadm5_get_policy(VALUE self, VALUE v_name){
694
733
  v_arg[0] = v_hash;
695
734
 
696
735
  v_policy = rb_class_new_instance(1, v_arg, cKadm5Policy);
736
+
737
+ kadm5_free_policy_ent(ptr->handle, &ent);
697
738
  }
698
739
 
699
740
  return v_policy;
@@ -749,6 +790,8 @@ static VALUE rkadm5_find_policy(VALUE self, VALUE v_name){
749
790
  v_arg[0] = v_hash;
750
791
 
751
792
  v_policy = rb_class_new_instance(1, v_arg, cKadm5Policy);
793
+
794
+ kadm5_free_policy_ent(ptr->handle, &ent);
752
795
  }
753
796
 
754
797
  return v_policy;
@@ -906,15 +949,14 @@ static VALUE rkadm5_get_principals(int argc, VALUE* argv, VALUE self){
906
949
  * KADM5_PRIV_ADD (0x02) => "ADD"
907
950
  * KADM5_PRIV_MODIFY (0x04) => "MODIFY"
908
951
  * KADM5_PRIV_DELETE (0x08) => "DELETE"
952
+ *
909
953
  */
910
954
  static VALUE rkadm5_get_privs(int argc, VALUE* argv, VALUE self){
911
955
  RUBY_KADM5* ptr;
912
956
  VALUE v_return = Qnil;
913
957
  VALUE v_strings = Qfalse;
914
958
  kadm5_ret_t kerror;
915
- unsigned int i;
916
959
  long privs;
917
- int result = 0;
918
960
 
919
961
  TypedData_Get_Struct(self, RUBY_KADM5, &rkadm5_data_type, ptr);
920
962
 
@@ -928,31 +970,17 @@ static VALUE rkadm5_get_privs(int argc, VALUE* argv, VALUE self){
928
970
  if(RTEST(v_strings)){
929
971
  v_return = rb_ary_new();
930
972
 
931
- for(i = 0; i < sizeof(privs); i++){
932
- result |= (privs & 1 << i);
933
- switch(privs & 1 << i){
934
- case KADM5_PRIV_GET:
935
- rb_ary_push(v_return, rb_str_new2("GET"));
936
- break;
937
- case KADM5_PRIV_ADD:
938
- rb_ary_push(v_return, rb_str_new2("ADD"));
939
- break;
940
- case KADM5_PRIV_MODIFY:
941
- rb_ary_push(v_return, rb_str_new2("MODIFY"));
942
- break;
943
- case KADM5_PRIV_DELETE:
944
- rb_ary_push(v_return, rb_str_new2("DELETE"));
945
- break;
946
- default:
947
- rb_ary_push(v_return, rb_str_new2("UNKNOWN"));
948
- };
949
- }
973
+ if(privs & KADM5_PRIV_GET)
974
+ rb_ary_push(v_return, rb_str_new2("GET"));
975
+ if(privs & KADM5_PRIV_ADD)
976
+ rb_ary_push(v_return, rb_str_new2("ADD"));
977
+ if(privs & KADM5_PRIV_MODIFY)
978
+ rb_ary_push(v_return, rb_str_new2("MODIFY"));
979
+ if(privs & KADM5_PRIV_DELETE)
980
+ rb_ary_push(v_return, rb_str_new2("DELETE"));
950
981
  }
951
982
  else{
952
- for(i = 0; i < sizeof(privs); i++){
953
- result |= (privs & 1 << i);
954
- }
955
- v_return = INT2FIX(result);
983
+ v_return = LONG2FIX(privs);
956
984
  }
957
985
 
958
986
  return v_return;
@@ -987,13 +1015,16 @@ static VALUE rkadm5_randkey_principal(VALUE self, VALUE v_user){
987
1015
 
988
1016
  kerror = kadm5_randkey_principal(ptr->handle, princ, &keys, &n_keys);
989
1017
 
990
- if(kerror)
1018
+ if(kerror){
1019
+ krb5_free_principal(ptr->ctx, princ);
991
1020
  rb_raise(cKadm5Exception, "kadm5_randkey_principal: %s (%li)", error_message(kerror), kerror);
1021
+ }
992
1022
 
993
1023
  for(i = 0; i < n_keys; i++)
994
1024
  krb5_free_keyblock_contents(ptr->ctx, &keys[i]);
995
1025
 
996
1026
  free(keys);
1027
+ krb5_free_principal(ptr->ctx, princ);
997
1028
 
998
1029
  return INT2NUM(n_keys);
999
1030
  }
@@ -1014,7 +1045,7 @@ char** parse_db_args(VALUE v_db_args){
1014
1045
  case T_ARRAY:
1015
1046
  // Multiple arguments
1016
1047
  array_length = RARRAY_LEN(v_db_args);
1017
- db_args = (char **) malloc(array_length * sizeof(char *) + 1);
1048
+ db_args = (char **) malloc((array_length + 1) * sizeof(char *));
1018
1049
  for(long i = 0; i < array_length; ++i){
1019
1050
  VALUE elem = rb_ary_entry(v_db_args, i);
1020
1051
  Check_Type(elem, T_STRING);
@@ -1046,6 +1077,15 @@ void add_db_args(kadm5_principal_ent_rec* entry, char** db_args){
1046
1077
  /**
1047
1078
  * Source code taken from kadmin source code at https://github.com/krb5/krb5/blob/master/src/kadmin/cli/kadmin.c
1048
1079
  */
1080
+ static void free_tl_data(krb5_tl_data *tl){
1081
+ while(tl){
1082
+ krb5_tl_data *next = tl->tl_data_next;
1083
+ free(tl->tl_data_contents);
1084
+ free(tl);
1085
+ tl = next;
1086
+ }
1087
+ }
1088
+
1049
1089
  void add_tl_data(krb5_int16 *n_tl_datap, krb5_tl_data **tl_datap,
1050
1090
  krb5_int16 tl_type, krb5_ui_2 len, krb5_octet *contents){
1051
1091
  krb5_tl_data* tl_data;