ruby-ldap 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }