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/ext/rkerberos/keytab.c
CHANGED
|
@@ -4,6 +4,13 @@ VALUE cKrb5Keytab, cKrb5KeytabException;
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// TypedData functions for RUBY_KRB5_KEYTAB
|
|
7
|
+
static void rkrb5_keytab_typed_mark(void *ptr) {
|
|
8
|
+
if (!ptr) return;
|
|
9
|
+
RUBY_KRB5_KEYTAB *kt = (RUBY_KRB5_KEYTAB *)ptr;
|
|
10
|
+
if (kt->rb_context != Qnil)
|
|
11
|
+
rb_gc_mark(kt->rb_context);
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
void rkrb5_keytab_typed_free(void *ptr) {
|
|
8
15
|
if (!ptr) return;
|
|
9
16
|
RUBY_KRB5_KEYTAB *kt = (RUBY_KRB5_KEYTAB *)ptr;
|
|
@@ -11,7 +18,7 @@ void rkrb5_keytab_typed_free(void *ptr) {
|
|
|
11
18
|
krb5_kt_close(kt->ctx, kt->keytab);
|
|
12
19
|
if (kt->ctx)
|
|
13
20
|
krb5_free_cred_contents(kt->ctx, &kt->creds);
|
|
14
|
-
if (kt->ctx)
|
|
21
|
+
if (kt->ctx && kt->rb_context == Qnil)
|
|
15
22
|
krb5_free_context(kt->ctx);
|
|
16
23
|
free(kt);
|
|
17
24
|
}
|
|
@@ -23,13 +30,14 @@ size_t rkrb5_keytab_typed_size(const void *ptr) {
|
|
|
23
30
|
// Must NOT be static so it is exported
|
|
24
31
|
const rb_data_type_t rkrb5_keytab_data_type = {
|
|
25
32
|
"RUBY_KRB5_KEYTAB",
|
|
26
|
-
{
|
|
33
|
+
{rkrb5_keytab_typed_mark, rkrb5_keytab_typed_free, rkrb5_keytab_typed_size,},
|
|
27
34
|
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
28
35
|
};
|
|
29
36
|
|
|
30
37
|
VALUE rkrb5_keytab_allocate(VALUE klass){
|
|
31
38
|
RUBY_KRB5_KEYTAB* ptr = ALLOC(RUBY_KRB5_KEYTAB);
|
|
32
39
|
memset(ptr, 0, sizeof(RUBY_KRB5_KEYTAB));
|
|
40
|
+
ptr->rb_context = Qnil;
|
|
33
41
|
return TypedData_Wrap_Struct(klass, &rkrb5_keytab_data_type, ptr);
|
|
34
42
|
}
|
|
35
43
|
|
|
@@ -51,7 +59,12 @@ static VALUE rkrb5_keytab_each_body(VALUE arg){
|
|
|
51
59
|
VALUE v_kt_entry;
|
|
52
60
|
|
|
53
61
|
while((kerror = krb5_kt_next_entry(ea->ctx, ea->keytab, &entry, &ea->cursor)) == 0){
|
|
54
|
-
krb5_unparse_name(ea->ctx, entry.principal, &principal);
|
|
62
|
+
kerror = krb5_unparse_name(ea->ctx, entry.principal, &principal);
|
|
63
|
+
|
|
64
|
+
if(kerror){
|
|
65
|
+
krb5_kt_free_entry(ea->ctx, &entry);
|
|
66
|
+
rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
|
67
|
+
}
|
|
55
68
|
|
|
56
69
|
v_kt_entry = rb_class_new_instance(0, NULL, cKrb5KtEntry);
|
|
57
70
|
|
|
@@ -162,109 +175,189 @@ static VALUE rkrb5_keytab_close(VALUE self){
|
|
|
162
175
|
if(ptr->ctx)
|
|
163
176
|
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
164
177
|
|
|
165
|
-
if(ptr->ctx)
|
|
178
|
+
if(ptr->ctx && ptr->rb_context == Qnil)
|
|
166
179
|
krb5_free_context(ptr->ctx);
|
|
167
180
|
|
|
168
181
|
ptr->ctx = NULL;
|
|
182
|
+
ptr->rb_context = Qnil;
|
|
169
183
|
|
|
170
184
|
return Qtrue;
|
|
171
185
|
}
|
|
172
186
|
|
|
173
187
|
/*
|
|
174
|
-
|
|
188
|
+
* call-seq:
|
|
189
|
+
* keytab.add_entry(principal:, password:, vno: 1, enctype: 18)
|
|
190
|
+
*
|
|
191
|
+
* Add a new entry to the keytab for the given +principal+ string.
|
|
192
|
+
*
|
|
193
|
+
* A key is derived from +password+ (and the principal-based salt) using
|
|
194
|
+
* +krb5_c_string_to_key+, so the resulting key will match what the KDC
|
|
195
|
+
* would generate for the same password.
|
|
196
|
+
*
|
|
197
|
+
* Options:
|
|
198
|
+
* principal:: A Kerberos principal name string (required).
|
|
199
|
+
* password:: The password used to derive the key (required).
|
|
200
|
+
* vno:: Key version number (default 1).
|
|
201
|
+
* enctype:: Encryption type as an integer (default 18,
|
|
202
|
+
* aes256-cts-hmac-sha1-96).
|
|
203
|
+
*
|
|
204
|
+
* Returns +self+.
|
|
205
|
+
*/
|
|
206
|
+
static VALUE rkrb5_keytab_add_entry(int argc, VALUE* argv, VALUE self){
|
|
175
207
|
RUBY_KRB5_KEYTAB* ptr;
|
|
176
208
|
krb5_error_code kerror;
|
|
177
209
|
krb5_keytab_entry entry;
|
|
178
|
-
|
|
179
|
-
VALUE
|
|
210
|
+
krb5_data pwd_data, salt;
|
|
211
|
+
VALUE v_opts, v_principal, v_password, v_vno, v_enctype;
|
|
212
|
+
ID kw_table[4] = { rb_intern("principal"), rb_intern("password"), rb_intern("vno"), rb_intern("enctype") };
|
|
213
|
+
VALUE kw_vals[4];
|
|
180
214
|
|
|
181
215
|
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
182
216
|
|
|
183
|
-
|
|
217
|
+
if(!ptr->ctx)
|
|
218
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
184
219
|
|
|
185
|
-
|
|
220
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
186
221
|
|
|
187
|
-
|
|
222
|
+
if(NIL_P(v_opts))
|
|
223
|
+
v_opts = rb_hash_new();
|
|
188
224
|
|
|
189
|
-
|
|
190
|
-
|
|
225
|
+
rb_get_kwargs(v_opts, kw_table, 2, 2, kw_vals);
|
|
226
|
+
v_principal = kw_vals[0];
|
|
227
|
+
v_password = kw_vals[1];
|
|
228
|
+
v_vno = kw_vals[2] == Qundef ? Qnil : kw_vals[2];
|
|
229
|
+
v_enctype = kw_vals[3] == Qundef ? Qnil : kw_vals[3];
|
|
230
|
+
|
|
231
|
+
Check_Type(v_principal, T_STRING);
|
|
232
|
+
Check_Type(v_password, T_STRING);
|
|
233
|
+
|
|
234
|
+
memset(&entry, 0, sizeof(entry));
|
|
191
235
|
|
|
192
|
-
kerror = krb5_parse_name(ptr->ctx,
|
|
236
|
+
kerror = krb5_parse_name(ptr->ctx, StringValueCStr(v_principal), &entry.principal);
|
|
193
237
|
|
|
194
238
|
if(kerror)
|
|
195
239
|
rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));
|
|
196
240
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
entry.vno = NUM2INT(v_vno);
|
|
241
|
+
entry.vno = NIL_P(v_vno) ? 1 : NUM2INT(v_vno);
|
|
242
|
+
entry.key.enctype = NIL_P(v_enctype) ? ENCTYPE_AES256_CTS_HMAC_SHA1_96 : NUM2INT(v_enctype);
|
|
243
|
+
entry.timestamp = time(NULL);
|
|
201
244
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
else
|
|
205
|
-
entry.key.enctype = NUM2INT(v_enctype);
|
|
245
|
+
// Derive the salt from the principal
|
|
246
|
+
kerror = krb5_principal2salt(ptr->ctx, entry.principal, &salt);
|
|
206
247
|
|
|
207
|
-
|
|
248
|
+
if(kerror){
|
|
249
|
+
krb5_free_principal(ptr->ctx, entry.principal);
|
|
250
|
+
rb_raise(cKrb5Exception, "krb5_principal2salt: %s", error_message(kerror));
|
|
251
|
+
}
|
|
208
252
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
);
|
|
253
|
+
// Derive key from password + salt
|
|
254
|
+
pwd_data.data = StringValuePtr(v_password);
|
|
255
|
+
pwd_data.length = (unsigned int)RSTRING_LEN(v_password);
|
|
256
|
+
|
|
257
|
+
kerror = krb5_c_string_to_key(ptr->ctx, entry.key.enctype, &pwd_data, &salt, &entry.key);
|
|
258
|
+
|
|
259
|
+
krb5_free_data_contents(ptr->ctx, &salt);
|
|
260
|
+
|
|
261
|
+
if(kerror){
|
|
262
|
+
krb5_free_principal(ptr->ctx, entry.principal);
|
|
263
|
+
rb_raise(cKrb5Exception, "krb5_c_string_to_key: %s", error_message(kerror));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
kerror = krb5_kt_add_entry(ptr->ctx, ptr->keytab, &entry);
|
|
267
|
+
|
|
268
|
+
krb5_free_keyblock_contents(ptr->ctx, &entry.key);
|
|
269
|
+
krb5_free_principal(ptr->ctx, entry.principal);
|
|
214
270
|
|
|
215
271
|
if(kerror)
|
|
216
|
-
rb_raise(cKrb5KeytabException, "
|
|
272
|
+
rb_raise(cKrb5KeytabException, "krb5_kt_add_entry: %s", error_message(kerror));
|
|
217
273
|
|
|
218
274
|
return self;
|
|
219
275
|
}
|
|
220
276
|
|
|
221
|
-
|
|
277
|
+
/*
|
|
278
|
+
* call-seq:
|
|
279
|
+
* keytab.remove_entry(principal:, vno: 0, enctype: 0)
|
|
280
|
+
*
|
|
281
|
+
* Remove entries from the keytab that match the given +principal+ string,
|
|
282
|
+
* +vno+, and +enctype+.
|
|
283
|
+
*
|
|
284
|
+
* A +vno+ of 0 (the default) matches any version number.
|
|
285
|
+
* An +enctype+ of 0 (the default) matches any encryption type.
|
|
286
|
+
*
|
|
287
|
+
* When both +vno+ and +enctype+ are 0 (the defaults), all entries for
|
|
288
|
+
* the +principal+ are removed.
|
|
289
|
+
*
|
|
290
|
+
* Options:
|
|
291
|
+
* principal:: A Kerberos principal name string (required).
|
|
292
|
+
* vno:: Key version number to match, 0 for any (default 0).
|
|
293
|
+
* enctype:: Encryption type to match, 0 for any (default 0).
|
|
294
|
+
*
|
|
295
|
+
* Returns +self+.
|
|
296
|
+
*/
|
|
297
|
+
static VALUE rkrb5_keytab_remove_entry(int argc, VALUE* argv, VALUE self){
|
|
222
298
|
RUBY_KRB5_KEYTAB* ptr;
|
|
223
299
|
krb5_error_code kerror;
|
|
224
|
-
krb5_keytab_entry
|
|
225
|
-
|
|
226
|
-
|
|
300
|
+
krb5_keytab_entry found_entry;
|
|
301
|
+
krb5_principal match_princ;
|
|
302
|
+
krb5_kvno match_vno;
|
|
303
|
+
krb5_enctype match_enctype;
|
|
304
|
+
int removed = 0;
|
|
305
|
+
VALUE v_opts, v_principal, v_vno, v_enctype;
|
|
306
|
+
ID kw_table[3] = { rb_intern("principal"), rb_intern("vno"), rb_intern("enctype") };
|
|
307
|
+
VALUE kw_vals[3];
|
|
227
308
|
|
|
228
309
|
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
229
310
|
|
|
230
|
-
|
|
311
|
+
if(!ptr->ctx)
|
|
312
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
231
313
|
|
|
232
|
-
|
|
314
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
233
315
|
|
|
234
|
-
|
|
316
|
+
if(NIL_P(v_opts))
|
|
317
|
+
v_opts = rb_hash_new();
|
|
235
318
|
|
|
236
|
-
|
|
237
|
-
|
|
319
|
+
rb_get_kwargs(v_opts, kw_table, 1, 2, kw_vals);
|
|
320
|
+
v_principal = kw_vals[0];
|
|
321
|
+
v_vno = kw_vals[1] == Qundef ? Qnil : kw_vals[1];
|
|
322
|
+
v_enctype = kw_vals[2] == Qundef ? Qnil : kw_vals[2];
|
|
238
323
|
|
|
239
|
-
|
|
324
|
+
Check_Type(v_principal, T_STRING);
|
|
325
|
+
|
|
326
|
+
kerror = krb5_parse_name(ptr->ctx, StringValueCStr(v_principal), &match_princ);
|
|
240
327
|
|
|
241
328
|
if(kerror)
|
|
242
329
|
rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));
|
|
243
330
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
else
|
|
247
|
-
entry.vno = NUM2INT(v_vno);
|
|
331
|
+
match_vno = NIL_P(v_vno) ? 0 : NUM2INT(v_vno);
|
|
332
|
+
match_enctype = NIL_P(v_enctype) ? 0 : NUM2INT(v_enctype);
|
|
248
333
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
334
|
+
// Retrieve the full entry via krb5_kt_get_entry and then pass the
|
|
335
|
+
// complete struct to krb5_kt_remove_entry so all fields match exactly.
|
|
336
|
+
// Loop to remove every matching entry when vno/enctype are wildcards.
|
|
337
|
+
while(1){
|
|
338
|
+
kerror = krb5_kt_get_entry(
|
|
339
|
+
ptr->ctx, ptr->keytab, match_princ,
|
|
340
|
+
match_vno, match_enctype, &found_entry
|
|
341
|
+
);
|
|
253
342
|
|
|
254
|
-
|
|
343
|
+
if(kerror){
|
|
344
|
+
krb5_free_principal(ptr->ctx, match_princ);
|
|
345
|
+
if(removed)
|
|
346
|
+
return self;
|
|
347
|
+
rb_raise(cKrb5KeytabException, "krb5_kt_remove_entry: %s", error_message(kerror));
|
|
348
|
+
}
|
|
255
349
|
|
|
256
|
-
|
|
257
|
-
ptr->ctx,
|
|
258
|
-
ptr->keytab,
|
|
259
|
-
&entry
|
|
260
|
-
);
|
|
350
|
+
kerror = krb5_kt_remove_entry(ptr->ctx, ptr->keytab, &found_entry);
|
|
351
|
+
krb5_kt_free_entry(ptr->ctx, &found_entry);
|
|
261
352
|
|
|
262
|
-
|
|
263
|
-
|
|
353
|
+
if(kerror){
|
|
354
|
+
krb5_free_principal(ptr->ctx, match_princ);
|
|
355
|
+
rb_raise(cKrb5KeytabException, "krb5_kt_remove_entry: %s", error_message(kerror));
|
|
356
|
+
}
|
|
264
357
|
|
|
265
|
-
|
|
358
|
+
removed = 1;
|
|
359
|
+
}
|
|
266
360
|
}
|
|
267
|
-
*/
|
|
268
361
|
|
|
269
362
|
/*
|
|
270
363
|
* call-seq:
|
|
@@ -425,7 +518,7 @@ static VALUE rkrb5_keytab_dup(VALUE self){
|
|
|
425
518
|
|
|
426
519
|
/*
|
|
427
520
|
* call-seq:
|
|
428
|
-
* Kerberos::Krb5::Keytab.new(name
|
|
521
|
+
* Kerberos::Krb5::Keytab.new(name: nil, context: nil)
|
|
429
522
|
*
|
|
430
523
|
* Creates and returns a new Kerberos::Krb5::Keytab object. This initializes
|
|
431
524
|
* the context and keytab for future method calls on that object.
|
|
@@ -434,28 +527,66 @@ static VALUE rkrb5_keytab_dup(VALUE self){
|
|
|
434
527
|
* name is used. If a +name+ is provided it must be in the form 'type:residual'
|
|
435
528
|
* where 'type' is a type known to the Kerberos library.
|
|
436
529
|
*
|
|
530
|
+
* An optional +context+ keyword argument may be provided. If given, it must
|
|
531
|
+
* be a Kerberos::Krb5::Context object and will be used instead of creating
|
|
532
|
+
* a new context via krb5_init_context.
|
|
533
|
+
*
|
|
437
534
|
* Examples:
|
|
438
535
|
*
|
|
439
536
|
* # Using the default keytab
|
|
440
537
|
* keytab = Kerberos::Krb5::Keytab.new
|
|
441
538
|
*
|
|
442
539
|
* # Using an explicit keytab
|
|
443
|
-
* keytab = Kerberos::Krb5::Keytab.new('FILE:/etc/krb5.keytab')
|
|
540
|
+
* keytab = Kerberos::Krb5::Keytab.new(name: 'FILE:/etc/krb5.keytab')
|
|
541
|
+
*
|
|
542
|
+
* # Using a custom context
|
|
543
|
+
* ctx = Kerberos::Krb5::Context.new
|
|
544
|
+
* keytab = Kerberos::Krb5::Keytab.new(name: 'FILE:/etc/krb5.keytab', context: ctx)
|
|
444
545
|
*/
|
|
445
546
|
static VALUE rkrb5_keytab_initialize(int argc, VALUE* argv, VALUE self){
|
|
446
547
|
RUBY_KRB5_KEYTAB* ptr;
|
|
447
548
|
krb5_error_code kerror;
|
|
448
549
|
char keytab_name[MAX_KEYTAB_NAME_LEN];
|
|
449
550
|
VALUE v_keytab_name = Qnil;
|
|
551
|
+
VALUE v_opts = Qnil;
|
|
552
|
+
VALUE v_context = Qnil;
|
|
553
|
+
ID kw_table[2] = { rb_intern("name"), rb_intern("context") };
|
|
554
|
+
VALUE kw_vals[2];
|
|
450
555
|
|
|
451
556
|
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
452
557
|
|
|
453
|
-
rb_scan_args(argc, argv, "
|
|
558
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
454
559
|
|
|
455
|
-
|
|
560
|
+
if(NIL_P(v_opts))
|
|
561
|
+
v_opts = rb_hash_new();
|
|
456
562
|
|
|
457
|
-
|
|
458
|
-
|
|
563
|
+
rb_get_kwargs(v_opts, kw_table, 0, 2, kw_vals);
|
|
564
|
+
v_keytab_name = kw_vals[0] == Qundef ? Qnil : kw_vals[0];
|
|
565
|
+
v_context = kw_vals[1] == Qundef ? Qnil : kw_vals[1];
|
|
566
|
+
|
|
567
|
+
// Initialize or borrow the context
|
|
568
|
+
if(!NIL_P(v_context)){
|
|
569
|
+
RUBY_KRB5_CONTEXT* ctx_ptr;
|
|
570
|
+
|
|
571
|
+
if(!rb_obj_is_kind_of(v_context, cKrb5Context))
|
|
572
|
+
rb_raise(rb_eTypeError, "context must be a Kerberos::Krb5::Context object");
|
|
573
|
+
|
|
574
|
+
TypedData_Get_Struct(v_context, RUBY_KRB5_CONTEXT, &rkrb5_context_data_type, ctx_ptr);
|
|
575
|
+
|
|
576
|
+
if(!ctx_ptr->ctx)
|
|
577
|
+
rb_raise(cKrb5Exception, "context is closed");
|
|
578
|
+
|
|
579
|
+
ptr->ctx = ctx_ptr->ctx;
|
|
580
|
+
ptr->rb_context = v_context;
|
|
581
|
+
}
|
|
582
|
+
else{
|
|
583
|
+
kerror = krb5_init_context(&ptr->ctx);
|
|
584
|
+
|
|
585
|
+
if(kerror)
|
|
586
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
|
587
|
+
|
|
588
|
+
ptr->rb_context = Qnil;
|
|
589
|
+
}
|
|
459
590
|
|
|
460
591
|
// Use the default keytab name if one isn't provided.
|
|
461
592
|
if(NIL_P(v_keytab_name)){
|
|
@@ -503,7 +634,12 @@ static VALUE rkrb5_s_keytab_foreach_body(VALUE arg){
|
|
|
503
634
|
VALUE v_kt_entry;
|
|
504
635
|
|
|
505
636
|
while((kerror = krb5_kt_next_entry(fa->ctx, fa->keytab, &entry, &fa->cursor)) == 0){
|
|
506
|
-
krb5_unparse_name(fa->ctx, entry.principal, &principal);
|
|
637
|
+
kerror = krb5_unparse_name(fa->ctx, entry.principal, &principal);
|
|
638
|
+
|
|
639
|
+
if(kerror){
|
|
640
|
+
krb5_kt_free_entry(fa->ctx, &entry);
|
|
641
|
+
rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
|
642
|
+
}
|
|
507
643
|
|
|
508
644
|
v_kt_entry = rb_class_new_instance(0, NULL, cKrb5KtEntry);
|
|
509
645
|
|
|
@@ -606,6 +742,26 @@ static VALUE rkrb5_s_keytab_foreach(int argc, VALUE* argv, VALUE klass){
|
|
|
606
742
|
return Qnil;
|
|
607
743
|
}
|
|
608
744
|
|
|
745
|
+
/*
|
|
746
|
+
* call-seq:
|
|
747
|
+
* keytab.have_content? -> true or false
|
|
748
|
+
*
|
|
749
|
+
* Returns true if the keytab exists and contains entries, false otherwise.
|
|
750
|
+
*/
|
|
751
|
+
static VALUE rkrb5_keytab_have_content(VALUE self){
|
|
752
|
+
RUBY_KRB5_KEYTAB* ptr;
|
|
753
|
+
krb5_error_code kerror;
|
|
754
|
+
|
|
755
|
+
TypedData_Get_Struct(self, RUBY_KRB5_KEYTAB, &rkrb5_keytab_data_type, ptr);
|
|
756
|
+
|
|
757
|
+
if(!ptr->ctx)
|
|
758
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
|
759
|
+
|
|
760
|
+
kerror = krb5_kt_have_content(ptr->ctx, ptr->keytab);
|
|
761
|
+
|
|
762
|
+
return kerror ? Qfalse : Qtrue;
|
|
763
|
+
}
|
|
764
|
+
|
|
609
765
|
void Init_keytab(void){
|
|
610
766
|
/* The Kerberos::Krb5::Keytab class encapsulates a Kerberos keytab. */
|
|
611
767
|
cKrb5Keytab = rb_define_class_under(cKrb5, "Keytab", rb_cObject);
|
|
@@ -634,11 +790,11 @@ void Init_keytab(void){
|
|
|
634
790
|
rb_define_method(cKrb5Keytab, "keytab_name", rkrb5_keytab_get_name, 0);
|
|
635
791
|
rb_define_method(cKrb5Keytab, "keytab_type", rkrb5_keytab_get_type, 0);
|
|
636
792
|
rb_define_method(cKrb5Keytab, "dup", rkrb5_keytab_dup, 0);
|
|
793
|
+
rb_define_method(cKrb5Keytab, "have_content?", rkrb5_keytab_have_content, 0);
|
|
637
794
|
rb_define_alias(cKrb5Keytab, "clone", "dup");
|
|
638
795
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
// rb_define_method(cKrb5Keytab, "remove_entry", rkrb5_keytab_remove_entry, -1);
|
|
796
|
+
rb_define_method(cKrb5Keytab, "add_entry", rkrb5_keytab_add_entry, -1);
|
|
797
|
+
rb_define_method(cKrb5Keytab, "remove_entry", rkrb5_keytab_remove_entry, -1);
|
|
642
798
|
|
|
643
799
|
// Accessors
|
|
644
800
|
|
data/ext/rkerberos/policy.c
CHANGED
|
@@ -32,12 +32,12 @@ static VALUE rkadm5_policy_allocate(VALUE klass){
|
|
|
32
32
|
|
|
33
33
|
/*
|
|
34
34
|
* call-seq:
|
|
35
|
-
* Kerberos::Kadm5::Policy.new(
|
|
35
|
+
* Kerberos::Kadm5::Policy.new(name:, min_life: nil, max_life: nil,
|
|
36
|
+
* min_length: nil, min_classes: nil, history_num: nil)
|
|
36
37
|
*
|
|
37
|
-
* Returns a new policy object using
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* Kadm5.create_policy method.
|
|
38
|
+
* Returns a new policy object using the keyword arguments you choose to pass.
|
|
39
|
+
* This does NOT actually create the policy within Kerberos. To do that pass
|
|
40
|
+
* your Policy object to the Kadm5.create_policy method.
|
|
41
41
|
*
|
|
42
42
|
* The possible options are:
|
|
43
43
|
*
|
|
@@ -50,32 +50,34 @@ static VALUE rkadm5_policy_allocate(VALUE klass){
|
|
|
50
50
|
*
|
|
51
51
|
* If you do not provide a :name then an ArgumentError will be raised.
|
|
52
52
|
*/
|
|
53
|
-
static VALUE rkadm5_policy_init(VALUE
|
|
53
|
+
static VALUE rkadm5_policy_init(int argc, VALUE* argv, VALUE self){
|
|
54
54
|
RUBY_KADM5_POLICY* ptr;
|
|
55
|
+
VALUE v_options;
|
|
55
56
|
VALUE v_name, v_minlife, v_maxlife, v_minlength;
|
|
56
57
|
VALUE v_minclasses, v_historynum;
|
|
58
|
+
ID kw_table[6] = {
|
|
59
|
+
rb_intern("name"), rb_intern("min_life"), rb_intern("max_life"),
|
|
60
|
+
rb_intern("min_length"), rb_intern("min_classes"), rb_intern("history_num")
|
|
61
|
+
};
|
|
62
|
+
VALUE kw_vals[6];
|
|
57
63
|
|
|
58
64
|
TypedData_Get_Struct(self, RUBY_KADM5_POLICY, &rkadm5_policy_data_type, ptr);
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
rb_scan_args(argc, argv, "0:", &v_options);
|
|
61
67
|
|
|
62
|
-
if(
|
|
63
|
-
|
|
68
|
+
if(NIL_P(v_options))
|
|
69
|
+
v_options = rb_hash_new();
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
rb_get_kwargs(v_options, kw_table, 1, 5, kw_vals);
|
|
72
|
+
v_name = kw_vals[0];
|
|
73
|
+
v_minlife = kw_vals[1] == Qundef ? Qnil : kw_vals[1];
|
|
74
|
+
v_maxlife = kw_vals[2] == Qundef ? Qnil : kw_vals[2];
|
|
75
|
+
v_minlength = kw_vals[3] == Qundef ? Qnil : kw_vals[3];
|
|
76
|
+
v_minclasses = kw_vals[4] == Qundef ? Qnil : kw_vals[4];
|
|
77
|
+
v_historynum = kw_vals[5] == Qundef ? Qnil : kw_vals[5];
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
else{
|
|
76
|
-
ptr->policy.policy = StringValueCStr(v_name);
|
|
77
|
-
rb_iv_set(self, "@policy", v_name);
|
|
78
|
-
}
|
|
79
|
+
ptr->policy.policy = StringValueCStr(v_name);
|
|
80
|
+
rb_iv_set(self, "@policy", v_name);
|
|
79
81
|
|
|
80
82
|
if(!NIL_P(v_minlife)){
|
|
81
83
|
ptr->policy.pw_min_life = NUM2LONG(v_minlife);
|
|
@@ -171,7 +173,7 @@ void Init_policy(void){
|
|
|
171
173
|
|
|
172
174
|
// Initialization Function
|
|
173
175
|
|
|
174
|
-
rb_define_method(cKadm5Policy, "initialize", rkadm5_policy_init, 1);
|
|
176
|
+
rb_define_method(cKadm5Policy, "initialize", rkadm5_policy_init, -1);
|
|
175
177
|
|
|
176
178
|
// Instance methods
|
|
177
179
|
|