rldap 0.0.3 → 0.0.4
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/.gitignore +9 -0
- data/Gemfile +5 -0
- data/README.md +16 -0
- data/Rakefile +2 -11
- data/ext/extconf.rb +5 -4
- data/ext/ldap.c +206 -80
- data/lib/ldap/version.rb +1 -1
- data/rldap.gemspec +21 -0
- metadata +25 -7
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
RLDAP
|
2
|
+
=====
|
3
|
+
|
4
|
+
RLDAP is a Ruby wrapper for the C OpenLDAP API.
|
5
|
+
|
6
|
+
Meta
|
7
|
+
----
|
8
|
+
|
9
|
+
* Code: `git clone git://github.com/dvyjones/rldap.git`
|
10
|
+
* Home: <http://github.com/dvyjones/rldap/>
|
11
|
+
* Bugs: <http://github.com/dvyjones/rldap/issues>
|
12
|
+
* Gems: <http://rubygems.org/gems/rldap>
|
13
|
+
|
14
|
+
The project uses [Semantic Versioning][sv].
|
15
|
+
|
16
|
+
[sv]: http://semver.org
|
data/Rakefile
CHANGED
@@ -1,11 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'ldap/version'
|
4
|
-
|
5
|
-
sh "gem build rldap.gemspec"
|
6
|
-
sh "gem push rldap-#{LDAP::Version}.gem"
|
7
|
-
sh "git tag v#{LDAP::Version}"
|
8
|
-
sh "git push origin v#{LDAP::Version}"
|
9
|
-
sh "git push origin master"
|
10
|
-
sh "git clean -fd"
|
11
|
-
end
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
data/ext/extconf.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
have_library('ldap')
|
4
|
-
|
3
|
+
unless have_library('ldap') && have_library('lber') && have_header('ldap.h') && have_header('lber.h')
|
4
|
+
abort 'You need to have libldap and liblber installed.'
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
have_header('
|
7
|
+
have_func('ldap_sasl_interactive_bind_s')
|
8
|
+
have_header('sasl.h') || have_header('sasl/sasl.h')
|
8
9
|
|
9
10
|
create_makefile('ldap')
|
data/ext/ldap.c
CHANGED
@@ -10,6 +10,12 @@
|
|
10
10
|
#include <lber.h>
|
11
11
|
#include <stdlib.h>
|
12
12
|
|
13
|
+
#ifdef HAVE_SASL_H
|
14
|
+
#include <sasl.h>
|
15
|
+
#elif defined(HAVE_SASL_SASL_H)
|
16
|
+
#include <sasl/sasl.h>
|
17
|
+
#endif
|
18
|
+
|
13
19
|
static VALUE cLDAP;
|
14
20
|
static VALUE cLDAP_Message;
|
15
21
|
static VALUE eLDAP;
|
@@ -18,11 +24,6 @@ typedef struct {
|
|
18
24
|
LDAP *ld;
|
19
25
|
} RLDAP_WRAP;
|
20
26
|
|
21
|
-
typedef struct {
|
22
|
-
LDAP *ld;
|
23
|
-
LDAPMessage *mesg;
|
24
|
-
} RLDAP_MSG_WRAP;
|
25
|
-
|
26
27
|
static RLDAP_WRAP *get_wrapper(VALUE obj)
|
27
28
|
{
|
28
29
|
RLDAP_WRAP *wrapper;
|
@@ -30,27 +31,12 @@ static RLDAP_WRAP *get_wrapper(VALUE obj)
|
|
30
31
|
return wrapper;
|
31
32
|
}
|
32
33
|
|
33
|
-
static RLDAP_MSG_WRAP *get_msg_wrapper(VALUE obj)
|
34
|
-
{
|
35
|
-
RLDAP_MSG_WRAP* wrapper;
|
36
|
-
Data_Get_Struct(obj, RLDAP_MSG_WRAP, wrapper);
|
37
|
-
return wrapper;
|
38
|
-
}
|
39
|
-
|
40
34
|
static void free_wrapper(RLDAP_WRAP *wrapper)
|
41
35
|
{
|
42
36
|
ldap_memfree(wrapper->ld);
|
43
37
|
free(wrapper);
|
44
38
|
}
|
45
39
|
|
46
|
-
static void free_msg_wrapper(RLDAP_MSG_WRAP *wrapper)
|
47
|
-
{
|
48
|
-
if (wrapper->mesg != NULL)
|
49
|
-
ldap_msgfree(wrapper->mesg);
|
50
|
-
wrapper->ld = NULL;
|
51
|
-
free(wrapper);
|
52
|
-
}
|
53
|
-
|
54
40
|
static void rldap_raise(int errno)
|
55
41
|
{
|
56
42
|
VALUE e = rb_exc_new2(eLDAP, ldap_err2string(errno));
|
@@ -172,8 +158,6 @@ static VALUE rldap_search(int argc, VALUE *argv, VALUE obj)
|
|
172
158
|
msg = ldap_next_entry(wrapper->ld, msg);
|
173
159
|
}
|
174
160
|
|
175
|
-
|
176
|
-
|
177
161
|
return ary;
|
178
162
|
}
|
179
163
|
|
@@ -249,94 +233,233 @@ static VALUE rldap_inspect(VALUE obj)
|
|
249
233
|
return ret;
|
250
234
|
}
|
251
235
|
|
236
|
+
static VALUE rldap_bind(int argc, VALUE *argv, VALUE obj)
|
237
|
+
{
|
238
|
+
RLDAP_WRAP *wrapper;
|
239
|
+
char *bind_dn = NULL, *bind_password = NULL;
|
240
|
+
int retval;
|
241
|
+
VALUE rdn, rpassword;
|
242
|
+
|
243
|
+
rb_scan_args(argc, argv, "02", &rdn, &rpassword);
|
244
|
+
|
245
|
+
if (NIL_P(rdn))
|
246
|
+
bind_dn = NULL;
|
247
|
+
else
|
248
|
+
bind_dn = StringValuePtr(rdn);
|
249
|
+
if (NIL_P(rpassword))
|
250
|
+
bind_password = NULL;
|
251
|
+
else
|
252
|
+
bind_password = StringValuePtr(rpassword);
|
253
|
+
|
254
|
+
wrapper = get_wrapper(obj);
|
252
255
|
|
253
|
-
|
256
|
+
retval = ldap_bind_s(wrapper->ld, bind_dn, bind_password, LDAP_AUTH_SIMPLE);
|
257
|
+
|
258
|
+
if (retval != LDAP_SUCCESS)
|
259
|
+
rldap_raise(retval);
|
260
|
+
else
|
261
|
+
return Qtrue;
|
262
|
+
}
|
254
263
|
|
255
|
-
static VALUE
|
264
|
+
static VALUE rldap_unbind(VALUE obj)
|
256
265
|
{
|
257
|
-
|
258
|
-
|
266
|
+
RLDAP_WRAP *wrapper;
|
267
|
+
int retval;
|
268
|
+
|
269
|
+
wrapper = get_wrapper(obj);
|
270
|
+
retval = ldap_unbind_s(wrapper->ld);
|
271
|
+
if (retval != LDAP_SUCCESS)
|
272
|
+
rldap_raise(retval);
|
273
|
+
else
|
274
|
+
return Qtrue;
|
275
|
+
}
|
259
276
|
|
260
|
-
|
261
|
-
wrapper->mesg = msg;
|
262
|
-
wrapper->ld = ld;
|
277
|
+
#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
|
263
278
|
|
264
|
-
|
279
|
+
typedef struct {
|
280
|
+
char *mech;
|
281
|
+
char *realm;
|
282
|
+
char *authcid;
|
283
|
+
char *passwd;
|
284
|
+
char *authzid;
|
285
|
+
} RLDAP_BICTX;
|
286
|
+
|
287
|
+
static RLDAP_BICTX *_rldap_sasl_setdefs(LDAP *ld, char *sasl_mech, char *sasl_realm, char *sasl_authc_id, char *passwd, char *sasl_authz_id)
|
288
|
+
{
|
289
|
+
RLDAP_BICTX *ctx;
|
290
|
+
|
291
|
+
ctx = ber_memalloc(sizeof(RLDAP_BICTX));
|
292
|
+
ctx->mech = (sasl_mech) ? ber_strdup(sasl_mech) : NULL;
|
293
|
+
ctx->realm = (sasl_realm) ? ber_strdup(sasl_realm) : NULL;
|
294
|
+
ctx->authcid = (sasl_authc_id) ? ber_strdup(sasl_authc_id) : NULL;
|
295
|
+
ctx->passwd = (passwd) ? ber_strdup(passwd) : NULL;
|
296
|
+
ctx->authzid = (sasl_authz_id) ? ber_strdup(sasl_authz_id) : NULL;
|
297
|
+
|
298
|
+
if (ctx->mech == NULL) {
|
299
|
+
ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &ctx->mech);
|
300
|
+
}
|
301
|
+
if (ctx->realm == NULL) {
|
302
|
+
ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &ctx->realm);
|
303
|
+
}
|
304
|
+
if (ctx->authcid == NULL) {
|
305
|
+
ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &ctx->authcid);
|
306
|
+
}
|
307
|
+
if (ctx->authzid == NULL) {
|
308
|
+
ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &ctx->authzid);
|
309
|
+
}
|
310
|
+
|
311
|
+
return ctx;
|
265
312
|
}
|
266
313
|
|
267
|
-
static
|
314
|
+
static void _rldap_sasl_freedefs(RLDAP_BICTX *ctx)
|
268
315
|
{
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
dn = ldap_get_dn(wrapper->ld, wrapper->mesg);
|
276
|
-
rdn = rb_str_new2(dn);
|
277
|
-
ldap_memfree(dn);
|
278
|
-
|
279
|
-
return rdn;
|
316
|
+
if (ctx->mech) ber_memfree(ctx->mech);
|
317
|
+
if (ctx->realm) ber_memfree(ctx->realm);
|
318
|
+
if (ctx->authcid) ber_memfree(ctx->authcid);
|
319
|
+
if (ctx->passwd) ber_memfree(ctx->passwd);
|
320
|
+
if (ctx->authzid) ber_memfree(ctx->authzid);
|
321
|
+
ber_memfree(ctx);
|
280
322
|
}
|
281
323
|
|
282
|
-
static
|
324
|
+
static int _rldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *in)
|
283
325
|
{
|
284
|
-
|
285
|
-
char *
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
326
|
+
sasl_interact_t *interact = in;
|
327
|
+
const char *p;
|
328
|
+
RLDAP_BICTX *ctx = defaults;
|
329
|
+
|
330
|
+
for (;interact->id != SASL_CB_LIST_END;interact++) {
|
331
|
+
p = interact->defresult;
|
332
|
+
switch(interact->id) {
|
333
|
+
case SASL_CB_GETREALM:
|
334
|
+
p = ctx->realm;
|
335
|
+
break;
|
336
|
+
case SASL_CB_AUTHNAME:
|
337
|
+
p = ctx->authcid;
|
338
|
+
break;
|
339
|
+
case SASL_CB_USER:
|
340
|
+
p = ctx->authzid;
|
341
|
+
break;
|
342
|
+
case SASL_CB_PASS:
|
343
|
+
p = ctx->passwd;
|
344
|
+
break;
|
345
|
+
}
|
346
|
+
if (p) {
|
347
|
+
interact->result = p;
|
348
|
+
interact->len = strlen(p);
|
349
|
+
}
|
350
|
+
}
|
351
|
+
return LDAP_SUCCESS;
|
352
|
+
}
|
353
|
+
|
354
|
+
static VALUE rldap_sasl_bind(int argc, VALUE *argv, VALUE obj)
|
355
|
+
{
|
356
|
+
RLDAP_WRAP *wrapper;
|
357
|
+
char *bind_dn = NULL, *passwd = NULL, *sasl_mech = NULL,
|
358
|
+
*sasl_realm = NULL, *sasl_authz_id = NULL, *sasl_authc_id = NULL;
|
359
|
+
VALUE rbind_dn, rpasswd, rsasl_mech, rsasl_realm,
|
360
|
+
rsasl_authz_id, rsasl_authc_id, rprops;
|
361
|
+
int retval;
|
362
|
+
RLDAP_BICTX *ctx;
|
290
363
|
|
291
|
-
wrapper =
|
292
|
-
|
364
|
+
wrapper = get_wrapper(obj);
|
365
|
+
rb_scan_args(argc, argv, "07", &rbind_dn, &rpasswd, &rsasl_mech, &rsasl_realm, &rsasl_authz_id, &rsasl_authc_id, &rprops);
|
293
366
|
|
294
|
-
|
295
|
-
|
296
|
-
if (values == NULL) {
|
297
|
-
rldap_raise(rldap_errno_c(obj));
|
298
|
-
}
|
367
|
+
if (!NIL_P(rprops))
|
368
|
+
ldap_set_option(wrapper->ld, LDAP_OPT_X_SASL_SECPROPS, StringValuePtr(rprops));
|
299
369
|
|
300
|
-
|
301
|
-
|
370
|
+
if (!NIL_P(rbind_dn))
|
371
|
+
bind_dn = StringValuePtr(rbind_dn);
|
372
|
+
if (!NIL_P(rpasswd))
|
373
|
+
passwd = StringValuePtr(rpasswd);
|
374
|
+
if (!NIL_P(rsasl_mech))
|
375
|
+
sasl_mech = StringValuePtr(rsasl_mech);
|
376
|
+
if (!NIL_P(rsasl_realm))
|
377
|
+
sasl_realm = StringValuePtr(rsasl_realm);
|
378
|
+
if (!NIL_P(rsasl_authz_id))
|
379
|
+
sasl_authz_id = StringValuePtr(rsasl_authz_id);
|
380
|
+
if (!NIL_P(rsasl_authc_id))
|
381
|
+
sasl_authc_id = StringValuePtr(rsasl_authc_id);
|
302
382
|
|
303
|
-
|
304
|
-
value = values[i];
|
305
|
-
str = rb_str_new(value->bv_val, value->bv_len);
|
306
|
-
rb_ary_push(ary, str);
|
307
|
-
}
|
383
|
+
ctx = _rldap_sasl_setdefs(wrapper->ld, sasl_mech, sasl_realm, sasl_authc_id, passwd, sasl_authz_id);
|
308
384
|
|
309
|
-
|
385
|
+
retval = ldap_sasl_interactive_bind_s(wrapper->ld, bind_dn, ctx->mech, NULL, NULL, LDAP_SASL_AUTOMATIC, _rldap_sasl_interact, ctx);
|
310
386
|
|
311
|
-
|
387
|
+
_rldap_sasl_freedefs(ctx);
|
388
|
+
|
389
|
+
if (retval != LDAP_SUCCESS)
|
390
|
+
rldap_raise(retval);
|
391
|
+
else
|
392
|
+
return Qtrue;
|
312
393
|
}
|
313
394
|
|
314
|
-
|
395
|
+
#endif
|
396
|
+
|
397
|
+
/* class LDAP::Message */
|
398
|
+
|
399
|
+
static VALUE ldapmessage2obj(LDAP *ld, LDAPMessage *msg)
|
315
400
|
{
|
316
|
-
|
317
|
-
|
401
|
+
VALUE obj;
|
402
|
+
|
403
|
+
char *dn, *attr;
|
318
404
|
BerElement *ber;
|
319
|
-
|
405
|
+
BerValue **values;
|
406
|
+
BerValue *value;
|
407
|
+
VALUE rdn, attrs, ary, str;
|
408
|
+
int length, i;
|
320
409
|
|
321
|
-
|
410
|
+
obj = rb_class_new_instance(0, NULL, cLDAP_Message);
|
411
|
+
|
412
|
+
// Set the DN
|
413
|
+
dn = ldap_get_dn(ld, msg);
|
414
|
+
rdn = rb_str_new2(dn);
|
415
|
+
ldap_memfree(dn);
|
416
|
+
rb_iv_set(obj, "@dn", rdn);
|
417
|
+
|
418
|
+
// Set the attributes
|
419
|
+
attrs = rb_hash_new();
|
420
|
+
attr = ldap_first_attribute(ld, msg, &ber);
|
421
|
+
do {
|
422
|
+
values = ldap_get_values_len(ld, msg, attr);
|
322
423
|
|
323
|
-
|
324
|
-
|
424
|
+
if (values == NULL) {
|
425
|
+
rldap_raise(rldap_errno_c(obj));
|
426
|
+
}
|
325
427
|
|
326
|
-
|
327
|
-
|
428
|
+
ary = rb_ary_new();
|
429
|
+
length = ldap_count_values_len(values);
|
328
430
|
|
329
|
-
|
330
|
-
|
331
|
-
|
431
|
+
for (i=0; i<length; i++) {
|
432
|
+
value = values[i];
|
433
|
+
str = rb_str_new(value->bv_val, value->bv_len);
|
434
|
+
rb_ary_push(ary, str);
|
435
|
+
}
|
436
|
+
|
437
|
+
rb_hash_aset(attrs, rb_str_new2(attr), ary);
|
438
|
+
|
439
|
+
ldap_value_free_len(values);
|
332
440
|
ldap_memfree(attr);
|
333
|
-
} while (attr = ldap_next_attribute(
|
441
|
+
} while (attr = ldap_next_attribute(ld, msg, ber));
|
334
442
|
|
335
443
|
ber_free(ber, 0);
|
336
444
|
|
337
|
-
rb_iv_set(obj, "@
|
445
|
+
rb_iv_set(obj, "@attrs", attrs);
|
338
446
|
|
339
|
-
return
|
447
|
+
return obj;
|
448
|
+
}
|
449
|
+
|
450
|
+
static VALUE rldap_msg_dn(VALUE obj)
|
451
|
+
{
|
452
|
+
return rb_iv_get(obj, "@dn");
|
453
|
+
}
|
454
|
+
|
455
|
+
static VALUE rldap_msg_get_val(VALUE obj, VALUE key)
|
456
|
+
{
|
457
|
+
return rb_hash_aref(rb_iv_get(obj, "@attrs"), key);
|
458
|
+
}
|
459
|
+
|
460
|
+
static VALUE rldap_msg_keys(VALUE obj)
|
461
|
+
{
|
462
|
+
return rb_funcall(rb_iv_get(obj, "@attrs"), rb_intern("keys"), 0);
|
340
463
|
}
|
341
464
|
|
342
465
|
|
@@ -356,6 +479,9 @@ void Init_ldap()
|
|
356
479
|
rb_define_method(cLDAP, "errno", rldap_errno, 0);
|
357
480
|
rb_define_method(cLDAP, "uri", rldap_uri, 0);
|
358
481
|
rb_define_method(cLDAP, "inspect", rldap_inspect, 0);
|
482
|
+
rb_define_method(cLDAP, "bind", rldap_bind, -1);
|
483
|
+
rb_define_method(cLDAP, "unbind", rldap_unbind, 0);
|
484
|
+
rb_define_method(cLDAP, "sasl_bind", rldap_sasl_bind, -1);
|
359
485
|
|
360
486
|
rb_define_method(cLDAP_Message, "dn", rldap_msg_dn, 0);
|
361
487
|
rb_define_method(cLDAP_Message, "[]", rldap_msg_get_val, 1);
|
data/lib/ldap/version.rb
CHANGED
data/rldap.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/ldap/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'rldap'
|
6
|
+
s.version = LDAP::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
9
|
+
s.summary = 'Ruby LDAP wrapper'
|
10
|
+
s.homepage = 'http://github.com/dvyjones/rldap'
|
11
|
+
s.email = 'dvyjones@binaryhex.com'
|
12
|
+
s.authors = [ 'Henrik Hodne' ]
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
16
|
+
s.require_path = 'lib'
|
17
|
+
|
18
|
+
s.extensions << 'ext/extconf.rb'
|
19
|
+
|
20
|
+
s.add_development_dependency 'bundler', '>= 1.0.0'
|
21
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Henrik Hodne
|
@@ -14,10 +14,24 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-11-27 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bundler
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 1.0.0
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
21
35
|
description:
|
22
36
|
email: dvyjones@binaryhex.com
|
23
37
|
executables: []
|
@@ -27,12 +41,16 @@ extensions:
|
|
27
41
|
extra_rdoc_files: []
|
28
42
|
|
29
43
|
files:
|
30
|
-
-
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
31
46
|
- LICENSE
|
32
|
-
-
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
33
49
|
- ext/constants.h
|
34
50
|
- ext/extconf.rb
|
35
51
|
- ext/ldap.c
|
52
|
+
- lib/ldap/version.rb
|
53
|
+
- rldap.gemspec
|
36
54
|
has_rdoc: true
|
37
55
|
homepage: http://github.com/dvyjones/rldap
|
38
56
|
licenses: []
|