r6028: A MAJOR update to intergrate the new credentails system fully with
[kai/samba-autobuild/.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, 
50                                 struct cli_credentials *creds)
51 {
52         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
53         int result;
54
55         if (!conn) {
56                 printf("We need a valid ldap_connection structure and be connected\n");
57                 return status;
58         }
59
60         result = ldap_bind_sasl(conn, creds);
61         if (result != LDAP_SUCCESS) {
62                 printf("Failed to bind with provided credentials and SASL mechanism\n");
63                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
64                           :-) sss */
65                 return status;
66         }
67  
68         return NT_STATUS_OK;
69 }
70
71 /* open a ldap connection to a server */
72 NTSTATUS torture_ldap_connection(TALLOC_CTX *mem_ctx, struct ldap_connection **conn, 
73                                 const char *url, const char *userdn, const char *password)
74 {
75         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
76         int ret;
77
78         if (!url) {
79                 printf("You must specify a url string\n");
80                 return NT_STATUS_INVALID_PARAMETER;
81         }
82
83         *conn = ldap_connect(mem_ctx, url);
84         if (!*conn) {
85                 printf("Failed to initialize ldap_connection structure\n");
86                 return status;
87         }
88
89         ret = ldap_bind_simple(*conn, userdn, password);
90         if (ret != LDAP_SUCCESS) {
91                 printf("Failed to connect with url [%s]\n", url);
92                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
93                           :-) sss */
94                 return status;
95         }
96  
97         return NT_STATUS_OK;
98 }
99
100 /* close an ldap connection to a server */
101 NTSTATUS torture_ldap_close(struct ldap_connection *conn)
102 {
103         /* FIXME: what about actually implementing ldap_close() ?
104                   :-) sss */
105         return NT_STATUS_OK;
106 }
107
108
109 /*
110  Write data to a fd
111 */
112 static ssize_t write_data(int fd, char *buffer, size_t N)
113 {
114         size_t total=0;
115         ssize_t ret;
116
117         while (total < N) {
118                 ret = sys_write(fd,buffer + total,N - total);
119
120                 if (ret == -1) {
121                         DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
122                         return -1;
123                 }
124                 if (ret == 0)
125                         return total;
126
127                 total += ret;
128         }
129
130         return (ssize_t)total;
131 }
132
133
134 /*
135  Read data from the client, reading exactly N bytes
136 */
137 static ssize_t read_data(int fd, char *buffer, size_t N)
138 {
139         ssize_t ret;
140         size_t total=0;  
141  
142         while (total < N) {
143
144                 ret = sys_read(fd,buffer + total,N - total);
145
146                 if (ret == 0) {
147                         DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", 
148                                   (int)(N - total), strerror(errno) ));
149                         return 0;
150                 }
151
152                 if (ret == -1) {
153                         DEBUG(0,("read_data: read failure for %d. Error = %s\n", 
154                                  (int)(N - total), strerror(errno) ));
155                         return -1;
156                 }
157                 total += ret;
158         }
159
160         return (ssize_t)total;
161 }
162
163 BOOL ldap_sasl_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
164                    const struct timeval *endtime)
165 {
166         NTSTATUS status;
167         DATA_BLOB request;
168         BOOL result;
169         DATA_BLOB wrapped;
170         int len;
171         char length[4];
172         struct asn1_data asn1;
173         TALLOC_CTX *mem_ctx;
174
175         msg->messageid = conn->next_msgid++;
176
177         if (!ldap_encode(msg, &request))
178                 return False;
179
180         status = gensec_wrap(conn->gensec, 
181                              msg->mem_ctx, 
182                              &request,
183                              &wrapped);
184         if (!NT_STATUS_IS_OK(status)) {
185                 DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status)));
186                 return False;
187         }
188
189         RSIVAL(length, 0, wrapped.length);
190
191         result = (write_data(conn->sock, length, 4) == 4);
192         if (!result)
193                 return result;
194
195         result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length);
196         if (!result)
197                 return result;
198
199         wrapped = data_blob(NULL, 0x4000);
200         data_blob_clear(&wrapped);
201
202         result = (read_data(conn->sock, length, 4) == 4);
203         if (!result)
204                 return result;
205
206         len = RIVAL(length,0);
207
208         result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len);
209         if (!result)
210                 return result;
211
212         wrapped.length = len;
213
214         status = gensec_unwrap(conn->gensec,
215                                msg->mem_ctx,
216                                &wrapped,
217                                &request);
218         if (!NT_STATUS_IS_OK(status)) {
219                 DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status)));
220                 return False;
221         }
222
223         mem_ctx = msg->mem_ctx;
224         ZERO_STRUCTP(msg);
225         msg->mem_ctx = mem_ctx;
226
227         asn1_load(&asn1, request);
228         if (!ldap_decode(&asn1, msg)) {
229                 return False;
230         }
231
232         result = True;
233
234         return result;
235 }