rkerberos 0.2.2 → 0.3.0
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 +22 -0
- data/EXAMPLES.md +1015 -0
- data/MANIFEST.md +17 -12
- data/README.md +5 -5
- data/ext/rkerberos/ccache.c +105 -26
- data/ext/rkerberos/config.c +59 -10
- data/ext/rkerberos/context.c +76 -7
- data/ext/rkerberos/extconf.rb +16 -3
- data/ext/rkerberos/kadm5.c +301 -96
- data/ext/rkerberos/keytab.c +222 -66
- data/ext/rkerberos/keytab_entry.c +2 -1
- data/ext/rkerberos/policy.c +25 -23
- data/ext/rkerberos/principal.c +136 -10
- data/ext/rkerberos/rkerberos.c +244 -34
- data/ext/rkerberos/rkerberos.h +8 -0
- data/rkerberos.gemspec +10 -7
- data/spec/config_spec.rb +58 -3
- data/spec/context_spec.rb +57 -7
- data/spec/credentials_cache_spec.rb +106 -39
- data/spec/kadm5_spec.rb +292 -17
- data/spec/krb5_keytab_spec.rb +229 -24
- data/spec/krb5_spec.rb +142 -29
- data/spec/policy_spec.rb +12 -7
- data/spec/principal_spec.rb +102 -4
- data/spec/spec_helper.rb +34 -0
- metadata +10 -8
data/MANIFEST.md
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
* CHANGES.md
|
|
2
|
+
* EXAMPLES.md
|
|
3
|
+
* Gemfile
|
|
4
|
+
* LICENSE
|
|
2
5
|
* rkerberos.gemspec
|
|
3
6
|
* MANIFEST.md
|
|
4
7
|
* Rakefile
|
|
5
|
-
* README
|
|
6
|
-
* ext/ccache.c
|
|
7
|
-
* ext/
|
|
8
|
-
* ext/
|
|
9
|
-
* ext/
|
|
10
|
-
* ext/
|
|
11
|
-
* ext/
|
|
12
|
-
* ext/rkerberos.c
|
|
13
|
-
* ext/rkerberos.
|
|
14
|
-
* ext/
|
|
15
|
-
* ext/
|
|
8
|
+
* README.md
|
|
9
|
+
* ext/rkerberos/ccache.c
|
|
10
|
+
* ext/rkerberos/config.c
|
|
11
|
+
* ext/rkerberos/context.c
|
|
12
|
+
* ext/rkerberos/extconf.rb
|
|
13
|
+
* ext/rkerberos/kadm5.c
|
|
14
|
+
* ext/rkerberos/keytab.c
|
|
15
|
+
* ext/rkerberos/keytab_entry.c
|
|
16
|
+
* ext/rkerberos/policy.c
|
|
17
|
+
* ext/rkerberos/principal.c
|
|
18
|
+
* ext/rkerberos/rkerberos.c
|
|
19
|
+
* ext/rkerberos/rkerberos.h
|
|
16
20
|
* spec/config_spec.rb
|
|
17
21
|
* spec/context_spec.rb
|
|
18
|
-
* spec/
|
|
22
|
+
* spec/credentials_cache_spec.rb
|
|
19
23
|
* spec/kadm5_spec.rb
|
|
20
24
|
* spec/keytab_entry_spec.rb
|
|
21
25
|
* spec/krb5_keytab_spec.rb
|
|
22
26
|
* spec/krb5_spec.rb
|
|
23
27
|
* spec/policy_spec.rb
|
|
24
28
|
* spec/principal_spec.rb
|
|
29
|
+
* spec/spec_helper.rb
|
data/README.md
CHANGED
|
@@ -18,17 +18,17 @@ puts krb.get_permitted_enctypes.keys.join(',')
|
|
|
18
18
|
|
|
19
19
|
# Credentials cache
|
|
20
20
|
cc = Kerberos::Krb5::CredentialsCache.new
|
|
21
|
-
krb.verify_init_creds(
|
|
21
|
+
krb.verify_init_creds(ccache: cc)
|
|
22
22
|
puts cc.primary_principal
|
|
23
23
|
|
|
24
24
|
# Keytab
|
|
25
25
|
kt_name = Kerberos::Krb5::Keytab.new.default_name # e.g. "FILE:/etc/krb5.keytab"
|
|
26
|
-
krb.get_init_creds_keytab('host/server.example.com', kt_name)
|
|
27
|
-
krb.get_init_creds_keytab('host/server.example.com', kt_name,
|
|
26
|
+
krb.get_init_creds_keytab(principal: 'host/server.example.com', keytab: kt_name)
|
|
27
|
+
krb.get_init_creds_keytab(principal: 'host/server.example.com', keytab: kt_name, ccache: cc) # or write to cache
|
|
28
28
|
|
|
29
29
|
# Admin
|
|
30
30
|
Kerberos::Kadm5.new(principal: ENV['KRB5_ADMIN_PRINCIPAL'], password: ENV['KRB5_ADMIN_PASSWORD']) do |kadmin|
|
|
31
|
-
kadmin.create_principal('newuser@EXAMPLE.COM', 'initialpass')
|
|
31
|
+
kadmin.create_principal(name: 'newuser@EXAMPLE.COM', password: 'initialpass')
|
|
32
32
|
kadmin.set_password('newuser@EXAMPLE.COM', 'betterpass')
|
|
33
33
|
kadmin.delete_principal('newuser@EXAMPLE.COM')
|
|
34
34
|
end
|
|
@@ -79,7 +79,7 @@ ctx.close
|
|
|
79
79
|
# Testing
|
|
80
80
|
|
|
81
81
|
## Prerequisites
|
|
82
|
-
- Ruby 3.
|
|
82
|
+
- Ruby 3.2 or later
|
|
83
83
|
- Docker or Podman
|
|
84
84
|
- docker-compose or podman-compose
|
|
85
85
|
|
data/ext/rkerberos/ccache.c
CHANGED
|
@@ -4,6 +4,13 @@ VALUE cKrb5CCache;
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// TypedData functions for RUBY_KRB5_CCACHE
|
|
7
|
+
static void rkrb5_ccache_typed_mark(void *ptr) {
|
|
8
|
+
if (!ptr) return;
|
|
9
|
+
RUBY_KRB5_CCACHE *c = (RUBY_KRB5_CCACHE *)ptr;
|
|
10
|
+
if (c->rb_context != Qnil)
|
|
11
|
+
rb_gc_mark(c->rb_context);
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
static void rkrb5_ccache_typed_free(void *ptr) {
|
|
8
15
|
if (!ptr) return;
|
|
9
16
|
RUBY_KRB5_CCACHE *c = (RUBY_KRB5_CCACHE *)ptr;
|
|
@@ -11,7 +18,7 @@ static void rkrb5_ccache_typed_free(void *ptr) {
|
|
|
11
18
|
krb5_cc_close(c->ctx, c->ccache);
|
|
12
19
|
if (c->principal)
|
|
13
20
|
krb5_free_principal(c->ctx, c->principal);
|
|
14
|
-
if (c->ctx)
|
|
21
|
+
if (c->ctx && c->rb_context == Qnil)
|
|
15
22
|
krb5_free_context(c->ctx);
|
|
16
23
|
free(c);
|
|
17
24
|
}
|
|
@@ -22,7 +29,7 @@ static size_t rkrb5_ccache_typed_size(const void *ptr) {
|
|
|
22
29
|
|
|
23
30
|
const rb_data_type_t rkrb5_ccache_data_type = {
|
|
24
31
|
"RUBY_KRB5_CCACHE",
|
|
25
|
-
{
|
|
32
|
+
{rkrb5_ccache_typed_mark, rkrb5_ccache_typed_free, rkrb5_ccache_typed_size,},
|
|
26
33
|
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
27
34
|
};
|
|
28
35
|
|
|
@@ -30,20 +37,28 @@ const rb_data_type_t rkrb5_ccache_data_type = {
|
|
|
30
37
|
static VALUE rkrb5_ccache_allocate(VALUE klass){
|
|
31
38
|
RUBY_KRB5_CCACHE* ptr = ALLOC(RUBY_KRB5_CCACHE);
|
|
32
39
|
memset(ptr, 0, sizeof(RUBY_KRB5_CCACHE));
|
|
40
|
+
ptr->rb_context = Qnil;
|
|
33
41
|
return TypedData_Wrap_Struct(klass, &rkrb5_ccache_data_type, ptr);
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
/*
|
|
37
45
|
* call-seq:
|
|
38
|
-
* Kerberos::CredentialsCache.new(principal
|
|
46
|
+
* Kerberos::CredentialsCache.new(principal: nil, cache_name: nil, context: nil)
|
|
47
|
+
*
|
|
48
|
+
* Creates and returns a new Kerberos::CredentialsCache object. Accepts the
|
|
49
|
+
* following keyword arguments:
|
|
50
|
+
*
|
|
51
|
+
* - +principal+: A string principal name. If specified, the credentials cache
|
|
52
|
+
* is created or refreshed with this as the primary principal. If a cache
|
|
53
|
+
* already exists, its contents are destroyed. May also be an object that
|
|
54
|
+
* responds to the `.principal` method.
|
|
39
55
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
56
|
+
* - +cache_name+: The name of the credentials cache to use, which must be in
|
|
57
|
+
* "type:residual" format, where 'type' is a type known to Kerberos
|
|
58
|
+
* (typically 'FILE'). If omitted, the default cache is used.
|
|
43
59
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* cache already exists, its contents are destroyed.
|
|
60
|
+
* - +context+: A Kerberos::Krb5::Context object. If provided, that context is
|
|
61
|
+
* used instead of creating a new one via krb5_init_context.
|
|
47
62
|
*
|
|
48
63
|
* Note that the principal's credentials are not set via the constructor.
|
|
49
64
|
* It merely creates the cache and sets the default principal.
|
|
@@ -51,23 +66,55 @@ static VALUE rkrb5_ccache_allocate(VALUE klass){
|
|
|
51
66
|
static VALUE rkrb5_ccache_initialize(int argc, VALUE* argv, VALUE self){
|
|
52
67
|
RUBY_KRB5_CCACHE* ptr;
|
|
53
68
|
krb5_error_code kerror;
|
|
54
|
-
VALUE v_principal, v_name;
|
|
69
|
+
VALUE v_opts, v_principal, v_name, v_context;
|
|
70
|
+
ID kw_table[3] = { rb_intern("principal"), rb_intern("cache_name"), rb_intern("context") };
|
|
71
|
+
VALUE kw_vals[3];
|
|
55
72
|
|
|
56
73
|
TypedData_Get_Struct(self, RUBY_KRB5_CCACHE, &rkrb5_ccache_data_type, ptr);
|
|
57
74
|
|
|
58
|
-
rb_scan_args(argc, argv, "
|
|
75
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
76
|
+
|
|
77
|
+
if(NIL_P(v_opts))
|
|
78
|
+
v_opts = rb_hash_new();
|
|
79
|
+
|
|
80
|
+
rb_get_kwargs(v_opts, kw_table, 0, 3, kw_vals);
|
|
81
|
+
v_principal = kw_vals[0] == Qundef ? Qnil : kw_vals[0];
|
|
82
|
+
v_name = kw_vals[1] == Qundef ? Qnil : kw_vals[1];
|
|
83
|
+
v_context = kw_vals[2] == Qundef ? Qnil : kw_vals[2];
|
|
84
|
+
|
|
85
|
+
if(!NIL_P(v_principal)){
|
|
86
|
+
if(rb_respond_to(v_principal, rb_intern("principal")))
|
|
87
|
+
v_principal = rb_funcall(v_principal, rb_intern("principal"), 0);
|
|
59
88
|
|
|
60
|
-
if(RTEST(v_principal))
|
|
61
89
|
Check_Type(v_principal, T_STRING);
|
|
90
|
+
}
|
|
62
91
|
|
|
63
|
-
// Initialize the context
|
|
64
|
-
|
|
92
|
+
// Initialize or borrow the context
|
|
93
|
+
if(!NIL_P(v_context)){
|
|
94
|
+
RUBY_KRB5_CONTEXT* ctx_ptr;
|
|
65
95
|
|
|
66
|
-
|
|
67
|
-
|
|
96
|
+
if(!rb_obj_is_kind_of(v_context, cKrb5Context))
|
|
97
|
+
rb_raise(rb_eTypeError, "context must be a Kerberos::Krb5::Context object");
|
|
98
|
+
|
|
99
|
+
TypedData_Get_Struct(v_context, RUBY_KRB5_CONTEXT, &rkrb5_context_data_type, ctx_ptr);
|
|
100
|
+
|
|
101
|
+
if(!ctx_ptr->ctx)
|
|
102
|
+
rb_raise(cKrb5Exception, "context is closed");
|
|
103
|
+
|
|
104
|
+
ptr->ctx = ctx_ptr->ctx;
|
|
105
|
+
ptr->rb_context = v_context;
|
|
106
|
+
}
|
|
107
|
+
else{
|
|
108
|
+
kerror = krb5_init_context(&ptr->ctx);
|
|
109
|
+
|
|
110
|
+
if(kerror)
|
|
111
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
|
112
|
+
|
|
113
|
+
ptr->rb_context = Qnil;
|
|
114
|
+
}
|
|
68
115
|
|
|
69
116
|
// Convert the principal name to a principal object
|
|
70
|
-
if(
|
|
117
|
+
if(!NIL_P(v_principal)){
|
|
71
118
|
kerror = krb5_parse_name(
|
|
72
119
|
ptr->ctx,
|
|
73
120
|
StringValueCStr(v_principal),
|
|
@@ -127,12 +174,13 @@ static VALUE rkrb5_ccache_close(VALUE self){
|
|
|
127
174
|
if(ptr->principal)
|
|
128
175
|
krb5_free_principal(ptr->ctx, ptr->principal);
|
|
129
176
|
|
|
130
|
-
if(ptr->ctx)
|
|
177
|
+
if(ptr->ctx && ptr->rb_context == Qnil)
|
|
131
178
|
krb5_free_context(ptr->ctx);
|
|
132
179
|
|
|
133
180
|
ptr->ccache = NULL;
|
|
134
181
|
ptr->ctx = NULL;
|
|
135
182
|
ptr->principal = NULL;
|
|
183
|
+
ptr->rb_context = Qnil;
|
|
136
184
|
|
|
137
185
|
return self;
|
|
138
186
|
}
|
|
@@ -228,11 +276,6 @@ static VALUE rkrb5_ccache_primary_principal(VALUE self){
|
|
|
228
276
|
return v_name;
|
|
229
277
|
}
|
|
230
278
|
|
|
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);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
279
|
/*
|
|
237
280
|
* call-seq:
|
|
238
281
|
* ccache.destroy
|
|
@@ -264,9 +307,14 @@ static VALUE rkrb5_ccache_destroy(VALUE self){
|
|
|
264
307
|
if(ptr->principal)
|
|
265
308
|
krb5_free_principal(ptr->ctx, ptr->principal);
|
|
266
309
|
|
|
267
|
-
if(ptr->ctx)
|
|
310
|
+
if(ptr->ctx && ptr->rb_context == Qnil)
|
|
268
311
|
krb5_free_context(ptr->ctx);
|
|
269
312
|
|
|
313
|
+
ptr->ccache = NULL;
|
|
314
|
+
ptr->ctx = NULL;
|
|
315
|
+
ptr->principal = NULL;
|
|
316
|
+
ptr->rb_context = Qnil;
|
|
317
|
+
|
|
270
318
|
rb_raise(cKrb5Exception, "krb5_cc_destroy: %s", error_message(kerror));
|
|
271
319
|
}
|
|
272
320
|
}
|
|
@@ -274,12 +322,13 @@ static VALUE rkrb5_ccache_destroy(VALUE self){
|
|
|
274
322
|
if(ptr->principal)
|
|
275
323
|
krb5_free_principal(ptr->ctx, ptr->principal);
|
|
276
324
|
|
|
277
|
-
if(ptr->ctx)
|
|
325
|
+
if(ptr->ctx && ptr->rb_context == Qnil)
|
|
278
326
|
krb5_free_context(ptr->ctx);
|
|
279
327
|
|
|
280
328
|
ptr->ccache = NULL;
|
|
281
329
|
ptr->ctx = NULL;
|
|
282
330
|
ptr->principal = NULL;
|
|
331
|
+
ptr->rb_context = Qnil;
|
|
283
332
|
|
|
284
333
|
return v_bool;
|
|
285
334
|
}
|
|
@@ -325,6 +374,35 @@ static VALUE rkrb5_ccache_dup(VALUE self){
|
|
|
325
374
|
return newobj;
|
|
326
375
|
}
|
|
327
376
|
|
|
377
|
+
/*
|
|
378
|
+
* call-seq:
|
|
379
|
+
* ccache.full_name -> String
|
|
380
|
+
*
|
|
381
|
+
* Returns the full name of the credential cache, including the type prefix,
|
|
382
|
+
* e.g. "FILE:/tmp/krb5cc_1000".
|
|
383
|
+
*/
|
|
384
|
+
static VALUE rkrb5_ccache_full_name(VALUE self){
|
|
385
|
+
RUBY_KRB5_CCACHE* ptr;
|
|
386
|
+
char *full_name;
|
|
387
|
+
krb5_error_code kerror;
|
|
388
|
+
VALUE result;
|
|
389
|
+
|
|
390
|
+
TypedData_Get_Struct(self, RUBY_KRB5_CCACHE, &rkrb5_ccache_data_type, ptr);
|
|
391
|
+
|
|
392
|
+
if(!ptr->ctx)
|
|
393
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
394
|
+
|
|
395
|
+
kerror = krb5_cc_get_full_name(ptr->ctx, ptr->ccache, &full_name);
|
|
396
|
+
|
|
397
|
+
if(kerror)
|
|
398
|
+
rb_raise(cKrb5Exception, "krb5_cc_get_full_name: %s", error_message(kerror));
|
|
399
|
+
|
|
400
|
+
result = rb_str_new2(full_name);
|
|
401
|
+
krb5_free_string(ptr->ctx, full_name);
|
|
402
|
+
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
|
|
328
406
|
void Init_ccache(void){
|
|
329
407
|
/* The Kerberos::Krb5::CredentialsCache class encapsulates a Kerberos credentials cache. */
|
|
330
408
|
cKrb5CCache = rb_define_class_under(cKrb5, "CredentialsCache", rb_cObject);
|
|
@@ -342,10 +420,11 @@ void Init_ccache(void){
|
|
|
342
420
|
rb_define_method(cKrb5CCache, "cache_type", rkrb5_ccache_get_type, 0);
|
|
343
421
|
rb_define_method(cKrb5CCache, "destroy", rkrb5_ccache_destroy, 0);
|
|
344
422
|
rb_define_method(cKrb5CCache, "primary_principal", rkrb5_ccache_primary_principal, 0);
|
|
345
|
-
rb_define_method(cKrb5CCache, "
|
|
423
|
+
rb_define_method(cKrb5CCache, "full_name", rkrb5_ccache_full_name, 0);
|
|
346
424
|
rb_define_method(cKrb5CCache, "dup", rkrb5_ccache_dup, 0);
|
|
347
425
|
rb_define_alias(cKrb5CCache, "clone", "dup");
|
|
348
426
|
|
|
349
427
|
// Aliases
|
|
350
428
|
rb_define_alias(cKrb5CCache, "delete", "destroy");
|
|
429
|
+
rb_define_alias(cKrb5CCache, "principal", "primary_principal");
|
|
351
430
|
}
|
data/ext/rkerberos/config.c
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#ifdef HAVE_KADM5_ADMIN_H
|
|
1
2
|
#include <rkerberos.h>
|
|
2
3
|
|
|
3
4
|
VALUE cKadm5Config;
|
|
@@ -5,12 +6,21 @@ VALUE cKeySalt;
|
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
// TypedData functions for RUBY_KADM5_CONFIG
|
|
9
|
+
static void rkadm5_config_typed_mark(void *ptr) {
|
|
10
|
+
if (!ptr) return;
|
|
11
|
+
RUBY_KADM5_CONFIG *c = (RUBY_KADM5_CONFIG *)ptr;
|
|
12
|
+
if (c->rb_context != Qnil)
|
|
13
|
+
rb_gc_mark(c->rb_context);
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
static void rkadm5_config_typed_free(void *ptr) {
|
|
9
17
|
if (!ptr) return;
|
|
10
18
|
RUBY_KADM5_CONFIG *c = (RUBY_KADM5_CONFIG *)ptr;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
if (c->ctx) {
|
|
20
|
+
kadm5_free_config_params(c->ctx, &c->config);
|
|
21
|
+
if (c->rb_context == Qnil)
|
|
22
|
+
krb5_free_context(c->ctx);
|
|
23
|
+
}
|
|
14
24
|
free(c);
|
|
15
25
|
}
|
|
16
26
|
|
|
@@ -20,7 +30,7 @@ static size_t rkadm5_config_typed_size(const void *ptr) {
|
|
|
20
30
|
|
|
21
31
|
const rb_data_type_t rkadm5_config_data_type = {
|
|
22
32
|
"RUBY_KADM5_CONFIG",
|
|
23
|
-
{
|
|
33
|
+
{rkadm5_config_typed_mark, rkadm5_config_typed_free, rkadm5_config_typed_size,},
|
|
24
34
|
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
25
35
|
};
|
|
26
36
|
|
|
@@ -28,6 +38,7 @@ const rb_data_type_t rkadm5_config_data_type = {
|
|
|
28
38
|
static VALUE rkadm5_config_allocate(VALUE klass){
|
|
29
39
|
RUBY_KADM5_CONFIG* ptr = ALLOC(RUBY_KADM5_CONFIG);
|
|
30
40
|
memset(ptr, 0, sizeof(RUBY_KADM5_CONFIG));
|
|
41
|
+
ptr->rb_context = Qnil;
|
|
31
42
|
return TypedData_Wrap_Struct(klass, &rkadm5_config_data_type, ptr);
|
|
32
43
|
}
|
|
33
44
|
|
|
@@ -41,23 +52,60 @@ static VALUE rkeysalt_new(krb5_enctype enctype, krb5_int32 salttype){
|
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
/*
|
|
55
|
+
* call-seq:
|
|
56
|
+
* Kerberos::Kadm5::Config.new(context: nil)
|
|
57
|
+
*
|
|
44
58
|
* Returns a Kerberos::Kadm5::Config object. This object contains Kerberos
|
|
45
59
|
* admin configuration.
|
|
46
60
|
*
|
|
61
|
+
* Accepts the following keyword argument:
|
|
62
|
+
*
|
|
63
|
+
* - +context+: A Kerberos::Krb5::Context object. If provided, that context is
|
|
64
|
+
* used instead of creating a new one via krb5_init_context.
|
|
65
|
+
*
|
|
47
66
|
* Note that the returned object is frozen. Changes made to the Kerberos
|
|
48
67
|
* admin configuration options after the call will not be reflected in this
|
|
49
68
|
* object.
|
|
50
69
|
*/
|
|
51
|
-
static VALUE rkadm5_config_initialize(VALUE self){
|
|
70
|
+
static VALUE rkadm5_config_initialize(int argc, VALUE* argv, VALUE self){
|
|
52
71
|
RUBY_KADM5_CONFIG* ptr;
|
|
53
72
|
krb5_error_code kerror;
|
|
73
|
+
VALUE v_opts, v_context;
|
|
74
|
+
ID kw_table[1] = { rb_intern("context") };
|
|
75
|
+
VALUE kw_vals[1];
|
|
54
76
|
|
|
55
77
|
TypedData_Get_Struct(self, RUBY_KADM5_CONFIG, &rkadm5_config_data_type, ptr);
|
|
56
78
|
|
|
57
|
-
|
|
79
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
58
80
|
|
|
59
|
-
if(
|
|
60
|
-
|
|
81
|
+
if(NIL_P(v_opts))
|
|
82
|
+
v_opts = rb_hash_new();
|
|
83
|
+
|
|
84
|
+
rb_get_kwargs(v_opts, kw_table, 0, 1, kw_vals);
|
|
85
|
+
v_context = kw_vals[0] == Qundef ? Qnil : kw_vals[0];
|
|
86
|
+
|
|
87
|
+
if(!NIL_P(v_context)){
|
|
88
|
+
RUBY_KRB5_CONTEXT* ctx_ptr;
|
|
89
|
+
|
|
90
|
+
if(!rb_obj_is_kind_of(v_context, cKrb5Context))
|
|
91
|
+
rb_raise(rb_eTypeError, "context must be a Kerberos::Krb5::Context object");
|
|
92
|
+
|
|
93
|
+
TypedData_Get_Struct(v_context, RUBY_KRB5_CONTEXT, &rkrb5_context_data_type, ctx_ptr);
|
|
94
|
+
|
|
95
|
+
if(!ctx_ptr->ctx)
|
|
96
|
+
rb_raise(cKrb5Exception, "context is closed");
|
|
97
|
+
|
|
98
|
+
ptr->ctx = ctx_ptr->ctx;
|
|
99
|
+
ptr->rb_context = v_context;
|
|
100
|
+
}
|
|
101
|
+
else{
|
|
102
|
+
kerror = krb5_init_context(&ptr->ctx);
|
|
103
|
+
|
|
104
|
+
if(kerror)
|
|
105
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
|
106
|
+
|
|
107
|
+
ptr->rb_context = Qnil;
|
|
108
|
+
}
|
|
61
109
|
|
|
62
110
|
kerror = kadm5_get_config_params(
|
|
63
111
|
ptr->ctx,
|
|
@@ -298,7 +346,7 @@ void Init_config(void){
|
|
|
298
346
|
|
|
299
347
|
// Initializer
|
|
300
348
|
|
|
301
|
-
rb_define_method(cKadm5Config, "initialize", rkadm5_config_initialize,
|
|
349
|
+
rb_define_method(cKadm5Config, "initialize", rkadm5_config_initialize, -1);
|
|
302
350
|
|
|
303
351
|
// Methods
|
|
304
352
|
|
|
@@ -332,4 +380,5 @@ void Init_config(void){
|
|
|
332
380
|
cKeySalt = rb_define_class_under(cKadm5, "KeySalt", rb_cObject);
|
|
333
381
|
rb_define_attr(cKeySalt, "enctype", 1, 0);
|
|
334
382
|
rb_define_attr(cKeySalt, "salttype", 1, 0);
|
|
335
|
-
}
|
|
383
|
+
}
|
|
384
|
+
#endif
|
data/ext/rkerberos/context.c
CHANGED
|
@@ -53,24 +53,28 @@ static VALUE rkrb5_context_close(VALUE self){
|
|
|
53
53
|
|
|
54
54
|
/*
|
|
55
55
|
* call-seq:
|
|
56
|
-
* Kerberos::Context.new(
|
|
56
|
+
* Kerberos::Krb5::Context.new(secure: false, profile: nil)
|
|
57
57
|
*
|
|
58
58
|
* Creates and returns a new Kerberos::Context object.
|
|
59
59
|
*
|
|
60
|
-
* The
|
|
60
|
+
* The following keyword arguments are supported:
|
|
61
61
|
*
|
|
62
62
|
* :secure => true|false # Use config files only, ignore env variables
|
|
63
63
|
* :profile => '/path/to/krb5.conf' # Use the specified profile file
|
|
64
|
+
*
|
|
65
|
+
* Note that the profile option may not be supported on your platform.
|
|
64
66
|
*/
|
|
65
67
|
static VALUE rkrb5_context_initialize(int argc, VALUE *argv, VALUE self){
|
|
66
68
|
RUBY_KRB5_CONTEXT* ptr;
|
|
67
69
|
VALUE v_opts;
|
|
68
70
|
VALUE v_secure, v_profile;
|
|
71
|
+
ID kw_table[2] = { rb_intern("secure"), rb_intern("profile") };
|
|
72
|
+
VALUE kw_vals[2];
|
|
69
73
|
krb5_error_code kerror;
|
|
70
74
|
|
|
71
75
|
TypedData_Get_Struct(self, RUBY_KRB5_CONTEXT, &rkrb5_context_data_type, ptr);
|
|
72
76
|
|
|
73
|
-
rb_scan_args(argc, argv, "
|
|
77
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
74
78
|
|
|
75
79
|
// Default behavior is a normal context that may respect environment.
|
|
76
80
|
if (NIL_P(v_opts)) {
|
|
@@ -81,10 +85,9 @@ static VALUE rkrb5_context_initialize(int argc, VALUE *argv, VALUE self){
|
|
|
81
85
|
return self;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
v_profile = rb_hash_aref2(v_opts, ID2SYM(rb_intern("profile")));
|
|
88
|
+
rb_get_kwargs(v_opts, kw_table, 0, 2, kw_vals);
|
|
89
|
+
v_secure = kw_vals[0] == Qundef ? Qfalse : kw_vals[0];
|
|
90
|
+
v_profile = kw_vals[1] == Qundef ? Qnil : kw_vals[1];
|
|
88
91
|
|
|
89
92
|
/*
|
|
90
93
|
* If a profile path is supplied, load it via profile_init_path() and
|
|
@@ -92,6 +95,9 @@ static VALUE rkrb5_context_initialize(int argc, VALUE *argv, VALUE self){
|
|
|
92
95
|
* is used when the :secure option is truthy.
|
|
93
96
|
*/
|
|
94
97
|
if (!NIL_P(v_profile)){
|
|
98
|
+
#ifndef HAVE_PROFILE_INIT_PATH
|
|
99
|
+
rb_raise(rb_eArgError, "profile option not supported on this platform");
|
|
100
|
+
#else
|
|
95
101
|
Check_Type(v_profile, T_STRING);
|
|
96
102
|
|
|
97
103
|
const char *profile_path = StringValueCStr(v_profile);
|
|
@@ -110,6 +116,7 @@ static VALUE rkrb5_context_initialize(int argc, VALUE *argv, VALUE self){
|
|
|
110
116
|
rb_raise(cKrb5Exception, "krb5_init_context_profile: %s", error_message(kerror));
|
|
111
117
|
|
|
112
118
|
return self;
|
|
119
|
+
#endif
|
|
113
120
|
}
|
|
114
121
|
|
|
115
122
|
// No profile given, choose secure or normal init.
|
|
@@ -127,6 +134,66 @@ static VALUE rkrb5_context_initialize(int argc, VALUE *argv, VALUE self){
|
|
|
127
134
|
return self;
|
|
128
135
|
}
|
|
129
136
|
|
|
137
|
+
/*
|
|
138
|
+
* call-seq:
|
|
139
|
+
* context.default_realm -> String
|
|
140
|
+
*
|
|
141
|
+
* Returns the default realm from this context.
|
|
142
|
+
*/
|
|
143
|
+
static VALUE rkrb5_context_default_realm(VALUE self){
|
|
144
|
+
RUBY_KRB5_CONTEXT* ptr;
|
|
145
|
+
char* realm;
|
|
146
|
+
krb5_error_code kerror;
|
|
147
|
+
|
|
148
|
+
TypedData_Get_Struct(self, RUBY_KRB5_CONTEXT, &rkrb5_context_data_type, ptr);
|
|
149
|
+
|
|
150
|
+
if(!ptr->ctx)
|
|
151
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
152
|
+
|
|
153
|
+
kerror = krb5_get_default_realm(ptr->ctx, &realm);
|
|
154
|
+
|
|
155
|
+
if(kerror)
|
|
156
|
+
rb_raise(cKrb5Exception, "krb5_get_default_realm: %s", error_message(kerror));
|
|
157
|
+
|
|
158
|
+
VALUE v_realm = rb_str_new2(realm);
|
|
159
|
+
krb5_free_default_realm(ptr->ctx, realm);
|
|
160
|
+
|
|
161
|
+
return v_realm;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* call-seq:
|
|
166
|
+
* context.default_realm = realm
|
|
167
|
+
*
|
|
168
|
+
* Sets the default realm for this context. If +realm+ is nil the default
|
|
169
|
+
* from krb5.conf is restored.
|
|
170
|
+
*/
|
|
171
|
+
static VALUE rkrb5_context_set_default_realm(VALUE self, VALUE v_realm){
|
|
172
|
+
RUBY_KRB5_CONTEXT* ptr;
|
|
173
|
+
char* realm;
|
|
174
|
+
krb5_error_code kerror;
|
|
175
|
+
|
|
176
|
+
TypedData_Get_Struct(self, RUBY_KRB5_CONTEXT, &rkrb5_context_data_type, ptr);
|
|
177
|
+
|
|
178
|
+
if(!ptr->ctx)
|
|
179
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
180
|
+
|
|
181
|
+
if(NIL_P(v_realm)){
|
|
182
|
+
realm = NULL;
|
|
183
|
+
}
|
|
184
|
+
else{
|
|
185
|
+
Check_Type(v_realm, T_STRING);
|
|
186
|
+
realm = StringValueCStr(v_realm);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
kerror = krb5_set_default_realm(ptr->ctx, realm);
|
|
190
|
+
|
|
191
|
+
if(kerror)
|
|
192
|
+
rb_raise(cKrb5Exception, "krb5_set_default_realm: %s", error_message(kerror));
|
|
193
|
+
|
|
194
|
+
return v_realm;
|
|
195
|
+
}
|
|
196
|
+
|
|
130
197
|
void Init_context(void){
|
|
131
198
|
/* The Kerberos::Krb5::Context class encapsulates a Kerberos context. */
|
|
132
199
|
cKrb5Context = rb_define_class_under(cKrb5, "Context", rb_cObject);
|
|
@@ -139,4 +206,6 @@ void Init_context(void){
|
|
|
139
206
|
|
|
140
207
|
// Instance Methods
|
|
141
208
|
rb_define_method(cKrb5Context, "close", rkrb5_context_close, 0);
|
|
209
|
+
rb_define_method(cKrb5Context, "default_realm", rkrb5_context_default_realm, 0);
|
|
210
|
+
rb_define_method(cKrb5Context, "default_realm=", rkrb5_context_set_default_realm, 1);
|
|
142
211
|
}
|
data/ext/rkerberos/extconf.rb
CHANGED
|
@@ -14,8 +14,19 @@ else
|
|
|
14
14
|
else
|
|
15
15
|
dir_config('rkerberos', '/usr/local')
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
if File::ALT_SEPARATOR
|
|
19
|
+
kfw_dir = ENV['KRB5_DIR'] || 'C:/Program Files/MIT/Kerberos'
|
|
20
|
+
kfw_inc = ENV['KRB5_INCLUDE'] || File.join(kfw_dir, 'include')
|
|
21
|
+
kfw_lib = ENV['KRB5_LIB'] || File.join(kfw_dir, 'lib')
|
|
22
|
+
$INCFLAGS << " -I\"#{kfw_inc}\""
|
|
23
|
+
$LDFLAGS << " -L\"#{kfw_lib}\""
|
|
24
|
+
end
|
|
25
|
+
|
|
17
26
|
have_header('krb5.h')
|
|
18
|
-
|
|
27
|
+
|
|
28
|
+
have_library('krb5') || have_library('krb5_64')
|
|
29
|
+
have_library('comerr') || have_library('comerr64')
|
|
19
30
|
end
|
|
20
31
|
|
|
21
32
|
pkg_config('com_err') || have_library('com_err')
|
|
@@ -26,8 +37,10 @@ end
|
|
|
26
37
|
|
|
27
38
|
if pkg_config('kdb5') || have_library('kdb5')
|
|
28
39
|
have_header('kdb.h')
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if have_header('profile.h')
|
|
43
|
+
have_func('profile_init_path')
|
|
31
44
|
end
|
|
32
45
|
|
|
33
46
|
create_makefile('rkerberos')
|