r2886: missing stuff from last commit
[metze/samba/wip.git] / source4 / ldap_server / ldap_bind.c
1 /* 
2    Unix SMB/CIFS implementation.
3    LDAP server
4    Copyright (C) Stefan Metzmacher 2004
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23
24 static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
25 {
26         struct ldap_BindRequest *req = &call->request.r.BindRequest;
27         struct ldapsrv_reply *reply;
28         struct ldap_BindResponse *resp;
29
30         DEBUG(10, ("BindSimple dn: %s\n",req->dn));
31
32         reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
33         if (!reply) {
34                 return NT_STATUS_NO_MEMORY;
35         }
36
37         resp = &reply->msg.r.BindResponse;
38         resp->response.resultcode = 0;
39         resp->response.dn = NULL;
40         resp->response.errormessage = NULL;
41         resp->response.referral = NULL;
42         resp->SASL.secblob = data_blob(NULL, 0);
43
44         return ldapsrv_queue_reply(call, reply);
45 }
46
47 static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
48 {
49         struct ldap_BindRequest *req = &call->request.r.BindRequest;
50         struct ldapsrv_reply *reply;
51         struct ldap_BindResponse *resp;
52         int result;
53         const char *errstr;
54         NTSTATUS status = NT_STATUS_OK;
55         NTSTATUS sasl_status;
56         BOOL ret;
57
58         DEBUG(10, ("BindSASL dn: %s\n",req->dn));
59
60         if (!call->conn->gensec) {
61                 call->conn->session_info = NULL;
62
63                 status = gensec_server_start(call->conn, &call->conn->gensec);
64                 if (!NT_STATUS_IS_OK(status)) {
65                         DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status)));
66                         return status;
67                 }
68
69                 /*gensec_want_feature(call->conn->gensec, GENSEC_WANT_SIGN|GENSEC_WANT_SEAL);*/
70
71                 status = gensec_start_mech_by_sasl_name(call->conn->gensec, req->creds.SASL.mechanism);
72                 if (!NT_STATUS_IS_OK(status)) {
73                         DEBUG(1, ("Failed to start GENSEC SASL[%s] server code: %s\n", 
74                                 req->creds.SASL.mechanism, nt_errstr(status)));
75                         goto reply;
76                 }
77         }
78
79 reply:
80         reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
81         if (!reply) {
82                 return NT_STATUS_NO_MEMORY;
83         }
84         resp = &reply->msg.r.BindResponse;
85
86         if (NT_STATUS_IS_OK(status)) {
87                 status = gensec_update(call->conn->gensec, reply,
88                                         req->creds.SASL.secblob, &resp->SASL.secblob);
89         }
90
91         if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
92                 result = LDAP_SASL_BIND_IN_PROGRESS;
93                 errstr = NULL;
94         } else if (NT_STATUS_IS_OK(status)) {
95                 result = LDAP_SUCCESS;
96                 errstr = NULL;
97         } else {
98                 result = 49;
99                 errstr = talloc_asprintf(reply, "SASL:[%s]: %s", req->creds.SASL.mechanism, nt_errstr(status));
100         }
101
102         resp->response.resultcode = result;
103         resp->response.dn = NULL;
104         resp->response.errormessage = errstr;
105         resp->response.referral = NULL;
106
107         sasl_status = status;
108         status = ldapsrv_queue_reply(call, reply);
109         if (!NT_STATUS_IS_OK(sasl_status) || !NT_STATUS_IS_OK(status)) {
110                 return status;
111         }
112
113         status = ldapsrv_do_responses(call->conn);
114         if (!NT_STATUS_IS_OK(status)) {
115                 return status;
116         }
117
118 /*      ret = ldapsrv_append_to_buf(&call->conn->sasl_out_buffer, call->conn->out_buffer.data, call->conn->out_buffer.length);
119         if (!ret) {
120                 return NT_STATUS_NO_MEMORY;
121         }
122         ldapsrv_consumed_from_buf(&call->conn->out_buffer, call->conn->out_buffer.length);
123 */
124         status = gensec_session_info(call->conn->gensec, &call->conn->session_info);
125         if (!NT_STATUS_IS_OK(status)) {
126                 return status;
127         }
128
129         //debug_session_info(0, 0, call->conn->session_info);
130
131         return status;
132 }
133
134 NTSTATUS ldapsrv_BindRequest(struct ldapsrv_call *call)
135 {
136         struct ldap_BindRequest *req = &call->request.r.BindRequest;
137         struct ldapsrv_reply *reply;
138         struct ldap_BindResponse *resp;
139
140         switch (req->mechanism) {
141                 case LDAP_AUTH_MECH_SIMPLE:
142                         return ldapsrv_BindSimple(call);
143                 case LDAP_AUTH_MECH_SASL:
144                         return ldapsrv_BindSASL(call);
145         }
146
147         reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
148         if (!reply) {
149                 return NT_STATUS_NO_MEMORY;
150         }
151
152         resp = &reply->msg.r.BindResponse;
153         resp->response.resultcode = 7;
154         resp->response.dn = NULL;
155         resp->response.errormessage = talloc_asprintf(reply, "Bad AuthenticationChoice [%d]", req->mechanism);
156         resp->response.referral = NULL;
157         resp->SASL.secblob = data_blob(NULL, 0);
158
159         return ldapsrv_queue_reply(call, reply);
160 }
161
162 NTSTATUS ldapsrv_UnbindRequest(struct ldapsrv_call *call)
163 {
164         DEBUG(10, ("UnbindRequest\n"));
165         return NT_STATUS_OK;
166 }