summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/config.mk6
-rw-r--r--source4/libnet/libnet.h1
-rw-r--r--source4/libnet/libnet_join.c171
-rw-r--r--source4/libnet/libnet_site.c252
4 files changed, 259 insertions, 171 deletions
diff --git a/source4/libnet/config.mk b/source4/libnet/config.mk
index baf81e36e64..8b312bb5ef7 100644
--- a/source4/libnet/config.mk
+++ b/source4/libnet/config.mk
@@ -7,14 +7,16 @@ RELEASE_VERSION = 1
DESCRIPTION = User-friendly access to Samba interfaces
PRIVATE_PROTO_HEADER = libnet_proto.h
PUBLIC_HEADERS = libnet.h libnet_join.h libnet_lookup.h libnet_passwd.h \
- libnet_rpc.h libnet_share.h libnet_time.h libnet_user.h \
- libnet_vampire.h userinfo.h userman.h
+ libnet_rpc.h libnet_share.h libnet_time.h \
+ libnet_user.h libnet_site.h libnet_vampire.h \
+ userinfo.h userman.h
OBJ_FILES = \
libnet.o \
libnet_passwd.o \
libnet_time.o \
libnet_rpc.o \
libnet_join.o \
+ libnet_site.o \
libnet_vampire.o \
libnet_samdump.o \
libnet_samdump_keytab.o \
diff --git a/source4/libnet/libnet.h b/source4/libnet/libnet.h
index 7b379b1fc6a..2496eb0a542 100644
--- a/source4/libnet/libnet.h
+++ b/source4/libnet/libnet.h
@@ -43,6 +43,7 @@ struct libnet_context {
#include "libnet/libnet_time.h"
#include "libnet/libnet_rpc.h"
#include "libnet/libnet_join.h"
+#include "libnet/libnet_site.h"
#include "libnet/libnet_vampire.h"
#include "libnet/libnet_user.h"
#include "libnet/libnet_share.h"
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index a467999023a..f4e4091ce3c 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -25,175 +25,10 @@
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
-#include "libcli/cldap/cldap.h"
#include "passdb/secrets.h"
#include "dsdb/samdb/samdb.h"
/*
- * find out Site specific stuff:
- * 1.) setup an CLDAP socket
- * 2.) lookup the Site name
- * 3.) Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>.
- * TODO: 4.) use DsAddEntry() to create CN=NTDS Settings,CN=<netbios name>,CN=Servers,CN=<site name>...
- */
-static NTSTATUS libnet_JoinSite(struct libnet_context *ctx,
- struct dcerpc_pipe *drsuapi_pipe,
- struct policy_handle drsuapi_bind_handle,
- struct ldb_context *remote_ldb,
- struct libnet_JoinDomain *libnet_r)
-{
- NTSTATUS status;
- TALLOC_CTX *tmp_ctx;
-
- struct cldap_socket *cldap = NULL;
- struct cldap_netlogon search;
-
- struct ldb_dn *server_dn;
- struct ldb_message *msg;
- int rtn;
-
- const char *site_name;
- const char *server_dn_str;
- const char *config_dn_str;
-
- tmp_ctx = talloc_named(libnet_r, 0, "libnet_JoinSite temp context");
- if (!tmp_ctx) {
- libnet_r->out.error_string = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- /* Resolve the site name. */
-
- ZERO_STRUCT(search);
- search.in.dest_address = libnet_r->out.samr_binding->host;
- search.in.acct_control = -1;
- search.in.version = 6;
-
- cldap = cldap_socket_init(tmp_ctx, NULL);
- status = cldap_netlogon(cldap, tmp_ctx, &search);
- if (!NT_STATUS_IS_OK(status)) {
- /* Default to using Default-First-Site-Name rather than returning status at this point. */
- site_name = talloc_asprintf(tmp_ctx, "%s", "Default-First-Site-Name");
- if (!site_name) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- } else {
- site_name = search.out.netlogon.logon5.site_name;
- }
-
- config_dn_str = talloc_asprintf(tmp_ctx, "CN=Configuration,%s", libnet_r->out.domain_dn_str);
- if (!config_dn_str) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- server_dn_str = talloc_asprintf(tmp_ctx, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
- libnet_r->in.netbios_name, site_name, config_dn_str);
- if (!server_dn_str) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- /*
- Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>.
- */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- rtn = ldb_msg_add_string(msg, "objectClass", "server");
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- rtn = ldb_msg_add_string(msg, "systemFlags", "50000000");
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str);
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- server_dn = ldb_dn_explode(tmp_ctx, server_dn_str);
- if (server_dn == NULL) {
- libnet_r->out.error_string = talloc_asprintf(libnet_r,
- "Invalid server dn: %s",
- server_dn_str);
- talloc_free(tmp_ctx);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- msg->dn = server_dn;
-
- rtn = ldb_add(remote_ldb, msg);
- if (rtn == LDB_ERR_ENTRY_ALREADY_EXISTS) {
- int i;
-
- /* make a 'modify' msg, and only for serverReference */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- msg->dn = server_dn;
-
- rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str);
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- /* mark all the message elements (should be just one)
- as LDB_FLAG_MOD_REPLACE */
- for (i=0;i<msg->num_elements;i++) {
- msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
- }
-
- rtn = ldb_modify(remote_ldb, msg);
- if (rtn != 0) {
- libnet_r->out.error_string
- = talloc_asprintf(libnet_r,
- "Failed to modify server entry %s: %s: %d",
- server_dn_str,
- ldb_errstring(remote_ldb), rtn);
- talloc_free(tmp_ctx);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- } else if (rtn != 0) {
- libnet_r->out.error_string
- = talloc_asprintf(libnet_r,
- "Failed to add server entry %s: %s: %d",
- server_dn_str,
- ldb_errstring(remote_ldb), rtn);
- talloc_free(tmp_ctx);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- DEBUG(0, ("We still need to perform a DsAddEntry() so that we can create the CN=NTDS Settings container.\n"));
-
- /* Store the server DN in libnet_r */
- libnet_r->out.server_dn_str = server_dn_str;
- talloc_steal(libnet_r, server_dn_str);
-
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
-}
-
-/*
* complete a domain join, when joining to a AD domain:
* 1.) connect and bind to the DRSUAPI pipe
* 2.) do a DsCrackNames() to find the machine account dn
@@ -532,10 +367,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
r->out.kvno = kvno;
- if (r->in.acct_type == ACB_SVRTRUST) {
- status = libnet_JoinSite(ctx,
- drsuapi_pipe, drsuapi_bind_handle,
- remote_ldb, r);
+ if (r->in.acct_type == ACB_SVRTRUST) {
+ status = libnet_JoinSite(remote_ldb, r);
}
talloc_free(tmp_ctx);
diff --git a/source4/libnet/libnet_site.c b/source4/libnet/libnet_site.c
new file mode 100644
index 00000000000..75efc0562db
--- /dev/null
+++ b/source4/libnet/libnet_site.c
@@ -0,0 +1,252 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Brad Henry 2005
+
+ 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 02139, USA.
+*/
+
+#include "includes.h"
+#include "libnet/libnet.h"
+#include "libcli/cldap/cldap.h"
+#include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
+
+/*
+ * 1. Setup a CLDAP socket.
+ * 2. Lookup the default Site-Name.
+ */
+NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_JoinSite *r)
+{
+ NTSTATUS status;
+ TALLOC_CTX *tmp_ctx;
+
+ char *site_name_str;
+ char *config_dn_str;
+ char *server_dn_str;
+
+ struct cldap_socket *cldap = NULL;
+ struct cldap_netlogon search;
+
+ tmp_ctx = talloc_named(ctx, 0, "libnet_FindSite temp context");
+ if (!tmp_ctx) {
+ r->out.error_string = NULL;
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Resolve the site name. */
+ ZERO_STRUCT(search);
+ search.in.dest_address = r->in.dest_address;
+ search.in.acct_control = -1;
+ search.in.version = 6;
+
+ cldap = cldap_socket_init(tmp_ctx, NULL);
+ status = cldap_netlogon(cldap, tmp_ctx, &search);
+ if (!NT_STATUS_IS_OK(status)) {
+ /*
+ If cldap_netlogon() returns in error,
+ default to using Default-First-Site-Name.
+ */
+ site_name_str = talloc_asprintf(tmp_ctx, "%s",
+ "Default-First-Site-Name");
+ if (!site_name_str) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ site_name_str = talloc_asprintf(tmp_ctx, "%s",
+ search.out.netlogon.logon5.site_name);
+ if (!site_name_str) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ /* Generate the CN=Configuration,... DN. */
+ config_dn_str = talloc_asprintf(tmp_ctx, "CN=Configuration,%s", r->in.domain_dn_str);
+ if (!config_dn_str) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Generate the CN=Servers,... DN. */
+ server_dn_str = talloc_asprintf(tmp_ctx, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
+ r->in.netbios_name, site_name_str, config_dn_str);
+ if (!server_dn_str) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ r->out.site_name_str = site_name_str;
+ talloc_steal(r, site_name_str);
+
+ r->out.config_dn_str = config_dn_str;
+ talloc_steal(r, config_dn_str);
+
+ r->out.server_dn_str = server_dn_str;
+ talloc_steal(r, server_dn_str);
+
+ talloc_free(tmp_ctx);
+ return NT_STATUS_OK;
+}
+
+/*
+ * find out Site specific stuff:
+ * 1. Lookup the Site name.
+ * 2. Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>.
+ * TODO: 3.) use DsAddEntry() to create CN=NTDS Settings,CN=<netbios name>,CN=Servers,CN=<site name>,...
+ */
+NTSTATUS libnet_JoinSite(struct ldb_context *remote_ldb,
+ struct libnet_JoinDomain *libnet_r)
+{
+ NTSTATUS status;
+ TALLOC_CTX *tmp_ctx;
+
+ struct libnet_JoinSite *r;
+
+ struct ldb_dn *server_dn;
+ struct ldb_message *msg;
+ int rtn;
+
+ const char *server_dn_str;
+ const char *config_dn_str;
+
+ tmp_ctx = talloc_named(libnet_r, 0, "libnet_JoinSite temp context");
+ if (!tmp_ctx) {
+ libnet_r->out.error_string = NULL;
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ r = talloc(tmp_ctx, struct libnet_JoinSite);
+ if (!r) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Resolve the site name and AD DN's. */
+ r->in.dest_address = libnet_r->out.samr_binding->host;
+ r->in.netbios_name = libnet_r->in.netbios_name;
+ r->in.domain_dn_str = libnet_r->out.domain_dn_str;
+
+ status = libnet_FindSite(tmp_ctx, r);
+ if (!NT_STATUS_IS_OK(status)) {
+ libnet_r->out.error_string =
+ talloc_steal(libnet_r, r->out.error_string);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ config_dn_str = r->out.config_dn_str;
+ server_dn_str = r->out.server_dn_str;
+
+ /*
+ Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>.
+ */
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ rtn = ldb_msg_add_string(msg, "objectClass", "server");
+ if (rtn != 0) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ rtn = ldb_msg_add_string(msg, "systemFlags", "50000000");
+ if (rtn != 0) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ rtn = ldb_msg_add_string(msg, "serverReference", libnet_r->out.account_dn_str);
+ if (rtn != 0) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ server_dn = ldb_dn_explode(tmp_ctx, server_dn_str);
+ if (server_dn == NULL) {
+ libnet_r->out.error_string = talloc_asprintf(libnet_r,
+ "Invalid server dn: %s",
+ server_dn_str);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ msg->dn = server_dn;
+
+ rtn = ldb_add(remote_ldb, msg);
+ if (rtn == LDB_ERR_ENTRY_ALREADY_EXISTS) {
+ int i;
+
+ /* make a 'modify' msg, and only for serverReference */
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ msg->dn = server_dn;
+
+ rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str);
+ if (rtn != 0) {
+ libnet_r->out.error_string = NULL;
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* mark all the message elements (should be just one)
+ as LDB_FLAG_MOD_REPLACE */
+ for (i=0;i<msg->num_elements;i++) {
+ msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+ }
+
+ rtn = ldb_modify(remote_ldb, msg);
+ if (rtn != 0) {
+ libnet_r->out.error_string
+ = talloc_asprintf(libnet_r,
+ "Failed to modify server entry %s: %s: %d",
+ server_dn_str,
+ ldb_errstring(remote_ldb), rtn);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ } else if (rtn != 0) {
+ libnet_r->out.error_string
+ = talloc_asprintf(libnet_r,
+ "Failed to add server entry %s: %s: %d",
+ server_dn_str, ldb_errstring(remote_ldb),
+ rtn);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ DEBUG(0, ("We still need to perform a DsAddEntry() so that we can create the CN=NTDS Settings container.\n"));
+
+ /* Store the server DN in libnet_r */
+ libnet_r->out.server_dn_str = server_dn_str;
+ talloc_steal(libnet_r, server_dn_str);
+
+ talloc_free(tmp_ctx);
+ return NT_STATUS_OK;
+}