1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-04 00:23:49 +03:00

r20149: Remove the smb.conf distinction between PDC and BDC. Now the correct

way to setup a Samba4 DC is to set 'server role = domain controller'.

We use the fSMORoleOwner attribute in the base DN to determine the PDC.

This patch is quite large, as I have corrected a number of places that
assumed taht we are always the PDC, or that used the smb.conf
lp_server_role() to determine that.

Also included is a warning fix in the SAMR code, where the IDL has
seperated a couple of types for group display enumeration.

We also now use the ldb database to determine if we should run the
global catalog service.

In the near future, I will complete the DRSUAPI
DsGetDomainControllerInfo server-side on the same basis.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett
2006-12-13 11:19:51 +00:00
committed by Gerald (Jerry) Carter
parent d2d9842914
commit 67d8365e83
14 changed files with 410 additions and 187 deletions

View File

@@ -22,7 +22,10 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_srvsvc.h"
#include "librpc/gen_ndr/svcctl.h"
#include "rpc_server/dcerpc_server.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
/*
Here are common server info functions used by some dcerpc server interfaces
@@ -81,7 +84,77 @@ _PUBLIC_ uint32_t dcesrv_common_get_version_build(TALLOC_CTX *mem_ctx, struct dc
/* This hardcoded value should go into a ldb database! */
_PUBLIC_ uint32_t dcesrv_common_get_server_type(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx)
{
return lp_default_server_announce();
int default_server_announce = 0;
default_server_announce |= SV_TYPE_WORKSTATION;
default_server_announce |= SV_TYPE_SERVER;
default_server_announce |= SV_TYPE_SERVER_UNIX;
switch (lp_announce_as()) {
case ANNOUNCE_AS_NT_SERVER:
default_server_announce |= SV_TYPE_SERVER_NT;
/* fall through... */
case ANNOUNCE_AS_NT_WORKSTATION:
default_server_announce |= SV_TYPE_NT;
break;
case ANNOUNCE_AS_WIN95:
default_server_announce |= SV_TYPE_WIN95_PLUS;
break;
case ANNOUNCE_AS_WFW:
default_server_announce |= SV_TYPE_WFW;
break;
default:
break;
}
switch (lp_server_role()) {
case ROLE_DOMAIN_MEMBER:
default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
break;
case ROLE_DOMAIN_CONTROLLER:
{
struct ldb_context *samctx;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
break;
}
/* open main ldb */
samctx = samdb_connect(tmp_ctx, anonymous_session(tmp_ctx));
if (samctx == NULL) {
DEBUG(2,("Unable to open samdb in determining server announce flags\n"));
} else {
/* Determine if we are the pdc */
BOOL is_pdc = samdb_is_pdc(samctx);
if (is_pdc) {
default_server_announce |= SV_TYPE_DOMAIN_CTRL;
} else {
default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
}
}
/* Close it */
talloc_free(tmp_ctx);
break;
}
case ROLE_STANDALONE:
default:
break;
}
if (lp_time_server())
default_server_announce |= SV_TYPE_TIME_SOURCE;
if (lp_host_msdfs())
default_server_announce |= SV_TYPE_DFS_SERVER;
#if 0
{
/* TODO: announce us as print server when we are a print server */
BOOL is_print_server = False;
if (is_print_server) {
default_server_announce |= SV_TYPE_PRINTQ_SERVER;
}
}
#endif
return default_server_announce;
}
/* This hardcoded value should go into a ldb database! */

View File

