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 +4 -4
- data/CHANGES.md +21 -8
- data/MANIFEST.md +24 -16
- data/Rakefile +4 -1
- data/ext/rkerberos/ccache.c +94 -1
- data/ext/rkerberos/config.c +4 -4
- data/ext/rkerberos/kadm5.c +79 -39
- data/ext/rkerberos/keytab.c +237 -106
- data/ext/rkerberos/rkerberos.c +74 -5
- data/rkerberos.gemspec +1 -1
- data/spec/config_spec.rb +4 -4
- data/spec/credentials_cache_spec.rb +53 -0
- data/spec/kadm5_spec.rb +40 -1
- data/spec/krb5_keytab_spec.rb +195 -0
- data/spec/krb5_spec.rb +71 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10c43a653634532f7c52f8156f9ea2c9b5646d9bdff60866f8dde301c1abe5e7
|
|
4
|
+
data.tar.gz: 99021863b149758d3231938481736878027ad99ef8b4056d3d994e0b0a8dbffb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c74926903cdbbcafe0e756189b0e5b53308fc30f4808d090d8091e92941c28f9c7e4629f61c9fb30df130990574bec809f42cfccee9d75d9b697e27e5654889f
|
|
7
|
+
data.tar.gz: 798be63f34c776a54d1ea54556edc36d965ac0149b7a04414f37b16db3439f8ea1dc8ae7d0f64a0c826c3f80d7cdea0818f5c519a2a77bac0495fa3cb4a44317
|
data/CHANGES.md
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
data/ext/rkerberos/ccache.c
CHANGED
|
@@ -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
|
-
|
|
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");
|
data/ext/rkerberos/config.c
CHANGED
|
@@ -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, "
|
|
267
|
-
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@
|
|
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, "
|
|
271
|
-
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@
|
|
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=");
|
data/ext/rkerberos/kadm5.c
CHANGED
|
@@ -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
|
-
|
|
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 =
|
|
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->
|
|
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->
|
|
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.
|
|
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
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
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
|
-
|
|
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 *)
|
|
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;
|