r5305: removed libcli/ldap/ldap.h from includes.h
[ira/wip.git] / source4 / torture / ldap / common.c
1 /* 
2    Unix SMB/CIFS mplementation.
3    LDAP protocol helper functions for SAMBA
4    
5    Copyright (C) Stefan Metzmacher 2004
6    Copyright (C) Simo Sorce 2004
7     
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21    
22 */
23
24 #include "includes.h"
25 #include "asn_1.h"
26 #include "libcli/ldap/ldap.h"
27
28 NTSTATUS torture_ldap_bind(struct ldap_connection *conn, const char *userdn, const char *password)
29 {
30         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
31         int result;
32
33         if (!conn) {
34                 printf("We need a valid ldap_connection structure and be connected\n");
35                 return status;
36         }
37
38         result = ldap_bind_simple(conn, userdn, password);
39         if (result != LDAP_SUCCESS) {
40                 printf("Failed to bind with provided credentials\n");
41                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
42                           :-) sss */
43                 return status;
44         }
45  
46         return NT_STATUS_OK;
47 }
48
49 NTSTATUS torture_ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password)
50 {
51         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
52         int result;
53
54         if (!conn) {
55                 printf("We need a valid ldap_connection structure and be connected\n");
56                 return status;
57         }
58
59         result = ldap_bind_sasl(conn, username, domain, password);
60         if (result != LDAP_SUCCESS) {
61                 printf("Failed to bind with provided credentials and SASL mechanism\n");
62                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
63                           :-) sss */
64                 return status;
65         }
66  
67         return NT_STATUS_OK;
68 }
69
70 /* open a ldap connection to a server */
71 NTSTATUS torture_ldap_connection(TALLOC_CTX *mem_ctx, struct ldap_connection **conn, 
72                                 const char *url, const char *userdn, const char *password)
73 {
74         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
75         int ret;
76
77         if (!url) {
78                 printf("You must specify a url string\n");
79                 return NT_STATUS_INVALID_PARAMETER;
80         }
81
82         *conn = ldap_connect(mem_ctx, url);
83         if (!*conn) {
84                 printf("Failed to initialize ldap_connection structure\n");
85                 return status;
86         }
87
88         ret = ldap_bind_simple(*conn, userdn, password);
89         if (ret != LDAP_SUCCESS) {
90                 printf("Failed to connect with url [%s]\n", url);
91                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
92                           :-) sss */
93                 return status;
94         }
95  
96         return NT_STATUS_OK;
97 }
98
99 /* close an ldap connection to a server */
100 NTSTATUS torture_ldap_close(struct ldap_connection *conn)
101 {
102         /* FIXME: what about actually implementing ldap_close() ?
103                   :-) sss */
104         return NT_STATUS_OK;
105 }
106
107
108 /*
109  Write data to a fd
110 */
111 static ssize_t write_data(int fd, char *buffer, size_t N)
112 {
113         size_t total=0;
114         ssize_t ret;
115
116         while (total < N) {
117                 ret = sys_write(fd,buffer + total,N - total);
118
119                 if (ret == -1) {
120                         DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
121                         return -1;
122                 }
123                 if (ret == 0)
124                         return total;
125
126                 total += ret;
127         }
128
129         return (ssize_t)total;
130 }
131
132
133 /*
134  Read data from the client, reading exactly N bytes
135 */
136 static ssize_t read_data(int fd, char *buffer, size_t N)
137 {
138         ssize_t ret;
139         size_t total=0;  
140  
141         while (total < N) {
142
143                 ret = sys_read(fd,buffer + total,N - total);
144
145                 if (ret == 0) {
146                         DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", 
147                                   (int)(N - total), strerror(errno) ));
148                         return 0;
149                 }
150
151                 if (ret == -1) {
152                         DEBUG(0,("read_data: read failure for %d. Error = %s\n", 
153                                  (int)(N - total), strerror(errno) ));
154                         return -1;
155                 }
156                 total += ret;
157         }
158
159         return (ssize_t)total;
160 }
161
162 BOOL ldap_sasl_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
163                    const struct timeval *endtime)
164 {
165         NTSTATUS status;
166         DATA_BLOB request;
167         BOOL result;
168         DATA_BLOB wrapped;
169         int len;
170         char length[4];
171         struct asn1_data asn1;
172         TALLOC_CTX *mem_ctx;
173
174         msg->messageid = conn->next_msgid++;
175
176         if (!ldap_encode(msg, &request))
177                 return False;
178
179         status = gensec_wrap(conn->gensec, 
180                              msg->mem_ctx, 
181                              &request,
182                              &wrapped);
183         if (!NT_STATUS_IS_OK(status)) {
184                 DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status)));
185                 return False;
186         }
187
188         RSIVAL(length, 0, wrapped.length);
189
190         result = (write_data(conn->sock, length, 4) == 4);
191         if (!result)
192                 return result;
193
194         result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length);
195         if (!result)
196                 return result;
197
198         wrapped = data_blob(NULL, 0x4000);
199         data_blob_clear(&wrapped);
200
201         result = (read_data(conn->sock, length, 4) == 4);
202         if (!result)
203                 return result;
204
205         len = RIVAL(length,0);
206
207         result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len);
208         if (!result)
209                 return result;
210
211         wrapped.length = len;
212
213         status = gensec_unwrap(conn->gensec,
214                                msg->mem_ctx,
215                                &wrapped,
216                                &request);
217         if (!NT_STATUS_IS_OK(status)) {
218                 DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status)));
219                 return False;
220         }
221
222         mem_ctx = msg->mem_ctx;
223         ZERO_STRUCTP(msg);
224         msg->mem_ctx = mem_ctx;
225
226         asn1_load(&asn1, request);
227         if (!ldap_decode(&asn1, msg)) {
228                 return False;
229         }
230
231         result = True;
232
233         return result;
234 }