rkerberos 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,84 @@
1
+ #include <rkerberos.h>
2
+
3
+ VALUE cKrb5KtEntry;
4
+
5
+ // Free function for the Kerberos::Krb5::Keytab::Entry class.
6
+ static void rkrb5_kt_entry_free(RUBY_KRB5_KT_ENTRY* ptr){
7
+ if(!ptr)
8
+ return;
9
+
10
+ free(ptr);
11
+ }
12
+
13
+ // Allocation function for the Kerberos::Krb5::Keytab::Entry class.
14
+ static VALUE rkrb5_kt_entry_allocate(VALUE klass){
15
+ RUBY_KRB5_KT_ENTRY* ptr = malloc(sizeof(RUBY_KRB5_KT_ENTRY));
16
+ memset(ptr, 0, sizeof(RUBY_KRB5_KT_ENTRY));
17
+ return Data_Wrap_Struct(klass, 0, rkrb5_kt_entry_free, ptr);
18
+ }
19
+
20
+ /*
21
+ * call-seq:
22
+ *
23
+ * Kerberos::Krb5::Keytab::Entry.new
24
+ *
25
+ * Creates and returns a new Kerberos::Krb5::Keytab::Entry object. These
26
+ * objects are what is typically returned from the various Krb5::Keytab
27
+ * methods.
28
+ */
29
+ static VALUE rkrb5_kt_entry_initialize(VALUE self){
30
+ RUBY_KRB5_KT_ENTRY* ptr;
31
+ Data_Get_Struct(self, RUBY_KRB5_KT_ENTRY, ptr);
32
+ return self;
33
+ }
34
+
35
+ /*
36
+ * A custom inspect method for nicer output.
37
+ */
38
+ static VALUE rkrb5_kt_entry_inspect(VALUE self){
39
+ RUBY_KRB5_KT_ENTRY* ptr;
40
+ Data_Get_Struct(self, RUBY_KRB5_KT_ENTRY, ptr);
41
+ VALUE v_str;
42
+
43
+ v_str = rb_str_new2("#<");
44
+ rb_str_buf_cat2(v_str, rb_obj_classname(self));
45
+ rb_str_buf_cat2(v_str, " ");
46
+
47
+ rb_str_buf_cat2(v_str, "principal=");
48
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@principal")));
49
+ rb_str_buf_cat2(v_str, " ");
50
+
51
+ rb_str_buf_cat2(v_str, "timestamp=");
52
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@timestamp")));
53
+ rb_str_buf_cat2(v_str, " ");
54
+
55
+ rb_str_buf_cat2(v_str, "vno=");
56
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@vno")));
57
+ rb_str_buf_cat2(v_str, " ");
58
+
59
+ rb_str_buf_cat2(v_str, "key=");
60
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@key")));
61
+ rb_str_buf_cat2(v_str, " ");
62
+
63
+ return v_str;
64
+ }
65
+
66
+ void Init_keytab_entry(){
67
+ // The Kerberos::Krb5::Keytab::Entry class encapsulates a Kerberos keytab entry.
68
+ cKrb5KtEntry = rb_define_class_under(cKrb5Keytab, "Entry", rb_cObject);
69
+
70
+ // Allocation function
71
+ rb_define_alloc_func(cKrb5KtEntry, rkrb5_kt_entry_allocate);
72
+
73
+ // Constructor
74
+ rb_define_method(cKrb5KtEntry, "initialize", rkrb5_kt_entry_initialize, 0);
75
+
76
+ // Instance Methods
77
+ rb_define_method(cKrb5KtEntry, "inspect", rkrb5_kt_entry_inspect, 0);
78
+
79
+ // Accessors
80
+ rb_define_attr(cKrb5KtEntry, "principal", 1, 1);
81
+ rb_define_attr(cKrb5KtEntry, "timestamp", 1, 1);
82
+ rb_define_attr(cKrb5KtEntry, "vno", 1, 1);
83
+ rb_define_attr(cKrb5KtEntry, "key", 1, 1);
84
+ }
@@ -0,0 +1,196 @@
1
+ #include <rkerberos.h>
2
+
3
+ VALUE cKadm5Policy;
4
+
5
+ // Free function for the Kerberos::Krb5::CCache class.
6
+ static void rkadm5_policy_free(RUBY_KADM5_POLICY* 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::Kadm5::Policy class.
17
+ static VALUE rkadm5_policy_allocate(VALUE klass){
18
+ RUBY_KADM5_POLICY* ptr = malloc(sizeof(RUBY_KADM5_POLICY));
19
+ memset(ptr, 0, sizeof(RUBY_KADM5_POLICY));
20
+ return Data_Wrap_Struct(klass, 0, rkadm5_policy_free, ptr);
21
+ }
22
+
23
+ /*
24
+ * call-seq:
25
+ * Kerberos::Kadm5::Policy.new(options)
26
+ *
27
+ * Returns a new policy object using +options+ you choose to pass, where
28
+ * the +options+ argument is a hash. This does NOT actually create the policy
29
+ * object within Kerberos. To do that pass your Policy object to the
30
+ * Kadm5.create_policy method.
31
+ *
32
+ * The possible options are:
33
+ *
34
+ * * name - the name of the policy (mandatory)
35
+ * * min_life - minimum lifetime of a password
36
+ * * max_life - maximum lifetime of a password
37
+ * * min_length - minimum length of a password
38
+ * * min_classes - minimum number of character classes allowed in a password
39
+ * * history_num - number of past key kept for a principal
40
+ *
41
+ * If you do not provide a :name then an ArgumentError will be raised.
42
+ */
43
+ static VALUE rkadm5_policy_init(VALUE self, VALUE v_options){
44
+ RUBY_KADM5_POLICY* ptr;
45
+ VALUE v_name, v_minlife, v_maxlife, v_minlength;
46
+ VALUE v_minclasses, v_historynum;
47
+
48
+ Data_Get_Struct(self, RUBY_KADM5_POLICY, ptr);
49
+
50
+ Check_Type(v_options, T_HASH);
51
+
52
+ if(RTEST(rb_funcall(v_options, rb_intern("empty?"), 0, 0)))
53
+ rb_raise(rb_eArgError, "no policy options provided");
54
+
55
+ v_name = rb_hash_aref2(v_options, "name");
56
+ v_minlife = rb_hash_aref2(v_options, "min_life");
57
+ v_maxlife = rb_hash_aref2(v_options, "max_life");
58
+ v_minlength = rb_hash_aref2(v_options, "min_length");
59
+ v_minclasses = rb_hash_aref2(v_options, "min_classes");
60
+ v_historynum = rb_hash_aref2(v_options, "history_num");
61
+
62
+ if(NIL_P(v_name)){
63
+ rb_raise(rb_eArgError, "name policy option is mandatory");
64
+ }
65
+ else{
66
+ ptr->policy.policy = StringValuePtr(v_name);
67
+ rb_iv_set(self, "@policy", v_name);
68
+ }
69
+
70
+ if(!NIL_P(v_minlife)){
71
+ ptr->policy.pw_min_life = NUM2LONG(v_minlife);
72
+ rb_iv_set(self, "@min_life", v_minlife);
73
+ }
74
+ else{
75
+ rb_iv_set(self, "@min_life", Qnil);
76
+ }
77
+
78
+ if(!NIL_P(v_maxlife)){
79
+ ptr->policy.pw_max_life = NUM2LONG(v_maxlife);
80
+ rb_iv_set(self, "@max_life", v_maxlife);
81
+ }
82
+ else{
83
+ rb_iv_set(self, "@max_life", Qnil);
84
+ }
85
+
86
+ if(!NIL_P(v_minlength)){
87
+ ptr->policy.pw_min_length = NUM2LONG(v_minlength);
88
+ rb_iv_set(self, "@min_length", v_minlength);
89
+ }
90
+ else{
91
+ rb_iv_set(self, "@min_length", Qnil);
92
+ }
93
+
94
+ if(!NIL_P(v_minclasses)){
95
+ ptr->policy.pw_min_classes = NUM2LONG(v_minclasses);
96
+ rb_iv_set(self, "@min_classes", v_minclasses);
97
+ }
98
+ else{
99
+ rb_iv_set(self, "@min_classes", Qnil);
100
+ }
101
+
102
+ if(!NIL_P(v_historynum)){
103
+ ptr->policy.pw_history_num = NUM2LONG(v_historynum);
104
+ rb_iv_set(self, "@history_num", v_historynum);
105
+ }
106
+ else{
107
+ rb_iv_set(self, "@history_num", Qnil);
108
+ }
109
+
110
+ return self;
111
+ }
112
+
113
+ /*
114
+ * call-seq:
115
+ * policy.inspect
116
+ *
117
+ * A custom inspect method for Policy objects.
118
+ */
119
+ static VALUE rkadm5_policy_inspect(VALUE self){
120
+ RUBY_KADM5_POLICY* ptr;
121
+ VALUE v_str;
122
+
123
+ Data_Get_Struct(self, RUBY_KADM5_POLICY, ptr);
124
+
125
+ v_str = rb_str_new2("#<");
126
+ rb_str_buf_cat2(v_str, rb_obj_classname(self));
127
+ rb_str_buf_cat2(v_str, " ");
128
+
129
+ rb_str_buf_cat2(v_str, "policy=");
130
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@policy")));
131
+ rb_str_buf_cat2(v_str, " ");
132
+
133
+ rb_str_buf_cat2(v_str, "min_life=");
134
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@min_life")));
135
+ rb_str_buf_cat2(v_str, " ");
136
+
137
+ rb_str_buf_cat2(v_str, "max_life=");
138
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@max_life")));
139
+ rb_str_buf_cat2(v_str, " ");
140
+
141
+ rb_str_buf_cat2(v_str, "min_length=");
142
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@min_length")));
143
+ rb_str_buf_cat2(v_str, " ");
144
+
145
+ rb_str_buf_cat2(v_str, "min_classes=");
146
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@min_classes")));
147
+ rb_str_buf_cat2(v_str, " ");
148
+
149
+ rb_str_buf_cat2(v_str, "history_num=");
150
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@history_num")));
151
+
152
+ rb_str_buf_cat2(v_str, ">");
153
+
154
+ return v_str;
155
+ }
156
+
157
+ void Init_policy(){
158
+ /* The Kerberos::Kadm5::Policy class encapsulates a Kerberos policy. */
159
+ cKadm5Policy = rb_define_class_under(cKadm5, "Policy", rb_cObject);
160
+
161
+ // Allocation Function
162
+
163
+ rb_define_alloc_func(cKadm5Policy, rkadm5_policy_allocate);
164
+
165
+ // Initialization Function
166
+
167
+ rb_define_method(cKadm5Policy, "initialize", rkadm5_policy_init, 1);
168
+
169
+ // Instance methods
170
+
171
+ rb_define_method(cKadm5Policy, "inspect", rkadm5_policy_inspect, 0);
172
+
173
+ // Accessors
174
+
175
+ /* The name of the policy. */
176
+ rb_define_attr(cKadm5Policy, "policy", 1, 0);
177
+
178
+ /* The minimum password lifetime, in seconds. */
179
+ rb_define_attr(cKadm5Policy, "min_life", 1, 1);
180
+
181
+ /* The maximum duration of a password, in seconds. */
182
+ rb_define_attr(cKadm5Policy, "max_life", 1, 1);
183
+
184
+ /* The minimum password length. */
185
+ rb_define_attr(cKadm5Policy, "min_length", 1, 1);
186
+
187
+ /* The minimum number of character classes (1-5). */
188
+ rb_define_attr(cKadm5Policy, "min_classes", 1, 1);
189
+
190
+ /* The number of past passwords that are stored. */
191
+ rb_define_attr(cKadm5Policy, "history_num", 1, 1);
192
+
193
+ // Aliases
194
+
195
+ rb_define_alias(cKadm5Policy, "name", "policy");
196
+ }
@@ -0,0 +1,263 @@
1
+ #include <rkerberos.h>
2
+
3
+ VALUE cKrb5Principal;
4
+
5
+ // Free function for the Kerberos::Krb5::Keytab class.
6
+ static void rkrb5_princ_free(RUBY_KRB5_PRINC* ptr){
7
+ if(!ptr)
8
+ return;
9
+
10
+ if(ptr->principal)
11
+ krb5_free_principal(ptr->ctx, ptr->principal);
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_princ_allocate(VALUE klass){
21
+ RUBY_KRB5_PRINC* ptr = malloc(sizeof(RUBY_KRB5_PRINC));
22
+ memset(ptr, 0, sizeof(RUBY_KRB5_PRINC));
23
+ return Data_Wrap_Struct(klass, 0, rkrb5_princ_free, ptr);
24
+ }
25
+
26
+ /*
27
+ * call-seq:
28
+ * Kerberos::Krb5::Principal.new(name)
29
+ *
30
+ * Creates and returns a new Krb5::Principal object. If a block is provided
31
+ * then it yields itself.
32
+ *
33
+ * Example:
34
+ *
35
+ * principal1 = Kerberos::Krb5::Principal.new('Jon')
36
+ *
37
+ * principal2 = Kerberos::Krb5::Principal.new('Jon') do |pr|
38
+ * pr.expire_time = Time.now + 20000
39
+ * end
40
+ */
41
+ static VALUE rkrb5_princ_initialize(VALUE self, VALUE v_name){
42
+ RUBY_KRB5_PRINC* ptr;
43
+ krb5_error_code kerror;
44
+
45
+ Data_Get_Struct(self, RUBY_KRB5_PRINC, ptr);
46
+
47
+ kerror = krb5_init_context(&ptr->ctx);
48
+
49
+ if(kerror)
50
+ rb_raise(cKrb5Exception, "krb5_init_context failed: %s", error_message(kerror));
51
+
52
+ if(NIL_P(v_name)){
53
+ rb_iv_set(self, "@principal", Qnil);
54
+ }
55
+ else{
56
+ char* name;
57
+ Check_Type(v_name, T_STRING);
58
+ name = StringValuePtr(v_name);
59
+ kerror = krb5_parse_name(ptr->ctx, name, &ptr->principal);
60
+
61
+ if(kerror)
62
+ rb_raise(cKrb5Exception, "krb5_parse_name failed: %s", error_message(kerror));
63
+
64
+ rb_iv_set(self, "@principal", v_name);
65
+ }
66
+
67
+ rb_iv_set(self, "@attributes", Qnil);
68
+ rb_iv_set(self, "@aux_attributes", Qnil);
69
+ rb_iv_set(self, "@expire_time", Qnil);
70
+ rb_iv_set(self, "@fail_auth_count", Qnil);
71
+ rb_iv_set(self, "@last_failed", Qnil);
72
+ rb_iv_set(self, "@last_password_change", Qnil);
73
+ rb_iv_set(self, "@last_success", Qnil);
74
+ rb_iv_set(self, "@max_life", Qnil);
75
+ rb_iv_set(self, "@max_renewable_life", Qnil);
76
+ rb_iv_set(self, "@mod_date", Qnil);
77
+ rb_iv_set(self, "@mod_name", Qnil);
78
+ rb_iv_set(self, "@password_expiration", Qnil);
79
+ rb_iv_set(self, "@policy", Qnil);
80
+ rb_iv_set(self, "@kvno", Qnil);
81
+
82
+ if(rb_block_given_p())
83
+ rb_yield(self);
84
+
85
+ return self;
86
+ }
87
+
88
+ /*
89
+ * call-seq:
90
+ * principal.realm
91
+ *
92
+ * Returns the realm for the given principal.
93
+ */
94
+ static VALUE rkrb5_princ_get_realm(VALUE self){
95
+ RUBY_KRB5_PRINC* ptr;
96
+ Data_Get_Struct(self, RUBY_KRB5_PRINC, ptr);
97
+
98
+ return rb_str_new2(krb5_princ_realm(ptr->ctx, ptr->principal)->data);
99
+ }
100
+
101
+ /*
102
+ * call-seq:
103
+ * principal.realm = 'YOUR.REALM'
104
+ *
105
+ * Sets the realm for the given principal.
106
+ */
107
+ static VALUE rkrb5_princ_set_realm(VALUE self, VALUE v_realm){
108
+ RUBY_KRB5_PRINC* ptr;
109
+ krb5_data kdata;
110
+
111
+ memset(&kdata, 0, sizeof(kdata));
112
+ Data_Get_Struct(self, RUBY_KRB5_PRINC, ptr);
113
+
114
+ Check_Type(v_realm, T_STRING);
115
+ kdata.data = StringValuePtr(v_realm);
116
+
117
+ krb5_princ_set_realm(ptr->ctx, ptr->principal, &kdata);
118
+
119
+ return v_realm;
120
+ }
121
+
122
+ /*
123
+ * call-seq:
124
+ * principal1 == principal2
125
+ *
126
+ * Returns whether or not two principals are the same.
127
+ */
128
+ static VALUE rkrb5_princ_equal(VALUE self, VALUE v_other){
129
+ RUBY_KRB5_PRINC* ptr1;
130
+ RUBY_KRB5_PRINC* ptr2;
131
+ VALUE v_bool = Qfalse;
132
+
133
+ Data_Get_Struct(self, RUBY_KRB5_PRINC, ptr1);
134
+ Data_Get_Struct(v_other, RUBY_KRB5_PRINC, ptr2);
135
+
136
+ if(krb5_principal_compare(ptr1->ctx, ptr1->principal, ptr2->principal))
137
+ v_bool = Qtrue;
138
+
139
+ return v_bool;
140
+ }
141
+
142
+ /*
143
+ * call-seq:
144
+ * principal.inspect
145
+ *
146
+ * A custom inspect method for the Principal object.
147
+ */
148
+ static VALUE rkrb5_princ_inspect(VALUE self){
149
+ RUBY_KRB5_PRINC* ptr;
150
+ VALUE v_str;
151
+
152
+ Data_Get_Struct(self, RUBY_KRB5_PRINC, ptr);
153
+
154
+ v_str = rb_str_new2("#<");
155
+ rb_str_buf_cat2(v_str, rb_obj_classname(self));
156
+ rb_str_buf_cat2(v_str, " ");
157
+
158
+ rb_str_buf_cat2(v_str, "attributes=");
159
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@attributes")));
160
+ rb_str_buf_cat2(v_str, " ");
161
+
162
+ rb_str_buf_cat2(v_str, "aux_attributes=");
163
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@aux_attributes")));
164
+ rb_str_buf_cat2(v_str, " ");
165
+
166
+ rb_str_buf_cat2(v_str, "expire_time=");
167
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@expire_time")));
168
+ rb_str_buf_cat2(v_str, " ");
169
+
170
+ rb_str_buf_cat2(v_str, "fail_auth_count=");
171
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@fail_auth_count")));
172
+ rb_str_buf_cat2(v_str, " ");
173
+
174
+ rb_str_buf_cat2(v_str, "kvno=");
175
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@kvno")));
176
+ rb_str_buf_cat2(v_str, " ");
177
+
178
+ rb_str_buf_cat2(v_str, "last_failed=");
179
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@last_failed")));
180
+ rb_str_buf_cat2(v_str, " ");
181
+
182
+ rb_str_buf_cat2(v_str, "last_password_change=");
183
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@last_password_change")));
184
+ rb_str_buf_cat2(v_str, " ");
185
+
186
+ rb_str_buf_cat2(v_str, "last_success=");
187
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@last_success")));
188
+ rb_str_buf_cat2(v_str, " ");
189
+
190
+ rb_str_buf_cat2(v_str, "max_life=");
191
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@max_life")));
192
+ rb_str_buf_cat2(v_str, " ");
193
+
194
+ rb_str_buf_cat2(v_str, "max_renewable_life=");
195
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@max_renewable_life")));
196
+ rb_str_buf_cat2(v_str, " ");
197
+
198
+ rb_str_buf_cat2(v_str, "mod_date=");
199
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@mod_date")));
200
+ rb_str_buf_cat2(v_str, " ");
201
+
202
+ rb_str_buf_cat2(v_str, "mod_name=");
203
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@mod_name")));
204
+ rb_str_buf_cat2(v_str, " ");
205
+
206
+ rb_str_buf_cat2(v_str, "password_expiration=");
207
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@password_expiration")));
208
+ rb_str_buf_cat2(v_str, " ");
209
+
210
+ rb_str_buf_cat2(v_str, "policy=");
211
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@policy")));
212
+ rb_str_buf_cat2(v_str, " ");
213
+
214
+ rb_str_buf_cat2(v_str, "principal=");
215
+ rb_str_buf_append(v_str, rb_inspect(rb_iv_get(self, "@principal")));
216
+ rb_str_buf_cat2(v_str, " ");
217
+
218
+ rb_str_buf_cat2(v_str, ">");
219
+
220
+ return v_str;
221
+ }
222
+
223
+ void Init_principal(){
224
+ /* The Kerberos::Krb5::Principal class encapsulates a Kerberos principal. */
225
+ cKrb5Principal = rb_define_class_under(cKrb5, "Principal", rb_cObject);
226
+
227
+ // Allocation Function
228
+
229
+ rb_define_alloc_func(cKrb5Principal, rkrb5_princ_allocate);
230
+
231
+ // Constructor
232
+
233
+ rb_define_method(cKrb5Principal, "initialize", rkrb5_princ_initialize, 1);
234
+
235
+ // Instance Methods
236
+
237
+ rb_define_method(cKrb5Principal, "inspect", rkrb5_princ_inspect, 0);
238
+ rb_define_method(cKrb5Principal, "realm", rkrb5_princ_get_realm, 0);
239
+ rb_define_method(cKrb5Principal, "realm=", rkrb5_princ_set_realm, 1);
240
+ rb_define_method(cKrb5Principal, "==", rkrb5_princ_equal, 1);
241
+
242
+ // Attributes
243
+
244
+ rb_define_attr(cKrb5Principal, "attributes", 1, 1);
245
+ rb_define_attr(cKrb5Principal, "aux_attributes", 1, 1);
246
+ rb_define_attr(cKrb5Principal, "expire_time", 1, 1);
247
+ rb_define_attr(cKrb5Principal, "fail_auth_count", 1, 1);
248
+ rb_define_attr(cKrb5Principal, "kvno", 1, 1);
249
+ rb_define_attr(cKrb5Principal, "last_failed", 1, 1);
250
+ rb_define_attr(cKrb5Principal, "last_password_change", 1, 1);
251
+ rb_define_attr(cKrb5Principal, "last_success", 1, 1);
252
+ rb_define_attr(cKrb5Principal, "max_life", 1, 1);
253
+ rb_define_attr(cKrb5Principal, "max_renewable_life", 1, 1);
254
+ rb_define_attr(cKrb5Principal, "mod_date", 1, 1);
255
+ rb_define_attr(cKrb5Principal, "mod_name", 1, 1);
256
+ rb_define_attr(cKrb5Principal, "password_expiration", 1, 1);
257
+ rb_define_attr(cKrb5Principal, "policy", 1, 1);
258
+ rb_define_attr(cKrb5Principal, "principal", 1, 0);
259
+
260
+ // Aliases
261
+
262
+ rb_define_alias(cKrb5Principal, "name", "principal");
263
+ }