r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h)
[jelmer/samba4-debian.git] / source / 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
27 NTSTATUS torture_ldap_bind(struct ldap_connection *conn, const char *userdn, const char *password)
28 {
29         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
30         int result;
31
32         if (!conn) {
33                 printf("We need a valid ldap_connection structure and be connected\n");
34                 return status;
35         }
36
37         result = ldap_bind_simple(conn, userdn, password);
38         if (result != LDAP_SUCCESS) {
39                 printf("Failed to bind with provided credentials\n");
40                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
41                           :-) sss */
42                 return status;
43         }
44  
45         return NT_STATUS_OK;
46 }
47
48 NTSTATUS torture_ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password)
49 {
50         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
51         int result;
52
53         if (!conn) {
54                 printf("We need a valid ldap_connection structure and be connected\n");
55                 return status;
56         }
57
58         result = ldap_bind_sasl(conn, username, domain, password);
59         if (result != LDAP_SUCCESS) {
60                 printf("Failed to bind with provided credentialsi and SASL mechanism\n");
61                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
62                           :-) sss */
63                 return status;
64         }
65  
66         return NT_STATUS_OK;
67 }
68
69 /* open a ldap connection to a server */
70 NTSTATUS torture_ldap_connection(struct ldap_connection **conn, 
71                                 const char *url, const char *userdn, const char *password)
72 {
73         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
74         BOOL ret;
75
76         if (!url) {
77                 printf("You must specify a url string\n");
78                 return NT_STATUS_INVALID_PARAMETER;
79         }
80
81         *conn = new_ldap_connection();
82         if (!*conn) {
83                 printf("Failed to initialize ldap_connection structure\n");
84                 return status;
85         }
86
87         ret = ldap_setup_connection(*conn, url, userdn, password);
88         if (!ret) {
89                 printf("Failed to connect with url [%s]\n", url);
90                 /* FIXME: what abut actually implementing an ldap_connection_free() function ?
91                           :-) sss */
92                 return status;
93         }
94  
95         return NT_STATUS_OK;
96 }
97
98 /* close an ldap connection to a server */
99 NTSTATUS torture_ldap_close(struct ldap_connection *conn)
100 {
101         /* FIXME: what about actually implementing ldap_close() ?
102                   :-) sss */
103         return NT_STATUS_OK;
104 }
105
106 BOOL ldap_sasl_send_msg(struct ldap_connection *conn, struct ldap_message *msg,
107                    const struct timeval *endtime)
108 {
109         NTSTATUS status;
110         DATA_BLOB request;
111         BOOL result;
112         DATA_BLOB creds;
113         DATA_BLOB pdu;
114         int len;
115         struct asn1_data asn1;
116         TALLOC_CTX *mem_ctx;
117
118         msg->messageid = conn->next_msgid++;
119
120         if (!ldap_encode(msg, &request))
121                 return False;
122
123         status = gensec_seal_packet(conn->gensec, 
124                                     msg->mem_ctx, 
125                                     request.data, request.length,
126                                     request.data, request.length,
127                                     &creds);
128         if (!NT_STATUS_IS_OK(status)) {
129                 DEBUG(0,("gensec_seal_packet: %s\n",nt_errstr(status)));
130                 return False;
131         }
132
133         len = 4 + creds.length + request.length;
134         pdu = data_blob_talloc(msg->mem_ctx, NULL, len);
135         RSIVAL(pdu.data, 0, len-4);
136         memcpy(pdu.data + 4, creds.data, creds.length);
137         memcpy(pdu.data + 4 + creds.length, request.data, request.length);
138
139         result = (write_data_until(conn->sock, pdu.data, pdu.length,
140                                    endtime) == pdu.length);
141         if (!result)
142                 return result;
143
144         pdu = data_blob(NULL, 0x4000);
145         data_blob_clear(&pdu);
146
147         result = (read_data_until(conn->sock, pdu.data, 4, NULL) == 4);
148         if (!result)
149                 return result;
150
151         len = RIVAL(pdu.data,0);
152
153         result = (read_data_until(conn->sock, pdu.data + 4, MIN(0x4000,len), NULL) == len);
154         if (!result)
155                 return result;
156
157         pdu.length = 4+len;
158
159         creds = data_blob(pdu.data + 4 , gensec_sig_size(conn->gensec));
160
161         request = data_blob(pdu.data + (4 + creds.length), pdu.length - (4 + creds.length));
162
163         status = gensec_unseal_packet(conn->gensec,
164                              msg->mem_ctx,
165                              request.data, request.length,
166                              request.data, request.length,
167                              &creds);
168         if (!NT_STATUS_IS_OK(status)) {
169                 DEBUG(0,("gensec_unseal_packet: %s\n",nt_errstr(status)));
170                 return False;
171         }
172
173         mem_ctx = msg->mem_ctx;
174         ZERO_STRUCTP(msg);
175         msg->mem_ctx = mem_ctx;
176
177         asn1_load(&asn1, request);
178         if (!ldap_decode(&asn1, msg)) {
179                 return False;
180         }
181
182         result = True;
183
184         return result;
185 }