rkerberos 0.2.0 → 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 +59 -0
- data/MANIFEST.md +24 -0
- data/README.md +55 -3
- data/Rakefile +35 -0
- data/ext/rkerberos/ccache.c +103 -9
- data/ext/rkerberos/config.c +4 -4
- data/ext/rkerberos/context.c +63 -8
- data/ext/rkerberos/kadm5.c +79 -65
- data/ext/rkerberos/keytab.c +237 -106
- data/ext/rkerberos/policy.c +1 -1
- data/ext/rkerberos/rkerberos.c +264 -8
- data/ext/rkerberos/rkerberos.h +2 -0
- data/rkerberos.gemspec +16 -7
- data/spec/config_spec.rb +4 -4
- data/spec/context_spec.rb +36 -0
- 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 +177 -1
- metadata +16 -27
- data/CHANGES +0 -34
- data/Dockerfile +0 -42
- data/MANIFEST +0 -16
- data/docker/Dockerfile.kdc +0 -16
- data/docker/docker-entrypoint.sh +0 -23
- data/docker/kadm5.acl +0 -1
- data/docker/kdc.conf +0 -13
- data/docker/krb5.conf +0 -14
- data/docker-compose.yml +0 -44
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);
|
|
@@ -142,7 +144,6 @@ static VALUE rkadm5_initialize(VALUE self, VALUE v_opts){
|
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
if(RTEST(v_password)){
|
|
145
|
-
#ifdef KADM5_API_VERSION_3
|
|
146
147
|
kerror = kadm5_init_with_password(
|
|
147
148
|
ptr->ctx,
|
|
148
149
|
user,
|
|
@@ -154,24 +155,11 @@ static VALUE rkadm5_initialize(VALUE self, VALUE v_opts){
|
|
|
154
155
|
ptr->db_args,
|
|
155
156
|
&ptr->handle
|
|
156
157
|
);
|
|
157
|
-
#else
|
|
158
|
-
kerror = kadm5_init_with_password(
|
|
159
|
-
user,
|
|
160
|
-
pass,
|
|
161
|
-
service,
|
|
162
|
-
NULL,
|
|
163
|
-
KADM5_STRUCT_VERSION,
|
|
164
|
-
KADM5_API_VERSION_2,
|
|
165
|
-
ptr->db_args,
|
|
166
|
-
&ptr->handle
|
|
167
|
-
);
|
|
168
|
-
#endif
|
|
169
158
|
|
|
170
159
|
if(kerror)
|
|
171
160
|
rb_raise(cKadm5Exception, "kadm5_init_with_password: %s", error_message(kerror));
|
|
172
161
|
}
|
|
173
162
|
else if(RTEST(v_keytab)){
|
|
174
|
-
#ifdef KADM5_API_VERSION_3
|
|
175
163
|
kerror = kadm5_init_with_skey(
|
|
176
164
|
ptr->ctx,
|
|
177
165
|
user,
|
|
@@ -183,18 +171,6 @@ static VALUE rkadm5_initialize(VALUE self, VALUE v_opts){
|
|
|
183
171
|
ptr->db_args,
|
|
184
172
|
&ptr->handle
|
|
185
173
|
);
|
|
186
|
-
#else
|
|
187
|
-
kerror = kadm5_init_with_skey(
|
|
188
|
-
user,
|
|
189
|
-
keytab,
|
|
190
|
-
service,
|
|
191
|
-
NULL,
|
|
192
|
-
KADM5_STRUCT_VERSION,
|
|
193
|
-
KADM5_API_VERSION_2,
|
|
194
|
-
ptr->db_args,
|
|
195
|
-
&ptr->handle
|
|
196
|
-
);
|
|
197
|
-
#endif
|
|
198
174
|
|
|
199
175
|
if(kerror)
|
|
200
176
|
rb_raise(cKadm5Exception, "kadm5_init_with_skey: %s", error_message(kerror));
|
|
@@ -232,6 +208,11 @@ static VALUE rkadm5_set_password(VALUE self, VALUE v_user, VALUE v_pass){
|
|
|
232
208
|
if(!ptr->ctx)
|
|
233
209
|
rb_raise(cKadm5Exception, "no context has been established");
|
|
234
210
|
|
|
211
|
+
if(ptr->princ){
|
|
212
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
213
|
+
ptr->princ = NULL;
|
|
214
|
+
}
|
|
215
|
+
|
|
235
216
|
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
|
236
217
|
|
|
237
218
|
if(kerror)
|
|
@@ -265,6 +246,11 @@ static VALUE rkadm5_set_pwexpire(VALUE self, VALUE v_user, VALUE v_pwexpire){
|
|
|
265
246
|
if(!ptr->ctx)
|
|
266
247
|
rb_raise(cKadm5Exception, "no context has been established");
|
|
267
248
|
|
|
249
|
+
if(ptr->princ){
|
|
250
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
251
|
+
ptr->princ = NULL;
|
|
252
|
+
}
|
|
253
|
+
|
|
268
254
|
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
|
269
255
|
|
|
270
256
|
if(kerror)
|
|
@@ -284,6 +270,8 @@ static VALUE rkadm5_set_pwexpire(VALUE self, VALUE v_user, VALUE v_pwexpire){
|
|
|
284
270
|
ent.pw_expiration=pwexpire;
|
|
285
271
|
kerror = kadm5_modify_principal(ptr->handle, &ent, KADM5_PW_EXPIRATION);
|
|
286
272
|
|
|
273
|
+
kadm5_free_principal_ent(ptr->handle, &ent);
|
|
274
|
+
|
|
287
275
|
if(kerror)
|
|
288
276
|
rb_raise(cKadm5Exception, "kadm5_set_pwexpire: %s", error_message(kerror));
|
|
289
277
|
|
|
@@ -333,15 +321,21 @@ static VALUE rkadm5_create_principal(int argc, VALUE* argv, VALUE self){
|
|
|
333
321
|
|
|
334
322
|
kerror = krb5_parse_name(ptr->ctx, user, &princ.principal);
|
|
335
323
|
|
|
336
|
-
if(kerror)
|
|
324
|
+
if(kerror){
|
|
325
|
+
free_tl_data(princ.tl_data);
|
|
337
326
|
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
|
327
|
+
}
|
|
338
328
|
|
|
339
329
|
kerror = kadm5_create_principal(ptr->handle, &princ, mask, pass);
|
|
340
330
|
|
|
341
|
-
if(kerror)
|
|
331
|
+
if(kerror){
|
|
332
|
+
krb5_free_principal(ptr->ctx, princ.principal);
|
|
333
|
+
free_tl_data(princ.tl_data);
|
|
342
334
|
rb_raise(cKadm5Exception, "kadm5_create_principal: %s", error_message(kerror));
|
|
335
|
+
}
|
|
343
336
|
|
|
344
337
|
krb5_free_principal(ptr->ctx, princ.principal);
|
|
338
|
+
free_tl_data(princ.tl_data);
|
|
345
339
|
|
|
346
340
|
return self;
|
|
347
341
|
}
|
|
@@ -363,6 +357,11 @@ static VALUE rkadm5_delete_principal(VALUE self, VALUE v_user){
|
|
|
363
357
|
if(!ptr->ctx)
|
|
364
358
|
rb_raise(cKadm5Exception, "no context has been established");
|
|
365
359
|
|
|
360
|
+
if(ptr->princ){
|
|
361
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
362
|
+
ptr->princ = NULL;
|
|
363
|
+
}
|
|
364
|
+
|
|
366
365
|
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
|
367
366
|
|
|
368
367
|
if(kerror)
|
|
@@ -390,15 +389,15 @@ static VALUE rkadm5_close(VALUE self){
|
|
|
390
389
|
RUBY_KADM5* ptr;
|
|
391
390
|
TypedData_Get_Struct(self, RUBY_KADM5, &rkadm5_data_type, ptr);
|
|
392
391
|
|
|
392
|
+
if(ptr->handle)
|
|
393
|
+
kadm5_destroy(ptr->handle);
|
|
394
|
+
|
|
393
395
|
if(ptr->princ)
|
|
394
396
|
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
395
397
|
|
|
396
398
|
if(ptr->ctx)
|
|
397
399
|
krb5_free_context(ptr->ctx);
|
|
398
400
|
|
|
399
|
-
if(ptr->handle)
|
|
400
|
-
kadm5_destroy(ptr->handle);
|
|
401
|
-
|
|
402
401
|
free(ptr->db_args);
|
|
403
402
|
|
|
404
403
|
ptr->db_args = NULL;
|
|
@@ -431,10 +430,10 @@ static VALUE create_principal_from_entry(VALUE v_name, RUBY_KADM5* ptr, kadm5_pr
|
|
|
431
430
|
if(ent->last_failed)
|
|
432
431
|
rb_iv_set(v_principal, "@last_failed", rb_time_new(ent->last_failed, 0));
|
|
433
432
|
|
|
434
|
-
if(ent->
|
|
433
|
+
if(ent->last_pwd_change)
|
|
435
434
|
rb_iv_set(v_principal, "@last_password_change", rb_time_new(ent->last_pwd_change, 0));
|
|
436
435
|
|
|
437
|
-
if(ent->
|
|
436
|
+
if(ent->last_success)
|
|
438
437
|
rb_iv_set(v_principal, "@last_success", rb_time_new(ent->last_success, 0));
|
|
439
438
|
|
|
440
439
|
rb_iv_set(v_principal, "@max_life", LONG2FIX(ent->max_life));
|
|
@@ -451,6 +450,7 @@ static VALUE create_principal_from_entry(VALUE v_name, RUBY_KADM5* ptr, kadm5_pr
|
|
|
451
450
|
rb_raise(cKadm5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
|
452
451
|
|
|
453
452
|
rb_iv_set(v_principal, "@mod_name", rb_str_new2(mod_name));
|
|
453
|
+
krb5_free_unparsed_name(ptr->ctx, mod_name);
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
if(ent->pw_expiration)
|
|
@@ -490,6 +490,11 @@ static VALUE rkadm5_find_principal(VALUE self, VALUE v_user){
|
|
|
490
490
|
if(!ptr->ctx)
|
|
491
491
|
rb_raise(cKadm5Exception, "no context has been established");
|
|
492
492
|
|
|
493
|
+
if(ptr->princ){
|
|
494
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
495
|
+
ptr->princ = NULL;
|
|
496
|
+
}
|
|
497
|
+
|
|
493
498
|
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
|
494
499
|
|
|
495
500
|
if(kerror)
|
|
@@ -513,6 +518,7 @@ static VALUE rkadm5_find_principal(VALUE self, VALUE v_user){
|
|
|
513
518
|
}
|
|
514
519
|
else{
|
|
515
520
|
v_principal = create_principal_from_entry(v_user, ptr, &ent);
|
|
521
|
+
kadm5_free_principal_ent(ptr->handle, &ent);
|
|
516
522
|
}
|
|
517
523
|
|
|
518
524
|
return v_principal;
|
|
@@ -546,6 +552,11 @@ static VALUE rkadm5_get_principal(VALUE self, VALUE v_user){
|
|
|
546
552
|
if(!ptr->ctx)
|
|
547
553
|
rb_raise(cKadm5Exception, "no context has been established");
|
|
548
554
|
|
|
555
|
+
if(ptr->princ){
|
|
556
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
557
|
+
ptr->princ = NULL;
|
|
558
|
+
}
|
|
559
|
+
|
|
549
560
|
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
|
550
561
|
|
|
551
562
|
if(kerror)
|
|
@@ -569,6 +580,8 @@ static VALUE rkadm5_get_principal(VALUE self, VALUE v_user){
|
|
|
569
580
|
|
|
570
581
|
v_principal = create_principal_from_entry(v_user, ptr, &ent);
|
|
571
582
|
|
|
583
|
+
kadm5_free_principal_ent(ptr->handle, &ent);
|
|
584
|
+
|
|
572
585
|
return v_principal;
|
|
573
586
|
}
|
|
574
587
|
|
|
@@ -635,7 +648,7 @@ static VALUE rkadm5_create_policy(VALUE self, VALUE v_policy){
|
|
|
635
648
|
|
|
636
649
|
if(RTEST(v_history_num)){
|
|
637
650
|
mask |= KADM5_PW_HISTORY_NUM;
|
|
638
|
-
ent.
|
|
651
|
+
ent.pw_history_num = NUM2LONG(v_history_num);
|
|
639
652
|
}
|
|
640
653
|
|
|
641
654
|
kerror = kadm5_create_policy(ptr->handle, &ent, mask);
|
|
@@ -720,6 +733,8 @@ static VALUE rkadm5_get_policy(VALUE self, VALUE v_name){
|
|
|
720
733
|
v_arg[0] = v_hash;
|
|
721
734
|
|
|
722
735
|
v_policy = rb_class_new_instance(1, v_arg, cKadm5Policy);
|
|
736
|
+
|
|
737
|
+
kadm5_free_policy_ent(ptr->handle, &ent);
|
|
723
738
|
}
|
|
724
739
|
|
|
725
740
|
return v_policy;
|
|
@@ -775,6 +790,8 @@ static VALUE rkadm5_find_policy(VALUE self, VALUE v_name){
|
|
|
775
790
|
v_arg[0] = v_hash;
|
|
776
791
|
|
|
777
792
|
v_policy = rb_class_new_instance(1, v_arg, cKadm5Policy);
|
|
793
|
+
|
|
794
|
+
kadm5_free_policy_ent(ptr->handle, &ent);
|
|
778
795
|
}
|
|
779
796
|
|
|
780
797
|
return v_policy;
|
|
@@ -932,15 +949,14 @@ static VALUE rkadm5_get_principals(int argc, VALUE* argv, VALUE self){
|
|
|
932
949
|
* KADM5_PRIV_ADD (0x02) => "ADD"
|
|
933
950
|
* KADM5_PRIV_MODIFY (0x04) => "MODIFY"
|
|
934
951
|
* KADM5_PRIV_DELETE (0x08) => "DELETE"
|
|
952
|
+
*
|
|
935
953
|
*/
|
|
936
954
|
static VALUE rkadm5_get_privs(int argc, VALUE* argv, VALUE self){
|
|
937
955
|
RUBY_KADM5* ptr;
|
|
938
956
|
VALUE v_return = Qnil;
|
|
939
957
|
VALUE v_strings = Qfalse;
|
|
940
958
|
kadm5_ret_t kerror;
|
|
941
|
-
unsigned int i;
|
|
942
959
|
long privs;
|
|
943
|
-
int result = 0;
|
|
944
960
|
|
|
945
961
|
TypedData_Get_Struct(self, RUBY_KADM5, &rkadm5_data_type, ptr);
|
|
946
962
|
|
|
@@ -954,31 +970,17 @@ static VALUE rkadm5_get_privs(int argc, VALUE* argv, VALUE self){
|
|
|
954
970
|
if(RTEST(v_strings)){
|
|
955
971
|
v_return = rb_ary_new();
|
|
956
972
|
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
break;
|
|
966
|
-
case KADM5_PRIV_MODIFY:
|
|
967
|
-
rb_ary_push(v_return, rb_str_new2("MODIFY"));
|
|
968
|
-
break;
|
|
969
|
-
case KADM5_PRIV_DELETE:
|
|
970
|
-
rb_ary_push(v_return, rb_str_new2("DELETE"));
|
|
971
|
-
break;
|
|
972
|
-
default:
|
|
973
|
-
rb_ary_push(v_return, rb_str_new2("UNKNOWN"));
|
|
974
|
-
};
|
|
975
|
-
}
|
|
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"));
|
|
976
981
|
}
|
|
977
982
|
else{
|
|
978
|
-
|
|
979
|
-
result |= (privs & 1 << i);
|
|
980
|
-
}
|
|
981
|
-
v_return = INT2FIX(result);
|
|
983
|
+
v_return = LONG2FIX(privs);
|
|
982
984
|
}
|
|
983
985
|
|
|
984
986
|
return v_return;
|
|
@@ -1013,13 +1015,16 @@ static VALUE rkadm5_randkey_principal(VALUE self, VALUE v_user){
|
|
|
1013
1015
|
|
|
1014
1016
|
kerror = kadm5_randkey_principal(ptr->handle, princ, &keys, &n_keys);
|
|
1015
1017
|
|
|
1016
|
-
if(kerror)
|
|
1018
|
+
if(kerror){
|
|
1019
|
+
krb5_free_principal(ptr->ctx, princ);
|
|
1017
1020
|
rb_raise(cKadm5Exception, "kadm5_randkey_principal: %s (%li)", error_message(kerror), kerror);
|
|
1021
|
+
}
|
|
1018
1022
|
|
|
1019
1023
|
for(i = 0; i < n_keys; i++)
|
|
1020
1024
|
krb5_free_keyblock_contents(ptr->ctx, &keys[i]);
|
|
1021
1025
|
|
|
1022
1026
|
free(keys);
|
|
1027
|
+
krb5_free_principal(ptr->ctx, princ);
|
|
1023
1028
|
|
|
1024
1029
|
return INT2NUM(n_keys);
|
|
1025
1030
|
}
|
|
@@ -1040,7 +1045,7 @@ char** parse_db_args(VALUE v_db_args){
|
|
|
1040
1045
|
case T_ARRAY:
|
|
1041
1046
|
// Multiple arguments
|
|
1042
1047
|
array_length = RARRAY_LEN(v_db_args);
|
|
1043
|
-
db_args = (char **) malloc(array_length * sizeof(char *)
|
|
1048
|
+
db_args = (char **) malloc((array_length + 1) * sizeof(char *));
|
|
1044
1049
|
for(long i = 0; i < array_length; ++i){
|
|
1045
1050
|
VALUE elem = rb_ary_entry(v_db_args, i);
|
|
1046
1051
|
Check_Type(elem, T_STRING);
|
|
@@ -1072,6 +1077,15 @@ void add_db_args(kadm5_principal_ent_rec* entry, char** db_args){
|
|
|
1072
1077
|
/**
|
|
1073
1078
|
* Source code taken from kadmin source code at https://github.com/krb5/krb5/blob/master/src/kadmin/cli/kadmin.c
|
|
1074
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
|
+
|
|
1075
1089
|
void add_tl_data(krb5_int16 *n_tl_datap, krb5_tl_data **tl_datap,
|
|
1076
1090
|
krb5_int16 tl_type, krb5_ui_2 len, krb5_octet *contents){
|
|
1077
1091
|
krb5_tl_data* tl_data;
|