r25398: Parse loadparm context to all lp_*() functions.
[ab/samba.git/.git] / source4 / cldap_server / cldap_server.c
index a15b93f91cd675730061f401395f001d59069fe1..466444ace81b0e420930212c42f087b57aa01454 100644 (file)
@@ -7,7 +7,7 @@
    
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    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 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "libcli/ldap/ldap.h"
-#include "lib/events/events.h"
 #include "lib/socket/socket.h"
+#include "lib/messaging/irpc.h"
 #include "smbd/service_task.h"
+#include "smbd/service.h"
 #include "cldap_server/cldap_server.h"
+#include "system/network.h"
+#include "lib/socket/netif.h"
+#include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
+#include "dsdb/samdb/samdb.h"
+#include "db_wrap.h"
+#include "auth/auth.h"
+#include "param/param.h"
 
 /*
   handle incoming cldap requests
 */
 static void cldapd_request_handler(struct cldap_socket *cldap, 
                                   struct ldap_message *ldap_msg, 
-                                  const char *src_address, int src_port)
+                                  struct socket_address *src)
 {
        struct ldap_SearchRequest *search;
        if (ldap_msg->type != LDAP_TAG_SearchRequest) {
                DEBUG(0,("Invalid CLDAP request type %d from %s:%d\n", 
-                        ldap_msg->type, src_address, src_port));
+                        ldap_msg->type, src->addr, src->port));
+               cldap_error_reply(cldap, ldap_msg->messageid, src,
+                                 LDAP_OPERATIONS_ERROR, "Invalid CLDAP request");
                return;
        }
 
        search = &ldap_msg->r.SearchRequest;
 
+       if (strcmp("", search->basedn) != 0) {
+               DEBUG(0,("Invalid CLDAP basedn '%s' from %s:%d\n", 
+                        search->basedn, src->addr, src->port));
+               cldap_error_reply(cldap, ldap_msg->messageid, src,
+                                 LDAP_OPERATIONS_ERROR, "Invalid CLDAP basedn");
+               return;
+       }
+
+       if (search->scope != LDAP_SEARCH_SCOPE_BASE) {
+               DEBUG(0,("Invalid CLDAP scope %d from %s:%d\n", 
+                        search->scope, src->addr, src->port));
+               cldap_error_reply(cldap, ldap_msg->messageid, src,
+                                 LDAP_OPERATIONS_ERROR, "Invalid CLDAP scope");
+               return;
+       }
+
        if (search->num_attributes == 1 &&
            strcasecmp(search->attributes[0], "netlogon") == 0) {
                cldapd_netlogon_request(cldap, ldap_msg->messageid,
-                                       search->filter, src_address, src_port);
-       } else {
-               DEBUG(0,("Unknown CLDAP search for '%s'\n", 
-                        ldap_msg->r.SearchRequest.filter));
-               cldap_empty_reply(cldap, ldap_msg->messageid, src_address, src_port);
+                                       search->tree, src);
+               return;
        }
+
+       cldapd_rootdse_request(cldap, ldap_msg->messageid,
+                              search, src);
 }
 
 
@@ -61,20 +87,30 @@ static void cldapd_request_handler(struct cldap_socket *cldap,
 static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, const char *address)
 {
        struct cldap_socket *cldapsock;
+       struct socket_address *socket_address;
        NTSTATUS status;
 
        /* listen for unicasts on the CLDAP port (389) */
        cldapsock = cldap_socket_init(cldapd, cldapd->task->event_ctx);
        NT_STATUS_HAVE_NO_MEMORY(cldapsock);
 
-       status = socket_listen(cldapsock->sock, address, lp_cldap_port(), 0, 0);
+       socket_address = socket_address_from_strings(cldapsock, cldapsock->sock->backend_name, 
+                                                    address, lp_cldap_port(global_loadparm));
+       if (!socket_address) {
+               talloc_free(cldapsock);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = socket_listen(cldapsock->sock, socket_address, 0, 0);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("Failed to bind to %s:%d - %s\n", 
-                        address, lp_cldap_port(), nt_errstr(status)));
+                        address, lp_cldap_port(global_loadparm), nt_errstr(status)));
                talloc_free(cldapsock);
                return status;
        }
 
+       talloc_free(socket_address);
+
        cldap_set_incoming_handler(cldapsock, cldapd_request_handler, cldapd);
 
        return NT_STATUS_OK;
@@ -84,7 +120,7 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, const char *addr
 /*
   setup our listening sockets on the configured network interfaces
 */
-NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd)
+static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd)
 {
        int num_interfaces = iface_count();
        TALLOC_CTX *tmp_ctx = talloc_new(cldapd);
@@ -92,7 +128,7 @@ NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd)
 
        /* if we are allowing incoming packets from any address, then
           we need to bind to the wildcard address */
-       if (!lp_bind_interfaces_only()) {
+       if (!lp_bind_interfaces_only(global_loadparm)) {
                status = cldapd_add_socket(cldapd, "0.0.0.0");
                NT_STATUS_NOT_OK_RETURN(status);
        } else {
@@ -119,25 +155,33 @@ static void cldapd_task_init(struct task_server *task)
        NTSTATUS status;
 
        if (iface_count() == 0) {
-               task_terminate(task, "cldapd: no network interfaces configured");
+               task_server_terminate(task, "cldapd: no network interfaces configured");
                return;
        }
 
+       task_server_set_title(task, "task[cldapd]");
+
        cldapd = talloc(task, struct cldapd_server);
        if (cldapd == NULL) {
-               task_terminate(task, "cldapd: out of memory");
+               task_server_terminate(task, "cldapd: out of memory");
                return;
        }
 
        cldapd->task = task;
-       cldapd->samctx = NULL;
+       cldapd->samctx = samdb_connect(cldapd, anonymous_session(cldapd));
+       if (cldapd->samctx == NULL) {
+               task_server_terminate(task, "cldapd failed to open samdb");
+               return;
+       }
 
        /* start listening on the configured network interfaces */
        status = cldapd_startup_interfaces(cldapd);
        if (!NT_STATUS_IS_OK(status)) {
-               task_terminate(task, "cldapd failed to setup interfaces");
+               task_server_terminate(task, "cldapd failed to setup interfaces");
                return;
        }
+
+       irpc_add_name(task->msg_ctx, "cldap_server");
 }