1 module dldap.connection;
2 
3 import dldap.constants;
4 import dldap.exception;
5 import dldap.result;
6 import dldap.c.all;
7 import dldap.c.liblber.lber_int;
8 
9 import std.string;
10 import std.conv : to;
11 
12 import std.stdio;
13 // TODO: docs
14 
15 const(char*) cString(inout string str)
16 {
17 	return cast(const char*)str.toStringz;
18 }
19 
20 char** cString(inout string[] strs, bool nullTerminate = true)
21 {
22 	if (strs == null)
23 		return null;
24 
25 	char*[] r;
26 
27 	foreach (s; strs)
28 		r ~= cast(char*)s.toStringz;	
29 
30 	if (nullTerminate)
31 		r ~= null;
32 
33 	return r.ptr;
34 }
35 
36 class LDAPConnection
37 {
38 	private
39 	{
40 		ldap* ld;
41 	}
42 
43 	this(const string uri)
44 	{
45 		ldap_initialize(&ld, uri.cString);
46 	}
47 
48 	this(const string host, const ushort port)
49 	{
50 		ld = ldap_init(host.cString, port);
51 	}
52 
53 	bool simpleBindS(string dn, string pass)
54 	{
55 		int status = ldap_simple_bind_s(
56 				ld, dn.cString, 
57 				pass.cString);
58 
59 		if (status != LDAP_SUCCESS)
60 			return false;
61 
62 		return true;
63 	}
64 
65 	alias bind = simpleBindS;
66 
67 	void unbindS()
68 	{
69 		ldap_unbind_s(ld);
70 	}
71 
72 	void unbind()
73 	{
74 		ldap_unbind(ld);
75 	}
76 
77 	LDAPResult search(
78 			string base, 
79 			LDAPScope searchScope, 
80 			string filter,
81 			string[] attrs = null, 
82 			bool attrsonly = false)
83 	{
84 		ldapmsg* msgs = new ldapmsg;
85 
86 		char** cAttrs = attrs.cString;
87 
88 		int status = ldap_search_s(
89 				ld, 
90 				base.cString, 
91 				searchScope.to!int, 
92 				filter.cString, 
93 				cAttrs, 
94 				attrsonly ? 1 : 0,
95 				&msgs);
96 
97 		return LDAPResult(this, msgs);
98 	}
99 
100 	// Functions used internally, working with C pointers
101 	package
102 	{
103 		ldapmsg* firstMessage(ldapmsg* res)
104 		{
105 			return ldap_first_message(ld, res);
106 		}
107 
108 		ldapmsg* nextMessage(ldapmsg* msg)
109 		{
110 			return ldap_next_message(ld, msg);
111 		}
112 
113 		string getDN(ldapmsg* msg)
114 		{
115 			return ldap_get_dn(ld, msg).fromStringz.to!string;
116 		}
117 
118 		string[string] getAttributes(ldapmsg* msg)
119 		{
120 			berelement* ber;
121 			string[string] result;
122 
123 			for (
124 					auto attr = ldap_first_attribute(ld, msg, &ber);
125 					attr != null;
126 					attr = ldap_next_attribute(ld, msg, ber))
127 			{
128 				auto vals = ldap_get_values(ld, msg, attr);
129 				if (vals != null)
130 				{
131 					for (int i = 0; vals[i] != null; ++i)
132 						result[attr.fromStringz.to!string] = vals[i].fromStringz.to!string;
133 
134 					ldap_value_free(vals);
135 				}
136 				ldap_memfree(attr);
137 			}
138 			return result;
139 		}
140 	}
141 }