rldap 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|