summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/socket_wrapper/socket_wrapper.c71
-rw-r--r--lib/socket_wrapper/socket_wrapper.h6
-rw-r--r--source4/auth/auth.h8
-rw-r--r--source4/auth/ntlm/auth_sam.c144
-rw-r--r--source4/auth/sam.c49
-rw-r--r--source4/cldap_server/netlogon.c116
-rw-r--r--source4/kdc/config.mk4
-rw-r--r--source4/kdc/hdb-samba4.c207
-rw-r--r--source4/kdc/kdc.h4
-rw-r--r--source4/kdc/pac-glue.c10
-rw-r--r--source4/nbt_server/dgram/netlogon.c21
-rw-r--r--source4/param/loadparm.c1
-rw-r--r--source4/param/param.h5
-rw-r--r--source4/param/util.c17
-rw-r--r--source4/rpc_server/config.mk3
-rw-r--r--source4/rpc_server/lsa/lsa_init.c69
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c82
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c128
18 files changed, 330 insertions, 615 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index d809d8a500..bd848f920b 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -118,6 +118,7 @@
#define real_setsockopt setsockopt
#define real_recvfrom recvfrom
#define real_sendto sendto
+#define real_sendmsg sendmsg
#define real_ioctl ioctl
#define real_recv recv
#define real_send send
@@ -2064,6 +2065,76 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
return ret;
}
+_PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags)
+{
+ int ret;
+ uint8_t *buf;
+ off_t ofs = 0;
+ size_t i;
+ size_t remain;
+
+ struct socket_info *si = find_socket_info(s);
+
+ if (!si) {
+ return real_sendmsg(s, msg, flags);
+ }
+
+ if (si->defer_connect) {
+ struct sockaddr_un un_addr;
+ int bcast = 0;
+
+ if (si->bound == 0) {
+ ret = swrap_auto_bind(si, si->family);
+ if (ret == -1) return -1;
+ }
+
+ ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
+ &un_addr, 0, &bcast);
+ if (ret == -1) return -1;
+
+ ret = real_connect(s, (struct sockaddr *)&un_addr,
+ sizeof(un_addr));
+
+ /* to give better errors */
+ if (ret == -1 && errno == ENOENT) {
+ errno = EHOSTUNREACH;
+ }
+
+ if (ret == -1) {
+ return ret;
+ }
+ si->defer_connect = 0;
+ }
+
+ ret = real_sendmsg(s, msg, flags);
+ remain = ret;
+
+ /* we capture it as one single packet */
+ buf = (uint8_t *)malloc(ret);
+ if (!buf) {
+ /* we just not capture the packet */
+ errno = 0;
+ return ret;
+ }
+
+ for (i=0; i < msg->msg_iovlen; i++) {
+ size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
+ memcpy(buf + ofs,
+ msg->msg_iov[i].iov_base,
+ this_time);
+ ofs += this_time;
+ remain -= this_time;
+ }
+
+ swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
+ free(buf);
+ if (ret == -1) {
+ swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
+ }
+
+ return ret;
+}
+
int swrap_readv(int s, const struct iovec *vector, size_t count)
{
int ret;
diff --git a/lib/socket_wrapper/socket_wrapper.h b/lib/socket_wrapper/socket_wrapper.h
index b2d44769ff..56282e23b9 100644
--- a/lib/socket_wrapper/socket_wrapper.h
+++ b/lib/socket_wrapper/socket_wrapper.h
@@ -49,6 +49,7 @@ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *opt
int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
+ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags);
int swrap_ioctl(int s, int req, void *ptr);
ssize_t swrap_recv(int s, void *buf, size_t len, int flags);
ssize_t swrap_send(int s, const void *buf, size_t len, int flags);
@@ -108,6 +109,11 @@ int swrap_close(int);
#endif
#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen)
+#ifdef sendmsg
+#undef sendmsg
+#endif
+#define sendmsg(s,msg,flags) swrap_sendmsg(s,msg,flags)
+
#ifdef ioctl
#undef ioctl
#endif
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 973102d842..f6d739325d 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -221,24 +221,26 @@ struct auth_critical_sizes {
struct ldb_message;
struct ldb_context;
+struct ldb_dn;
struct gensec_security;
NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal);
NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
struct ldb_context *sam_ctx,
uint32_t logon_parameters,
+ struct ldb_dn *domain_dn,
struct ldb_message *msg,
- struct ldb_message *msg_domain_ref,
const char *logon_workstation,
const char *name_for_logs,
bool allow_domain_trust);
struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
const char *netbios_name,
+ const char *domain_name,
+ struct ldb_dn *domain_dn,
struct ldb_message *msg,
- struct ldb_message *msg_domain_ref,
DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
- struct auth_serversupplied_info **_server_info);
+ struct auth_serversupplied_info **_server_info);
NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx,
struct loadparm_context *lp_ctx,
struct auth_session_info **_session_info) ;
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index e99d0e1f51..75ed3243d4 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -42,26 +42,12 @@ extern const char *domain_ref_attrs[];
static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
const char *account_name,
- const char *domain_name,
- struct ldb_message ***ret_msgs,
- struct ldb_message ***ret_msgs_domain_ref)
+ struct ldb_dn *domain_dn,
+ struct ldb_message ***ret_msgs)
{
- struct ldb_message **msgs_tmp;
struct ldb_message **msgs;
- struct ldb_message **msgs_domain_ref;
- struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
int ret;
- int ret_domain;
-
- struct ldb_dn *domain_dn = NULL;
-
- if (domain_name) {
- domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx, domain_name);
- if (!domain_dn) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- }
/* pull the user attributes */
ret = gendb_search(sam_ctx, mem_ctx, domain_dn, &msgs, user_attrs,
@@ -72,8 +58,8 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
}
if (ret == 0) {
- DEBUG(3,("sam_search_user: Couldn't find user [%s\\%s] in samdb, under %s\n",
- domain_name, account_name, ldb_dn_get_linearized(domain_dn)));
+ DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n",
+ account_name, ldb_dn_get_linearized(domain_dn)));
return NT_STATUS_NO_SUCH_USER;
}
@@ -82,57 +68,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- if (!domain_dn) {
- struct dom_sid *domain_sid;
-
- domain_sid = samdb_result_sid_prefix(mem_ctx, msgs[0], "objectSid");
- if (!domain_sid) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- /* find the domain's DN */
- ret = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_tmp, NULL,
- "(&(objectSid=%s)(objectClass=domain))",
- ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
- if (ret == -1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- if (ret == 0) {
- DEBUG(3,("check_sam_security: Couldn't find domain_sid [%s] in passdb file.\n",
- dom_sid_string(mem_ctx, domain_sid)));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- if (ret > 1) {
- DEBUG(0,("Found %d records matching domain_sid [%s]\n",
- ret, dom_sid_string(mem_ctx, domain_sid)));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- domain_dn = msgs_tmp[0]->dn;
- }
-
- ret_domain = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &msgs_domain_ref, domain_ref_attrs,
- "(nCName=%s)", ldb_dn_get_linearized(domain_dn));
- if (ret_domain == -1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- if (ret_domain == 0) {
- DEBUG(3,("check_sam_security: Couldn't find domain [%s] in passdb file.\n",
- ldb_dn_get_linearized(msgs_tmp[0]->dn)));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- if (ret_domain > 1) {
- DEBUG(0,("Found %d records matching domain [%s]\n",
- ret_domain, ldb_dn_get_linearized(msgs_tmp[0]->dn)));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
*ret_msgs = msgs;
- *ret_msgs_domain_ref = msgs_domain_ref;
return NT_STATUS_OK;
}
@@ -210,14 +146,13 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context,
static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
+ struct ldb_dn *domain_dn,
struct ldb_message **msgs,
- struct ldb_message **msgs_domain_ref,
const struct auth_usersupplied_info *user_info,
DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key)
{
struct samr_Password *lm_pwd, *nt_pwd;
NTSTATUS nt_status;
- struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msgs_domain_ref[0], "nCName", NULL);
uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msgs[0], domain_dn);
@@ -245,8 +180,8 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
nt_status = authsam_account_ok(mem_ctx, sam_ctx,
user_info->logon_parameters,
+ domain_dn,
msgs[0],
- msgs_domain_ref[0],
user_info->workstation_name,
user_info->mapped.account_name,
false);
@@ -258,15 +193,14 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx,
TALLOC_CTX *mem_ctx,
- const char *domain,
const struct auth_usersupplied_info *user_info,
struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
const char *account_name = user_info->mapped.account_name;
struct ldb_message **msgs;
- struct ldb_message **domain_ref_msgs;
struct ldb_context *sam_ctx;
+ struct ldb_dn *domain_dn;
DATA_BLOB user_sess_key, lm_sess_key;
TALLOC_CTX *tmp_ctx;
@@ -286,13 +220,19 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain, &msgs, &domain_ref_msgs);
+ domain_dn = ldb_get_default_basedn(sam_ctx);
+ if (domain_dn == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+ nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msgs);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(tmp_ctx);
return nt_status;
}
- nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, msgs, domain_ref_msgs, user_info,
+ nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msgs, user_info,
&user_sess_key, &lm_sess_key);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(tmp_ctx);
@@ -300,7 +240,9 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
}
nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
- msgs[0], domain_ref_msgs[0],
+ lp_sam_name(ctx->auth_ctx->lp_ctx),
+ domain_dn,
+ msgs[0],
user_sess_key, lm_sess_key,
server_info);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -325,14 +267,6 @@ static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx,
return NT_STATUS_OK;
}
-static NTSTATUS authsam_ignoredomain_check_password(struct auth_method_context *ctx,
- TALLOC_CTX *mem_ctx,
- const struct auth_usersupplied_info *user_info,
- struct auth_serversupplied_info **server_info)
-{
- return authsam_check_password_internals(ctx, mem_ctx, NULL, user_info, server_info);
-}
-
/****************************************************************************
Check SAM security (above) but with a few extra checks.
****************************************************************************/
@@ -377,34 +311,6 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
return NT_STATUS_NOT_IMPLEMENTED;
}
-/****************************************************************************
-Check SAM security (above) but with a few extra checks.
-****************************************************************************/
-static NTSTATUS authsam_check_password(struct auth_method_context *ctx,
- TALLOC_CTX *mem_ctx,
- const struct auth_usersupplied_info *user_info,
- struct auth_serversupplied_info **server_info)
-{
- const char *domain;
-
- /* check whether or not we service this domain/workgroup name */
- switch (lp_server_role(ctx->auth_ctx->lp_ctx)) {
- case ROLE_STANDALONE:
- case ROLE_DOMAIN_MEMBER:
- domain = lp_netbios_name(ctx->auth_ctx->lp_ctx);
- break;
-
- case ROLE_DOMAIN_CONTROLLER:
- domain = lp_workgroup(ctx->auth_ctx->lp_ctx);
- break;
-
- default:
- return NT_STATUS_NO_SUCH_USER;
- }
-
- return authsam_check_password_internals(ctx, mem_ctx, domain, user_info, server_info);
-}
-
/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
@@ -417,9 +323,9 @@ NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
DATA_BLOB lm_sess_key = data_blob(NULL, 0);
struct ldb_message **msgs;
- struct ldb_message **msgs_domain_ref;
struct ldb_context *sam_ctx;
-
+ struct ldb_dn *domain_dn;
+
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
return NT_STATUS_NO_MEMORY;
@@ -433,14 +339,16 @@ NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
}
nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal,
- &msgs, &msgs_domain_ref);
+ &domain_dn, &msgs);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
nt_status = authsam_make_server_info(tmp_ctx, sam_ctx,
lp_netbios_name(auth_context->lp_ctx),
- msgs[0], msgs_domain_ref[0],
+ lp_workgroup(auth_context->lp_ctx),
+ domain_dn,
+ msgs[0],
user_sess_key, lm_sess_key,
server_info);
if (NT_STATUS_IS_OK(nt_status)) {
@@ -454,7 +362,7 @@ static const struct auth_operations sam_ignoredomain_ops = {
.name = "sam_ignoredomain",
.get_challenge = auth_get_challenge_not_implemented,
.want_check = authsam_ignoredomain_want_check,
- .check_password = authsam_ignoredomain_check_password,
+ .check_password = authsam_check_password_internals,
.get_server_info_principal = authsam_get_server_info_principal
};
@@ -462,7 +370,7 @@ static const struct auth_operations sam_ops = {
.name = "sam",
.get_challenge = auth_get_challenge_not_implemented,
.want_check = authsam_want_check,
- .check_password = authsam_check_password,
+ .check_password = authsam_check_password_internals,
.get_server_info_principal = authsam_get_server_info_principal
};
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index 819bca0db0..ebdf1932af 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -139,21 +139,19 @@ static bool logon_hours_ok(struct ldb_message *msg, const char *name_for_logs)
(ie not disabled, expired and the like).
****************************************************************************/
_PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
- struct ldb_context *sam_ctx,
- uint32_t logon_parameters,
- struct ldb_message *msg,
- struct ldb_message *msg_domain_ref,
- const char *logon_workstation,
- const char *name_for_logs,
- bool allow_domain_trust)
+ struct ldb_context *sam_ctx,
+ uint32_t logon_parameters,
+ struct ldb_dn *domain_dn,
+ struct ldb_message *msg,
+ const char *logon_workstation,
+ const char *name_for_logs,
+ bool allow_domain_trust)
{
uint16_t acct_flags;
const char *workstation_list;
NTTIME acct_expiry;
NTTIME must_change_time;
- struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx, sam_ctx, NULL));
-
NTTIME now;
DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs));
@@ -256,8 +254,9 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
_PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
const char *netbios_name,
+ const char *domain_name,
+ struct ldb_dn *domain_dn,
struct ldb_message *msg,
- struct ldb_message *msg_domain_ref,
DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
struct auth_serversupplied_info **_server_info)
{
@@ -269,7 +268,6 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
struct dom_sid **groupSIDs = NULL;
struct dom_sid *account_sid;
struct dom_sid *primary_group_sid;
- struct ldb_dn *domain_dn;
const char *str;
struct ldb_dn *ncname;
int i;
@@ -327,7 +325,8 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
server_info->account_name = talloc_steal(server_info, samdb_result_string(msg, "sAMAccountName", NULL));
- server_info->domain_name = talloc_steal(server_info, samdb_result_string(msg_domain_ref, "nETBIOSName", NULL));
+ server_info->domain_name = talloc_strdup(server_info, domain_name);
+ NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
str = samdb_result_string(msg, "displayName", "");
server_info->full_name = talloc_strdup(server_info, str);
@@ -357,10 +356,6 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
server_info->acct_expiry = samdb_result_account_expires(msg);
server_info->last_password_change = samdb_result_nttime(msg, "pwdLastSet", 0);
- ncname = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
- if (!ncname) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
server_info->allow_password_change
= samdb_result_allow_password_change(sam_ctx, mem_ctx,
ncname, msg, "pwdLastSet");
@@ -371,8 +366,6 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);
server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount", 0);
- domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
-
server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
msg, domain_dn);
@@ -388,34 +381,24 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
TALLOC_CTX *mem_ctx, const char *principal,
- struct ldb_message ***msgs,
- struct ldb_message ***msgs_domain_ref)
+ struct ldb_dn **domain_dn,
+ struct ldb_message ***msgs)
{
- struct ldb_dn *user_dn, *domain_dn;
+ struct ldb_dn *user_dn;
NTSTATUS nt_status;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
int ret;
- struct ldb_dn *partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
if (!tmp_ctx) {
return NT_STATUS_NO_MEMORY;
}
- nt_status = crack_user_principal_name(sam_ctx, tmp_ctx, principal, &user_dn, &domain_dn);
+ nt_status = crack_user_principal_name(sam_ctx, tmp_ctx, principal, &user_dn, domain_dn);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(tmp_ctx);
return nt_status;
}
- /* grab domain info from the reference */
- ret = gendb_search(sam_ctx, tmp_ctx, partitions_basedn, msgs_domain_ref, domain_ref_attrs,
- "(ncName=%s)", ldb_dn_get_linearized(domain_dn));
-
- if (ret != 1) {
- talloc_free(tmp_ctx);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
/* pull the user attributes */
ret = gendb_search_dn(sam_ctx, tmp_ctx, user_dn, msgs, user_attrs);
if (ret != 1) {
@@ -423,7 +406,7 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
talloc_steal(mem_ctx, *msgs);
- talloc_steal(mem_ctx, *msgs_domain_ref);
+ talloc_steal(mem_ctx, *domain_dn);
talloc_free(tmp_ctx);
return NT_STATUS_OK;
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c
index 33c0adc3b1..8a21ea55c9 100644
--- a/source4/cldap_server/netlogon.c
+++ b/source4/cldap_server/netlogon.c
@@ -53,10 +53,9 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
struct loadparm_context *lp_ctx,
struct netlogon_samlogon_response *netlogon)
{
- const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
const char *dom_attrs[] = {"objectGUID", NULL};
const char *none_attrs[] = {NULL};
- struct ldb_result *ref_res = NULL, *dom_res = NULL, *user_res = NULL;
+ struct ldb_result *dom_res = NULL, *user_res = NULL;
int ret;
const char **services = lp_server_services(lp_ctx);
uint32_t server_type;
@@ -69,94 +68,39 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
const char *server_site;
const char *client_site;
const char *pdc_ip;
- struct ldb_dn *partitions_basedn;
+ struct ldb_dn *domain_dn = NULL;
struct interface *ifaces;
bool user_known;
NTSTATUS status;
- partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
-
/* the domain has an optional trailing . */
if (domain && domain[strlen(domain)-1] == '.') {
domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1);
}
- if (domain) {
- struct ldb_dn *dom_dn;
- /* try and find the domain */
-
- ret = ldb_search(sam_ctx, mem_ctx, &ref_res,
- partitions_basedn, LDB_SCOPE_ONELEVEL,
- ref_attrs,
- "(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))",
- ldb_binary_encode_string(mem_ctx, domain));
-
- if (ret != LDB_SUCCESS) {
- DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
- domain,
- ldb_errstring(sam_ctx)));
- return NT_STATUS_NO_SUCH_DOMAIN;
- } else if (ref_res->count == 1) {
- dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName");
- if (!dom_dn) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
- dom_dn, LDB_SCOPE_BASE, dom_attrs,
- "objectClass=domain");
- if (ret != LDB_SUCCESS) {
- DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx)));
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- if (dom_res->count != 1) {
- DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn)));
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else if (ref_res->count > 1) {
- talloc_free(ref_res);
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
+ if (domain && strcasecmp_m(domain, lp_realm(lp_ctx)) == 0) {
+ domain_dn = ldb_get_default_basedn(sam_ctx);
}
- if (netbios_domain) {
- struct ldb_dn *dom_dn;
- /* try and find the domain */
+ if (netbios_domain && strcasecmp_m(domain, lp_sam_name(lp_ctx))) {
+ domain_dn = ldb_get_default_basedn(sam_ctx);
+ }
- ret = ldb_search(sam_ctx, mem_ctx, &ref_res,
- partitions_basedn, LDB_SCOPE_ONELEVEL,
- ref_attrs,
- "(&(objectClass=crossRef)(ncName=*)(nETBIOSName=%s))",
- ldb_binary_encode_string(mem_ctx, netbios_domain));
-
+ if (domain_dn) {
+ ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
+ domain_dn, LDB_SCOPE_BASE, dom_attrs,
+ "objectClass=domain");
if (ret != LDB_SUCCESS) {
- DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
- netbios_domain,
- ldb_errstring(sam_ctx)));
+ DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(domain_dn), ldb_errstring(sam_ctx)));
return NT_STATUS_NO_SUCH_DOMAIN;
- } else if (ref_res->count == 1) {
- dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName");
- if (!dom_dn) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
- dom_dn, LDB_SCOPE_BASE, dom_attrs,
- "objectClass=domain");
- if (ret != LDB_SUCCESS) {
- DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx)));
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- if (dom_res->count != 1) {
- DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn)));
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else if (ref_res->count > 1) {
- talloc_free(ref_res);
+ }
+ if (dom_res->count != 1) {
+ DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(domain_dn)));
return NT_STATUS_NO_SUCH_DOMAIN;
}
}
if ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) {
- ref_res = NULL;
if (domain_guid) {
struct GUID binary_guid;
@@ -206,36 +150,17 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
ldb_errstring(sam_ctx)));
return NT_STATUS_NO_SUCH_DOMAIN;
} else if (dom_res->count == 1) {
- /* try and find the domain */
- ret = ldb_search(sam_ctx, mem_ctx, &ref_res,
- partitions_basedn, LDB_SCOPE_ONELEVEL,
- ref_attrs,
- "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(dom_res->msgs[0]->dn));
+ /* Ok, now just check it is our domain */
- if (ret != LDB_SUCCESS) {
- DEBUG(2,("Unable to find referece to '%s' in sam: %s\n",
- ldb_dn_get_linearized(dom_res->msgs[0]->dn),
- ldb_errstring(sam_ctx)));
- return NT_STATUS_NO_SUCH_DOMAIN;
-
- } else if (ref_res->count != 1) {
- DEBUG(2,("Unable to find referece to '%s' in sam\n",
- ldb_dn_get_linearized(dom_res->msgs[0]->dn)));
+ if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx), dom_res->msgs[0]->dn) != 0) {
return NT_STATUS_NO_SUCH_DOMAIN;
}
} else if (dom_res->count > 1) {
- talloc_free(ref_res);
return NT_STATUS_NO_SUCH_DOMAIN;
}
}
- if ((ref_res == NULL || ref_res->count == 0)) {
- DEBUG(2,("Unable to find domain reference with name %s or GUID {%s}\n", domain, domain_guid));
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
-
if ((dom_res == NULL || dom_res->count == 0)) {
DEBUG(2,("Unable to find domain with name %s or GUID {%s}\n", domain, domain_guid));
return NT_STATUS_NO_SUCH_DOMAIN;
@@ -308,15 +233,14 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
pdc_name = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name(lp_ctx));
domain_uuid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
- realm = samdb_result_string(ref_res->msgs[0], "dnsRoot", lp_realm(lp_ctx));
- dns_domain = samdb_result_string(ref_res->msgs[0], "dnsRoot", lp_realm(lp_ctx));
+ realm = lp_realm(lp_ctx);
+ dns_domain = lp_realm(lp_ctx);
pdc_dns_name = talloc_asprintf(mem_ctx, "%s.%s",
strlower_talloc(mem_ctx,
lp_netbios_name(lp_ctx)),
dns_domain);
- flatname = samdb_result_string(ref_res->msgs[0], "nETBIOSName",
- lp_workgroup(lp_ctx));
+ flatname = lp_sam_name(lp_ctx);
/* FIXME: Hardcoded site names */
server_site = "Default-First-Site-Name";
client_site = "Default-First-Site-Name";
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index bd8a313316..03fa2db295 100644
--- a/source4/kdc/config.mk
+++ b/source4/kdc/config.mk
@@ -6,7 +6,7 @@
INIT_FUNCTION = server_service_kdc_init
SUBSYSTEM = service
PRIVATE_DEPENDENCIES = \
- HEIMDAL_KDC HDB_SAMBA4
+ HEIMDAL_KDC HDB_SAMBA4 LIBSAMBA-HOSTCONFIG
# End SUBSYSTEM KDC
#######################
@@ -18,7 +18,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o)
CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
PRIVATE_DEPENDENCIES = \
LIBLDB auth_sam auth_sam_reply CREDENTIALS \
- HEIMDAL_HDB
+ HEIMDAL_HDB LIBSAMBA-HOSTCONFIG
# End SUBSYSTEM KDC
#######################
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index daeed77975..1fdb744a84 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd.
- * Copyright (c) 2004, Andrew Bartlett <abartlet@samba.org>.
+ * Copyright (c) 2004-2009, Andrew Bartlett <abartlet@samba.org>.
* Copyright (c) 2004, Stefan Metzmacher <metze@samba.org>
* All rights reserved.
*
@@ -62,12 +62,6 @@ enum trust_direction {
OUTBOUND = LSA_TRUST_DIRECTION_OUTBOUND
};
-static const char *realm_ref_attrs[] = {
- "nCName",
- "dnsRoot",
- NULL
-};
-
static const char *trust_attrs[] = {
"trustPartner",
"trustAuthIncoming",
@@ -491,32 +485,33 @@ out:
*/
static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
TALLOC_CTX *mem_ctx, krb5_const_principal principal,
- enum hdb_ldb_ent_type ent_type,
+ enum hdb_ldb_ent_type ent_type,
+ struct ldb_dn *realm_dn,
struct ldb_message *msg,
- struct ldb_message *realm_ref_msg,
hdb_entry_ex *entry_ex)
{
unsigned int userAccountControl;
int i;
krb5_error_code ret = 0;
krb5_boolean is_computer = FALSE;
- const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg, "dnsRoot", NULL);
- char *realm = strupper_talloc(mem_ctx, dnsdomain);
struct loadparm_context *lp_ctx = ldb_get_opaque((struct ldb_context *)db->hdb_db, "loadparm");
- struct ldb_dn *domain_dn = samdb_result_dn((struct ldb_context *)db->hdb_db,
- mem_ctx,
- realm_ref_msg,
- "nCName",
- ldb_dn_new(mem_ctx, (struct ldb_context *)db->hdb_db, NULL));
+ char *realm = strupper_talloc(mem_ctx, lp_realm(lp_ctx));
struct hdb_ldb_private *p;
NTTIME acct_expiry;
struct ldb_message_element *objectclasses;
struct ldb_val computer_val;
+ const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
computer_val.data = discard_const_p(uint8_t,"computer");
computer_val.length = strlen((const char *)computer_val.data);
+ if (!samAccountName) {
+ krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
+ ret = ENOENT;
+ goto out;
+ }
+
objectclasses = ldb_msg_find_element(msg, "objectClass");
if (objectclasses && ldb_msg_find_val(objectclasses, &computer_val)) {
@@ -539,7 +534,12 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
p->entry_ex = entry_ex;
p->iconv_convenience = lp_iconv_convenience(lp_ctx);
- p->netbios_name = lp_netbios_name(lp_ctx);
+ p->lp_ctx = lp_ctx;
+ p->realm_dn = talloc_reference(p, realm_dn);
+ if (!p->realm_dn) {
+ ret = ENOMEM;
+ goto out;
+ }
talloc_set_destructor(p, hdb_ldb_destructor);
@@ -551,13 +551,6 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) {
- const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
- if (!samAccountName) {
- krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
- ret = ENOENT;
- goto out;
- }
- samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL);
} else {
char *strdup_realm;
@@ -584,6 +577,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm);
}
+ /* First try and figure out the flags based on the userAccountControl */
entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) {
@@ -593,6 +587,11 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.flags.ok_as_delegate = 1;
}
+ /* Windows 2008 seems to enforce this (very sensible) rule by
+ * default - don't allow offline attacks on a user's password
+ * by asking for a ticket to them as a service (encrypted with
+ * their probably patheticly insecure password) */
+
if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) {
if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) {
entry_ex->entry.flags.server = 0;
@@ -618,22 +617,19 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.valid_start = NULL;
- acct_expiry = samdb_result_account_expires(msg);
- if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {
+ /* The account/password expiry only applies when the account is used as a
+ * client (ie password login), not when used as a server */
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT || ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) {
+ /* Make very well sure we don't use this for a client,
+ * it could bypass the above password restrictions */
+ entry_ex->entry.flags.client = 0;
entry_ex->entry.valid_end = NULL;
- } else {
- entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end));
- if (entry_ex->entry.valid_end == NULL) {
- ret = ENOMEM;
- goto out;
- }
- *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
- }
+ entry_ex->entry.pw_end = NULL;
- if (ent_type != HDB_SAMBA4_ENT_TYPE_KRBTGT) {
+ } else {
NTTIME must_change_time
= samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx,
- domain_dn, msg);
+ realm_dn, msg);
if (must_change_time == 0x7FFFFFFFFFFFFFFFULL) {
entry_ex->entry.pw_end = NULL;
} else {
@@ -644,8 +640,18 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
}
*entry_ex->entry.pw_end = nt_time_to_unix(must_change_time);
}
- } else {
- entry_ex->entry.pw_end = NULL;
+
+ acct_expiry = samdb_result_account_expires(msg);
+ if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {
+ entry_ex->entry.valid_end = NULL;
+ } else {
+ entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end));
+ if (entry_ex->entry.valid_end == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
+ }
}
entry_ex->entry.max_life = NULL;
@@ -680,7 +686,6 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
p->msg = talloc_steal(p, msg);
- p->realm_ref_msg = talloc_steal(p, realm_ref_msg);
p->samdb = (struct ldb_context *)db->hdb_db;
out:
@@ -701,6 +706,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx, krb5_const_principal principal,
enum trust_direction direction,
+ struct ldb_dn *realm_dn,
struct ldb_message *msg,
hdb_entry_ex *entry_ex)
{
@@ -725,7 +731,8 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
p->entry_ex = entry_ex;
p->iconv_convenience = lp_iconv_convenience(lp_ctx);
- p->netbios_name = lp_netbios_name(lp_ctx);
+ p->lp_ctx = lp_ctx;
+ p->realm_dn = realm_dn;
talloc_set_destructor(p, hdb_ldb_destructor);
@@ -869,7 +876,6 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
p->msg = talloc_steal(p, msg);
- p->realm_ref_msg = NULL;
p->samdb = (struct ldb_context *)db->hdb_db;
out:
@@ -988,40 +994,6 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
return 0;
}
-static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context *ldb_ctx,
- TALLOC_CTX *mem_ctx,
- const char *realm,
- struct ldb_message ***pmsg)
-{
- int ret;
- struct ldb_result *cross_ref_res;
- struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx);
-
- ret = ldb_search(ldb_ctx, mem_ctx, &cross_ref_res,
- partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs,
- "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
- realm, realm);
-
- if (ret != LDB_SUCCESS) {
- DEBUG(3, ("Failed to search to lookup realm(%s): %s\n", realm, ldb_errstring(ldb_ctx)));
- talloc_free(cross_ref_res);
- return HDB_ERR_NOENTRY;
- } else if (cross_ref_res->count == 0 || cross_ref_res->count > 1) {
- DEBUG(3, ("Failed find a single entry for realm %s: got %d\n", realm, cross_ref_res->count));
- talloc_free(cross_ref_res);
- return HDB_ERR_NOENTRY;
- }
-
- if (pmsg) {
- *pmsg = cross_ref_res->msgs;
- talloc_steal(mem_ctx, cross_ref_res->msgs);
- }
- talloc_free(cross_ref_res);
-
- return 0;
-}
-
-
static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
{
if (db->hdb_master_key_set) {
@@ -1060,9 +1032,9 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
hdb_entry_ex *entry_ex) {
NTSTATUS nt_status;
char *principal_string;
+ struct ldb_dn *realm_dn;
krb5_error_code ret;
struct ldb_message **msg = NULL;
- struct ldb_message **realm_ref_msg = NULL;
ret = krb5_unparse_name(context, principal, &principal_string);
@@ -1072,7 +1044,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
nt_status = sam_get_results_principal((struct ldb_context *)db->hdb_db,
mem_ctx, principal_string,
- &msg, &realm_ref_msg);
+ &realm_dn, &msg);
free(principal_string);
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
return HDB_ERR_NOENTRY;
@@ -1084,7 +1056,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
ret = LDB_message2entry(context, db, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
- msg[0], realm_ref_msg[0], entry_ex);
+ realm_dn, msg[0], entry_ex);
return ret;
}
@@ -1096,10 +1068,9 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
{
krb5_error_code ret;
struct ldb_message **msg = NULL;
- struct ldb_message **realm_ref_msg_1 = NULL;
- struct ldb_message **realm_ref_msg_2 = NULL;
- struct ldb_dn *realm_dn;
+ struct ldb_dn *realm_dn = ldb_get_default_basedn(db->hdb_db);
const char *realm;
+ struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
krb5_principal alloc_principal = NULL;
if (principal->name.name_string.len != 2
@@ -1110,18 +1081,14 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
/* krbtgt case. Either us or a trusted realm */
- if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
- mem_ctx, principal->realm, &realm_ref_msg_1) == 0)
- && (LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
- mem_ctx, principal->name.name_string.val[1], &realm_ref_msg_2) == 0)
- && (ldb_dn_compare(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) {
+ if (lp_is_my_domain_or_realm(lp_ctx, principal->realm)
+ && lp_is_my_domain_or_realm(lp_ctx, principal->name.name_string.val[1])) {
/* us */
/* Cludge, cludge cludge. If the realm part of krbtgt/realm,
* is in our db, then direct the caller at our primary
* krbtgt */
- const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg_1[0], "dnsRoot", NULL);
- char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain);
+ char *realm_fixed = strupper_talloc(mem_ctx, lp_realm(lp_ctx));
if (!realm_fixed) {
krb5_set_error_string(context, "strupper_talloc: out of memory");
return ENOMEM;
@@ -1140,8 +1107,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
return ENOMEM;
}
principal = alloc_principal;
- realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg_1[0], "nCName", NULL);
-
+
ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db,
mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, &msg);
@@ -1154,7 +1120,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
ret = LDB_message2entry(context, db, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_KRBTGT,
- msg[0], realm_ref_msg_1[0], entry_ex);
+ realm_dn, msg[0], entry_ex);
if (ret != 0) {
krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed");
}
@@ -1163,7 +1129,6 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
} else {
enum trust_direction direction = UNKNOWN;
- struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
/* Either an inbound or outbound trust */
if (strcasecmp(lp_realm(lp_ctx), principal->realm) == 0) {
@@ -1192,7 +1157,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx,
principal, direction,
- msg[0], entry_ex);
+ realm_dn, msg[0], entry_ex);
if (ret != 0) {
krb5_warnx(context, "LDB_fetch: trust_message2entry failed");
}
@@ -1214,13 +1179,12 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
krb5_error_code ret;
const char *realm;
struct ldb_message **msg = NULL;
- struct ldb_message **realm_ref_msg = NULL;
- struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx);
+ struct ldb_dn *realm_dn;
if (principal->name.name_string.len >= 2) {
/* 'normal server' case */
int ldb_ret;
NTSTATUS nt_status;
- struct ldb_dn *user_dn, *domain_dn;
+ struct ldb_dn *user_dn;
char *principal_string;
ret = krb5_unparse_name_flags(context, principal,
@@ -1235,7 +1199,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
* referral instead */
nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db,
mem_ctx, principal_string,
- &user_dn, &domain_dn);
+ &user_dn, &realm_dn);
free(principal_string);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1249,28 +1213,13 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
return HDB_ERR_NOENTRY;
}
- ldb_ret = gendb_search((struct ldb_context *)db->hdb_db,
- mem_ctx, partitions_basedn, &realm_ref_msg, realm_ref_attrs,
- "ncName=%s", ldb_dn_get_linearized(domain_dn));
-
- if (ldb_ret != 1) {
- return HDB_ERR_NOENTRY;
- }
-
} else {
- struct ldb_dn *realm_dn;
/* server as client principal case, but we must not lookup userPrincipalNames */
-
+ realm_dn = ldb_get_default_basedn((struct ldb_context *)db->hdb_db);
realm = krb5_principal_get_realm(context, principal);
- ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
- mem_ctx, realm, &realm_ref_msg);
- if (ret != 0) {
- return HDB_ERR_NOENTRY;
- }
-
- realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL);
-
+ /* Check if it is our realm, otherwise give referall */
+
ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db,
mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, &msg);
@@ -1282,7 +1231,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
ret = LDB_message2entry(context, db, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_SERVER,
- msg[0], realm_ref_msg[0], entry_ex);
+ realm_dn, msg[0], entry_ex);
if (ret != 0) {
krb5_warnx(context, "LDB_fetch: message2entry failed");
}
@@ -1342,7 +1291,7 @@ struct hdb_ldb_seq {
int index;
int count;
struct ldb_message **msgs;
- struct ldb_message **realm_ref_msgs;
+ struct ldb_dn *realm_dn;
};
static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
@@ -1367,8 +1316,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
if (priv->index < priv->count) {
ret = LDB_message2entry(context, db, mem_ctx,
NULL, HDB_SAMBA4_ENT_TYPE_ANY,
- priv->msgs[priv->index++],
- priv->realm_ref_msgs[0], entry);
+ priv->realm_dn, priv->msgs[priv->index++], entry);
} else {
ret = HDB_ERR_NOENTRY;
}
@@ -1389,9 +1337,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;
char *realm;
- struct ldb_dn *realm_dn = NULL;
struct ldb_result *res = NULL;
- struct ldb_message **realm_ref_msgs = NULL;
krb5_error_code ret;
TALLOC_CTX *mem_ctx;
int lret;
@@ -1410,7 +1356,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
priv->ctx = ldb_ctx;
priv->index = 0;
priv->msgs = NULL;
- priv->realm_ref_msgs = NULL;
+ priv->realm_dn = ldb_get_default_basedn(ldb_ctx);
priv->count = 0;
mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
@@ -1426,23 +1372,8 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
return ret;
}
- ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
- mem_ctx, realm, &realm_ref_msgs);
-
- free(realm);
-
- if (ret != 0) {
- talloc_free(priv);
- krb5_warnx(context, "LDB_firstkey: could not find realm\n");
- return HDB_ERR_NOENTRY;
- }
-
- realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msgs[0], "nCName", NULL);
-
- priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs);
-
lret = ldb_search(ldb_ctx, priv, &res,
- realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
+ priv->realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
"(objectClass=user)");
if (lret != LDB_SUCCESS) {
diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h
index 417f327a57..a281e1d9c9 100644
--- a/source4/kdc/kdc.h
+++ b/source4/kdc/kdc.h
@@ -55,8 +55,8 @@ struct kdc_server {
struct hdb_ldb_private {
struct ldb_context *samdb;
struct smb_iconv_convenience *iconv_convenience;
+ struct loadparm_context *lp_ctx;
struct ldb_message *msg;
- struct ldb_message *realm_ref_msg;
+ struct ldb_dn *realm_dn;
hdb_entry_ex *entry_ex;
- const char *netbios_name;
};
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
index 1a0df8e4a1..411e752c04 100644
--- a/source4/kdc/pac-glue.c
+++ b/source4/kdc/pac-glue.c
@@ -3,7 +3,7 @@
PAC Glue between Samba and the KDC
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2009
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
@@ -29,6 +29,7 @@
#include "auth/auth_sam.h"
#include "auth/auth_sam_reply.h"
#include "kdc/kdc.h"
+#include "param/param.h"
struct krb5_dh_moduli;
struct _krb5_krb_auth_data;
@@ -127,9 +128,10 @@ krb5_error_code samba_kdc_get_pac(void *priv,
}
nt_status = authsam_make_server_info(mem_ctx, p->samdb,
- p->netbios_name,
+ lp_netbios_name(p->lp_ctx),
+ lp_sam_name(p->lp_ctx),
+ p->realm_dn,
p->msg,
- p->realm_ref_msg,
data_blob(NULL, 0),
data_blob(NULL, 0),
&server_info);
@@ -274,8 +276,8 @@ krb5_error_code samba_kdc_check_client_access(void *priv,
nt_status = authsam_account_ok(tmp_ctx,
p->samdb,
MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,
+ p->realm_dn,
p->msg,
- p->realm_ref_msg,
workstation,
name, true);
free(name);
diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c
index e5c82280e3..2ed37fde59 100644
--- a/source4/nbt_server/dgram/netlogon.c
+++ b/source4/nbt_server/dgram/netlogon.c
@@ -45,33 +45,22 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
struct nbt_name *name = &packet->data.msg.dest_name;
struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
struct nbt_netlogon_response_from_pdc *pdc;
- const char *ref_attrs[] = {"nETBIOSName", NULL};
- struct ldb_message **ref_res;
struct ldb_context *samctx;
- struct ldb_dn *partitions_basedn;
struct nbt_netlogon_response netlogon_response;
- int ret;
/* only answer getdc requests on the PDC or LOGON names */
if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
return;
}
- samctx = iface->nbtsrv->sam_ctx;
-
- if (!samdb_is_pdc(samctx)) {
+ if (lp_server_role(iface->nbtsrv->task->lp_ctx) != ROLE_DOMAIN_CONTROLLER
+ || !samdb_is_pdc(samctx)) {
DEBUG(2, ("Not a PDC, so not processing LOGON_PRIMARY_QUERY\n"));
return;
}
- partitions_basedn = samdb_partitions_dn(samctx, packet);
-
- ret = gendb_search(samctx, packet, partitions_basedn, &ref_res, ref_attrs,
- "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))",
- name->name);
-
- if (ret != 1) {
- DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name));
+ if (strcasecmp_m(name->name, lp_workgroup(iface->nbtsrv->task->lp_ctx)) != 0) {
+ DEBUG(5,("GetDC requested for a domian %s that we don't host\n", name->name));
return;
}
@@ -83,7 +72,7 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
pdc->command = NETLOGON_RESPONSE_FROM_PDC;
pdc->pdc_name = lp_netbios_name(iface->nbtsrv->task->lp_ctx);
pdc->unicode_pdc_name = pdc->pdc_name;
- pdc->domain_name = samdb_result_string(ref_res[0], "nETBIOSName", name->name);;
+ pdc->domain_name = lp_workgroup(iface->nbtsrv->task->lp_ctx);
pdc->nt_version = 1;
pdc->lmnt_token = 0xFFFF;
pdc->lm20_token = 0xFFFF;
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index d6f418e568..eeffe9874f 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -2725,3 +2725,4 @@ struct gensec_settings *lp_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_
settings->target_hostname = lp_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
return settings;
}
+
diff --git a/source4/param/param.h b/source4/param/param.h
index 3d257be062..27bc32f9b9 100644
--- a/source4/param/param.h
+++ b/source4/param/param.h
@@ -362,6 +362,9 @@ int param_write(struct param_context *ctx, const char *fn);
bool lp_is_mydomain(struct loadparm_context *lp_ctx,
const char *domain);
+bool lp_is_my_domain_or_realm(struct loadparm_context *lp_ctx,
+ const char *domain);
+
/**
see if a string matches either our primary or one of our secondary
netbios aliases. do a case insensitive match
@@ -434,6 +437,8 @@ const char *lp_messaging_path(TALLOC_CTX *mem_ctx,
struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx);
+const char *lp_sam_name(struct loadparm_context *lp_ctx);
+
/* The following definitions come from lib/version.c */
const char *samba_version_string(void);
diff --git a/source4/param/util.c b/source4/param/util.c
index 3881107cbc..366c3f1d78 100644
--- a/source4/param/util.c
+++ b/source4/param/util.c
@@ -41,6 +41,13 @@ bool lp_is_mydomain(struct loadparm_context *lp_ctx,
return strequal(lp_workgroup(lp_ctx), domain);
}
+bool lp_is_my_domain_or_realm(struct loadparm_context *lp_ctx,
+ const char *domain)
+{
+ return strequal(lp_workgroup(lp_ctx), domain) ||
+ strequal(lp_realm(lp_ctx), domain);
+}
+
/**
see if a string matches either our primary or one of our secondary
netbios aliases. do a case insensitive match
@@ -296,3 +303,13 @@ struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
}
+const char *lp_sam_name(struct loadparm_context *lp_ctx)
+{
+ switch (lp_server_role(lp_ctx)) {
+ case ROLE_DOMAIN_CONTROLLER:
+ return lp_workgroup(lp_ctx);
+ default:
+ return lp_netbios_name(lp_ctx);
+ }
+}
+
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index d05b0a0c0d..dfc3d17bed 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -129,7 +129,8 @@ PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
SCHANNELDB \
NDR_NETLOGON \
- auth_sam
+ auth_sam \
+ LIBSAMBA-HOSTCONFIG
# End MODULE dcerpc_netlogon
################################################
diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c
index 8d8417109f..ae565a3ff1 100644
--- a/source4/rpc_server/lsa/lsa_init.c
+++ b/source4/rpc_server/lsa/lsa_init.c
@@ -26,7 +26,6 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
struct lsa_policy_state **_state)
{
struct lsa_policy_state *state;
- struct ldb_dn *partitions_basedn;
struct ldb_result *dom_res;
const char *dom_attrs[] = {
"objectSid",
@@ -35,13 +34,7 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
"fSMORoleOwner",
NULL
};
- struct ldb_result *ref_res;
- struct ldb_result *forest_ref_res;
- const char *ref_attrs[] = {
- "nETBIOSName",
- "dnsRoot",
- NULL
- };
+ char *p;
int ret;
state = talloc(mem_ctx, struct lsa_policy_state);
@@ -55,11 +48,9 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
-
/* work out the domain_dn - useful for so many calls its worth
fetching here */
- state->domain_dn = samdb_base_dn(state->sam_ldb);
+ state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
if (!state->domain_dn) {
return NT_STATUS_NO_MEMORY;
}
@@ -86,66 +77,30 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
}
state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
- if (!state->domain_sid) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
talloc_free(dom_res);
- ret = ldb_search(state->sam_ldb, state, &ref_res,
- partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
- "(&(objectclass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(state->domain_dn));
-
- if (ret != LDB_SUCCESS) {
- talloc_free(ref_res);
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
- if (ref_res->count != 1) {
- talloc_free(ref_res);
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
-
- state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
- if (!state->domain_name) {
- talloc_free(ref_res);
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- talloc_steal(state, state->domain_name);
+ state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
- state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
+ state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
if (!state->domain_dns) {
- talloc_free(ref_res);
return NT_STATUS_NO_SUCH_DOMAIN;
}
- talloc_steal(state, state->domain_dns);
-
- talloc_free(ref_res);
-
- ret = ldb_search(state->sam_ldb, state, &forest_ref_res,
- partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
- "(&(objectclass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(state->forest_dn));
-
- if (ret != LDB_SUCCESS) {
- talloc_free(forest_ref_res);
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
- if (forest_ref_res->count != 1) {
- talloc_free(forest_ref_res);
- return NT_STATUS_NO_SUCH_DOMAIN;
+ p = strchr(state->domain_dns, '/');
+ if (p) {
+ *p = '\0';
}
- state->forest_dns = ldb_msg_find_attr_as_string(forest_ref_res->msgs[0], "dnsRoot", NULL);
+ state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
if (!state->forest_dns) {
- talloc_free(forest_ref_res);
return NT_STATUS_NO_SUCH_DOMAIN;
}
- talloc_steal(state, state->forest_dns);
-
- talloc_free(forest_ref_res);
+ p = strchr(state->forest_dns, '/');
+ if (p) {
+ *p = '\0';
+ }
/* work out the builtin_dn - useful for so many calls its worth
fetching here */
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index b17ab86e26..51849fc52e 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -1010,8 +1010,9 @@ static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TAL
fill in a netr_DomainTrustInfo from a ldb search result
*/
static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
+ struct loadparm_context *lp_ctx,
+ struct ldb_context *sam_ctx,
struct ldb_message *res,
- struct ldb_message *ref_res,
struct netr_DomainTrustInfo *info,
bool is_local, bool is_trust_list)
{
@@ -1020,9 +1021,10 @@ static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
info->trust_extension.length = 16;
info->trust_extension.info->flags =
- NETR_TRUST_FLAG_TREEROOT |
+ NETR_TRUST_FLAG_TREEROOT |
NETR_TRUST_FLAG_IN_FOREST |
NETR_TRUST_FLAG_PRIMARY;
+
info->trust_extension.info->parent_index = 0; /* should be index into array
of parent */
info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
@@ -1032,13 +1034,21 @@ static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
/* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
info->forest.string = NULL;
} else {
+ char *p;
/* TODO: we need a common function for pulling the forest */
- info->forest.string = samdb_result_string(ref_res, "dnsRoot", NULL);
+ info->forest.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
+ if (!info->forest.string) {
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+ p = strchr(info->forest.string, '/');
+ if (p) {
+ *p = '\0';
+ }
}
if (is_local) {
- info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
- info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
+ info->domainname.string = lp_sam_name(lp_ctx);
+ info->fulldomainname.string = lp_realm(lp_ctx);
info->guid = samdb_result_guid(res, "objectGUID");
info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
} else {
@@ -1064,13 +1074,11 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
const char * const attrs[] = { "objectSid",
"objectGUID", "flatName", "securityIdentifier",
"trustPartner", NULL };
- const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
struct ldb_context *sam_ctx;
- struct ldb_message **res1, **res2, **ref_res;
+ struct ldb_message **res1, **res2;
struct netr_DomainInfo1 *info1;
- int ret, ret1, ret2, i;
+ int ret1, ret2, i;
NTSTATUS status;
- struct ldb_dn *partitions_basedn;
const char *local_domain;
@@ -1090,8 +1098,6 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
-
/* we need to do two searches. The first will pull our primary
domain and the second will pull any trusted domains. Our
primary domain is also a "trusted" domain, so we need to
@@ -1103,15 +1109,7 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
}
/* try and find the domain */
- ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
- &ref_res, ref_attrs,
- "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(res1[0]->dn));
- if (ret != 1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
+ local_domain = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
if (ret2 == -1) {
@@ -1128,21 +1126,21 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal
info1->num_trusts);
NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
- status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo,
+ status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->domaininfo,
true, false);
NT_STATUS_NOT_OK_RETURN(status);
for (i=0;i<ret2;i++) {
- status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i],
+ status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[i], &info1->trusts[i],
false, true);
NT_STATUS_NOT_OK_RETURN(status);
}
- status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i],
+ status = fill_domain_trust_info(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0], &info1->trusts[i],
true, true);
NT_STATUS_NOT_OK_RETURN(status);
- info1->dns_hostname.string = samdb_result_string(ref_res[0], "dnsRoot", NULL);
+ info1->dns_hostname.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
info1->workstation_flags =
NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
info1->supported_enc_types = 0; /* w2008 gives this 0 */
@@ -1191,7 +1189,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
struct netr_DsRGetDCNameEx2 *r)
{
const char * const attrs[] = { "objectGUID", NULL };
- void *sam_ctx;
+ struct ldb_context *sam_ctx;
struct ldb_message **res;
struct ldb_dn *domain_dn;
int ret;
@@ -1206,21 +1204,19 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
/* Win7-beta will send the domain name in the form the user typed, so we have to cope
with both the short and long form here */
- if (r->in.domain_name == NULL || strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
- r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+ if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
+ r->in.domain_name)) {
+ return WERR_NO_SUCH_DOMAIN;
}
- domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx,
- mem_ctx,
- r->in.domain_name);
+ domain_dn = ldb_get_default_basedn(sam_ctx);
if (domain_dn == NULL) {
return WERR_DS_SERVICE_UNAVAILABLE;
}
- ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ ret = gendb_search_dn(sam_ctx, mem_ctx,
domain_dn, &res, attrs);
if (ret != 1) {
- return WERR_NO_SUCH_DOMAIN;
}
info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
@@ -1359,10 +1355,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
struct netr_DomainTrustList *trusts;
void *sam_ctx;
int ret;
- struct ldb_message **dom_res, **ref_res;
+ struct ldb_message **dom_res;
const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
- const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
- struct ldb_dn *partitions_basedn;
ZERO_STRUCT(r->out);
@@ -1371,9 +1365,6 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
return WERR_GENERAL_FAILURE;
}
- partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx,
- mem_ctx);
-
ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
&dom_res, dom_attrs);
if (ret == -1) {
@@ -1383,17 +1374,6 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
return WERR_GENERAL_FAILURE;
}
- ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
- partitions_basedn, &ref_res, ref_attrs,
- "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(dom_res[0]->dn));
- if (ret == -1) {
- return WERR_GENERAL_FAILURE;
- }
- if (ret != 1) {
- return WERR_GENERAL_FAILURE;
- }
-
trusts = talloc(mem_ctx, struct netr_DomainTrustList);
W_ERROR_HAVE_NO_MEMORY(trusts);
@@ -1406,8 +1386,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
/* TODO: add filtering by trust_flags, and correct trust_type
and attributes */
- trusts->array[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
- trusts->array[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
+ trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
+ trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
trusts->array[0].trust_flags =
NETR_TRUST_FLAG_TREEROOT |
NETR_TRUST_FLAG_IN_FOREST |
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index df23e11a67..fabc88d02d 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -273,11 +273,8 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
struct dcesrv_handle *h;
struct dom_sid *sid;
const char * const dom_attrs[] = { "objectSid", NULL};
- const char * const ref_attrs[] = { "ncName", NULL};
struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
int ret;
- struct ldb_dn *partitions_basedn;
*r->out.sid = NULL;
@@ -289,27 +286,17 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_INVALID_PARAMETER;
}
- partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
-
if (strcasecmp(r->in.domain_name->string, "BUILTIN") == 0) {
ret = gendb_search(c_state->sam_ctx,
mem_ctx, NULL, &dom_msgs, dom_attrs,
"(objectClass=builtinDomain)");
- } else {
- ret = gendb_search(c_state->sam_ctx,
- mem_ctx, partitions_basedn, &ref_msgs, ref_attrs,
- "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))",
- ldb_binary_encode_string(mem_ctx, r->in.domain_name->string));
- if (ret != 1) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
-
- ret = gendb_search_dn(c_state->sam_ctx, mem_ctx,
- samdb_result_dn(c_state->sam_ctx, mem_ctx,
- ref_msgs[0], "ncName", NULL),
+ } else if (strcasecmp_m(r->in.domain_name->string, lp_sam_name(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
+ ret = gendb_search_dn(c_state->sam_ctx,
+ mem_ctx, ldb_get_default_basedn(c_state->sam_ctx),
&dom_msgs, dom_attrs);
+ } else {
+ return NT_STATUS_NO_SUCH_DOMAIN;
}
-
if (ret != 1) {
return NT_STATUS_NO_SUCH_DOMAIN;
}
@@ -338,12 +325,7 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
struct samr_connect_state *c_state;
struct dcesrv_handle *h;
struct samr_SamArray *array;
- int i, start_i, ret;
- const char * const dom_attrs[] = { "cn", NULL};
- const char * const ref_attrs[] = { "nETBIOSName", NULL};
- struct ldb_result *dom_res;
- struct ldb_result *ref_res;
- struct ldb_dn *partitions_basedn;
+ int i, start_i;
*r->out.resume_handle = 0;
*r->out.sam = NULL;
@@ -353,20 +335,11 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
c_state = h->data;
- partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
-
- ret = ldb_search(c_state->sam_ctx, mem_ctx, &dom_res, ldb_get_default_basedn(c_state->sam_ctx),
- LDB_SCOPE_SUBTREE, dom_attrs, "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
- if (ret != LDB_SUCCESS) {
- DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- *r->out.resume_handle = dom_res->count;
+ *r->out.resume_handle = 2;
start_i = *r->in.resume_handle;
- if (start_i >= dom_res->count) {
+ if (start_i >= 2) {
/* search past end of list is not an error for this call */
return NT_STATUS_OK;
}
@@ -379,27 +352,17 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
array->count = 0;
array->entries = NULL;
- array->entries = talloc_array(mem_ctx, struct samr_SamEntry, dom_res->count - start_i);
+ array->entries = talloc_array(mem_ctx, struct samr_SamEntry, 2 - start_i);
if (array->entries == NULL) {
return NT_STATUS_NO_MEMORY;
}
- for (i=0;i<dom_res->count-start_i;i++) {
+ for (i=0;i<2-start_i;i++) {
array->entries[i].idx = start_i + i;
- /* try and find the domain */
- ret = ldb_search(c_state->sam_ctx, mem_ctx, &ref_res, partitions_basedn,
- LDB_SCOPE_SUBTREE, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))",
- ldb_dn_get_linearized(dom_res->msgs[i]->dn));
-
- if (ret != LDB_SUCCESS) {
- DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- if (ref_res->count == 1) {
- array->entries[i].name.string = samdb_result_string(ref_res->msgs[0], "nETBIOSName", NULL);
+ if (i == 0) {
+ array->entries[i].name.string = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
} else {
- array->entries[i].name.string = samdb_result_string(dom_res->msgs[i], "cn", NULL);
+ array->entries[i].name.string = "BUILTIN";
}
}
@@ -418,15 +381,11 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
struct samr_OpenDomain *r)
{
struct dcesrv_handle *h_conn, *h_domain;
- const char *domain_name;
struct samr_connect_state *c_state;
struct samr_domain_state *d_state;
const char * const dom_attrs[] = { "cn", NULL};
- const char * const ref_attrs[] = { "nETBIOSName", NULL};
struct ldb_message **dom_msgs;
- struct ldb_message **ref_msgs;
int ret;
- struct ldb_dn *partitions_basedn;
ZERO_STRUCTP(r->out.domain_handle);
@@ -438,63 +397,44 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
return NT_STATUS_INVALID_PARAMETER;
}
- partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
+ d_state = talloc(c_state, struct samr_domain_state);
+ if (!d_state) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ d_state->domain_sid = talloc_steal(d_state, r->in.sid);
+
+ if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+ d_state->builtin = true;
+ d_state->domain_name = "BUILTIN";
+ } else {
+ d_state->builtin = false;
+ d_state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
+ }
ret = gendb_search(c_state->sam_ctx,
- mem_ctx, NULL, &dom_msgs, dom_attrs,
- "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
+ mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), &dom_msgs, dom_attrs,
+ "(objectSid=%s)",
ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
+
if (ret == 0) {
+ talloc_free(d_state);
return NT_STATUS_NO_SUCH_DOMAIN;
} else if (ret > 1) {
+ talloc_free(d_state);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else if (ret == -1) {
+ talloc_free(d_state);
DEBUG(1, ("Failed to open domain %s: %s\n", dom_sid_string(mem_ctx, r->in.sid), ldb_errstring(c_state->sam_ctx)));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
- } else {
- ret = gendb_search(c_state->sam_ctx,
- mem_ctx, partitions_basedn, &ref_msgs, ref_attrs,
- "(&(&(nETBIOSName=*)(objectclass=crossRef))(ncName=%s))",
- ldb_dn_get_linearized(dom_msgs[0]->dn));
- if (ret == 0) {
- domain_name = ldb_msg_find_attr_as_string(dom_msgs[0], "cn", NULL);
- if (domain_name == NULL) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else if (ret == 1) {
-
- domain_name = ldb_msg_find_attr_as_string(ref_msgs[0], "nETBIOSName", NULL);
- if (domain_name == NULL) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- }
-
- d_state = talloc(c_state, struct samr_domain_state);
- if (!d_state) {
- return NT_STATUS_NO_MEMORY;
}
+ d_state->domain_dn = talloc_steal(d_state, dom_msgs[0]->dn);
d_state->role = lp_server_role(dce_call->conn->dce_ctx->lp_ctx);
d_state->connect_state = talloc_reference(d_state, c_state);
d_state->sam_ctx = c_state->sam_ctx;
- d_state->domain_sid = dom_sid_dup(d_state, r->in.sid);
- d_state->domain_name = talloc_strdup(d_state, domain_name);
- d_state->domain_dn = ldb_dn_copy(d_state, dom_msgs[0]->dn);
- if (!d_state->domain_sid || !d_state->domain_name || !d_state->domain_dn) {
- talloc_free(d_state);
- return NT_STATUS_NO_MEMORY;
- }
d_state->access_mask = r->in.access_mask;
- if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
- d_state->builtin = true;
- } else {
- d_state->builtin = false;
- }
-
d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);