1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00

Merge branch 'master' of ssh://git.samba.org/data/git/samba

This commit is contained in:
Andrew Tridgell 2009-05-26 14:18:16 +10:00
commit 0299609308
18 changed files with 335 additions and 620 deletions

View File

@ -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;

View File

@ -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

View File

@ -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) ;

View File

@ -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
};

View File

@ -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;

View File

@ -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";

View File

@ -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
#######################

View File

@ -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) {

View File

@ -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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -129,7 +129,8 @@ PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
SCHANNELDB \
NDR_NETLOGON \
auth_sam
auth_sam \
LIBSAMBA-HOSTCONFIG
# End MODULE dcerpc_netlogon
################################################

View File

@ -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 = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
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_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 */

View File

@ -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 |

View File

@ -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);
ret = gendb_search(c_state->sam_ctx,
mem_ctx, NULL, &dom_msgs, dom_attrs,
"(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid));
if (ret == 0) {
return NT_STATUS_NO_SUCH_DOMAIN;
} else if (ret > 1) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else if (ret == -1) {
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->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;
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, 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;
}
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->access_mask = r->in.access_mask;
d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);