@@ -277,6 +277,7 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
"objectSid",
"objectGUID",
"nTMixedDomain",
"fSMORoleOwner",
NULL
};
struct ldb_result *ref_res;
@@ -317,7 +318,7 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
if (ret != LDB_SUCCESS) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
talloc_steal(state, dom_res);
talloc_steal(mem_ctx, dom_res);
if (dom_res->count != 1) {
return NT_STATUS_NO_SUCH_DOMAIN;
}
@@ -333,7 +334,7 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
}
state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
talloc_free(dom_res);
ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
@@ -431,11 +432,12 @@ static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state
case ROLE_DOMAIN_MEMBER:
role = DS_ROLE_MEMBER_SERVER;
break;
case ROLE_DOMAIN_BDC:
role = DS_ROLE_BACKUP_DC;
break;
case ROLE_DOMAIN_PDC:
role = DS_ROLE_PRIMARY_DC;
case ROLE_DOMAIN_CONTROLLER:
if (samdb_is_pdc(state->sam_ldb)) {
role = DS_ROLE_PRIMARY_DC;
} else {
role = DS_ROLE_BACKUP_DC;
}
break;
}
@@ -449,8 +451,7 @@ static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state
W_ERROR_HAVE_NO_MEMORY(domain);
/* TODO: what is with dns_domain and forest and guid? */
break;
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_CONTROLLER:
flags = DS_ROLE_PRIMARY_DS_RUNNING;
if (state->mixed_domain == 1) {

View File

@@ -395,6 +395,7 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *
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,
@@ -474,18 +475,39 @@ static NTSTATUS samr_info_DomInfo2(struct samr_domain_state *state, TALLOC_CTX *
struct ldb_message **dom_msgs,
struct samr_DomInfo2 *info)
{
enum server_role role = lp_server_role();
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
string */
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, dom_msgs[0], "fSMORoleOwner");
info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff",
0x8000000000000000LL);
info->comment.string = samdb_result_string(dom_msgs[0], "comment", NULL);
info->domain_name.string = state->domain_name;
/* FIXME: We should find the name of the real PDC emulator */
info->primary.string = lp_netbios_name();
info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount",
0);
info->role = lp_server_role();
switch (role) {
case ROLE_DOMAIN_CONTROLLER:
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
string */
if (samdb_is_pdc(state->sam_ctx)) {
info->role = SAMR_ROLE_DOMAIN_PDC;
} else {
info->role = SAMR_ROLE_DOMAIN_BDC;
}
break;
case ROLE_DOMAIN_MEMBER:
info->role = SAMR_ROLE_DOMAIN_MEMBER;
break;
case ROLE_STANDALONE:
info->role = SAMR_ROLE_STANDALONE;
break;
}
/* TODO: Should these filter on SID, to avoid counting BUILTIN? */
info->num_users = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,
@@ -545,12 +567,14 @@ static NTSTATUS samr_info_DomInfo5(struct samr_domain_state *state,
*/
static NTSTATUS samr_info_DomInfo6(struct samr_domain_state *state,
TALLOC_CTX *mem_ctx,
struct ldb_message **dom_msgs,
struct ldb_message **dom_msgs,
struct samr_DomInfo6 *info)
{
/* FIXME: We should find the name of the real PDC emulator */
info->primary.string = lp_netbios_name();
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
string */
info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx,
dom_msgs[0], "fSMORoleOwner");
return NT_STATUS_OK;
}
@@ -563,7 +587,27 @@ static NTSTATUS samr_info_DomInfo7(struct samr_domain_state *state,
struct ldb_message **dom_msgs,
struct samr_DomInfo7 *info)
{
info->role = lp_server_role();
enum server_role role = lp_server_role();
switch (role) {
case ROLE_DOMAIN_CONTROLLER:
/* This pulls the NetBIOS name from the
cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
string */
if (samdb_is_pdc(state->sam_ctx)) {
info->role = SAMR_ROLE_DOMAIN_PDC;
} else {
info->role = SAMR_ROLE_DOMAIN_BDC;
}
break;
case ROLE_DOMAIN_MEMBER:
info->role = SAMR_ROLE_DOMAIN_MEMBER;
break;
case ROLE_STANDALONE:
info->role = SAMR_ROLE_STANDALONE;
break;
}
return NT_STATUS_OK;
}
@@ -695,6 +739,7 @@ static NTSTATUS samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_
static const char * const attrs2[] = {"forceLogoff",
"comment",
"modifiedCount",
"fSMORoleOwner",
NULL};
attrs = attrs2;
break;
@@ -714,7 +759,17 @@ static NTSTATUS samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_
break;
}
case 5:
{
attrs = NULL;
break;
}
case 6:
{
static const char * const attrs2[] = {"fSMORoleOwner",
NULL};
attrs = attrs2;
break;
}
case 7:
{
attrs = NULL;
@@ -3517,6 +3572,7 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
const char * const attrs[4] = { "objectSid", "sAMAccountName",
"description", NULL };
struct samr_DispEntryFull *entriesFull = NULL;
struct samr_DispEntryFullGroup *entriesFullGroup = NULL;
struct samr_DispEntryAscii *entriesAscii = NULL;
struct samr_DispEntryGeneral * entriesGeneral = NULL;
const char *filter;
@@ -3566,11 +3622,15 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
ldb_cnt);
break;
case 2:
case 3:
entriesFull = talloc_array(mem_ctx,
struct samr_DispEntryFull,
ldb_cnt);
break;
case 3:
entriesFullGroup = talloc_array(mem_ctx,
struct samr_DispEntryFullGroup,
ldb_cnt);
break;
case 4:
case 5:
entriesAscii = talloc_array(mem_ctx,
@@ -3580,7 +3640,7 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
}
if ((entriesGeneral == NULL) && (entriesFull == NULL) &&
(entriesAscii == NULL))
(entriesAscii == NULL) && (entriesFullGroup == NULL))
return NT_STATUS_NO_MEMORY;
count = 0;
@@ -3610,23 +3670,34 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
samdb_result_string(res[i], "description", "");
break;
case 2:
case 3:
entriesFull[count].idx = count + 1;
entriesFull[count].rid =
objectsid->sub_auths[objectsid->num_auths-1];
entriesFull[count].acct_flags =
samdb_result_acct_flags(res[i],
"userAccountControl");
if (r->in.level == 3) {
/* We get a "7" here for groups */
entriesFull[count].acct_flags = 7;
}
entriesFull[count].account_name.string =
samdb_result_string(res[i], "sAMAccountName",
"");
entriesFull[count].description.string =
samdb_result_string(res[i], "description", "");
break;
case 3:
entriesFullGroup[count].idx = count + 1;
entriesFullGroup[count].rid =
objectsid->sub_auths[objectsid->num_auths-1];
entriesFullGroup[count].acct_flags =
samdb_result_acct_flags(res[i],
"userAccountControl");
/* We get a "7" here for groups */
entriesFullGroup[count].acct_flags
= SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
entriesFullGroup[count].account_name.string =
samdb_result_string(res[i], "sAMAccountName",
"");
entriesFullGroup[count].description.string =
samdb_result_string(res[i], "description", "");
break;
case 4:
case 5:
entriesAscii[count].idx = count + 1;
@@ -3682,7 +3753,7 @@ static NTSTATUS samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC
case 3:
r->out.info.info3.count = r->out.returned_size;
r->out.info.info3.entries =
&(entriesFull[r->in.start_idx]);
&(entriesFullGroup[r->in.start_idx]);
break;
case 4:
r->out.info.info4.count = r->out.returned_size;