ruby-ldap 0.9.9

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.
@@ -0,0 +1,129 @@
1
+ # Manipulation of LDAP schema data.
2
+ #
3
+ #--
4
+ # $Id: schema.rb,v 1.9 2006/02/08 23:15:17 ianmacd Exp $
5
+ #++
6
+
7
+ # The LDAP module encapsulates the various LDAP-related classes in their own
8
+ # namespace.
9
+ #
10
+ module LDAP
11
+
12
+ # Retrieve and process information pertaining to LDAP schemas.
13
+ #
14
+ class Schema < Hash
15
+
16
+ def initialize(entry)
17
+ if( entry )
18
+ entry.each{|key,vals|
19
+ self[key] = vals
20
+ }
21
+ end
22
+ end
23
+
24
+ # Return the list of values related to the schema component given in
25
+ # +key+. See LDAP::Conn#schema for common values of +key+.
26
+ #
27
+ def names(key)
28
+ self[key].collect{|val| val =~ /NAME\s+'([\w\d_\-]+)'/; $1}
29
+ end
30
+
31
+ # Return the list of attributes in object class +oc+ that are of category
32
+ # +at+. +at+ may be the string *MUST*, *MAY* or *SUP*.
33
+ #
34
+ def attr(oc,at)
35
+ self['objectClasses'].each{|s|
36
+ if( s =~ /NAME\s+'#{oc}'/ )
37
+ case s
38
+ when /#{at}\s+\(([\w\d_\-\s\$]+)\)/i then return $1.split("$").collect{|attr| attr.strip}
39
+ when /#{at}\s+([\w\d_\-]+)/i then return $1.split("$").collect{|attr| attr.strip}
40
+ end
41
+ end
42
+ }
43
+ return nil
44
+ end
45
+
46
+ # Return the list of attributes that an entry with object class +oc+
47
+ # _must_ possess.
48
+ #
49
+ def must(oc)
50
+ attr(oc, "MUST")
51
+ end
52
+
53
+ # Return the list of attributes that an entry with object class +oc+
54
+ # _may_ possess.
55
+ #
56
+ def may(oc)
57
+ attr(oc, "MAY")
58
+ end
59
+
60
+ # Return the superior object class of object class +oc+.
61
+ #
62
+ def sup(oc)
63
+ attr(oc, "SUP")
64
+ end
65
+ end
66
+
67
+ class Conn
68
+
69
+ # Fetch the schema data for the connection.
70
+ #
71
+ # If +base+ is given, it gives the base DN for the search. +attrs+, if
72
+ # given, is an array of attributes that should be returned from the
73
+ # server. The default list is *objectClasses*, *attributeTypes*,
74
+ # *matchingRules*, *matchingRuleUse*, *dITStructureRules*,
75
+ # *dITContentRules*, *nameForms* and *ldapSyntaxes*.
76
+ #
77
+ # +sec+ and +usec+ can be used to specify a time-out for the search in
78
+ # seconds and microseconds, respectively.
79
+ #
80
+ def schema(base = nil, attrs = nil, sec = 0, usec = 0)
81
+ attrs ||= [
82
+ 'objectClasses',
83
+ 'attributeTypes',
84
+ 'matchingRules',
85
+ 'matchingRuleUse',
86
+ 'dITStructureRules',
87
+ 'dITContentRules',
88
+ 'nameForms',
89
+ 'ldapSyntaxes',
90
+ ]
91
+ base ||= root_dse(['subschemaSubentry'], sec, usec)[0]['subschemaSubentry'][0]
92
+ base ||= 'cn=schema'
93
+ ent = search2(base, LDAP_SCOPE_BASE, '(objectClass=subschema)',
94
+ attrs, false, sec, usec)
95
+ return Schema.new(ent[0])
96
+ end
97
+
98
+ # Fetch the root DSE (DSA-specific Entry) for the connection. DSA stands
99
+ # for Directory System Agent and simply refers to the LDAP server you are
100
+ # using.
101
+ #
102
+ # +attrs+, if given, is an array of attributes that should be returned
103
+ # from the server. The default list is *subschemaSubentry*,
104
+ # *namingContexts*, *monitorContext*, *altServer*, *supportedControl*,
105
+ # *supportedExtension*, *supportedFeatures*, *supportedSASLMechanisms*
106
+ # and *supportedLDAPVersion*.
107
+ #
108
+ # +sec+ and +usec+ can be used to specify a time-out for the search in
109
+ # seconds and microseconds, respectively.
110
+ #
111
+ def root_dse(attrs = nil, sec = 0, usec = 0)
112
+ attrs ||= [
113
+ 'subschemaSubentry',
114
+ 'namingContexts',
115
+ 'monitorContext',
116
+ 'altServer',
117
+ 'supportedControl',
118
+ 'supportedExtension',
119
+ 'supportedFeatures',
120
+ 'supportedSASLMechanisms',
121
+ 'supportedLDAPVersion',
122
+ ]
123
+
124
+ entries = search2('', LDAP_SCOPE_BASE, '(objectClass=*)',
125
+ attrs, false, sec, usec)
126
+ return entries
127
+ end
128
+ end
129
+ end
data/misc.c ADDED
@@ -0,0 +1,512 @@
1
+ /* -*- C -*-
2
+ * $Id: misc.c,v 1.11 2006/07/03 22:54:52 ianmacd Exp $
3
+ */
4
+
5
+ #include "ruby.h"
6
+ #include "rbldap.h"
7
+
8
+ VALUE rb_sLDAP_APIInfo;
9
+ VALUE rb_cLDAP_Control;
10
+
11
+ #ifdef LDAP_OPT_API_INFO
12
+ VALUE
13
+ rb_ldap_apiinfo_new (LDAPAPIInfo * info)
14
+ {
15
+ VALUE info_version, api_version, protocol_version;
16
+ VALUE extensions, vendor_name, vendor_version;
17
+ int i;
18
+
19
+ info_version = INT2NUM (info->ldapai_info_version);
20
+ api_version = INT2NUM (info->ldapai_api_version);
21
+ protocol_version = INT2NUM (info->ldapai_protocol_version);
22
+ vendor_version = INT2NUM (info->ldapai_vendor_version);
23
+ vendor_name = rb_tainted_str_new2 (info->ldapai_vendor_name);
24
+ extensions = rb_ary_new ();
25
+
26
+ for (i = 0; info->ldapai_extensions[i]; i++)
27
+ {
28
+ rb_ary_push (extensions,
29
+ rb_tainted_str_new2 (info->ldapai_extensions[i]));
30
+ }
31
+
32
+ return rb_struct_new (rb_sLDAP_APIInfo,
33
+ info_version, api_version, protocol_version,
34
+ extensions, vendor_name, vendor_version, 0);
35
+ }
36
+
37
+ LDAPAPIInfo *
38
+ rb_ldap_get_apiinfo (VALUE data)
39
+ {
40
+ LDAPAPIInfo *info;
41
+ VALUE r_extensions;
42
+ int len, i;
43
+ char **c_extensions;
44
+
45
+ if (data == Qnil)
46
+ return NULL;
47
+
48
+ info = ALLOC_N (LDAPAPIInfo, 1);
49
+ info->ldapai_info_version =
50
+ FIX2INT (rb_struct_getmember (data, rb_intern ("info_version")));
51
+ info->ldapai_api_version =
52
+ FIX2INT (rb_struct_getmember (data, rb_intern ("api_version")));
53
+ info->ldapai_protocol_version =
54
+ FIX2INT (rb_struct_getmember (data, rb_intern ("protocol_version")));
55
+ r_extensions = rb_struct_getmember (data, rb_intern ("extensions"));
56
+ len = RARRAY_LEN (r_extensions);
57
+ c_extensions = ALLOCA_N (char *, len);
58
+ for (i = 0; i <= len - 1; i++)
59
+ {
60
+ VALUE str = RARRAY_PTR (r_extensions)[i];
61
+ RB_LDAP_SET_STR (c_extensions[i], str);
62
+ }
63
+ info->ldapai_extensions = c_extensions;
64
+ RB_LDAP_SET_STR (info->ldapai_vendor_name,
65
+ rb_struct_getmember (data, rb_intern ("vendor_name")));
66
+ info->ldapai_vendor_version =
67
+ FIX2INT (rb_struct_getmember (data, rb_intern ("vendor_version")));
68
+
69
+ return info;
70
+ }
71
+ #endif /* LDAP_OPT_API_INFO */
72
+
73
+ #ifdef HAVE_LDAPCONTROL
74
+ static void
75
+ rb_ldap_control_free (LDAPControl * ctl)
76
+ {
77
+ if (ctl)
78
+ {
79
+ if (ctl->ldctl_value.bv_val)
80
+ xfree (ctl->ldctl_value.bv_val);
81
+ if (ctl->ldctl_oid)
82
+ xfree (ctl->ldctl_oid);
83
+ xfree (ctl);
84
+ }
85
+ }
86
+
87
+ VALUE
88
+ rb_ldap_control_new (LDAPControl * ctl)
89
+ {
90
+ if (!ctl)
91
+ return Qnil;
92
+ else
93
+ return Data_Wrap_Struct (rb_cLDAP_Control, 0, rb_ldap_control_free, ctl);
94
+ }
95
+
96
+ /* Identical to rb_ldap_control_new, but does not define a routine with which
97
+ to free memory. This should be called only by rb_ldap_parse_result().
98
+ */
99
+ VALUE
100
+ rb_ldap_control_new2 (LDAPControl * ctl)
101
+ {
102
+ if (!ctl)
103
+ return Qnil;
104
+ else
105
+ return Data_Wrap_Struct (rb_cLDAP_Control, 0, 0, ctl);
106
+ }
107
+
108
+ /* This is called by #initialize_copy and is using for duping/cloning. */
109
+ VALUE
110
+ rb_ldap_control_copy (VALUE copy, VALUE orig)
111
+ {
112
+ LDAPControl *orig_ctl, *copy_ctl;
113
+
114
+ Data_Get_Struct (orig, LDAPControl, orig_ctl);
115
+ Data_Get_Struct (copy, LDAPControl, copy_ctl);
116
+ memcpy (copy_ctl, orig_ctl, (size_t) sizeof (LDAPControl));
117
+
118
+ return copy;
119
+ }
120
+
121
+ static VALUE
122
+ rb_ldap_control_s_allocate (VALUE klass)
123
+ {
124
+ LDAPControl *ctl;
125
+
126
+ ctl = ALLOC_N (LDAPControl, 1);
127
+ ctl->ldctl_value.bv_val = NULL;
128
+ ctl->ldctl_value.bv_len = 0;
129
+ ctl->ldctl_oid = NULL;
130
+ ctl->ldctl_iscritical = 0;
131
+ return Data_Wrap_Struct (klass, 0, rb_ldap_control_free, ctl);
132
+ }
133
+
134
+ #if RUBY_VERSION_CODE < 170
135
+ static VALUE
136
+ rb_ldap_control_s_new (int argc, VALUE argv[], VALUE klass)
137
+ {
138
+ VALUE obj;
139
+
140
+ obj = rb_ldap_control_s_allocate (klass);
141
+ rb_obj_call_init (obj, argc, argv);
142
+
143
+ return obj;
144
+ }
145
+ #endif
146
+
147
+ static VALUE
148
+ rb_ldap_control_set_value (VALUE self, VALUE val)
149
+ {
150
+ LDAPControl *ctl;
151
+
152
+ Data_Get_Struct (self, LDAPControl, ctl);
153
+
154
+ if (ctl->ldctl_value.bv_val)
155
+ free (ctl->ldctl_value.bv_val);
156
+
157
+ if (val == Qnil)
158
+ {
159
+ ctl->ldctl_value.bv_val = NULL;
160
+ ctl->ldctl_value.bv_len = 0;
161
+ }
162
+ else
163
+ {
164
+ RB_LDAP_SET_STR (ctl->ldctl_value.bv_val, val);
165
+ ctl->ldctl_value.bv_len = RSTRING_LEN (val);
166
+ }
167
+
168
+ return val;
169
+ }
170
+
171
+ static VALUE
172
+ rb_ldap_control_get_value (VALUE self)
173
+ {
174
+ LDAPControl *ctl;
175
+ VALUE val;
176
+
177
+ Data_Get_Struct (self, LDAPControl, ctl);
178
+
179
+ if (ctl->ldctl_value.bv_len == 0 || ctl->ldctl_value.bv_val == NULL)
180
+ {
181
+ val = Qnil;
182
+ }
183
+ else
184
+ {
185
+ val =
186
+ rb_tainted_str_new (ctl->ldctl_value.bv_val, ctl->ldctl_value.bv_len);
187
+ }
188
+
189
+ return val;
190
+ }
191
+
192
+ /*
193
+ * Document-method: value
194
+ *
195
+ * call-seq:
196
+ * ctrl.value => String or nil
197
+ *
198
+ * Return the value of the control.
199
+ */
200
+
201
+ /*
202
+ * Document-method: value=
203
+ *
204
+ * call-seq:
205
+ * ctrl.value=(val) => val
206
+ *
207
+ * Set the value of the control.
208
+ */
209
+ static VALUE
210
+ rb_ldap_control_value (int argc, VALUE argv[], VALUE self)
211
+ {
212
+ VALUE val;
213
+
214
+ if (rb_scan_args (argc, argv, "01", &val) == 1)
215
+ val = rb_ldap_control_set_value (self, val);
216
+ else
217
+ val = rb_ldap_control_get_value (self);
218
+ return val;
219
+ }
220
+
221
+ static VALUE
222
+ rb_ldap_control_set_oid (VALUE self, VALUE val)
223
+ {
224
+ LDAPControl *ctl;
225
+
226
+ Data_Get_Struct (self, LDAPControl, ctl);
227
+
228
+ if (ctl->ldctl_oid)
229
+ free (ctl->ldctl_oid);
230
+
231
+ if (val == Qnil)
232
+ {
233
+ ctl->ldctl_oid = NULL;
234
+ }
235
+ else
236
+ {
237
+ RB_LDAP_SET_STR (ctl->ldctl_oid, val);
238
+ }
239
+
240
+ return val;
241
+ }
242
+
243
+ static VALUE
244
+ rb_ldap_control_get_oid (VALUE self)
245
+ {
246
+ LDAPControl *ctl;
247
+ VALUE val;
248
+
249
+ Data_Get_Struct (self, LDAPControl, ctl);
250
+
251
+ if (ctl->ldctl_oid == NULL)
252
+ {
253
+ val = Qnil;
254
+ }
255
+ else
256
+ {
257
+ val = rb_tainted_str_new2 (ctl->ldctl_oid);
258
+ }
259
+
260
+ return val;
261
+ }
262
+
263
+ /*
264
+ * Document-method: oid
265
+ *
266
+ * call-seq:
267
+ * ctrl.oid => String or nil
268
+ *
269
+ * Return the OID of the control.
270
+ */
271
+
272
+ /*
273
+ * Document-method: oid=
274
+ *
275
+ * call-seq:
276
+ * ctrl.oid=(oid) => oid
277
+ *
278
+ * Set the OID of the control.
279
+ */
280
+ static VALUE
281
+ rb_ldap_control_oid (int argc, VALUE argv[], VALUE self)
282
+ {
283
+ VALUE val;
284
+ LDAPControl *ctl;
285
+
286
+ Data_Get_Struct (self, LDAPControl, ctl);
287
+ if (rb_scan_args (argc, argv, "01", &val) == 1)
288
+ {
289
+ val = rb_ldap_control_set_oid (self, val);
290
+ }
291
+ else
292
+ {
293
+ val = rb_ldap_control_get_oid (self);
294
+ }
295
+ return val;
296
+ }
297
+
298
+ static VALUE
299
+ rb_ldap_control_set_critical (VALUE self, VALUE val)
300
+ {
301
+ LDAPControl *ctl;
302
+
303
+ Data_Get_Struct (self, LDAPControl, ctl);
304
+ ctl->ldctl_iscritical = (val == Qtrue) ? 1 : 0;
305
+ return val;
306
+ }
307
+
308
+ static VALUE
309
+ rb_ldap_control_get_critical (VALUE self)
310
+ {
311
+ LDAPControl *ctl;
312
+ VALUE val;
313
+
314
+ Data_Get_Struct (self, LDAPControl, ctl);
315
+ val = ctl->ldctl_iscritical ? Qtrue : Qfalse;
316
+
317
+ return val;
318
+ }
319
+
320
+ /*
321
+ * Document-method: critical
322
+ *
323
+ * call-seq:
324
+ * ctrl.critical => true or false
325
+ * ctrl.critical? => true or false
326
+ * ctrl.iscritical => true or false
327
+ *
328
+ * Return the criticality of the control.
329
+ */
330
+
331
+ /*
332
+ * Document-method: critical=
333
+ *
334
+ * call-seq:
335
+ * ctrl.critical=(val) => val
336
+ * ctrl.iscritical=(val) => val
337
+ *
338
+ * Set the criticality of the control. +val+ should be *true* or *false*.
339
+ */
340
+ static VALUE
341
+ rb_ldap_control_critical (int argc, VALUE argv[], VALUE self)
342
+ {
343
+ VALUE val;
344
+ LDAPControl *ctl;
345
+
346
+ Data_Get_Struct (self, LDAPControl, ctl);
347
+ if (rb_scan_args (argc, argv, "01", &val) == 1)
348
+ {
349
+ val = rb_ldap_control_set_critical (self, val);
350
+ }
351
+ else
352
+ {
353
+ val = rb_ldap_control_get_critical (self);
354
+ }
355
+ return val;
356
+ }
357
+
358
+ /*
359
+ * Document-method: new
360
+ *
361
+ * call-seq:
362
+ * LDAP::Control.new(oid, value, criticality) => LDAP::Control
363
+ *
364
+ * Create a new LDAP::Control. +oid+ is the OID of the control, +value+ is the
365
+ * value to be assigned to the control, and +criticality+ is the criticality
366
+ * of the control, which should be *true* or *false*.
367
+ */
368
+ static VALUE
369
+ rb_ldap_control_initialize (int argc, VALUE argv[], VALUE self)
370
+ {
371
+ VALUE oid, value, critical;
372
+
373
+ switch (rb_scan_args (argc, argv, "03", &oid, &value, &critical))
374
+ {
375
+ case 3:
376
+ rb_ldap_control_set_critical (self, critical);
377
+ case 2:
378
+ rb_ldap_control_set_value (self, value);
379
+ case 1:
380
+ rb_ldap_control_set_oid (self, oid);
381
+ default:
382
+ break;
383
+ }
384
+
385
+ return Qnil;
386
+ }
387
+
388
+ /*
389
+ * call-seq:
390
+ * ctrl.inspect => String
391
+ *
392
+ * Produce a concise representation of the control.
393
+ */
394
+ static VALUE
395
+ rb_ldap_control_inspect (VALUE self)
396
+ {
397
+ VALUE str;
398
+
399
+ str = rb_tainted_str_new2 ("#<");
400
+ rb_str_cat2 (str, rb_class2name (CLASS_OF (self)));
401
+ rb_str_cat2 (str, " oid=");
402
+ rb_str_concat (str, rb_inspect (rb_ldap_control_get_oid (self)));
403
+ rb_str_cat2 (str, " value=");
404
+ rb_str_concat (str, rb_inspect (rb_ldap_control_get_value (self)));
405
+ rb_str_cat2 (str, " iscritical=");
406
+ rb_str_concat (str, rb_inspect (rb_ldap_control_get_critical (self)));
407
+ rb_str_cat2 (str, ">");
408
+
409
+ return str;
410
+ }
411
+
412
+ VALUE
413
+ rb_ldap_controls_new (LDAPControl ** ctrls)
414
+ {
415
+ int i;
416
+ VALUE ary;
417
+
418
+ if (!ctrls)
419
+ return Qnil;
420
+
421
+ ary = rb_ary_new ();
422
+ for (i = 0; ctrls[i]; i++)
423
+ rb_ary_push (ary, rb_ldap_control_new (ctrls[i]));
424
+
425
+ return ary;
426
+ }
427
+
428
+ LDAPControl *
429
+ rb_ldap_get_control (VALUE obj)
430
+ {
431
+ LDAPControl *ctl;
432
+
433
+ if (obj == Qnil)
434
+ {
435
+ return NULL;
436
+ }
437
+ else
438
+ {
439
+ Data_Get_Struct (obj, LDAPControl, ctl);
440
+ return ctl;
441
+ }
442
+ }
443
+
444
+ LDAPControl **
445
+ rb_ldap_get_controls (VALUE data)
446
+ {
447
+ LDAPControl **ctls;
448
+ int len, i;
449
+
450
+ if (data == Qnil)
451
+ return NULL;
452
+
453
+ Check_Type (data, T_ARRAY);
454
+ len = RARRAY_LEN (data);
455
+ ctls = ALLOC_N (LDAPControl *, len + 1);
456
+ for (i = 0; i < len; i++)
457
+ {
458
+ ctls[i] = rb_ldap_get_control (rb_ary_entry (data, i));
459
+ }
460
+ ctls[len] = NULL;
461
+
462
+ return ctls;
463
+ }
464
+ #endif
465
+
466
+ /* Document-class: LDAP::Control
467
+ *
468
+ * Create, manipulate and inspect LDAP controls.
469
+ */
470
+ void
471
+ Init_ldap_misc ()
472
+ {
473
+ rb_sLDAP_APIInfo = rb_struct_define ("APIInfo", "info_version", /* ldapai_xxxx */
474
+ "api_version",
475
+ "protocol_version",
476
+ "extensions",
477
+ "vendor_name", "vendor_version", NULL);
478
+ rb_define_const (rb_mLDAP, "APIInfo", rb_sLDAP_APIInfo);
479
+
480
+ #ifdef HAVE_LDAPCONTROL
481
+ rb_cLDAP_Control = rb_define_class_under (rb_mLDAP, "Control", rb_cObject);
482
+ #if RUBY_VERSION_CODE < 170
483
+ rb_define_singleton_method (rb_cLDAP_Control, "new",
484
+ rb_ldap_control_s_new, -1);
485
+ #endif
486
+ #if RUBY_VERSION_CODE >= 173
487
+ rb_define_alloc_func (rb_cLDAP_Control, rb_ldap_control_s_allocate);
488
+ #else
489
+ rb_define_singleton_method (rb_cLDAP_Control, "allocate",
490
+ rb_ldap_control_s_allocate, 0);
491
+ #endif
492
+ rb_define_method (rb_cLDAP_Control, "initialize",
493
+ rb_ldap_control_initialize, -1);
494
+ rb_define_method (rb_cLDAP_Control, "initialize_copy", rb_ldap_control_copy,
495
+ 1);
496
+ rb_define_method (rb_cLDAP_Control, "inspect", rb_ldap_control_inspect, 0);
497
+ rb_define_method (rb_cLDAP_Control, "oid", rb_ldap_control_oid, -1);
498
+ rb_define_method (rb_cLDAP_Control, "oid=", rb_ldap_control_oid, -1);
499
+ rb_define_method (rb_cLDAP_Control, "value", rb_ldap_control_value, -1);
500
+ rb_define_method (rb_cLDAP_Control, "value=", rb_ldap_control_value, -1);
501
+ rb_define_method (rb_cLDAP_Control, "critical?", rb_ldap_control_critical,
502
+ -1);
503
+ rb_define_method (rb_cLDAP_Control, "critical", rb_ldap_control_critical,
504
+ -1);
505
+ rb_define_method (rb_cLDAP_Control, "critical=", rb_ldap_control_critical,
506
+ -1);
507
+ rb_define_method (rb_cLDAP_Control, "iscritical", rb_ldap_control_critical,
508
+ -1);
509
+ rb_define_method (rb_cLDAP_Control, "iscritical=", rb_ldap_control_critical,
510
+ -1);
511
+ #endif
512
+ }