rkerberos 0.1.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.
- data/CHANGES +3 -0
- data/MANIFEST +16 -0
- data/README +51 -0
- data/Rakefile +148 -0
- data/ext/rkerberos/ccache.c +250 -0
- data/ext/rkerberos/config.c +312 -0
- data/ext/rkerberos/context.c +77 -0
- data/ext/rkerberos/extconf.rb +14 -0
- data/ext/rkerberos/kadm5.c +991 -0
- data/ext/rkerberos/keytab.c +509 -0
- data/ext/rkerberos/keytab_entry.c +84 -0
- data/ext/rkerberos/policy.c +196 -0
- data/ext/rkerberos/principal.c +263 -0
- data/ext/rkerberos/rkerberos.c +566 -0
- data/ext/rkerberos/rkerberos.h +95 -0
- data/rkerberos.gemspec +28 -0
- data/test/test_config.rb +129 -0
- data/test/test_context.rb +33 -0
- data/test/test_credentials_cache.rb +153 -0
- data/test/test_kadm5.rb +424 -0
- data/test/test_keytab_entry.rb +66 -0
- data/test/test_krb5.rb +198 -0
- data/test/test_krb5_keytab.rb +294 -0
- data/test/test_policy.rb +123 -0
- data/test/test_principal.rb +134 -0
- metadata +155 -0
@@ -0,0 +1,509 @@
|
|
1
|
+
#include <rkerberos.h>
|
2
|
+
|
3
|
+
VALUE cKrb5Keytab, cKrb5KeytabException;
|
4
|
+
|
5
|
+
// Free function for the Kerberos::Krb5::Keytab class.
|
6
|
+
static void rkrb5_keytab_free(RUBY_KRB5_KEYTAB* ptr){
|
7
|
+
if(!ptr)
|
8
|
+
return;
|
9
|
+
|
10
|
+
if(ptr->keytab)
|
11
|
+
krb5_kt_close(ptr->ctx, ptr->keytab);
|
12
|
+
|
13
|
+
if(ptr->ctx)
|
14
|
+
krb5_free_context(ptr->ctx);
|
15
|
+
|
16
|
+
free(ptr);
|
17
|
+
}
|
18
|
+
|
19
|
+
// Allocation function for the Kerberos::Krb5::Keytab class.
|
20
|
+
static VALUE rkrb5_keytab_allocate(VALUE klass){
|
21
|
+
RUBY_KRB5_KEYTAB* ptr = malloc(sizeof(RUBY_KRB5_KEYTAB));
|
22
|
+
memset(ptr, 0, sizeof(RUBY_KRB5_KEYTAB));
|
23
|
+
return Data_Wrap_Struct(klass, 0, rkrb5_keytab_free, ptr);
|
24
|
+
}
|
25
|
+
|
26
|
+
/*
|
27
|
+
* call-seq:
|
28
|
+
*
|
29
|
+
* keytab.each{ |entry| p entry }
|
30
|
+
*
|
31
|
+
* Iterates over each entry, and yield the principal name.
|
32
|
+
*--
|
33
|
+
* TODO: Mixin Enumerable properly.
|
34
|
+
*/
|
35
|
+
static VALUE rkrb5_keytab_each(VALUE self){
|
36
|
+
RUBY_KRB5_KEYTAB* ptr;
|
37
|
+
VALUE v_kt_entry;
|
38
|
+
VALUE v_args[0];
|
39
|
+
krb5_error_code kerror;
|
40
|
+
krb5_kt_cursor cursor;
|
41
|
+
krb5_keytab_entry entry;
|
42
|
+
char* principal;
|
43
|
+
|
44
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
45
|
+
|
46
|
+
kerror = krb5_kt_start_seq_get(
|
47
|
+
ptr->ctx,
|
48
|
+
ptr->keytab,
|
49
|
+
&cursor
|
50
|
+
);
|
51
|
+
|
52
|
+
if(kerror)
|
53
|
+
rb_raise(cKrb5Exception, "krb5_kt_start_seq_get: %s", error_message(kerror));
|
54
|
+
|
55
|
+
while((kerror = krb5_kt_next_entry(ptr->ctx, ptr->keytab, &entry, &cursor)) == 0){
|
56
|
+
krb5_unparse_name(ptr->ctx, entry.principal, &principal);
|
57
|
+
|
58
|
+
v_kt_entry = rb_class_new_instance(0, v_args, cKrb5KtEntry);
|
59
|
+
|
60
|
+
rb_iv_set(v_kt_entry, "@principal", rb_str_new2(principal));
|
61
|
+
rb_iv_set(v_kt_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
62
|
+
rb_iv_set(v_kt_entry, "@vno", INT2FIX(entry.vno));
|
63
|
+
rb_iv_set(v_kt_entry, "@key", INT2FIX(entry.key.enctype));
|
64
|
+
|
65
|
+
rb_yield(v_kt_entry);
|
66
|
+
|
67
|
+
free(principal);
|
68
|
+
|
69
|
+
krb5_kt_free_entry(ptr->ctx, &entry);
|
70
|
+
}
|
71
|
+
|
72
|
+
kerror = krb5_kt_end_seq_get(
|
73
|
+
ptr->ctx,
|
74
|
+
ptr->keytab,
|
75
|
+
&cursor
|
76
|
+
);
|
77
|
+
|
78
|
+
if(kerror)
|
79
|
+
rb_raise(cKrb5Exception, "krb5_kt_end_seq_get: %s", error_message(kerror));
|
80
|
+
|
81
|
+
return self;
|
82
|
+
}
|
83
|
+
|
84
|
+
/*
|
85
|
+
* call-seq:
|
86
|
+
*
|
87
|
+
* keytab.default_name
|
88
|
+
*
|
89
|
+
* Returns the default keytab name.
|
90
|
+
*/
|
91
|
+
static VALUE rkrb5_keytab_default_name(VALUE self){
|
92
|
+
char default_name[MAX_KEYTAB_NAME_LEN];
|
93
|
+
krb5_error_code kerror;
|
94
|
+
RUBY_KRB5_KEYTAB* ptr;
|
95
|
+
VALUE v_default_name;
|
96
|
+
|
97
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
98
|
+
|
99
|
+
kerror = krb5_kt_default_name(ptr->ctx, default_name, MAX_KEYTAB_NAME_LEN);
|
100
|
+
|
101
|
+
if(kerror)
|
102
|
+
rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
|
103
|
+
|
104
|
+
v_default_name = rb_str_new2(default_name);
|
105
|
+
|
106
|
+
return v_default_name;
|
107
|
+
}
|
108
|
+
|
109
|
+
/*
|
110
|
+
* call-seq:
|
111
|
+
* keytab.close
|
112
|
+
*
|
113
|
+
* Close the keytab object. Internally this frees up any associated
|
114
|
+
* credential contents and the Kerberos context. Once a keytab object
|
115
|
+
* is closed it cannot be reused.
|
116
|
+
*/
|
117
|
+
static VALUE rkrb5_keytab_close(VALUE self){
|
118
|
+
RUBY_KRB5_KEYTAB* ptr;
|
119
|
+
|
120
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
121
|
+
|
122
|
+
if(ptr->ctx)
|
123
|
+
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
124
|
+
|
125
|
+
if(ptr->ctx)
|
126
|
+
krb5_free_context(ptr->ctx);
|
127
|
+
|
128
|
+
ptr->ctx = NULL;
|
129
|
+
|
130
|
+
return Qtrue;
|
131
|
+
}
|
132
|
+
|
133
|
+
/*
|
134
|
+
static VALUE rkrb5_keytab_remove_entry(int argc, VALUE* argv, VALUE self){
|
135
|
+
RUBY_KRB5_KEYTAB* ptr;
|
136
|
+
krb5_error_code kerror;
|
137
|
+
krb5_keytab_entry entry;
|
138
|
+
char* name;
|
139
|
+
VALUE v_name, v_vno, v_enctype;
|
140
|
+
|
141
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
142
|
+
|
143
|
+
rb_scan_args(argc, argv, "12", &v_name, &v_vno, &v_enctype);
|
144
|
+
|
145
|
+
Check_Type(v_name, T_STRING);
|
146
|
+
|
147
|
+
name = StringValuePtr(v_name);
|
148
|
+
|
149
|
+
if(!ptr->ctx)
|
150
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
151
|
+
|
152
|
+
kerror = krb5_parse_name(ptr->ctx, name, &entry.principal);
|
153
|
+
|
154
|
+
if(kerror)
|
155
|
+
rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));
|
156
|
+
|
157
|
+
if(NIL_P(v_vno))
|
158
|
+
entry.vno = 0;
|
159
|
+
else
|
160
|
+
entry.vno = NUM2INT(v_vno);
|
161
|
+
|
162
|
+
if(NIL_P(v_enctype))
|
163
|
+
entry.key.enctype = 0;
|
164
|
+
else
|
165
|
+
entry.key.enctype = NUM2INT(v_enctype);
|
166
|
+
|
167
|
+
entry.key.length = 16;
|
168
|
+
|
169
|
+
kerror = krb5_kt_remove_entry(
|
170
|
+
ptr->ctx,
|
171
|
+
ptr->keytab,
|
172
|
+
&entry
|
173
|
+
);
|
174
|
+
|
175
|
+
if(kerror)
|
176
|
+
rb_raise(cKrb5KeytabException, "krb5_kt_remove_entry: %s", error_message(kerror));
|
177
|
+
|
178
|
+
return self;
|
179
|
+
}
|
180
|
+
|
181
|
+
static VALUE rkrb5_keytab_add_entry(int argc, VALUE* argv, VALUE self){
|
182
|
+
RUBY_KRB5_KEYTAB* ptr;
|
183
|
+
krb5_error_code kerror;
|
184
|
+
krb5_keytab_entry entry;
|
185
|
+
char* name;
|
186
|
+
VALUE v_name, v_vno, v_enctype;
|
187
|
+
|
188
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
189
|
+
|
190
|
+
rb_scan_args(argc, argv, "12", &v_name, &v_vno, &v_enctype);
|
191
|
+
|
192
|
+
Check_Type(v_name, T_STRING);
|
193
|
+
|
194
|
+
name = StringValuePtr(v_name);
|
195
|
+
|
196
|
+
if(!ptr->ctx)
|
197
|
+
rb_raise(cKrb5Exception, "no context has been established");
|
198
|
+
|
199
|
+
kerror = krb5_parse_name(ptr->ctx, name, &entry.principal);
|
200
|
+
|
201
|
+
if(kerror)
|
202
|
+
rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));
|
203
|
+
|
204
|
+
if(NIL_P(v_vno))
|
205
|
+
entry.vno = 0;
|
206
|
+
else
|
207
|
+
entry.vno = NUM2INT(v_vno);
|
208
|
+
|
209
|
+
if(NIL_P(v_enctype))
|
210
|
+
entry.key.enctype = 0;
|
211
|
+
else
|
212
|
+
entry.key.enctype = NUM2INT(v_enctype);
|
213
|
+
|
214
|
+
entry.key.length = 16;
|
215
|
+
|
216
|
+
kerror = krb5_kt_add_entry(
|
217
|
+
ptr->ctx,
|
218
|
+
ptr->keytab,
|
219
|
+
&entry
|
220
|
+
);
|
221
|
+
|
222
|
+
if(kerror)
|
223
|
+
rb_raise(cKrb5KeytabException, "krb5_kt_add_entry: %s", error_message(kerror));
|
224
|
+
|
225
|
+
return self;
|
226
|
+
}
|
227
|
+
*/
|
228
|
+
|
229
|
+
/*
|
230
|
+
* call-seq:
|
231
|
+
* keytab.get_entry(principal, vno = 0, encoding_type = nil)
|
232
|
+
*
|
233
|
+
* Searches the keytab by +principal+, +vno+ and +encoding_type+. If the
|
234
|
+
* +vno+ is zero (the default), then the first entry that matches +principal+
|
235
|
+
* is returned.
|
236
|
+
*
|
237
|
+
* Returns a Kerberos::Krb5::KeytabEntry object if the entry is found.
|
238
|
+
*
|
239
|
+
* Raises an exception if no entry is found.
|
240
|
+
*/
|
241
|
+
static VALUE rkrb5_keytab_get_entry(int argc, VALUE* argv, VALUE self){
|
242
|
+
RUBY_KRB5_KEYTAB* ptr;
|
243
|
+
krb5_error_code kerror;
|
244
|
+
krb5_principal principal;
|
245
|
+
krb5_kvno vno;
|
246
|
+
krb5_enctype enctype;
|
247
|
+
krb5_keytab_entry entry;
|
248
|
+
char* name;
|
249
|
+
VALUE v_principal, v_vno, v_enctype, v_entry;
|
250
|
+
VALUE v_args[0];
|
251
|
+
|
252
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
253
|
+
|
254
|
+
rb_scan_args(argc, argv, "12", &v_principal, &v_vno, &v_enctype);
|
255
|
+
|
256
|
+
Check_Type(v_principal, T_STRING);
|
257
|
+
name = StringValuePtr(v_principal);
|
258
|
+
|
259
|
+
kerror = krb5_parse_name(ptr->ctx, name, &principal);
|
260
|
+
|
261
|
+
if(kerror)
|
262
|
+
rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
263
|
+
|
264
|
+
vno = 0;
|
265
|
+
enctype = 0;
|
266
|
+
|
267
|
+
kerror = krb5_kt_get_entry(
|
268
|
+
ptr->ctx,
|
269
|
+
ptr->keytab,
|
270
|
+
principal,
|
271
|
+
vno,
|
272
|
+
enctype,
|
273
|
+
&entry
|
274
|
+
);
|
275
|
+
|
276
|
+
if(kerror)
|
277
|
+
rb_raise(cKrb5Exception, "krb5_kt_get_entry: %s", error_message(kerror));
|
278
|
+
|
279
|
+
v_entry = rb_class_new_instance(0, v_args, cKrb5KtEntry);
|
280
|
+
|
281
|
+
rb_iv_set(v_entry, "@principal", rb_str_new2(name));
|
282
|
+
rb_iv_set(v_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
283
|
+
rb_iv_set(v_entry, "@vno", INT2FIX(entry.vno));
|
284
|
+
rb_iv_set(v_entry, "@key", INT2FIX(entry.key.enctype));
|
285
|
+
|
286
|
+
krb5_kt_free_entry(ptr->ctx, &entry);
|
287
|
+
|
288
|
+
return v_entry;
|
289
|
+
}
|
290
|
+
|
291
|
+
/*
|
292
|
+
* call-seq:
|
293
|
+
* Kerberos::Krb5::Keytab.new(name = nil)
|
294
|
+
*
|
295
|
+
* Creates and returns a new Kerberos::Krb5::Keytab object. This initializes
|
296
|
+
* the context and keytab for future method calls on that object.
|
297
|
+
*
|
298
|
+
* A keytab file +name+ may be provided. If not, the system's default keytab
|
299
|
+
* name is used. If a +name+ is provided it must be in the form 'type:residual'
|
300
|
+
* where 'type' is a type known to the Kerberos library.
|
301
|
+
*
|
302
|
+
* Examples:
|
303
|
+
*
|
304
|
+
* # Using the default keytab
|
305
|
+
* keytab = Kerberos::Krb5::Keytab.new
|
306
|
+
*
|
307
|
+
* # Using an explicit keytab
|
308
|
+
* keytab = Kerberos::Krb5::Keytab.new('FILE:/etc/krb5.keytab')
|
309
|
+
*/
|
310
|
+
static VALUE rkrb5_keytab_initialize(int argc, VALUE* argv, VALUE self){
|
311
|
+
RUBY_KRB5_KEYTAB* ptr;
|
312
|
+
krb5_error_code kerror;
|
313
|
+
char keytab_name[MAX_KEYTAB_NAME_LEN];
|
314
|
+
VALUE v_keytab_name = Qnil;
|
315
|
+
|
316
|
+
Data_Get_Struct(self, RUBY_KRB5_KEYTAB, ptr);
|
317
|
+
|
318
|
+
rb_scan_args(argc, argv, "01", &v_keytab_name);
|
319
|
+
|
320
|
+
kerror = krb5_init_context(&ptr->ctx);
|
321
|
+
|
322
|
+
if(kerror)
|
323
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
324
|
+
|
325
|
+
// Use the default keytab name if one isn't provided.
|
326
|
+
if(NIL_P(v_keytab_name)){
|
327
|
+
kerror = krb5_kt_default_name(ptr->ctx, keytab_name, MAX_KEYTAB_NAME_LEN);
|
328
|
+
|
329
|
+
if(kerror)
|
330
|
+
rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
|
331
|
+
|
332
|
+
rb_iv_set(self, "@name", rb_str_new2(keytab_name));
|
333
|
+
}
|
334
|
+
else{
|
335
|
+
Check_Type(v_keytab_name, T_STRING);
|
336
|
+
strncpy(keytab_name, StringValuePtr(v_keytab_name), MAX_KEYTAB_NAME_LEN);
|
337
|
+
rb_iv_set(self, "@name", v_keytab_name);
|
338
|
+
}
|
339
|
+
|
340
|
+
kerror = krb5_kt_resolve(
|
341
|
+
ptr->ctx,
|
342
|
+
keytab_name,
|
343
|
+
&ptr->keytab
|
344
|
+
);
|
345
|
+
|
346
|
+
if(kerror)
|
347
|
+
rb_raise(cKrb5KeytabException, "krb5_kt_resolve: %s", error_message(kerror));
|
348
|
+
|
349
|
+
return self;
|
350
|
+
}
|
351
|
+
|
352
|
+
// Singleton Methods
|
353
|
+
|
354
|
+
/*
|
355
|
+
* call-seq:
|
356
|
+
* Kerberos::Krb5::Keytab.foreach(keytab = nil){ |entry|
|
357
|
+
* puts entry.inspect
|
358
|
+
* }
|
359
|
+
*
|
360
|
+
* Iterate over each entry in the +keytab+ and yield a Krb5::Keytab::Entry
|
361
|
+
* object for each entry found.
|
362
|
+
*
|
363
|
+
* If no +keytab+ is provided, then the default keytab is used.
|
364
|
+
*/
|
365
|
+
static VALUE rkrb5_s_keytab_foreach(int argc, VALUE* argv, VALUE klass){
|
366
|
+
VALUE v_kt_entry;
|
367
|
+
VALUE v_keytab_name;
|
368
|
+
VALUE v_args[0];
|
369
|
+
krb5_error_code kerror;
|
370
|
+
krb5_kt_cursor cursor;
|
371
|
+
krb5_keytab keytab;
|
372
|
+
krb5_keytab_entry entry;
|
373
|
+
krb5_context context;
|
374
|
+
char* principal;
|
375
|
+
char keytab_name[MAX_KEYTAB_NAME_LEN];
|
376
|
+
|
377
|
+
rb_scan_args(argc, argv, "01", &v_keytab_name);
|
378
|
+
|
379
|
+
kerror = krb5_init_context(&context);
|
380
|
+
|
381
|
+
if(kerror)
|
382
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
383
|
+
|
384
|
+
// Use the default keytab name if one isn't provided.
|
385
|
+
if(NIL_P(v_keytab_name)){
|
386
|
+
kerror = krb5_kt_default_name(context, keytab_name, MAX_KEYTAB_NAME_LEN);
|
387
|
+
|
388
|
+
if(kerror){
|
389
|
+
if(context)
|
390
|
+
krb5_free_context(context);
|
391
|
+
|
392
|
+
rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
|
393
|
+
}
|
394
|
+
}
|
395
|
+
else{
|
396
|
+
Check_Type(v_keytab_name, T_STRING);
|
397
|
+
strncpy(keytab_name, StringValuePtr(v_keytab_name), MAX_KEYTAB_NAME_LEN);
|
398
|
+
}
|
399
|
+
|
400
|
+
kerror = krb5_kt_resolve(
|
401
|
+
context,
|
402
|
+
keytab_name,
|
403
|
+
&keytab
|
404
|
+
);
|
405
|
+
|
406
|
+
if(kerror){
|
407
|
+
if(context)
|
408
|
+
krb5_free_context(context);
|
409
|
+
|
410
|
+
rb_raise(cKrb5Exception, "krb5_kt_resolve: %s", error_message(kerror));
|
411
|
+
}
|
412
|
+
|
413
|
+
kerror = krb5_kt_start_seq_get(
|
414
|
+
context,
|
415
|
+
keytab,
|
416
|
+
&cursor
|
417
|
+
);
|
418
|
+
|
419
|
+
if(kerror){
|
420
|
+
if(context)
|
421
|
+
krb5_free_context(context);
|
422
|
+
|
423
|
+
if(keytab)
|
424
|
+
krb5_kt_close(context, keytab);
|
425
|
+
|
426
|
+
rb_raise(cKrb5Exception, "krb5_kt_start_seq_get: %s", error_message(kerror));
|
427
|
+
}
|
428
|
+
|
429
|
+
while((kerror = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){
|
430
|
+
krb5_unparse_name(context, entry.principal, &principal);
|
431
|
+
|
432
|
+
v_kt_entry = rb_class_new_instance(0, v_args, cKrb5KtEntry);
|
433
|
+
|
434
|
+
rb_iv_set(v_kt_entry, "@principal", rb_str_new2(principal));
|
435
|
+
rb_iv_set(v_kt_entry, "@timestamp", rb_time_new(entry.timestamp, 0));
|
436
|
+
rb_iv_set(v_kt_entry, "@vno", INT2FIX(entry.vno));
|
437
|
+
rb_iv_set(v_kt_entry, "@key", INT2FIX(entry.key.enctype));
|
438
|
+
|
439
|
+
rb_yield(v_kt_entry);
|
440
|
+
|
441
|
+
free(principal);
|
442
|
+
|
443
|
+
krb5_kt_free_entry(context, &entry);
|
444
|
+
}
|
445
|
+
|
446
|
+
kerror = krb5_kt_end_seq_get(
|
447
|
+
context,
|
448
|
+
keytab,
|
449
|
+
&cursor
|
450
|
+
);
|
451
|
+
|
452
|
+
if(kerror){
|
453
|
+
if(context)
|
454
|
+
krb5_free_context(context);
|
455
|
+
|
456
|
+
if(keytab)
|
457
|
+
krb5_kt_close(context, keytab);
|
458
|
+
|
459
|
+
rb_raise(cKrb5Exception, "krb5_kt_end_seq_get: %s", error_message(kerror));
|
460
|
+
}
|
461
|
+
|
462
|
+
if(keytab)
|
463
|
+
krb5_kt_close(context, keytab);
|
464
|
+
|
465
|
+
if(context)
|
466
|
+
krb5_free_context(context);
|
467
|
+
|
468
|
+
return Qnil;
|
469
|
+
}
|
470
|
+
|
471
|
+
void Init_keytab(){
|
472
|
+
/* The Kerberos::Krb5::Keytab class encapsulates a Kerberos keytab. */
|
473
|
+
cKrb5Keytab = rb_define_class_under(cKrb5, "Keytab", rb_cObject);
|
474
|
+
|
475
|
+
/* The Keytab::Exception is typically raised if any of the Keytab methods fail. */
|
476
|
+
cKrb5KeytabException = rb_define_class_under(cKrb5Keytab, "Exception", rb_eStandardError);
|
477
|
+
|
478
|
+
// Allocation Function
|
479
|
+
|
480
|
+
rb_define_alloc_func(cKrb5Keytab, rkrb5_keytab_allocate);
|
481
|
+
|
482
|
+
// Constructor
|
483
|
+
|
484
|
+
rb_define_method(cKrb5Keytab, "initialize", rkrb5_keytab_initialize, -1);
|
485
|
+
|
486
|
+
// Singleton Methods
|
487
|
+
|
488
|
+
rb_define_singleton_method(cKrb5Keytab, "foreach", rkrb5_s_keytab_foreach, -1);
|
489
|
+
|
490
|
+
// Instance Methods
|
491
|
+
|
492
|
+
rb_define_method(cKrb5Keytab, "default_name", rkrb5_keytab_default_name, 0);
|
493
|
+
rb_define_method(cKrb5Keytab, "close", rkrb5_keytab_close, 0);
|
494
|
+
rb_define_method(cKrb5Keytab, "each", rkrb5_keytab_each, 0);
|
495
|
+
rb_define_method(cKrb5Keytab, "get_entry", rkrb5_keytab_get_entry, -1);
|
496
|
+
|
497
|
+
// TODO: Move these into Kadm5 and/or figure out how to set the vno properly.
|
498
|
+
// rb_define_method(cKrb5Keytab, "add_entry", rkrb5_keytab_add_entry, -1);
|
499
|
+
// rb_define_method(cKrb5Keytab, "remove_entry", rkrb5_keytab_remove_entry, -1);
|
500
|
+
|
501
|
+
// Accessors
|
502
|
+
|
503
|
+
/* The name of the keytab associated with the current keytab object. */
|
504
|
+
rb_define_attr(cKrb5Keytab, "name", 1, 0);
|
505
|
+
|
506
|
+
// Aliases
|
507
|
+
|
508
|
+
rb_define_alias(cKrb5Keytab, "find", "get_entry");
|
509
|
+
}
|