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);
}
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;
/*
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);
/* 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 {
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");
}