2004-09-13 10:36:59 +00:00
/*
Unix SMB / CIFS implementation .
LDAP server
Copyright ( C ) Volker Lendecke 2004
Copyright ( C ) Stefan Metzmacher 2004
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2005-02-03 11:56:03 +00:00
# include "lib/events/events.h"
2004-11-02 02:57:18 +00:00
# include "auth/auth.h"
2004-11-02 06:42:15 +00:00
# include "dlinklist.h"
# include "asn_1.h"
2004-11-02 06:52:59 +00:00
# include "ldap_server/ldap_server.h"
2005-01-30 00:54:57 +00:00
# include "smbd/service_stream.h"
2005-02-10 06:59:29 +00:00
# include "lib/socket/socket.h"
2004-09-13 10:36:59 +00:00
/*
close the socket and shutdown a server_context
*/
2004-09-27 13:20:59 +00:00
static void ldapsrv_terminate_connection ( struct ldapsrv_connection * ldap_conn , const char * reason )
2004-09-13 10:36:59 +00:00
{
2005-01-30 00:54:57 +00:00
stream_terminate_connection ( ldap_conn - > connection , reason ) ;
2004-09-13 10:36:59 +00:00
}
/* This rw-buf api is made to avoid memcpy. For now do that like mad... The
idea is to write into a circular list of buffers where the ideal case is
that a read ( 2 ) holds a complete request that is then thrown away
completely . */
2004-10-09 22:00:00 +00:00
void ldapsrv_consumed_from_buf ( struct rw_buffer * buf ,
2004-09-22 10:48:32 +00:00
size_t length )
{
2004-12-31 22:45:11 +00:00
memmove ( buf - > data , buf - > data + length , buf - > length - length ) ;
2004-09-22 10:48:32 +00:00
buf - > length - = length ;
}
2004-10-08 12:19:08 +00:00
static void peek_into_read_buf ( struct rw_buffer * buf , uint8_t * * out ,
size_t * out_length )
{
* out = buf - > data ;
* out_length = buf - > length ;
}
2004-10-09 22:00:00 +00:00
BOOL ldapsrv_append_to_buf ( struct rw_buffer * buf , uint8_t * data , size_t length )
2004-09-13 10:36:59 +00:00
{
buf - > data = realloc ( buf - > data , buf - > length + length ) ;
if ( buf - > data = = NULL )
return False ;
memcpy ( buf - > data + buf - > length , data , length ) ;
buf - > length + = length ;
return True ;
}
2004-09-20 12:31:07 +00:00
static BOOL read_into_buf ( struct socket_context * sock , struct rw_buffer * buf )
2004-09-13 10:36:59 +00:00
{
2004-09-20 12:31:07 +00:00
NTSTATUS status ;
DATA_BLOB tmp_blob ;
BOOL ret ;
2004-10-28 04:00:43 +00:00
size_t nread ;
2004-09-13 10:36:59 +00:00
2004-10-28 04:00:43 +00:00
tmp_blob = data_blob_talloc ( sock , NULL , 1024 ) ;
if ( tmp_blob . data = = NULL ) {
return False ;
}
status = socket_recv ( sock , tmp_blob . data , tmp_blob . length , & nread , 0 ) ;
2004-10-28 08:36:23 +00:00
if ( NT_STATUS_IS_ERR ( status ) ) {
2004-09-28 13:50:15 +00:00
DEBUG ( 10 , ( " socket_recv: %s \n " , nt_errstr ( status ) ) ) ;
2004-10-28 04:00:43 +00:00
talloc_free ( tmp_blob . data ) ;
2004-09-13 10:36:59 +00:00
return False ;
2004-09-20 12:31:07 +00:00
}
2004-11-15 17:27:07 +00:00
tmp_blob . length = nread ;
2004-09-20 12:31:07 +00:00
2004-10-09 22:00:00 +00:00
ret = ldapsrv_append_to_buf ( buf , tmp_blob . data , tmp_blob . length ) ;
2004-09-13 10:36:59 +00:00
2004-09-20 12:31:07 +00:00
talloc_free ( tmp_blob . data ) ;
return ret ;
2004-09-13 10:36:59 +00:00
}
2004-10-08 12:19:08 +00:00
static BOOL ldapsrv_read_buf ( struct ldapsrv_connection * conn )
{
NTSTATUS status ;
DATA_BLOB tmp_blob ;
2004-12-31 22:45:11 +00:00
DATA_BLOB wrapped ;
DATA_BLOB unwrapped ;
2004-10-08 12:19:08 +00:00
BOOL ret ;
uint8_t * buf ;
2004-11-15 17:27:07 +00:00
size_t buf_length , sasl_length ;
2004-10-08 12:19:08 +00:00
struct socket_context * sock = conn - > connection - > socket ;
TALLOC_CTX * mem_ctx ;
2004-10-28 04:00:43 +00:00
size_t nread ;
2004-10-08 12:19:08 +00:00
2004-12-31 22:45:11 +00:00
if ( ! conn - > gensec ) {
return read_into_buf ( sock , & conn - > in_buffer ) ;
}
if ( ! conn - > session_info ) {
return read_into_buf ( sock , & conn - > in_buffer ) ;
}
if ( ! ( gensec_have_feature ( conn - > gensec , GENSEC_FEATURE_SIGN ) | |
gensec_have_feature ( conn - > gensec , GENSEC_FEATURE_SEAL ) ) ) {
2004-10-08 12:19:08 +00:00
return read_into_buf ( sock , & conn - > in_buffer ) ;
}
2005-01-06 02:32:43 +00:00
mem_ctx = talloc_new ( conn ) ;
2004-10-08 12:19:08 +00:00
if ( ! mem_ctx ) {
DEBUG ( 0 , ( " no memory \n " ) ) ;
return False ;
}
2004-10-28 04:00:43 +00:00
tmp_blob = data_blob_talloc ( mem_ctx , NULL , 1024 ) ;
if ( tmp_blob . data = = NULL ) {
talloc_free ( mem_ctx ) ;
return False ;
}
status = socket_recv ( sock , tmp_blob . data , tmp_blob . length , & nread , 0 ) ;
2004-10-28 08:36:23 +00:00
if ( NT_STATUS_IS_ERR ( status ) ) {
2004-10-08 12:19:08 +00:00
DEBUG ( 10 , ( " socket_recv: %s \n " , nt_errstr ( status ) ) ) ;
talloc_free ( mem_ctx ) ;
return False ;
}
2004-10-28 04:00:43 +00:00
tmp_blob . length = nread ;
2004-10-08 12:19:08 +00:00
2004-10-09 22:00:00 +00:00
ret = ldapsrv_append_to_buf ( & conn - > sasl_in_buffer , tmp_blob . data , tmp_blob . length ) ;
2004-10-08 12:19:08 +00:00
if ( ! ret ) {
talloc_free ( mem_ctx ) ;
return False ;
}
peek_into_read_buf ( & conn - > sasl_in_buffer , & buf , & buf_length ) ;
if ( buf_length < 4 ) {
/* not enough yet */
talloc_free ( mem_ctx ) ;
return True ;
}
sasl_length = RIVAL ( buf , 0 ) ;
2004-12-31 22:45:11 +00:00
if ( ( buf_length - 4 ) < sasl_length ) {
2004-10-08 12:19:08 +00:00
/* not enough yet */
talloc_free ( mem_ctx ) ;
return True ;
}
2004-12-31 22:45:11 +00:00
wrapped . data = buf + 4 ;
wrapped . length = sasl_length ;
2004-10-08 12:19:08 +00:00
2004-12-31 22:45:11 +00:00
status = gensec_unwrap ( conn - > gensec , mem_ctx ,
& wrapped ,
& unwrapped ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " gensec_unwrap: %s \n " , nt_errstr ( status ) ) ) ;
2004-10-08 12:19:08 +00:00
talloc_free ( mem_ctx ) ;
return False ;
}
2004-12-31 22:45:11 +00:00
ret = ldapsrv_append_to_buf ( & conn - > in_buffer , unwrapped . data , unwrapped . length ) ;
2004-10-08 12:19:08 +00:00
if ( ! ret ) {
talloc_free ( mem_ctx ) ;
return False ;
}
2004-10-09 22:00:00 +00:00
ldapsrv_consumed_from_buf ( & conn - > sasl_in_buffer , 4 + sasl_length ) ;
2004-10-08 12:19:08 +00:00
talloc_free ( mem_ctx ) ;
return ret ;
}
2004-09-20 12:31:07 +00:00
static BOOL write_from_buf ( struct socket_context * sock , struct rw_buffer * buf )
2004-09-13 10:36:59 +00:00
{
2004-09-20 12:31:07 +00:00
NTSTATUS status ;
DATA_BLOB tmp_blob ;
size_t sendlen ;
tmp_blob . data = buf - > data ;
tmp_blob . length = buf - > length ;
2004-09-13 10:36:59 +00:00
2004-10-28 04:00:43 +00:00
status = socket_send ( sock , & tmp_blob , & sendlen , 0 ) ;
2004-09-20 12:31:07 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-09-28 13:50:15 +00:00
DEBUG ( 10 , ( " socket_send() %s \n " , nt_errstr ( status ) ) ) ;
2004-09-13 10:36:59 +00:00
return False ;
2004-09-20 12:31:07 +00:00
}
2004-10-09 22:00:00 +00:00
ldapsrv_consumed_from_buf ( buf , sendlen ) ;
2004-09-13 10:36:59 +00:00
return True ;
}
2004-10-08 12:19:08 +00:00
static BOOL ldapsrv_write_buf ( struct ldapsrv_connection * conn )
2004-09-13 10:36:59 +00:00
{
2004-10-08 12:19:08 +00:00
NTSTATUS status ;
2004-12-31 22:45:11 +00:00
DATA_BLOB wrapped ;
2004-10-08 12:19:08 +00:00
DATA_BLOB tmp_blob ;
DATA_BLOB sasl ;
size_t sendlen ;
BOOL ret ;
struct socket_context * sock = conn - > connection - > socket ;
TALLOC_CTX * mem_ctx ;
2004-12-31 22:45:11 +00:00
if ( ! conn - > gensec ) {
return write_from_buf ( sock , & conn - > out_buffer ) ;
}
if ( ! conn - > session_info ) {
return write_from_buf ( sock , & conn - > out_buffer ) ;
}
if ( ! ( gensec_have_feature ( conn - > gensec , GENSEC_FEATURE_SIGN ) | |
gensec_have_feature ( conn - > gensec , GENSEC_FEATURE_SEAL ) ) ) {
2004-10-08 12:19:08 +00:00
return write_from_buf ( sock , & conn - > out_buffer ) ;
}
2005-01-06 02:32:43 +00:00
mem_ctx = talloc_new ( conn ) ;
2004-10-08 12:19:08 +00:00
if ( ! mem_ctx ) {
DEBUG ( 0 , ( " no memory \n " ) ) ;
return False ;
}
2004-12-31 22:45:11 +00:00
if ( conn - > out_buffer . length = = 0 ) {
2004-10-09 22:00:00 +00:00
goto nodata ;
}
2004-12-31 22:45:11 +00:00
tmp_blob . data = conn - > out_buffer . data ;
tmp_blob . length = conn - > out_buffer . length ;
status = gensec_wrap ( conn - > gensec , mem_ctx ,
& tmp_blob ,
& wrapped ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " gensec_wrap: %s \n " , nt_errstr ( status ) ) ) ;
talloc_free ( mem_ctx ) ;
return False ;
2004-10-08 12:19:08 +00:00
}
2004-12-31 22:45:11 +00:00
sasl = data_blob_talloc ( mem_ctx , NULL , 4 + wrapped . length ) ;
2004-10-08 12:19:08 +00:00
if ( ! sasl . data ) {
DEBUG ( 0 , ( " no memory \n " ) ) ;
talloc_free ( mem_ctx ) ;
return False ;
}
2004-12-31 22:45:11 +00:00
RSIVAL ( sasl . data , 0 , wrapped . length ) ;
memcpy ( sasl . data + 4 , wrapped . data , wrapped . length ) ;
2004-10-08 12:19:08 +00:00
2004-10-09 22:00:00 +00:00
ret = ldapsrv_append_to_buf ( & conn - > sasl_out_buffer , sasl . data , sasl . length ) ;
2004-10-08 12:19:08 +00:00
if ( ! ret ) {
talloc_free ( mem_ctx ) ;
return False ;
}
2004-12-31 22:45:11 +00:00
ldapsrv_consumed_from_buf ( & conn - > out_buffer , conn - > out_buffer . length ) ;
2004-10-09 22:00:00 +00:00
nodata :
tmp_blob . data = conn - > sasl_out_buffer . data ;
tmp_blob . length = conn - > sasl_out_buffer . length ;
2004-10-08 12:19:08 +00:00
2004-10-28 04:00:43 +00:00
status = socket_send ( sock , & tmp_blob , & sendlen , 0 ) ;
2004-10-08 12:19:08 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " socket_send() %s \n " , nt_errstr ( status ) ) ) ;
talloc_free ( mem_ctx ) ;
return False ;
}
2004-10-09 22:00:00 +00:00
ldapsrv_consumed_from_buf ( & conn - > sasl_out_buffer , sendlen ) ;
2004-10-08 12:19:08 +00:00
talloc_free ( mem_ctx ) ;
return True ;
2004-09-13 10:36:59 +00:00
}
2004-10-09 22:00:00 +00:00
static BOOL ldap_encode_to_buf ( struct ldap_message * msg , struct rw_buffer * buf )
2004-09-13 10:36:59 +00:00
{
DATA_BLOB blob ;
BOOL res ;
if ( ! ldap_encode ( msg , & blob ) )
return False ;
2004-10-09 22:00:00 +00:00
res = ldapsrv_append_to_buf ( buf , blob . data , blob . length ) ;
2004-09-13 10:36:59 +00:00
data_blob_free ( & blob ) ;
return res ;
}
2004-10-09 22:00:00 +00:00
NTSTATUS ldapsrv_do_responses ( struct ldapsrv_connection * conn )
2004-09-13 10:36:59 +00:00
{
2004-09-22 10:48:32 +00:00
struct ldapsrv_call * call , * next_call = NULL ;
struct ldapsrv_reply * reply , * next_reply = NULL ;
2004-09-13 10:36:59 +00:00
2004-09-22 10:48:32 +00:00
for ( call = conn - > calls ; call ; call = next_call ) {
for ( reply = call - > replies ; reply ; reply = next_reply ) {
2004-10-09 22:00:00 +00:00
if ( ! ldap_encode_to_buf ( & reply - > msg , & conn - > out_buffer ) ) {
2004-09-27 13:20:59 +00:00
return NT_STATUS_FOOBAR ;
2004-09-22 10:48:32 +00:00
}
next_reply = reply - > next ;
DLIST_REMOVE ( call - > replies , reply ) ;
reply - > state = LDAPSRV_REPLY_STATE_SEND ;
talloc_free ( reply ) ;
}
next_call = call - > next ;
DLIST_REMOVE ( conn - > calls , call ) ;
call - > state = LDAPSRV_CALL_STATE_COMPLETE ;
talloc_free ( call ) ;
2004-09-13 10:36:59 +00:00
}
2004-09-27 13:20:59 +00:00
return NT_STATUS_OK ;
2004-09-13 10:36:59 +00:00
}
2004-10-09 22:00:00 +00:00
NTSTATUS ldapsrv_flush_responses ( struct ldapsrv_connection * conn )
{
return NT_STATUS_OK ;
}
2004-09-13 10:36:59 +00:00
/*
called when a LDAP socket becomes readable
*/
2005-02-03 11:25:52 +00:00
static void ldapsrv_recv ( struct stream_connection * conn , uint16_t flags )
2004-09-13 10:36:59 +00:00
{
2005-01-30 00:54:57 +00:00
struct ldapsrv_connection * ldap_conn = talloc_get_type ( conn - > private , struct ldapsrv_connection ) ;
2004-09-13 10:36:59 +00:00
uint8_t * buf ;
2004-11-15 17:27:07 +00:00
size_t buf_length , msg_length ;
2004-09-13 10:36:59 +00:00
DATA_BLOB blob ;
2004-11-02 06:42:15 +00:00
struct asn1_data data ;
2004-09-22 10:48:32 +00:00
struct ldapsrv_call * call ;
2004-09-27 13:20:59 +00:00
NTSTATUS status ;
2004-09-13 10:36:59 +00:00
DEBUG ( 10 , ( " ldapsrv_recv \n " ) ) ;
2004-10-08 12:19:08 +00:00
if ( ! ldapsrv_read_buf ( ldap_conn ) ) {
ldapsrv_terminate_connection ( ldap_conn , " ldapsrv_read_buf() failed " ) ;
2004-09-13 10:36:59 +00:00
return ;
}
peek_into_read_buf ( & ldap_conn - > in_buffer , & buf , & buf_length ) ;
while ( buf_length > 0 ) {
/* LDAP Messages are always SEQUENCES */
if ( ! asn1_object_length ( buf , buf_length , ASN1_SEQUENCE ( 0 ) ,
& msg_length ) ) {
ldapsrv_terminate_connection ( ldap_conn , " asn1_object_length() failed " ) ;
return ;
}
if ( buf_length < msg_length ) {
/* Not enough yet */
break ;
}
/* We've got a complete LDAP request in the in-buffer, convert
* that to a ldap_message and put it into the incoming
* queue . */
blob . data = buf ;
blob . length = msg_length ;
if ( ! asn1_load ( & data , blob ) ) {
ldapsrv_terminate_connection ( ldap_conn , " asn1_load() failed " ) ;
return ;
}
2005-01-27 07:08:20 +00:00
call = talloc ( ldap_conn , struct ldapsrv_call ) ;
2004-09-22 10:48:32 +00:00
if ( ! call ) {
ldapsrv_terminate_connection ( ldap_conn , " no memory " ) ;
return ;
2004-09-13 10:36:59 +00:00
}
2004-09-22 10:48:32 +00:00
ZERO_STRUCTP ( call ) ;
call - > state = LDAPSRV_CALL_STATE_NEW ;
call - > conn = ldap_conn ;
call - > request . mem_ctx = call ;
2004-09-13 10:36:59 +00:00
2004-09-22 10:48:32 +00:00
if ( ! ldap_decode ( & data , & call - > request ) ) {
dump_data ( 0 , buf , msg_length ) ;
2004-09-28 12:36:20 +00:00
asn1_free ( & data ) ;
2004-09-22 10:48:32 +00:00
ldapsrv_terminate_connection ( ldap_conn , " ldap_decode() failed " ) ;
2004-09-13 10:36:59 +00:00
return ;
}
2004-09-28 12:36:20 +00:00
asn1_free ( & data ) ;
2004-09-22 10:48:32 +00:00
DLIST_ADD_END ( ldap_conn - > calls , call ,
struct ldapsrv_call * ) ;
2004-09-13 10:36:59 +00:00
2004-10-09 22:00:00 +00:00
ldapsrv_consumed_from_buf ( & ldap_conn - > in_buffer , msg_length ) ;
2004-09-13 10:36:59 +00:00
2004-09-27 13:20:59 +00:00
status = ldapsrv_do_call ( call ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ldapsrv_terminate_connection ( ldap_conn , " ldapsrv_do_call() failed " ) ;
return ;
}
2004-09-13 10:36:59 +00:00
peek_into_read_buf ( & ldap_conn - > in_buffer , & buf , & buf_length ) ;
}
2004-09-27 13:20:59 +00:00
status = ldapsrv_do_responses ( ldap_conn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ldapsrv_terminate_connection ( ldap_conn , " ldapsrv_do_responses() failed " ) ;
return ;
}
2004-09-13 10:36:59 +00:00
2004-10-08 12:19:08 +00:00
if ( ( ldap_conn - > out_buffer . length > 0 ) | | ( ldap_conn - > sasl_out_buffer . length > 0 ) ) {
2005-02-03 02:35:52 +00:00
EVENT_FD_WRITEABLE ( conn - > event . fde ) ;
2004-09-22 10:48:32 +00:00
}
2004-09-18 08:13:06 +00:00
2004-09-13 10:36:59 +00:00
return ;
}
/*
called when a LDAP socket becomes writable
*/
2005-02-03 11:25:52 +00:00
static void ldapsrv_send ( struct stream_connection * conn , uint16_t flags )
2004-09-13 10:36:59 +00:00
{
2005-01-30 00:54:57 +00:00
struct ldapsrv_connection * ldap_conn = talloc_get_type ( conn - > private , struct ldapsrv_connection ) ;
2004-09-13 10:36:59 +00:00
DEBUG ( 10 , ( " ldapsrv_send \n " ) ) ;
2004-10-08 12:19:08 +00:00
if ( ! ldapsrv_write_buf ( ldap_conn ) ) {
ldapsrv_terminate_connection ( ldap_conn , " ldapsrv_write_buf() failed " ) ;
2004-09-13 10:36:59 +00:00
return ;
}
2004-10-08 12:19:08 +00:00
if ( ldap_conn - > out_buffer . length = = 0 & & ldap_conn - > sasl_out_buffer . length = = 0 ) {
2005-02-03 02:35:52 +00:00
EVENT_FD_NOT_WRITEABLE ( conn - > event . fde ) ;
2004-09-22 10:48:32 +00:00
}
2004-09-18 08:13:06 +00:00
2004-09-13 10:36:59 +00:00
return ;
}
/*
initialise a server_context from a open socket and register a event handler
for reading from that socket
*/
2005-01-30 00:54:57 +00:00
static void ldapsrv_accept ( struct stream_connection * conn )
2004-09-13 10:36:59 +00:00
{
struct ldapsrv_connection * ldap_conn ;
2004-09-28 13:50:15 +00:00
DEBUG ( 10 , ( " ldapsrv_accept \n " ) ) ;
2004-09-13 10:36:59 +00:00
2005-01-30 00:54:57 +00:00
ldap_conn = talloc_zero ( conn , struct ldapsrv_connection ) ;
2004-09-13 10:36:59 +00:00
if ( ldap_conn = = NULL )
return ;
ldap_conn - > connection = conn ;
2005-01-30 00:54:57 +00:00
ldap_conn - > service = talloc_get_type ( conn - > private , struct ldapsrv_service ) ;
conn - > private = ldap_conn ;
2004-09-13 10:36:59 +00:00
}
2005-01-30 00:54:57 +00:00
static const struct stream_server_ops ldap_stream_ops = {
2005-01-14 01:32:56 +00:00
. name = " ldap " ,
. accept_connection = ldapsrv_accept ,
. recv_handler = ldapsrv_recv ,
. send_handler = ldapsrv_send ,
} ;
2005-01-30 00:54:57 +00:00
/*
add a socket address to the list of events , one event per port
*/
static NTSTATUS add_socket ( struct event_context * event_context , const struct model_ops * model_ops ,
const char * address , struct ldapsrv_service * ldap_service )
2004-09-13 10:36:59 +00:00
{
2005-01-30 00:54:57 +00:00
uint16_t port = 389 ;
NTSTATUS status ;
status = stream_setup_socket ( event_context , model_ops , & ldap_stream_ops ,
" ipv4 " , address , & port , ldap_service ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
port = 3268 ;
return stream_setup_socket ( event_context , model_ops , & ldap_stream_ops ,
" ipv4 " , address , & port , ldap_service ) ;
2004-09-13 10:36:59 +00:00
}
2005-01-30 00:54:57 +00:00
/*
open the ldap server sockets
*/
static NTSTATUS ldapsrv_init ( struct event_context * event_context , const struct model_ops * model_ops )
{
struct ldapsrv_service * ldap_service ;
struct ldapsrv_partition * rootDSE_part ;
struct ldapsrv_partition * part ;
NTSTATUS status ;
2004-09-13 10:36:59 +00:00
2005-01-30 00:54:57 +00:00
DEBUG ( 10 , ( " ldapsrv_init \n " ) ) ;
ldap_service = talloc_zero ( event_context , struct ldapsrv_service ) ;
NT_STATUS_HAVE_NO_MEMORY ( ldap_service ) ;
rootDSE_part = talloc ( ldap_service , struct ldapsrv_partition ) ;
NT_STATUS_HAVE_NO_MEMORY ( rootDSE_part ) ;
rootDSE_part - > base_dn = " " ; /* RootDSE */
rootDSE_part - > ops = ldapsrv_get_rootdse_partition_ops ( ) ;
ldap_service - > rootDSE = rootDSE_part ;
DLIST_ADD_END ( ldap_service - > partitions , rootDSE_part , struct ldapsrv_partition * ) ;
part = talloc ( ldap_service , struct ldapsrv_partition ) ;
NT_STATUS_HAVE_NO_MEMORY ( part ) ;
part - > base_dn = " * " ; /* default partition */
if ( lp_parm_bool ( - 1 , " ldapsrv " , " hacked " , False ) ) {
part - > ops = ldapsrv_get_hldb_partition_ops ( ) ;
} else {
part - > ops = ldapsrv_get_sldb_partition_ops ( ) ;
}
ldap_service - > default_partition = part ;
DLIST_ADD_END ( ldap_service - > partitions , part , struct ldapsrv_partition * ) ;
if ( lp_interfaces ( ) & & lp_bind_interfaces_only ( ) ) {
int num_interfaces = iface_count ( ) ;
int i ;
/* We have been given an interfaces line, and been
told to only bind to those interfaces . Create a
socket per interface and bind to only these .
*/
for ( i = 0 ; i < num_interfaces ; i + + ) {
2005-02-10 03:22:47 +00:00
const char * address = iface_n_ip ( i ) ;
2005-01-30 00:54:57 +00:00
status = add_socket ( event_context , model_ops , address , ldap_service ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
}
} else {
status = add_socket ( event_context , model_ops , lp_socket_address ( ) , ldap_service ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
}
return NT_STATUS_OK ;
2004-09-13 10:36:59 +00:00
}
2005-01-30 00:54:57 +00:00
2004-09-13 10:36:59 +00:00
NTSTATUS server_service_ldap_init ( void )
{
2005-01-30 00:54:57 +00:00
return register_server_service ( " ldap " , ldapsrv_init ) ;
2004-09-13 10:36:59 +00:00
}