summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/libnet.h20
-rw-r--r--source4/libnet/libnet_rpc.c51
2 files changed, 62 insertions, 9 deletions
diff --git a/source4/libnet/libnet.h b/source4/libnet/libnet.h
index 0a96e6c530..72c2fecdad 100644
--- a/source4/libnet/libnet.h
+++ b/source4/libnet/libnet.h
@@ -32,6 +32,26 @@ struct libnet_context {
} user;
};
+/* struct and enum for finding a domain controller */
+enum libnet_find_pdc_level {
+ LIBNET_FIND_PDC_GENERIC
+};
+
+union libnet_find_pdc {
+ /* find to a domains PDC */
+ struct {
+ enum libnet_find_pdc_level level;
+
+ struct {
+ const char *domain_name;
+ } in;
+
+ struct {
+ const char *pdc_name;
+ } out;
+ } generic;
+};
+
/* struct and enum for connecting to a dcerpc inferface */
enum libnet_rpc_connect_level {
LIBNET_RPC_CONNECT_PDC
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index c76498d0bb..7cee7681e8 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -20,21 +20,54 @@
#include "includes.h"
+/* find a domain pdc generic */
+static NTSTATUS libnet_find_pdc_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_find_pdc *r)
+{
+ BOOL ret;
+ struct in_addr ip;
+
+ ret = get_pdc_ip(mem_ctx, r->generic.in.domain_name, &ip);
+ if (!ret) {
+ /* fallback to a workstation name */
+ ret = resolve_name(mem_ctx, r->generic.in.domain_name, &ip, 0x20);
+ if (!ret) {
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+ }
+
+ r->generic.out.pdc_name = talloc_strdup(mem_ctx, inet_ntoa(ip));
+
+ return NT_STATUS_OK;
+}
+
+/* find a domain pdc */
+NTSTATUS libnet_find_pdc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_find_pdc *r)
+{
+ switch (r->generic.level) {
+ case LIBNET_FIND_PDC_GENERIC:
+ return libnet_find_pdc_generic(ctx, mem_ctx, r);
+ }
+
+ return NT_STATUS_INVALID_LEVEL;
+}
+
/* connect to a dcerpc interface of a domains PDC */
-NTSTATUS libnet_rpc_connect_pdc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_rpc_connect *r)
+static NTSTATUS libnet_rpc_connect_pdc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_rpc_connect *r)
{
NTSTATUS status;
const char *binding = NULL;
- const char *pdc = NULL;
+ union libnet_find_pdc f;
+
+ f.generic.level = LIBNET_FIND_PDC_GENERIC;
+ f.generic.in.domain_name = r->pdc.in.domain_name;
- /* TODO: find real PDC!
- * for now I use the lp_netbios_name()
- * that's the most important for me as we don't have
- * smbpasswd in samba4 (and this is good!:-) --metze
- */
- pdc = lp_netbios_name();
+ status = libnet_find_pdc(ctx, mem_ctx, &f);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- binding = talloc_asprintf(mem_ctx, "ncacn_np:%s",pdc);
+ binding = talloc_asprintf(mem_ctx, "ncacn_np:%s",
+ f.generic.out.pdc_name);
status = dcerpc_pipe_connect(&r->pdc.out.dcerpc_pipe,
binding,