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,312 @@
|
|
1
|
+
#include <rkerberos.h>
|
2
|
+
|
3
|
+
VALUE cKadm5Config;
|
4
|
+
|
5
|
+
static void rkadm5_config_free(RUBY_KADM5_CONFIG* ptr){
|
6
|
+
if(!ptr)
|
7
|
+
return;
|
8
|
+
|
9
|
+
kadm5_free_config_params(ptr->ctx, &ptr->config);
|
10
|
+
|
11
|
+
if(ptr->ctx)
|
12
|
+
krb5_free_context(ptr->ctx);
|
13
|
+
|
14
|
+
free(ptr);
|
15
|
+
}
|
16
|
+
|
17
|
+
// Allocation function for the Kerberos::Krb5 class.
|
18
|
+
static VALUE rkadm5_config_allocate(VALUE klass){
|
19
|
+
RUBY_KADM5_CONFIG* ptr = malloc(sizeof(RUBY_KADM5_CONFIG));
|
20
|
+
memset(ptr, 0, sizeof(RUBY_KADM5_CONFIG));
|
21
|
+
return Data_Wrap_Struct(klass, 0, rkadm5_config_free, ptr);
|
22
|
+
}
|
23
|
+
|
24
|
+
/*
|
25
|
+
* Returns a Kerberos::Kadm5::Config object. This object contains Kerberos
|
26
|
+
* admin configuration.
|
27
|
+
*
|
28
|
+
* Note that the returned object is frozen. Changes made to the Kerberos
|
29
|
+
* admin configuration options after the call will not be reflected in this
|
30
|
+
* object.
|
31
|
+
*/
|
32
|
+
static VALUE rkadm5_config_initialize(VALUE self){
|
33
|
+
RUBY_KADM5_CONFIG* ptr;
|
34
|
+
krb5_error_code kerror;
|
35
|
+
|
36
|
+
Data_Get_Struct(self, RUBY_KADM5_CONFIG, ptr);
|
37
|
+
|
38
|
+
kerror = krb5_init_context(&ptr->ctx);
|
39
|
+
|
40
|
+
if(kerror)
|
41
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
42
|
+
|
43
|
+
kerror = kadm5_get_config_params(
|
44
|
+
ptr->ctx,
|
45
|
+
1,
|
46
|
+
&ptr->config,
|
47
|
+
&ptr->config
|
48
|
+
);
|
49
|
+
|
50
|
+
if(kerror)
|
51
|
+
rb_raise(cKrb5Exception, "kadm5_get_config_params: %s", error_message(kerror));
|
52
|
+
|
53
|
+
if(ptr->config.realm)
|
54
|
+
rb_iv_set(self, "@realm", rb_str_new2(ptr->config.realm));
|
55
|
+
else
|
56
|
+
rb_iv_set(self, "@realm", Qnil);
|
57
|
+
|
58
|
+
if(ptr->config.admin_server)
|
59
|
+
rb_iv_set(self, "@admin_server", rb_str_new2(ptr->config.admin_server));
|
60
|
+
else
|
61
|
+
rb_iv_set(self, "@admin_server", Qnil);
|
62
|
+
|
63
|
+
if(ptr->config.kadmind_port)
|
64
|
+
rb_iv_set(self, "@kadmind_port", INT2FIX(ptr->config.kadmind_port));
|
65
|
+
else
|
66
|
+
rb_iv_set(self, "@kadmind_port", Qnil);
|
67
|
+
|
68
|
+
if(ptr->config.kpasswd_port)
|
69
|
+
rb_iv_set(self, "@kpasswd_port", INT2FIX(ptr->config.kpasswd_port));
|
70
|
+
else
|
71
|
+
rb_iv_set(self, "@kpasswd_port", Qnil);
|
72
|
+
|
73
|
+
if(ptr->config.admin_keytab)
|
74
|
+
rb_iv_set(self, "@admin_keytab", rb_str_new2(ptr->config.admin_keytab));
|
75
|
+
else
|
76
|
+
rb_iv_set(self, "@admin_keytab", Qnil);
|
77
|
+
|
78
|
+
if(ptr->config.acl_file)
|
79
|
+
rb_iv_set(self, "@acl_file", rb_str_new2(ptr->config.acl_file));
|
80
|
+
else
|
81
|
+
rb_iv_set(self, "@acl_file", Qnil);
|
82
|
+
|
83
|
+
if(ptr->config.dict_file)
|
84
|
+
rb_iv_set(self, "@dict_file", rb_str_new2(ptr->config.dict_file));
|
85
|
+
else
|
86
|
+
rb_iv_set(self, "@dict_file", Qnil);
|
87
|
+
|
88
|
+
if(ptr->config.stash_file)
|
89
|
+
rb_iv_set(self, "@stash_file", rb_str_new2(ptr->config.stash_file));
|
90
|
+
else
|
91
|
+
rb_iv_set(self, "@stash_file", Qnil);
|
92
|
+
|
93
|
+
if(ptr->config.mkey_name)
|
94
|
+
rb_iv_set(self, "@mkey_name", rb_str_new2(ptr->config.mkey_name));
|
95
|
+
else
|
96
|
+
rb_iv_set(self, "@mkey_name", Qnil);
|
97
|
+
|
98
|
+
if(ptr->config.mkey_from_kbd)
|
99
|
+
rb_iv_set(self, "@mkey_from_kbd", INT2FIX(ptr->config.mkey_from_kbd));
|
100
|
+
else
|
101
|
+
rb_iv_set(self, "@mkey_from_kbd", Qnil);
|
102
|
+
|
103
|
+
if(ptr->config.enctype)
|
104
|
+
rb_iv_set(self, "@enctype", INT2FIX(ptr->config.enctype));
|
105
|
+
else
|
106
|
+
rb_iv_set(self, "@enctype", Qnil);
|
107
|
+
|
108
|
+
if(ptr->config.max_life)
|
109
|
+
rb_iv_set(self, "@max_life", INT2FIX(ptr->config.max_life));
|
110
|
+
else
|
111
|
+
rb_iv_set(self, "@max_life", Qnil);
|
112
|
+
|
113
|
+
if(ptr->config.max_rlife)
|
114
|
+
rb_iv_set(self, "@max_rlife", INT2FIX(ptr->config.max_rlife));
|
115
|
+
else
|
116
|
+
rb_iv_set(self, "@max_rlife", Qnil);
|
117
|
+
|
118
|
+
if(ptr->config.expiration)
|
119
|
+
rb_iv_set(self, "@expiration", rb_time_new(ptr->config.expiration, 0));
|
120
|
+
else
|
121
|
+
rb_iv_set(self, "@expiration", Qnil);
|
122
|
+
|
123
|
+
if(ptr->config.flags)
|
124
|
+
rb_iv_set(self, "@flags", INT2FIX(ptr->config.flags));
|
125
|
+
else
|
126
|
+
rb_iv_set(self, "@flags", Qnil);
|
127
|
+
|
128
|
+
if(ptr->config.kvno)
|
129
|
+
rb_iv_set(self, "@kvno", INT2FIX(ptr->config.kvno));
|
130
|
+
else
|
131
|
+
rb_iv_set(self, "@kvno", Qnil);
|
132
|
+
|
133
|
+
if(ptr->config.iprop_enabled)
|
134
|
+
rb_iv_set(self, "@iprop_enabled", Qtrue);
|
135
|
+
else
|
136
|
+
rb_iv_set(self, "@iprop_enabled", Qfalse);
|
137
|
+
|
138
|
+
if(ptr->config.iprop_logfile)
|
139
|
+
rb_iv_set(self, "@iprop_logfile", rb_str_new2(ptr->config.iprop_logfile));
|
140
|
+
else
|
141
|
+
rb_iv_set(self, "@iprop_logfile", Qnil);
|
142
|
+
|
143
|
+
if(ptr->config.iprop_poll_time)
|
144
|
+
rb_iv_set(self, "@iprop_poll_time", INT2FIX(ptr->config.iprop_poll_time));
|
145
|
+
else
|
146
|
+
rb_iv_set(self, "@iprop_poll_time", Qnil);
|
147
|
+
|
148
|
+
if(ptr->config.iprop_port)
|
149
|
+
rb_iv_set(self, "@iprop_port", INT2FIX(ptr->config.iprop_port));
|
150
|
+
else
|
151
|
+
rb_iv_set(self, "@iprop_port", Qnil);
|
152
|
+
|
153
|
+
if(ptr->config.num_keysalts)
|
154
|
+
rb_iv_set(self, "@num_keysalts", INT2FIX(ptr->config.num_keysalts));
|
155
|
+
else
|
156
|
+
rb_iv_set(self, "@num_keysalts", Qnil);
|
157
|
+
|
158
|
+
// Not very useful at the moment. How do you iterate over an enum in C?
|
159
|
+
if(ptr->config.keysalts)
|
160
|
+
rb_iv_set(self, "@keysalts", INT2FIX(ptr->config.keysalts));
|
161
|
+
else
|
162
|
+
rb_iv_set(self, "@keysalts", Qnil);
|
163
|
+
|
164
|
+
// This is read only data
|
165
|
+
rb_obj_freeze(self);
|
166
|
+
|
167
|
+
return self;
|
168
|
+
}
|
169
|
+
|
170
|
+
static VALUE rkadm5_config_inspect(VALUE self){
|
171
|
+
RUBY_KADM5_CONFIG* ptr;
|
172
|
+
VALUE v_str;
|
173
|
+
|
174
|
+
Data_Get_Struct(self, RUBY_KADM5_CONFIG, ptr);
|
175
|
+
|
176
|
+
v_str = rb_str_new2("#<");
|
177
|
+
rb_str_buf_cat2(v_str, rb_obj_classname(self));
|
178
|
+
rb_str_buf_cat2(v_str, " ");
|
179
|
+
|
180
|
+
rb_str_buf_cat2(v_str, "acl_file=");
|
181
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@acl_file")));
|
182
|
+
rb_str_buf_cat2(v_str, " ");
|
183
|
+
|
184
|
+
rb_str_buf_cat2(v_str, "admin_keytab=");
|
185
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@admin_keytab")));
|
186
|
+
rb_str_buf_cat2(v_str, " ");
|
187
|
+
|
188
|
+
rb_str_buf_cat2(v_str, "admin_server=");
|
189
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@admin_server")));
|
190
|
+
rb_str_buf_cat2(v_str, " ");
|
191
|
+
|
192
|
+
rb_str_buf_cat2(v_str, "dict_file=");
|
193
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@dict_file")));
|
194
|
+
rb_str_buf_cat2(v_str, " ");
|
195
|
+
|
196
|
+
rb_str_buf_cat2(v_str, "enctype=");
|
197
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@enctype")));
|
198
|
+
rb_str_buf_cat2(v_str, " ");
|
199
|
+
|
200
|
+
rb_str_buf_cat2(v_str, "expiration=");
|
201
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@expiration")));
|
202
|
+
rb_str_buf_cat2(v_str, " ");
|
203
|
+
|
204
|
+
rb_str_buf_cat2(v_str, "flags=");
|
205
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@flags")));
|
206
|
+
rb_str_buf_cat2(v_str, " ");
|
207
|
+
|
208
|
+
rb_str_buf_cat2(v_str, "iprop_enabled=");
|
209
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@iprop_enabled")));
|
210
|
+
rb_str_buf_cat2(v_str, " ");
|
211
|
+
|
212
|
+
rb_str_buf_cat2(v_str, "iprop_logfile=");
|
213
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@iprop_logfile")));
|
214
|
+
rb_str_buf_cat2(v_str, " ");
|
215
|
+
|
216
|
+
rb_str_buf_cat2(v_str, "iprop_poll_time=");
|
217
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@iprop_poll_time")));
|
218
|
+
rb_str_buf_cat2(v_str, " ");
|
219
|
+
|
220
|
+
rb_str_buf_cat2(v_str, "iprop_port=");
|
221
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@iprop_port")));
|
222
|
+
rb_str_buf_cat2(v_str, " ");
|
223
|
+
|
224
|
+
rb_str_buf_cat2(v_str, "kadmind_port=");
|
225
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@kadmind_port")));
|
226
|
+
rb_str_buf_cat2(v_str, " ");
|
227
|
+
|
228
|
+
rb_str_buf_cat2(v_str, "keysalts=");
|
229
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@keysalts")));
|
230
|
+
rb_str_buf_cat2(v_str, " ");
|
231
|
+
|
232
|
+
rb_str_buf_cat2(v_str, "kpasswd_port=");
|
233
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@kpasswd_port")));
|
234
|
+
rb_str_buf_cat2(v_str, " ");
|
235
|
+
|
236
|
+
rb_str_buf_cat2(v_str, "kvno=");
|
237
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@kvno")));
|
238
|
+
rb_str_buf_cat2(v_str, " ");
|
239
|
+
|
240
|
+
rb_str_buf_cat2(v_str, "mkey_name=");
|
241
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@mkey_name")));
|
242
|
+
rb_str_buf_cat2(v_str, " ");
|
243
|
+
|
244
|
+
rb_str_buf_cat2(v_str, "mkey_from_kbd=");
|
245
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@mkey_from_kbd")));
|
246
|
+
rb_str_buf_cat2(v_str, " ");
|
247
|
+
|
248
|
+
rb_str_buf_cat2(v_str, "maxlife=");
|
249
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@maxlife")));
|
250
|
+
rb_str_buf_cat2(v_str, " ");
|
251
|
+
|
252
|
+
rb_str_buf_cat2(v_str, "maxrlife=");
|
253
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@maxrlife")));
|
254
|
+
rb_str_buf_cat2(v_str, " ");
|
255
|
+
|
256
|
+
rb_str_buf_cat2(v_str, "num_keysalts=");
|
257
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@num_keysalts")));
|
258
|
+
rb_str_buf_cat2(v_str, " ");
|
259
|
+
|
260
|
+
rb_str_buf_cat2(v_str, "realm=");
|
261
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@realm")));
|
262
|
+
rb_str_buf_cat2(v_str, " ");
|
263
|
+
|
264
|
+
rb_str_buf_cat2(v_str, "stash_file=");
|
265
|
+
rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@stash_file")));
|
266
|
+
rb_str_buf_cat2(v_str, " ");
|
267
|
+
|
268
|
+
rb_str_buf_cat2(v_str, ">");
|
269
|
+
|
270
|
+
return v_str;
|
271
|
+
}
|
272
|
+
|
273
|
+
void Init_config(){
|
274
|
+
cKadm5Config = rb_define_class_under(cKadm5, "Config", rb_cObject);
|
275
|
+
|
276
|
+
// Allocation function
|
277
|
+
|
278
|
+
rb_define_alloc_func(cKadm5Config, rkadm5_config_allocate);
|
279
|
+
|
280
|
+
// Initializer
|
281
|
+
|
282
|
+
rb_define_method(cKadm5Config, "initialize", rkadm5_config_initialize, 0);
|
283
|
+
|
284
|
+
// Methods
|
285
|
+
|
286
|
+
rb_define_method(cKadm5Config, "inspect", rkadm5_config_inspect, 0);
|
287
|
+
|
288
|
+
// Accessors
|
289
|
+
|
290
|
+
rb_define_attr(cKadm5Config, "acl_file", 1, 0);
|
291
|
+
rb_define_attr(cKadm5Config, "admin_keytab", 1, 0);
|
292
|
+
rb_define_attr(cKadm5Config, "admin_server", 1, 0);
|
293
|
+
rb_define_attr(cKadm5Config, "dict_file", 1, 0);
|
294
|
+
rb_define_attr(cKadm5Config, "enctype", 1, 0);
|
295
|
+
rb_define_attr(cKadm5Config, "expiration", 1, 0);
|
296
|
+
rb_define_attr(cKadm5Config, "flags", 1, 0);
|
297
|
+
rb_define_attr(cKadm5Config, "iprop_enabled", 1, 0);
|
298
|
+
rb_define_attr(cKadm5Config, "iprop_logfile", 1, 0);
|
299
|
+
rb_define_attr(cKadm5Config, "iprop_poll_time", 1, 0);
|
300
|
+
rb_define_attr(cKadm5Config, "iprop_port", 1, 0);
|
301
|
+
rb_define_attr(cKadm5Config, "kadmind_port", 1, 0);
|
302
|
+
rb_define_attr(cKadm5Config, "keysalts", 1, 0);
|
303
|
+
rb_define_attr(cKadm5Config, "kpasswd_port", 1, 0);
|
304
|
+
rb_define_attr(cKadm5Config, "kvno", 1, 0);
|
305
|
+
rb_define_attr(cKadm5Config, "mkey_name", 1, 0);
|
306
|
+
rb_define_attr(cKadm5Config, "mkey_from_kbd", 1, 0);
|
307
|
+
rb_define_attr(cKadm5Config, "max_life", 1, 0);
|
308
|
+
rb_define_attr(cKadm5Config, "max_rlife", 1, 0);
|
309
|
+
rb_define_attr(cKadm5Config, "num_keysalts", 1, 0);
|
310
|
+
rb_define_attr(cKadm5Config, "realm", 1, 0);
|
311
|
+
rb_define_attr(cKadm5Config, "stash_file", 1, 0);
|
312
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#include <rkerberos.h>
|
2
|
+
|
3
|
+
VALUE cKrb5Context;
|
4
|
+
|
5
|
+
// Free function for the Kerberos::Krb5::Context class.
|
6
|
+
static void rkrb5_context_free(RUBY_KRB5_CONTEXT* ptr){
|
7
|
+
if(!ptr)
|
8
|
+
return;
|
9
|
+
|
10
|
+
if(ptr->ctx)
|
11
|
+
krb5_free_context(ptr->ctx);
|
12
|
+
|
13
|
+
free(ptr);
|
14
|
+
}
|
15
|
+
|
16
|
+
// Allocation function for the Kerberos::Krb5::Context class.
|
17
|
+
static VALUE rkrb5_context_allocate(VALUE klass){
|
18
|
+
RUBY_KRB5_CONTEXT* ptr = malloc(sizeof(RUBY_KRB5_CONTEXT));
|
19
|
+
memset(ptr, 0, sizeof(RUBY_KRB5_CONTEXT));
|
20
|
+
return Data_Wrap_Struct(klass, 0, rkrb5_context_free, ptr);
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* call-seq:
|
25
|
+
* context.close
|
26
|
+
*
|
27
|
+
* Closes the context object.
|
28
|
+
*/
|
29
|
+
static VALUE rkrb5_context_close(VALUE self){
|
30
|
+
RUBY_KRB5_CONTEXT* ptr;
|
31
|
+
|
32
|
+
Data_Get_Struct(self, RUBY_KRB5_CONTEXT, ptr);
|
33
|
+
|
34
|
+
if(ptr->ctx)
|
35
|
+
krb5_free_context(ptr->ctx);
|
36
|
+
|
37
|
+
ptr->ctx = NULL;
|
38
|
+
|
39
|
+
return self;
|
40
|
+
}
|
41
|
+
|
42
|
+
/*
|
43
|
+
* call-seq:
|
44
|
+
* Kerberos::Context.new
|
45
|
+
*
|
46
|
+
* Creates and returns a new Kerberos::Context object.
|
47
|
+
*
|
48
|
+
* This class is not typically instantiated directly, but is used internally
|
49
|
+
* by the krb5-auth library.
|
50
|
+
*/
|
51
|
+
static VALUE rkrb5_context_initialize(VALUE self){
|
52
|
+
RUBY_KRB5_CONTEXT* ptr;
|
53
|
+
krb5_error_code kerror;
|
54
|
+
|
55
|
+
Data_Get_Struct(self, RUBY_KRB5_CONTEXT, ptr);
|
56
|
+
|
57
|
+
kerror = krb5_init_context(&ptr->ctx);
|
58
|
+
|
59
|
+
if(kerror)
|
60
|
+
rb_raise(cKrb5Exception, "krb5_init_context: %s", error_message(kerror));
|
61
|
+
|
62
|
+
return self;
|
63
|
+
}
|
64
|
+
|
65
|
+
void Init_context(){
|
66
|
+
/* The Kerberos::Krb5::Context class encapsulates a Kerberos context. */
|
67
|
+
cKrb5Context = rb_define_class_under(cKrb5, "Context", rb_cObject);
|
68
|
+
|
69
|
+
// Allocation Function
|
70
|
+
rb_define_alloc_func(cKrb5Context, rkrb5_context_allocate);
|
71
|
+
|
72
|
+
// Constructor
|
73
|
+
rb_define_method(cKrb5Context, "initialize", rkrb5_context_initialize, 0);
|
74
|
+
|
75
|
+
// Instance Methods
|
76
|
+
rb_define_method(cKrb5Context, "close", rkrb5_context_close, 0);
|
77
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
dir_config('rkerberos', '/usr/local')
|
4
|
+
|
5
|
+
have_header('krb5.h')
|
6
|
+
have_library('krb5')
|
7
|
+
|
8
|
+
if have_header('kadm5/admin.h')
|
9
|
+
have_library('kadm5clnt')
|
10
|
+
else
|
11
|
+
raise "kadm5clnt library not found"
|
12
|
+
end
|
13
|
+
|
14
|
+
create_makefile('rkerberos')
|
@@ -0,0 +1,991 @@
|
|
1
|
+
#include <rkerberos.h>
|
2
|
+
|
3
|
+
VALUE cKadm5;
|
4
|
+
VALUE cKadm5Exception;
|
5
|
+
VALUE cKadm5PrincipalNotFoundException;
|
6
|
+
|
7
|
+
// Prototype
|
8
|
+
static VALUE rkadm5_close(VALUE);
|
9
|
+
|
10
|
+
// Free function for the Kerberos::Kadm5 class.
|
11
|
+
static void rkadm5_free(RUBY_KADM5* ptr){
|
12
|
+
if(!ptr)
|
13
|
+
return;
|
14
|
+
|
15
|
+
if(ptr->princ)
|
16
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
17
|
+
|
18
|
+
if(ptr->ctx)
|
19
|
+
krb5_free_context(ptr->ctx);
|
20
|
+
|
21
|
+
free(ptr);
|
22
|
+
}
|
23
|
+
|
24
|
+
// Allocation function for the Kerberos::Kadm5 class.
|
25
|
+
static VALUE rkadm5_allocate(VALUE klass){
|
26
|
+
RUBY_KADM5* ptr = malloc(sizeof(RUBY_KADM5));
|
27
|
+
memset(ptr, 0, sizeof(RUBY_KADM5));
|
28
|
+
return Data_Wrap_Struct(klass, 0, rkadm5_free, ptr);
|
29
|
+
}
|
30
|
+
|
31
|
+
/*
|
32
|
+
* call-seq:
|
33
|
+
* Kerberos::Kadm5.new(:principal => 'name', :password => 'xxxxx')
|
34
|
+
* Kerberos::Kadm5.new(:principal => 'name', :keytab => '/path/to/your/keytab')
|
35
|
+
* Kerberos::Kadm5.new(:principal => 'name', :keytab => true)
|
36
|
+
*
|
37
|
+
* Creates and returns a new Kerberos::Kadm5 object. A hash argument is
|
38
|
+
* accepted that allows you to specify a principal and a password, or
|
39
|
+
* a keytab file.
|
40
|
+
*
|
41
|
+
* If you pass a string as the :keytab value it will attempt to use that file
|
42
|
+
* for the keytab. If you pass true as the value it will attempt to use the
|
43
|
+
* default keytab file, typically /etc/krb5.keytab.
|
44
|
+
*
|
45
|
+
* You may also pass the :service option to specify the service name. The
|
46
|
+
* default is kadmin/admin.
|
47
|
+
*/
|
48
|
+
static VALUE rkadm5_initialize(VALUE self, VALUE v_opts){
|
49
|
+
RUBY_KADM5* ptr;
|
50
|
+
VALUE v_principal, v_password, v_keytab, v_service;
|
51
|
+
char* user;
|
52
|
+
char* pass = NULL;
|
53
|
+
char* keytab = NULL;
|
54
|
+
char* service = NULL;
|
55
|
+
krb5_error_code kerror;
|
56
|
+
|
57
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
58
|
+
Check_Type(v_opts, T_HASH);
|
59
|
+
|
60
|
+
v_principal = rb_hash_aref2(v_opts, "principal");
|
61
|
+
|
62
|
+
// Principal must be specified
|
63
|
+
if(NIL_P(v_principal))
|
64
|
+
rb_raise(rb_eArgError, "principal must be specified");
|
65
|
+
|
66
|
+
Check_Type(v_principal, T_STRING);
|
67
|
+
user = StringValuePtr(v_principal);
|
68
|
+
|
69
|
+
v_password = rb_hash_aref2(v_opts, "password");
|
70
|
+
v_keytab = rb_hash_aref2(v_opts, "keytab");
|
71
|
+
|
72
|
+
if(RTEST(v_password) && RTEST(v_keytab))
|
73
|
+
rb_raise(rb_eArgError, "cannot use both a password and a keytab");
|
74
|
+
|
75
|
+
if(RTEST(v_password)){
|
76
|
+
Check_Type(v_password, T_STRING);
|
77
|
+
pass = StringValuePtr(v_password);
|
78
|
+
}
|
79
|
+
|
80
|
+
v_service = rb_hash_aref2(v_opts, "service");
|
81
|
+
|
82
|
+
if(NIL_P(v_service)){
|
83
|
+
service = "kadmin/admin";
|
84
|
+
}
|
85
|
+
else{
|
86
|
+
Check_Type(v_service, T_STRING);
|
87
|
+
service = StringValuePtr(v_service);
|
88
|
+
}
|
89
|
+
|
90
|
+
// Normally I would wait to initialize the context, but we might need it
|
91
|
+
// to get the default keytab file name.
|
92
|
+
kerror = krb5_init_context(&ptr->ctx);
|
93
|
+
|
94
|
+
if(kerror)
|
95
|
+
rb_raise(cKadm5Exception, "krb5_init_context: %s", error_message(kerror));
|
96
|
+
|
97
|
+
// The docs say I can use NULL to get the default, but reality appears to be otherwise.
|
98
|
+
if(RTEST(v_keytab)){
|
99
|
+
if(TYPE(v_keytab) == T_TRUE){
|
100
|
+
char default_name[MAX_KEYTAB_NAME_LEN];
|
101
|
+
|
102
|
+
kerror = krb5_kt_default_name(ptr->ctx, default_name, MAX_KEYTAB_NAME_LEN);
|
103
|
+
|
104
|
+
if(kerror)
|
105
|
+
rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
|
106
|
+
|
107
|
+
keytab = default_name;
|
108
|
+
}
|
109
|
+
else{
|
110
|
+
Check_Type(v_keytab, T_STRING);
|
111
|
+
keytab = StringValuePtr(v_keytab);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
if(RTEST(v_password)){
|
116
|
+
#ifdef KADM5_API_VERSION_3
|
117
|
+
kerror = kadm5_init_with_password(
|
118
|
+
ptr->ctx,
|
119
|
+
user,
|
120
|
+
pass,
|
121
|
+
service,
|
122
|
+
NULL,
|
123
|
+
KADM5_STRUCT_VERSION,
|
124
|
+
KADM5_API_VERSION_3,
|
125
|
+
NULL,
|
126
|
+
&ptr->handle
|
127
|
+
);
|
128
|
+
#else
|
129
|
+
kerror = kadm5_init_with_password(
|
130
|
+
user,
|
131
|
+
pass,
|
132
|
+
service,
|
133
|
+
NULL,
|
134
|
+
KADM5_STRUCT_VERSION,
|
135
|
+
KADM5_API_VERSION_2,
|
136
|
+
NULL,
|
137
|
+
&ptr->handle
|
138
|
+
);
|
139
|
+
#endif
|
140
|
+
|
141
|
+
if(kerror)
|
142
|
+
rb_raise(cKadm5Exception, "kadm5_init_with_password: %s", error_message(kerror));
|
143
|
+
}
|
144
|
+
else if(RTEST(v_keytab)){
|
145
|
+
#ifdef KADM5_API_VERSION_3
|
146
|
+
kerror = kadm5_init_with_skey(
|
147
|
+
ptr->ctx,
|
148
|
+
user,
|
149
|
+
keytab,
|
150
|
+
service,
|
151
|
+
NULL,
|
152
|
+
KADM5_STRUCT_VERSION,
|
153
|
+
KADM5_API_VERSION_3,
|
154
|
+
NULL,
|
155
|
+
&ptr->handle
|
156
|
+
);
|
157
|
+
#else
|
158
|
+
kerror = kadm5_init_with_skey(
|
159
|
+
user,
|
160
|
+
keytab,
|
161
|
+
service,
|
162
|
+
NULL,
|
163
|
+
KADM5_STRUCT_VERSION,
|
164
|
+
KADM5_API_VERSION_2,
|
165
|
+
NULL,
|
166
|
+
&ptr->handle
|
167
|
+
);
|
168
|
+
#endif
|
169
|
+
|
170
|
+
if(kerror)
|
171
|
+
rb_raise(cKadm5Exception, "kadm5_init_with_skey: %s", error_message(kerror));
|
172
|
+
}
|
173
|
+
else{
|
174
|
+
// TODO: Credentials cache.
|
175
|
+
}
|
176
|
+
|
177
|
+
if(rb_block_given_p()){
|
178
|
+
rb_ensure(rb_yield, self, rkadm5_close, self);
|
179
|
+
return Qnil;
|
180
|
+
}
|
181
|
+
|
182
|
+
return self;
|
183
|
+
}
|
184
|
+
|
185
|
+
/* call-seq:
|
186
|
+
* kadm5.set_password(user, password)
|
187
|
+
*
|
188
|
+
* Set the password for +user+ (i.e. the principal) to +password+.
|
189
|
+
*/
|
190
|
+
static VALUE rkadm5_set_password(VALUE self, VALUE v_user, VALUE v_pass){
|
191
|
+
Check_Type(v_user, T_STRING);
|
192
|
+
Check_Type(v_pass, T_STRING);
|
193
|
+
|
194
|
+
RUBY_KADM5* ptr;
|
195
|
+
char* user = StringValuePtr(v_user);
|
196
|
+
char* pass = StringValuePtr(v_pass);
|
197
|
+
krb5_error_code kerror;
|
198
|
+
|
199
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
200
|
+
|
201
|
+
if(!ptr->ctx)
|
202
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
203
|
+
|
204
|
+
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
205
|
+
|
206
|
+
if(kerror)
|
207
|
+
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
208
|
+
|
209
|
+
kerror = kadm5_chpass_principal(ptr->handle, ptr->princ, pass);
|
210
|
+
|
211
|
+
if(kerror)
|
212
|
+
rb_raise(cKadm5Exception, "kadm5_chpass_principal: %s", error_message(kerror));
|
213
|
+
|
214
|
+
return self;
|
215
|
+
}
|
216
|
+
|
217
|
+
/*
|
218
|
+
* call-seq:
|
219
|
+
* kadm5.create_principal(name, password)
|
220
|
+
* kadm5.create_principal(principal)
|
221
|
+
*
|
222
|
+
* Creates a new principal +name+ with an initial password of +password+.
|
223
|
+
*--
|
224
|
+
* TODO: Allow a Principal object to be passed in as an argument.
|
225
|
+
*/
|
226
|
+
static VALUE rkadm5_create_principal(VALUE self, VALUE v_user, VALUE v_pass){
|
227
|
+
RUBY_KADM5* ptr;
|
228
|
+
char* user;
|
229
|
+
char* pass;
|
230
|
+
int mask;
|
231
|
+
kadm5_principal_ent_rec princ;
|
232
|
+
krb5_error_code kerror;
|
233
|
+
|
234
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
235
|
+
|
236
|
+
Check_Type(v_user, T_STRING);
|
237
|
+
Check_Type(v_pass, T_STRING);
|
238
|
+
|
239
|
+
memset(&princ, 0, sizeof(princ));
|
240
|
+
|
241
|
+
mask = KADM5_PRINCIPAL;
|
242
|
+
user = StringValuePtr(v_user);
|
243
|
+
pass = StringValuePtr(v_pass);
|
244
|
+
|
245
|
+
if(!ptr->ctx)
|
246
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
247
|
+
|
248
|
+
kerror = krb5_parse_name(ptr->ctx, user, &princ.principal);
|
249
|
+
|
250
|
+
if(kerror)
|
251
|
+
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
252
|
+
|
253
|
+
kerror = kadm5_create_principal(ptr->handle, &princ, mask, pass);
|
254
|
+
|
255
|
+
if(kerror)
|
256
|
+
rb_raise(cKadm5Exception, "kadm5_create_principal: %s", error_message(kerror));
|
257
|
+
|
258
|
+
krb5_free_principal(ptr->ctx, princ.principal);
|
259
|
+
|
260
|
+
return self;
|
261
|
+
}
|
262
|
+
|
263
|
+
/* call-seq:
|
264
|
+
* kadm5.delete_principal(name)
|
265
|
+
*
|
266
|
+
* Deletes the principal +name+ from the Kerberos database.
|
267
|
+
*/
|
268
|
+
static VALUE rkadm5_delete_principal(VALUE self, VALUE v_user){
|
269
|
+
RUBY_KADM5* ptr;
|
270
|
+
char* user;
|
271
|
+
krb5_error_code kerror;
|
272
|
+
|
273
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
274
|
+
Check_Type(v_user, T_STRING);
|
275
|
+
user = StringValuePtr(v_user);
|
276
|
+
|
277
|
+
if(!ptr->ctx)
|
278
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
279
|
+
|
280
|
+
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
281
|
+
|
282
|
+
if(kerror)
|
283
|
+
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
284
|
+
|
285
|
+
kerror = kadm5_delete_principal(ptr->handle, ptr->princ);
|
286
|
+
|
287
|
+
if(kerror)
|
288
|
+
rb_raise(cKadm5Exception, "kadm5_delete_principal: %s", error_message(kerror));
|
289
|
+
|
290
|
+
return self;
|
291
|
+
}
|
292
|
+
|
293
|
+
/*
|
294
|
+
* call-seq:
|
295
|
+
* kadm5.close
|
296
|
+
*
|
297
|
+
* Closes the kadm5 object. Specifically, it frees the principal and context
|
298
|
+
* associated with the kadm5 object, as well as the server handle.
|
299
|
+
*
|
300
|
+
* Any attempt to call a method on a kadm5 object after it has been closed
|
301
|
+
* will fail with an error message indicating a lack of context.
|
302
|
+
*/
|
303
|
+
static VALUE rkadm5_close(VALUE self){
|
304
|
+
RUBY_KADM5* ptr;
|
305
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
306
|
+
|
307
|
+
if(ptr->princ)
|
308
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
309
|
+
|
310
|
+
if(ptr->ctx)
|
311
|
+
krb5_free_context(ptr->ctx);
|
312
|
+
|
313
|
+
if(ptr->handle)
|
314
|
+
kadm5_destroy(ptr->handle);
|
315
|
+
|
316
|
+
ptr->ctx = NULL;
|
317
|
+
ptr->princ = NULL;
|
318
|
+
ptr->handle = NULL;
|
319
|
+
|
320
|
+
return self;
|
321
|
+
}
|
322
|
+
|
323
|
+
// Private function for creating a Principal object from a entry record.
|
324
|
+
static VALUE create_principal_from_entry(VALUE v_name, RUBY_KADM5* ptr, kadm5_principal_ent_rec* ent){
|
325
|
+
krb5_error_code kerror;
|
326
|
+
VALUE v_principal;
|
327
|
+
VALUE v_args[1];
|
328
|
+
|
329
|
+
v_args[0] = v_name;
|
330
|
+
|
331
|
+
v_principal = rb_class_new_instance(1, v_args, cKrb5Principal);
|
332
|
+
|
333
|
+
rb_iv_set(v_principal, "@attributes", LONG2FIX(ent->attributes));
|
334
|
+
rb_iv_set(v_principal, "@aux_attributes", INT2FIX(ent->aux_attributes));
|
335
|
+
|
336
|
+
if(ent->princ_expire_time)
|
337
|
+
rb_iv_set(v_principal, "@expire_time", rb_time_new(ent->princ_expire_time, 0));
|
338
|
+
|
339
|
+
rb_iv_set(v_principal, "@fail_auth_count", INT2FIX(ent->fail_auth_count));
|
340
|
+
rb_iv_set(v_principal, "@kvno", INT2FIX(ent->kvno));
|
341
|
+
|
342
|
+
if(ent->last_failed)
|
343
|
+
rb_iv_set(v_principal, "@last_failed", rb_time_new(ent->last_failed, 0));
|
344
|
+
|
345
|
+
if(ent->last_failed)
|
346
|
+
rb_iv_set(v_principal, "@last_password_change", rb_time_new(ent->last_pwd_change, 0));
|
347
|
+
|
348
|
+
if(ent->last_failed)
|
349
|
+
rb_iv_set(v_principal, "@last_success", rb_time_new(ent->last_success, 0));
|
350
|
+
|
351
|
+
rb_iv_set(v_principal, "@max_life", LONG2FIX(ent->max_life));
|
352
|
+
rb_iv_set(v_principal, "@max_renewable_life", LONG2FIX(ent->max_renewable_life));
|
353
|
+
|
354
|
+
if(ent->mod_date)
|
355
|
+
rb_iv_set(v_principal, "@mod_date", rb_time_new(ent->mod_date, 0));
|
356
|
+
|
357
|
+
if(ent->mod_name){
|
358
|
+
char* mod_name;
|
359
|
+
kerror = krb5_unparse_name(ptr->ctx, ent->mod_name, &mod_name);
|
360
|
+
|
361
|
+
if(kerror)
|
362
|
+
rb_raise(cKadm5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
363
|
+
|
364
|
+
rb_iv_set(v_principal, "@mod_name", rb_str_new2(mod_name));
|
365
|
+
}
|
366
|
+
|
367
|
+
if(ent->pw_expiration)
|
368
|
+
rb_iv_set(v_principal, "@password_expiration", rb_time_new(ent->pw_expiration, 0));
|
369
|
+
|
370
|
+
if(ent->policy)
|
371
|
+
rb_iv_set(v_principal, "policy", rb_str_new2(ent->policy));
|
372
|
+
|
373
|
+
return v_principal;
|
374
|
+
}
|
375
|
+
|
376
|
+
/*
|
377
|
+
* call-seq:
|
378
|
+
* kadm5.find_principal(principal_name)
|
379
|
+
*
|
380
|
+
* Returns a Principal object for +principal_name+ containing various bits
|
381
|
+
* of information regarding that principal, such as policy, attributes,
|
382
|
+
* expiration information, etc.
|
383
|
+
*
|
384
|
+
* Unlike the get_principal method, this method returns nil if the principal
|
385
|
+
* cannot be found instead of raising an error.
|
386
|
+
*/
|
387
|
+
static VALUE rkadm5_find_principal(VALUE self, VALUE v_user){
|
388
|
+
RUBY_KADM5* ptr;
|
389
|
+
VALUE v_principal;
|
390
|
+
char* user;
|
391
|
+
int mask;
|
392
|
+
kadm5_principal_ent_rec ent;
|
393
|
+
krb5_error_code kerror;
|
394
|
+
|
395
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
396
|
+
Check_Type(v_user, T_STRING);
|
397
|
+
user = StringValuePtr(v_user);
|
398
|
+
|
399
|
+
memset(&ent, 0, sizeof(ent));
|
400
|
+
|
401
|
+
if(!ptr->ctx)
|
402
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
403
|
+
|
404
|
+
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
405
|
+
|
406
|
+
if(kerror)
|
407
|
+
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
408
|
+
|
409
|
+
mask = KADM5_PRINCIPAL_NORMAL_MASK;
|
410
|
+
|
411
|
+
kerror = kadm5_get_principal(
|
412
|
+
ptr->handle,
|
413
|
+
ptr->princ,
|
414
|
+
&ent,
|
415
|
+
mask
|
416
|
+
);
|
417
|
+
|
418
|
+
// Return nil if not found instead of raising an error.
|
419
|
+
if(kerror){
|
420
|
+
if(kerror == KADM5_UNK_PRINC)
|
421
|
+
v_principal = Qnil;
|
422
|
+
else
|
423
|
+
rb_raise(cKadm5Exception, "kadm5_get_principal: %s", error_message(kerror));
|
424
|
+
}
|
425
|
+
else{
|
426
|
+
v_principal = create_principal_from_entry(v_user, ptr, &ent);
|
427
|
+
}
|
428
|
+
|
429
|
+
return v_principal;
|
430
|
+
}
|
431
|
+
|
432
|
+
/*
|
433
|
+
* call-seq:
|
434
|
+
* kadm5.get_principal(principal_name)
|
435
|
+
*
|
436
|
+
* Returns a Principal object for +principal_name+ containing various bits
|
437
|
+
* of information regarding that principal, such as policy, attributes,
|
438
|
+
* expiration information, etc.
|
439
|
+
*
|
440
|
+
* If the +principal_name+ cannot be found then a PrincipalNotFoundException
|
441
|
+
* is raised.
|
442
|
+
*/
|
443
|
+
static VALUE rkadm5_get_principal(VALUE self, VALUE v_user){
|
444
|
+
RUBY_KADM5* ptr;
|
445
|
+
VALUE v_principal;
|
446
|
+
char* user;
|
447
|
+
int mask;
|
448
|
+
kadm5_principal_ent_rec ent;
|
449
|
+
krb5_error_code kerror;
|
450
|
+
|
451
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
452
|
+
Check_Type(v_user, T_STRING);
|
453
|
+
user = StringValuePtr(v_user);
|
454
|
+
|
455
|
+
memset(&ent, 0, sizeof(ent));
|
456
|
+
|
457
|
+
if(!ptr->ctx)
|
458
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
459
|
+
|
460
|
+
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
461
|
+
|
462
|
+
if(kerror)
|
463
|
+
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
464
|
+
|
465
|
+
mask = KADM5_PRINCIPAL_NORMAL_MASK;
|
466
|
+
|
467
|
+
kerror = kadm5_get_principal(
|
468
|
+
ptr->handle,
|
469
|
+
ptr->princ,
|
470
|
+
&ent,
|
471
|
+
mask
|
472
|
+
);
|
473
|
+
|
474
|
+
if(kerror){
|
475
|
+
if(kerror == KADM5_UNK_PRINC)
|
476
|
+
rb_raise(cKadm5PrincipalNotFoundException, "principal not found");
|
477
|
+
else
|
478
|
+
rb_raise(cKadm5Exception, "kadm5_get_principal: %s", error_message(kerror));
|
479
|
+
}
|
480
|
+
|
481
|
+
v_principal = create_principal_from_entry(v_user, ptr, &ent);
|
482
|
+
|
483
|
+
return v_principal;
|
484
|
+
}
|
485
|
+
|
486
|
+
/*
|
487
|
+
* call-seq:
|
488
|
+
* kadm5.create_policy(policy)
|
489
|
+
*
|
490
|
+
* Creates a new Kerberos policy based on the Policy object.
|
491
|
+
*
|
492
|
+
* Example:
|
493
|
+
*
|
494
|
+
* # Using a Policy object
|
495
|
+
* policy = Kerberos::Kadm5::Policy.new(:name => 'test', :min_length => 5)
|
496
|
+
* kadm5.create_policy(policy)
|
497
|
+
*
|
498
|
+
* # Using a hash
|
499
|
+
* kadm5.create_policy(:name => 'test', :min_length => 5)
|
500
|
+
*/
|
501
|
+
static VALUE rkadm5_create_policy(VALUE self, VALUE v_policy){
|
502
|
+
RUBY_KADM5* ptr;
|
503
|
+
kadm5_ret_t kerror;
|
504
|
+
kadm5_policy_ent_rec ent;
|
505
|
+
long mask = KADM5_POLICY;
|
506
|
+
VALUE v_name, v_min_classes, v_min_life, v_max_life, v_min_length, v_history_num;
|
507
|
+
|
508
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
509
|
+
|
510
|
+
// Allow a hash or a Policy object
|
511
|
+
if(rb_obj_is_kind_of(v_policy, rb_cHash)){
|
512
|
+
VALUE v_args[1];
|
513
|
+
v_args[0] = v_policy;
|
514
|
+
v_policy = rb_class_new_instance(1, v_args, cKadm5Policy);
|
515
|
+
}
|
516
|
+
|
517
|
+
v_name = rb_iv_get(v_policy, "@policy");
|
518
|
+
v_min_classes = rb_iv_get(v_policy, "@min_classes");
|
519
|
+
v_min_length = rb_iv_get(v_policy, "@min_length");
|
520
|
+
v_min_life = rb_iv_get(v_policy, "@min_life");
|
521
|
+
v_max_life = rb_iv_get(v_policy, "@max_life");
|
522
|
+
v_history_num = rb_iv_get(v_policy, "@history_num");
|
523
|
+
|
524
|
+
ent.policy = StringValuePtr(v_name);
|
525
|
+
|
526
|
+
if(RTEST(v_min_classes)){
|
527
|
+
mask |= KADM5_PW_MIN_CLASSES;
|
528
|
+
ent.pw_min_classes = NUM2LONG(v_min_classes);
|
529
|
+
}
|
530
|
+
|
531
|
+
if(RTEST(v_min_length)){
|
532
|
+
mask |= KADM5_PW_MIN_LENGTH;
|
533
|
+
ent.pw_min_length = NUM2LONG(v_min_length);
|
534
|
+
}
|
535
|
+
|
536
|
+
if(RTEST(v_min_life)){
|
537
|
+
mask |= KADM5_PW_MIN_LIFE;
|
538
|
+
ent.pw_min_life = NUM2LONG(v_min_life);
|
539
|
+
}
|
540
|
+
|
541
|
+
if(RTEST(v_max_life)){
|
542
|
+
mask |= KADM5_PW_MAX_LIFE;
|
543
|
+
ent.pw_max_life = NUM2LONG(v_max_life);
|
544
|
+
}
|
545
|
+
|
546
|
+
if(RTEST(v_history_num)){
|
547
|
+
mask |= KADM5_PW_HISTORY_NUM;
|
548
|
+
ent.pw_max_life = NUM2LONG(v_history_num);
|
549
|
+
}
|
550
|
+
|
551
|
+
kerror = kadm5_create_policy(ptr->handle, &ent, mask);
|
552
|
+
|
553
|
+
if(kerror)
|
554
|
+
rb_raise(cKadm5Exception, "kadm5_create_policy: %s (%li)", error_message(kerror), kerror);
|
555
|
+
|
556
|
+
return self;
|
557
|
+
}
|
558
|
+
|
559
|
+
/*
|
560
|
+
* call-seq:
|
561
|
+
* kadm5.delete_policy(name)
|
562
|
+
*
|
563
|
+
* Deletes the Kerberos policy +name+.
|
564
|
+
*
|
565
|
+
* Example:
|
566
|
+
*
|
567
|
+
* kadm5.delete_policy('test')
|
568
|
+
*/
|
569
|
+
static VALUE rkadm5_delete_policy(VALUE self, VALUE v_policy){
|
570
|
+
RUBY_KADM5* ptr;
|
571
|
+
kadm5_ret_t kerror;
|
572
|
+
char* policy;
|
573
|
+
|
574
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
575
|
+
|
576
|
+
policy = StringValuePtr(v_policy);
|
577
|
+
|
578
|
+
kerror = kadm5_delete_policy(ptr->handle, policy);
|
579
|
+
|
580
|
+
if(kerror)
|
581
|
+
rb_raise(cKadm5Exception, "kadm5_delete_policy: %s (%li)", error_message(kerror), kerror);
|
582
|
+
|
583
|
+
return self;
|
584
|
+
}
|
585
|
+
|
586
|
+
/*
|
587
|
+
* call-seq:
|
588
|
+
* kadm5.get_policy(name)
|
589
|
+
*
|
590
|
+
* Get and return a Policy object for +name+. If the +name+ cannot be found,
|
591
|
+
* then an exception is raised.
|
592
|
+
*
|
593
|
+
* This method is nearly identical to kadm5.find_policy, except that method
|
594
|
+
* returns nil if not found.
|
595
|
+
*/
|
596
|
+
static VALUE rkadm5_get_policy(VALUE self, VALUE v_name){
|
597
|
+
RUBY_KADM5* ptr;
|
598
|
+
VALUE v_policy = Qnil;
|
599
|
+
kadm5_policy_ent_rec ent;
|
600
|
+
kadm5_ret_t kerror;
|
601
|
+
char* policy_name;
|
602
|
+
|
603
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
604
|
+
memset(&ent, 0, sizeof(ent));
|
605
|
+
|
606
|
+
if(!ptr->ctx)
|
607
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
608
|
+
|
609
|
+
policy_name = StringValuePtr(v_name);
|
610
|
+
|
611
|
+
kerror = kadm5_get_policy(ptr->handle, policy_name, &ent);
|
612
|
+
|
613
|
+
if(kerror){
|
614
|
+
rb_raise(
|
615
|
+
cKadm5Exception,
|
616
|
+
"kadm5_get_policy: %s (%li)", error_message(kerror), kerror
|
617
|
+
);
|
618
|
+
}
|
619
|
+
else{
|
620
|
+
VALUE v_arg[1];
|
621
|
+
VALUE v_hash = rb_hash_new();
|
622
|
+
|
623
|
+
rb_hash_aset(v_hash, rb_str_new2("name"), rb_str_new2(ent.policy));
|
624
|
+
rb_hash_aset(v_hash, rb_str_new2("min_life"), LONG2FIX(ent.pw_min_life));
|
625
|
+
rb_hash_aset(v_hash, rb_str_new2("max_life"), LONG2FIX(ent.pw_max_life));
|
626
|
+
rb_hash_aset(v_hash, rb_str_new2("min_length"), LONG2FIX(ent.pw_min_length));
|
627
|
+
rb_hash_aset(v_hash, rb_str_new2("min_classes"), LONG2FIX(ent.pw_min_classes));
|
628
|
+
rb_hash_aset(v_hash, rb_str_new2("history_num"), LONG2FIX(ent.pw_history_num));
|
629
|
+
|
630
|
+
v_arg[0] = v_hash;
|
631
|
+
|
632
|
+
v_policy = rb_class_new_instance(1, v_arg, cKadm5Policy);
|
633
|
+
}
|
634
|
+
|
635
|
+
return v_policy;
|
636
|
+
}
|
637
|
+
|
638
|
+
/*
|
639
|
+
* call-seq:
|
640
|
+
* kadm5.find_policy(name)
|
641
|
+
*
|
642
|
+
* Get and return a Policy object for +name+. If the +name+ cannot be found,
|
643
|
+
* then nil is returned.
|
644
|
+
*
|
645
|
+
* This method is nearly identical to kadm5.get_policy, except that method
|
646
|
+
* raises an exception if not found.
|
647
|
+
*/
|
648
|
+
static VALUE rkadm5_find_policy(VALUE self, VALUE v_name){
|
649
|
+
RUBY_KADM5* ptr;
|
650
|
+
VALUE v_policy = Qnil;
|
651
|
+
kadm5_policy_ent_rec ent;
|
652
|
+
kadm5_ret_t kerror;
|
653
|
+
char* policy_name;
|
654
|
+
|
655
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
656
|
+
memset(&ent, 0, sizeof(ent));
|
657
|
+
|
658
|
+
if(!ptr->ctx)
|
659
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
660
|
+
|
661
|
+
policy_name = StringValuePtr(v_name);
|
662
|
+
|
663
|
+
kerror = kadm5_get_policy(ptr->handle, policy_name, &ent);
|
664
|
+
|
665
|
+
// Return nil if not found rather than raising an error.
|
666
|
+
if(kerror){
|
667
|
+
if(kerror != KADM5_UNK_POLICY){
|
668
|
+
rb_raise(
|
669
|
+
cKadm5Exception,
|
670
|
+
"kadm5_get_policy: %s (%li)", error_message(kerror), kerror
|
671
|
+
);
|
672
|
+
}
|
673
|
+
}
|
674
|
+
else{
|
675
|
+
VALUE v_arg[1];
|
676
|
+
VALUE v_hash = rb_hash_new();
|
677
|
+
|
678
|
+
rb_hash_aset(v_hash, rb_str_new2("name"), rb_str_new2(ent.policy));
|
679
|
+
rb_hash_aset(v_hash, rb_str_new2("min_life"), LONG2FIX(ent.pw_min_life));
|
680
|
+
rb_hash_aset(v_hash, rb_str_new2("max_life"), LONG2FIX(ent.pw_max_life));
|
681
|
+
rb_hash_aset(v_hash, rb_str_new2("min_length"), LONG2FIX(ent.pw_min_length));
|
682
|
+
rb_hash_aset(v_hash, rb_str_new2("min_classes"), LONG2FIX(ent.pw_min_classes));
|
683
|
+
rb_hash_aset(v_hash, rb_str_new2("history_num"), LONG2FIX(ent.pw_history_num));
|
684
|
+
|
685
|
+
v_arg[0] = v_hash;
|
686
|
+
|
687
|
+
v_policy = rb_class_new_instance(1, v_arg, cKadm5Policy);
|
688
|
+
}
|
689
|
+
|
690
|
+
return v_policy;
|
691
|
+
}
|
692
|
+
|
693
|
+
/*
|
694
|
+
* call-seq:
|
695
|
+
* kadm5.modify_policy(policy)
|
696
|
+
*
|
697
|
+
* Modify an existing Kerberos policy using a +policy+ object.
|
698
|
+
*
|
699
|
+
* Example:
|
700
|
+
*
|
701
|
+
* policy = Kerberos::Kadm5::Policy.find('test')
|
702
|
+
* policy.max_length = 1024
|
703
|
+
* kadm5.modify_policy(policy)
|
704
|
+
*/
|
705
|
+
static VALUE rkadm5_modify_policy(VALUE self, VALUE v_policy){
|
706
|
+
RUBY_KADM5* ptr;
|
707
|
+
RUBY_KADM5_POLICY* pptr;
|
708
|
+
kadm5_ret_t kerror;
|
709
|
+
long mask = KADM5_POLICY;
|
710
|
+
|
711
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
712
|
+
Data_Get_Struct(v_policy, RUBY_KADM5_POLICY, pptr);
|
713
|
+
|
714
|
+
if(!ptr->ctx)
|
715
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
716
|
+
|
717
|
+
if(pptr->policy.pw_min_classes)
|
718
|
+
mask |= KADM5_PW_MIN_CLASSES;
|
719
|
+
|
720
|
+
if(pptr->policy.pw_min_length)
|
721
|
+
mask |= KADM5_PW_MIN_LENGTH;
|
722
|
+
|
723
|
+
if(pptr->policy.pw_min_life)
|
724
|
+
mask |= KADM5_PW_MIN_LIFE;
|
725
|
+
|
726
|
+
if(pptr->policy.pw_max_life)
|
727
|
+
mask |= KADM5_PW_MAX_LIFE;
|
728
|
+
|
729
|
+
kerror = kadm5_modify_policy(ptr->handle, &pptr->policy, mask);
|
730
|
+
|
731
|
+
if(kerror)
|
732
|
+
rb_raise(cKadm5Exception, "kadm5_modify_policy: %s (%li)", error_message(kerror), kerror);
|
733
|
+
|
734
|
+
return self;
|
735
|
+
}
|
736
|
+
|
737
|
+
/*
|
738
|
+
* call-seq:
|
739
|
+
* kadm5.get_policies(expr = nil)
|
740
|
+
*
|
741
|
+
* Returns a list of policy names matching +expr+, or all policy names if
|
742
|
+
* +expr+ is nil.
|
743
|
+
*
|
744
|
+
* The valid characters for +expr+ are '*', '?', '[]' and '\'. All other
|
745
|
+
* characters match themselves.
|
746
|
+
*
|
747
|
+
* kadm5.get_policies # => Get all policies
|
748
|
+
* kadm5.get_policies('test*') # => Get all policies that start with 'test'
|
749
|
+
*/
|
750
|
+
static VALUE rkadm5_get_policies(int argc, VALUE* argv, VALUE self){
|
751
|
+
RUBY_KADM5* ptr;
|
752
|
+
VALUE v_array, v_expr;
|
753
|
+
kadm5_ret_t kerror;
|
754
|
+
char** pols;
|
755
|
+
char* expr;
|
756
|
+
int i, count;
|
757
|
+
|
758
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
759
|
+
|
760
|
+
rb_scan_args(argc, argv, "01", &v_expr);
|
761
|
+
|
762
|
+
if(NIL_P(v_expr))
|
763
|
+
expr = NULL;
|
764
|
+
else
|
765
|
+
expr = StringValuePtr(v_expr);
|
766
|
+
|
767
|
+
kerror = kadm5_get_policies(ptr->handle, expr, &pols, &count);
|
768
|
+
|
769
|
+
if(kerror)
|
770
|
+
rb_raise(cKadm5Exception, "kadm5_get_policies: %s (%li)", error_message(kerror), kerror);
|
771
|
+
|
772
|
+
v_array = rb_ary_new();
|
773
|
+
|
774
|
+
for(i = 0; i < count; i++){
|
775
|
+
rb_ary_push(v_array, rb_str_new2(pols[i]));
|
776
|
+
}
|
777
|
+
|
778
|
+
kadm5_free_name_list(ptr->handle, pols, count);
|
779
|
+
|
780
|
+
return v_array;
|
781
|
+
}
|
782
|
+
|
783
|
+
/*
|
784
|
+
* call-seq:
|
785
|
+
* kadm5.get_principals(expr = nil)
|
786
|
+
*
|
787
|
+
* Returns a list of principals matching +expr+, or all principals if
|
788
|
+
* +expr+ is nil.
|
789
|
+
*
|
790
|
+
* The valid characters for +expr+ are '*', '?', '[]' and '\'. All other
|
791
|
+
* characters match themselves.
|
792
|
+
*
|
793
|
+
* Example:
|
794
|
+
*
|
795
|
+
* kadm5.get_principals # => Get all principals
|
796
|
+
* kadm5.get_principals('test*') # => Get all principals that start with 'test'
|
797
|
+
*/
|
798
|
+
static VALUE rkadm5_get_principals(int argc, VALUE* argv, VALUE self){
|
799
|
+
RUBY_KADM5* ptr;
|
800
|
+
VALUE v_array, v_expr;
|
801
|
+
kadm5_ret_t kerror;
|
802
|
+
char** princs;
|
803
|
+
char* expr;
|
804
|
+
int i, count;
|
805
|
+
|
806
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
807
|
+
|
808
|
+
rb_scan_args(argc, argv, "01", &v_expr);
|
809
|
+
|
810
|
+
if(NIL_P(v_expr))
|
811
|
+
expr = NULL;
|
812
|
+
else
|
813
|
+
expr = StringValuePtr(v_expr);
|
814
|
+
|
815
|
+
kerror = kadm5_get_principals(ptr->handle, expr, &princs, &count);
|
816
|
+
|
817
|
+
if(kerror)
|
818
|
+
rb_raise(cKadm5Exception, "kadm5_get_principals: %s (%li)", error_message(kerror), kerror);
|
819
|
+
|
820
|
+
v_array = rb_ary_new();
|
821
|
+
|
822
|
+
for(i = 0; i < count; i++){
|
823
|
+
rb_ary_push(v_array, rb_str_new2(princs[i]));
|
824
|
+
}
|
825
|
+
|
826
|
+
kadm5_free_name_list(ptr->handle, princs, count);
|
827
|
+
|
828
|
+
return v_array;
|
829
|
+
}
|
830
|
+
|
831
|
+
/*
|
832
|
+
* call-seq:
|
833
|
+
* kadm5.get_privileges(:strings => false)
|
834
|
+
*
|
835
|
+
* Returns a numeric bitmask indicating the caller's privileges. If the
|
836
|
+
* +strings+ option is true, then an array of human readable strings are
|
837
|
+
* returned instead.
|
838
|
+
*
|
839
|
+
* The possible values, and their string equivalent, are:
|
840
|
+
*
|
841
|
+
* KADM5_PRIV_GET (0x01) => "GET"
|
842
|
+
* KADM5_PRIV_ADD (0x02) => "ADD"
|
843
|
+
* KADM5_PRIV_MODIFY (0x04) => "MODIFY"
|
844
|
+
* KADM5_PRIV_DELETE (0x08) => "DELETE"
|
845
|
+
*/
|
846
|
+
static VALUE rkadm5_get_privs(int argc, VALUE* argv, VALUE self){
|
847
|
+
RUBY_KADM5* ptr;
|
848
|
+
VALUE v_return = Qnil;
|
849
|
+
VALUE v_strings = Qfalse;
|
850
|
+
kadm5_ret_t kerror;
|
851
|
+
int i;
|
852
|
+
long privs;
|
853
|
+
int result = 0;
|
854
|
+
|
855
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
856
|
+
|
857
|
+
rb_scan_args(argc, argv, "01", &v_strings);
|
858
|
+
|
859
|
+
kerror = kadm5_get_privs(ptr->handle, &privs);
|
860
|
+
|
861
|
+
if(kerror)
|
862
|
+
rb_raise(cKadm5Exception, "kadm5_get_privs: %s (%li)", error_message(kerror), kerror);
|
863
|
+
|
864
|
+
if(RTEST(v_strings)){
|
865
|
+
v_return = rb_ary_new();
|
866
|
+
|
867
|
+
for(i = 0; i < sizeof(privs); i++){
|
868
|
+
result |= (privs & 1 << i);
|
869
|
+
switch(privs & 1 << i){
|
870
|
+
case KADM5_PRIV_GET:
|
871
|
+
rb_ary_push(v_return, rb_str_new2("GET"));
|
872
|
+
break;
|
873
|
+
case KADM5_PRIV_ADD:
|
874
|
+
rb_ary_push(v_return, rb_str_new2("ADD"));
|
875
|
+
break;
|
876
|
+
case KADM5_PRIV_MODIFY:
|
877
|
+
rb_ary_push(v_return, rb_str_new2("MODIFY"));
|
878
|
+
break;
|
879
|
+
case KADM5_PRIV_DELETE:
|
880
|
+
rb_ary_push(v_return, rb_str_new2("DELETE"));
|
881
|
+
break;
|
882
|
+
default:
|
883
|
+
rb_ary_push(v_return, rb_str_new2("UNKNOWN"));
|
884
|
+
};
|
885
|
+
}
|
886
|
+
}
|
887
|
+
else{
|
888
|
+
for(i = 0; i < sizeof(privs); i++){
|
889
|
+
result |= (privs & 1 << i);
|
890
|
+
}
|
891
|
+
v_return = INT2FIX(result);
|
892
|
+
}
|
893
|
+
|
894
|
+
return v_return;
|
895
|
+
}
|
896
|
+
|
897
|
+
/*
|
898
|
+
* call-seq:
|
899
|
+
* kadm.generate_random_key(principal)
|
900
|
+
*
|
901
|
+
* Generates and assigns a new random key to the named +principal+ and
|
902
|
+
* returns the number of generated keys.
|
903
|
+
*/
|
904
|
+
static VALUE rkadm5_randkey_principal(VALUE self, VALUE v_user){
|
905
|
+
RUBY_KADM5* ptr;
|
906
|
+
krb5_keyblock* keys;
|
907
|
+
kadm5_ret_t kerror;
|
908
|
+
krb5_principal princ;
|
909
|
+
char* user;
|
910
|
+
int n_keys, i;
|
911
|
+
|
912
|
+
Data_Get_Struct(self, RUBY_KADM5, ptr);
|
913
|
+
|
914
|
+
user = StringValuePtr(v_user);
|
915
|
+
|
916
|
+
if(!ptr->ctx)
|
917
|
+
rb_raise(cKadm5Exception, "no context has been established");
|
918
|
+
|
919
|
+
kerror = krb5_parse_name(ptr->ctx, user, &princ);
|
920
|
+
|
921
|
+
if(kerror)
|
922
|
+
rb_raise(cKadm5Exception, "krb5_parse_name: %s", error_message(kerror));
|
923
|
+
|
924
|
+
kerror = kadm5_randkey_principal(ptr->handle, princ, &keys, &n_keys);
|
925
|
+
|
926
|
+
if(kerror)
|
927
|
+
rb_raise(cKadm5Exception, "kadm5_randkey_principal: %s (%li)", error_message(kerror), kerror);
|
928
|
+
|
929
|
+
for(i = 0; i < n_keys; i++)
|
930
|
+
krb5_free_keyblock_contents(ptr->ctx, &keys[i]);
|
931
|
+
|
932
|
+
free(keys);
|
933
|
+
|
934
|
+
return INT2NUM(n_keys);
|
935
|
+
}
|
936
|
+
|
937
|
+
void Init_kadm5(){
|
938
|
+
/* The Kadm5 class encapsulates administrative Kerberos functions. */
|
939
|
+
cKadm5 = rb_define_class_under(mKerberos, "Kadm5", rb_cObject);
|
940
|
+
|
941
|
+
/* Error typically raised if any of the Kadm5 methods fail. */
|
942
|
+
cKadm5Exception = rb_define_class_under(cKadm5, "Exception", rb_eStandardError);
|
943
|
+
|
944
|
+
/* Error raised if a get_principal call cannot find the principal. */
|
945
|
+
cKadm5PrincipalNotFoundException = rb_define_class_under(
|
946
|
+
cKadm5, "PrincipalNotFoundException", rb_eStandardError
|
947
|
+
);
|
948
|
+
|
949
|
+
// Allocation Functions
|
950
|
+
|
951
|
+
rb_define_alloc_func(cKadm5, rkadm5_allocate);
|
952
|
+
|
953
|
+
// Initialization Method
|
954
|
+
|
955
|
+
rb_define_method(cKadm5, "initialize", rkadm5_initialize, 1);
|
956
|
+
|
957
|
+
// Instance Methods
|
958
|
+
|
959
|
+
rb_define_method(cKadm5, "close", rkadm5_close, 0);
|
960
|
+
rb_define_method(cKadm5, "create_policy", rkadm5_create_policy, 1);
|
961
|
+
rb_define_method(cKadm5, "create_principal", rkadm5_create_principal, 2);
|
962
|
+
rb_define_method(cKadm5, "delete_policy", rkadm5_delete_policy, 1);
|
963
|
+
rb_define_method(cKadm5, "delete_principal", rkadm5_delete_principal, 1);
|
964
|
+
rb_define_method(cKadm5, "find_principal", rkadm5_find_principal, 1);
|
965
|
+
rb_define_method(cKadm5, "find_policy", rkadm5_find_policy, 1);
|
966
|
+
rb_define_method(cKadm5, "generate_random_key", rkadm5_randkey_principal, 1);
|
967
|
+
rb_define_method(cKadm5, "get_policy", rkadm5_get_policy, 1);
|
968
|
+
rb_define_method(cKadm5, "get_policies", rkadm5_get_policies, -1);
|
969
|
+
rb_define_method(cKadm5, "get_principal", rkadm5_get_principal, 1);
|
970
|
+
rb_define_method(cKadm5, "get_principals", rkadm5_get_principals, -1);
|
971
|
+
rb_define_method(cKadm5, "get_privileges", rkadm5_get_privs, -1);
|
972
|
+
rb_define_method(cKadm5, "modify_policy", rkadm5_modify_policy, 1);
|
973
|
+
rb_define_method(cKadm5, "set_password", rkadm5_set_password, 2);
|
974
|
+
|
975
|
+
// Constants
|
976
|
+
|
977
|
+
rb_define_const(cKadm5, "DISALLOW_POSTDATED", INT2FIX(KRB5_KDB_DISALLOW_POSTDATED));
|
978
|
+
rb_define_const(cKadm5, "DISALLOW_FORWARDABLE", INT2FIX(KRB5_KDB_DISALLOW_FORWARDABLE));
|
979
|
+
rb_define_const(cKadm5, "DISALLOW_TGT_BASED", INT2FIX(KRB5_KDB_DISALLOW_TGT_BASED));
|
980
|
+
rb_define_const(cKadm5, "DISALLOW_RENEWABLE", INT2FIX(KRB5_KDB_DISALLOW_RENEWABLE));
|
981
|
+
rb_define_const(cKadm5, "DISALLOW_PROXIABLE", INT2FIX(KRB5_KDB_DISALLOW_PROXIABLE));
|
982
|
+
rb_define_const(cKadm5, "DISALLOW_DUP_SKEY", INT2FIX(KRB5_KDB_DISALLOW_DUP_SKEY));
|
983
|
+
rb_define_const(cKadm5, "DISALLOW_ALL_TIX", INT2FIX(KRB5_KDB_DISALLOW_ALL_TIX));
|
984
|
+
rb_define_const(cKadm5, "REQUIRES_PRE_AUTH", INT2FIX(KRB5_KDB_REQUIRES_PRE_AUTH));
|
985
|
+
rb_define_const(cKadm5, "REQUIRES_HW_AUTH", INT2FIX(KRB5_KDB_REQUIRES_HW_AUTH));
|
986
|
+
rb_define_const(cKadm5, "REQUIRES_PWCHANGE", INT2FIX(KRB5_KDB_REQUIRES_PWCHANGE));
|
987
|
+
rb_define_const(cKadm5, "DISALLOW_SVR", INT2FIX(KRB5_KDB_DISALLOW_SVR));
|
988
|
+
rb_define_const(cKadm5, "PWCHANGE_SERVICE", INT2FIX(KRB5_KDB_PWCHANGE_SERVICE));
|
989
|
+
rb_define_const(cKadm5, "SUPPORT_DESMD5", INT2FIX(KRB5_KDB_SUPPORT_DESMD5));
|
990
|
+
rb_define_const(cKadm5, "NEW_PRINC", INT2FIX(KRB5_KDB_NEW_PRINC));
|
991
|
+
}
|