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:
commit
0299609308
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) ;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
#######################
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,8 @@ PRIVATE_DEPENDENCIES = \
|
||||
DCERPC_COMMON \
|
||||
SCHANNELDB \
|
||||
NDR_NETLOGON \
|
||||
auth_sam
|
||||
auth_sam \
|
||||
LIBSAMBA-HOSTCONFIG
|
||||
# End MODULE dcerpc_netlogon
|
||||
################################################
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 |
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user