1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +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 used to be commit 67d8365e83)
This commit is contained in:
Andrew Bartlett 2006-12-13 11:19:51 +00:00 committed by Gerald (Jerry) Carter
parent 5cc44027dc
commit d471e52d23
14 changed files with 410 additions and 187 deletions

View File

@ -382,8 +382,7 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
}
return NT_STATUS_OK;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_CONTROLLER:
if (!is_local_name && !is_my_domain) {
DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n",
user_info->mapped.domain_name));
@ -413,8 +412,7 @@ static NTSTATUS authsam_check_password(struct auth_method_context *ctx,
domain = lp_netbios_name();
break;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_CONTROLLER:
domain = lp_workgroup();
break;

View File

@ -1047,18 +1047,25 @@ struct ldb_dn *samdb_partitions_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
return new_dn;
}
struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
{
struct ldb_dn *new_dn;
new_dn = ldb_dn_copy(mem_ctx, samdb_base_dn(sam_ctx));
if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Sites,CN=Configuration")) {
talloc_free(new_dn);
return NULL;
}
return new_dn;
}
/*
work out the domain sid for the current open ldb
*/
const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
{
const char *attrs[] = { "rootDomainNamingContext", NULL };
int ret;
struct ldb_result *res = NULL;
TALLOC_CTX *tmp_ctx;
struct dom_sid *domain_sid;
const char *basedn_s;
struct ldb_dn *basedn;
/* see if we have a cached copy */
domain_sid = ldb_get_opaque(ldb, "cache.domain_sid");
@ -1071,30 +1078,8 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
goto failed;
}
basedn = ldb_dn_new(tmp_ctx, ldb, NULL);
if (basedn == NULL) {
goto failed;
}
/* find the basedn of the domain from the rootdse */
ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, attrs, &res);
talloc_steal(tmp_ctx, res);
if (ret != LDB_SUCCESS || res->count != 1) {
goto failed;
}
basedn_s = ldb_msg_find_attr_as_string(res->msgs[0], "rootDomainNamingContext", NULL);
if (basedn_s == NULL) {
goto failed;
}
basedn = ldb_dn_new(tmp_ctx, ldb, basedn_s);
if ( ! ldb_dn_validate(basedn)) {
goto failed;
}
/* find the domain_sid */
domain_sid = samdb_search_dom_sid(ldb, tmp_ctx, basedn,
domain_sid = samdb_search_dom_sid(ldb, tmp_ctx, ldb_get_default_basedn(ldb),
"objectSid", "objectClass=domainDNS");
if (domain_sid == NULL) {
goto failed;
@ -1116,6 +1101,130 @@ failed:
return NULL;
}
/* Obtain the short name of the flexible single master operator
* (FSMO), such as the PDC Emulator */
const char *samdb_result_fsmo_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
const char *attr)
{
/* Format is cn=NTDS Settings,cn=<NETBIOS name of FSMO>,.... */
struct ldb_dn *fsmo_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, msg, attr);
const struct ldb_val *val = ldb_dn_get_component_val(fsmo_dn, 1);
const char *name = ldb_dn_get_component_name(fsmo_dn, 1);
if (!name || (ldb_attr_cmp(name, "cn") != 0)) {
/* Ensure this matches the format. This gives us a
* bit more confidence that a 'cn' value will be a
* ascii string */
return NULL;
}
if (val) {
return (char *)val->data;
}
return NULL;
}
/*
work out the ntds settings dn for the current open ldb
*/
const struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
{
TALLOC_CTX *tmp_ctx;
const char *root_attrs[] = { "dsServiceName", NULL };
int ret;
struct ldb_result *root_res;
struct ldb_dn *settings_dn;
/* see if we have a cached copy */
settings_dn = ldb_get_opaque(ldb, "cache.settings_dn");
if (settings_dn) {
return settings_dn;
}
tmp_ctx = talloc_new(ldb);
if (tmp_ctx == NULL) {
goto failed;
}
ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, NULL, root_attrs, &root_res);
if (ret) {
goto failed;
}
if (root_res->count != 1) {
goto failed;
}
settings_dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, root_res->msgs[0], "dsServiceName");
/* cache the domain_sid in the ldb */
if (ldb_set_opaque(ldb, "cache.settings_dn", settings_dn) != LDB_SUCCESS) {
goto failed;
}
talloc_steal(ldb, settings_dn);
talloc_free(tmp_ctx);
return settings_dn;
failed:
DEBUG(1,("Failed to find our own NTDS Settings DN in the ldb!\n"));
talloc_free(tmp_ctx);
return NULL;
}
/*
work out the server dn for the current open ldb
*/
struct ldb_dn *samdb_server_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
{
return ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb));
}
/*
work out the domain sid for the current open ldb
*/
BOOL samdb_is_pdc(struct ldb_context *ldb)
{
const char *dom_attrs[] = { "fSMORoleOwner", NULL };
int ret;
struct ldb_result *dom_res;
TALLOC_CTX *tmp_ctx;
BOOL is_pdc;
struct ldb_dn *pdc;
tmp_ctx = talloc_new(ldb);
if (tmp_ctx == NULL) {
goto failed;
}
ret = ldb_search(ldb, ldb_get_default_basedn(ldb), LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
if (ret) {
goto failed;
}
talloc_steal(tmp_ctx, dom_res);
if (dom_res->count != 1) {
goto failed;
}
pdc = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, dom_res->msgs[0], "fSMORoleOwner");
if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc) == 0) {
is_pdc = True;
} else {
is_pdc = False;
}
talloc_free(tmp_ctx);
return is_pdc;
failed:
DEBUG(1,("Failed to find if we are the PDC for this ldb\n"));
talloc_free(tmp_ctx);
return False;
}
/*
check that a password is sufficiently complex
*/

View File

@ -95,6 +95,18 @@ enum brl_type {
PENDING_WRITE_LOCK
};
enum server_role {
ROLE_STANDALONE=0,
ROLE_DOMAIN_MEMBER=1,
ROLE_DOMAIN_CONTROLLER=2,
};
enum announce_as {/* Types of machine we can announce as. */
ANNOUNCE_AS_NT_SERVER=1,
ANNOUNCE_AS_WIN95=2,
ANNOUNCE_AS_WFW=3,
ANNOUNCE_AS_NT_WORKSTATION=4
};
#endif /* _SAMBA_CORE_H */

View File

@ -40,7 +40,7 @@
#include "lib/ldb/include/ldb_errors.h"
#include "system/network.h"
#include "lib/socket/netif.h"
#include "dsdb/samdb/samdb.h"
/*
close the socket and shutdown a server_context
*/
@ -245,8 +245,13 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
}
ret = ldb_search(conn->ldb, basedn, LDB_SCOPE_BASE, NULL, attrs, &res);
if (ret != LDB_SUCCESS) {
goto failed;
}
talloc_steal(tmp_ctx, res);
if (ret != LDB_SUCCESS || res->count != 1) {
if (res->count != 1) {
goto failed;
}
@ -262,8 +267,13 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
}
ret = ldb_search(conn->ldb, policy_dn, LDB_SCOPE_BASE, NULL, attrs2, &res);
if (ret != LDB_SUCCESS) {
goto failed;
}
talloc_steal(tmp_ctx, res);
if (ret != LDB_SUCCESS || res->count != 1) {
if (res->count != 1) {
goto failed;
}
@ -431,6 +441,11 @@ static NTSTATUS add_socket(struct event_context *event_context,
{
uint16_t port = 389;
NTSTATUS status;
const char *attrs[] = { "options", NULL };
int ret;
struct ldb_result *res;
struct ldb_context *ldb;
int options;
status = stream_setup_socket(event_context, model_ops, &ldap_stream_ops,
"ipv4", address, &port, ldap_service);
@ -450,8 +465,28 @@ static NTSTATUS add_socket(struct event_context *event_context,
}
}
/* if we are a PDC, then also enable the global catalog server port, 3268 */
if (lp_server_role() == ROLE_DOMAIN_PDC) {
/* Load LDAP database */
ldb = samdb_connect(ldap_service, system_session(ldap_service));
if (!ldb) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
/* Query cn=ntds settings,.... */
ret = ldb_search(ldb, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, NULL, attrs, &res);
if (ret) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
if (res->count != 1) {
talloc_free(res);
return NT_STATUS_NOT_FOUND;
}
options = ldb_msg_find_attr_as_int(res->msgs[0], "options", 0);
talloc_free(res);
talloc_free(ldb);
/* if options attribute is 1, then enable the global catlog */
if (options == 1) {
port = 3268;
status = stream_setup_socket(event_context, model_ops, &ldap_stream_ops,
"ipv4", address, &port, ldap_service);

View File

@ -129,10 +129,10 @@ import "misc.idl", "lsa.idl", "security.idl";
/* Function 0x08 */
/* server roles */
typedef [v1_enum] enum {
ROLE_STANDALONE = 0,
ROLE_DOMAIN_MEMBER = 1,
ROLE_DOMAIN_BDC = 2,
ROLE_DOMAIN_PDC = 3
SAMR_ROLE_STANDALONE = 0,
SAMR_ROLE_DOMAIN_MEMBER = 1,
SAMR_ROLE_DOMAIN_BDC = 2,
SAMR_ROLE_DOMAIN_PDC = 3
} samr_Role;
/* password properties flags */

View File

@ -27,6 +27,8 @@
#include "nbt_server/wins/winsserver.h"
#include "system/network.h"
#include "lib/socket/netif.h"
#include "auth/auth.h"
#include "dsdb/samdb/samdb.h"
/*
startup the nbtd task
@ -61,6 +63,12 @@ static void nbtd_task_init(struct task_server *task)
return;
}
nbtsrv->sam_ctx = samdb_connect(nbtsrv, anonymous_session(nbtsrv));
if (nbtsrv->sam_ctx == NULL) {
task_server_terminate(task, "nbtd failed to open samdb");
return;
}
/* start the WINS server, if appropriate */
status = nbtd_winsserver_init(nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
@ -74,6 +82,8 @@ static void nbtd_task_init(struct task_server *task)
nbtd_register_names(nbtsrv);
irpc_add_name(task->msg_ctx, "nbt_server");
}

View File

@ -75,6 +75,8 @@ struct nbtd_server {
struct wins_server *winssrv;
struct nbtd_statistics stats;
struct ldb_context *sam_ctx;
};

View File

@ -29,6 +29,7 @@
#include "librpc/gen_ndr/ndr_samr.h"
#include "nbt_server/wins/winsserver.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "dsdb/samdb/samdb.h"
static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
@ -271,15 +272,14 @@ void nbtd_register_names(struct nbtd_server *nbtsrv)
aliases++;
}
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_PDC, nb_flags);
nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
break;
case ROLE_DOMAIN_BDC:
nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
default:
break;
if (lp_server_role() == ROLE_DOMAIN_CONTROLLER) {
BOOL is_pdc = samdb_is_pdc(nbtsrv->sam_ctx);
if (is_pdc) {
nbtd_register_name(nbtsrv, lp_workgroup(),
NBT_NAME_PDC, nb_flags);
}
nbtd_register_name(nbtsrv, lp_workgroup(),
NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
}
nb_flags |= NBT_NM_GROUP;

View File

@ -59,8 +59,6 @@
#include "system/time.h"
#include "system/locale.h"
#include "system/network.h" /* needed for TCP_NODELAY */
#include "librpc/gen_ndr/svcctl.h"
#include "librpc/gen_ndr/samr.h"
#include "smb_server/smb_server.h"
#include "libcli/raw/signing.h"
#include "lib/util/dlinklist.h"
@ -274,7 +272,6 @@ static service **ServicePtrs = NULL;
static int iNumServices = 0;
static int iServiceIndex = 0;
static BOOL bInGlobalSection = True;
static int default_server_announce;
#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
@ -282,8 +279,6 @@ static int default_server_announce;
static BOOL handle_include(const char *pszParmValue, char **ptr);
static BOOL handle_copy(const char *pszParmValue, char **ptr);
static void set_default_server_announce_type(void);
static const struct enum_list enum_protocol[] = {
{PROTOCOL_SMB2, "SMB2"},
{PROTOCOL_NT1, "NT1"},
@ -301,12 +296,6 @@ static const struct enum_list enum_security[] = {
{-1, NULL}
};
/* Types of machine we can announce as. */
#define ANNOUNCE_AS_NT_SERVER 1
#define ANNOUNCE_AS_WIN95 2
#define ANNOUNCE_AS_WFW 3
#define ANNOUNCE_AS_NT_WORKSTATION 4
static const struct enum_list enum_announce_as[] = {
{ANNOUNCE_AS_NT_SERVER, "NT"},
{ANNOUNCE_AS_NT_SERVER, "NT Server"},
@ -365,8 +354,7 @@ static const struct enum_list enum_smb_signing_vals[] = {
static const struct enum_list enum_server_role[] = {
{ROLE_STANDALONE, "standalone"},
{ROLE_DOMAIN_MEMBER, "member server"},
{ROLE_DOMAIN_BDC, "bdc"},
{ROLE_DOMAIN_PDC, "pdc"},
{ROLE_DOMAIN_CONTROLLER, "domain controller"},
{-1, NULL}
};
@ -886,7 +874,7 @@ _PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
_PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
_PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
_PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
_PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
_PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
_PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
_PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
@ -912,7 +900,7 @@ _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, &Globals.cli_minprotocol)
_PUBLIC_ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
_PUBLIC_ FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
_PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
_PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
_PUBLIC_ FN_GLOBAL_LIST(lp_js_include, &Globals.jsInclude)
_PUBLIC_ FN_GLOBAL_STRING(lp_jsonrpc_services_dir, &Globals.jsonrpcServicesDir)
_PUBLIC_
@ -1373,8 +1361,6 @@ BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
DEBUG(3, ("adding printer service %s\n", pszPrintername));
update_server_announce_as_printserver();
return (True);
}
@ -1554,7 +1540,6 @@ static BOOL service_ok(int iService)
DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
ServicePtrs[iService]->szService));
ServicePtrs[iService]->bPrint_ok = True;
update_server_announce_as_printserver();
}
/* [printers] service must also be non-browsable. */
if (ServicePtrs[iService]->bBrowseable)
@ -2380,15 +2365,6 @@ static void lp_add_auto_services(const char *str)
return;
}
/***************************************************************************
Announce ourselves as a print server.
***************************************************************************/
void update_server_announce_as_printserver(void)
{
default_server_announce |= SV_TYPE_PRINTQ_SERVER;
}
/***************************************************************************
Have we loaded a services file yet?
***************************************************************************/
@ -2478,8 +2454,6 @@ BOOL lp_load(void)
lp_add_hidden("IPC$", "IPC");
lp_add_hidden("ADMIN$", "DISK");
set_default_server_announce_type();
bLoaded = True;
if (!Globals.szWINSservers && Globals.bWINSsupport) {
@ -2603,83 +2577,13 @@ const char *volume_label(int snum)
}
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/
static void set_default_server_announce_type(void)
{
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_PDC:
default_server_announce |= SV_TYPE_DOMAIN_CTRL;
break;
case ROLE_DOMAIN_BDC:
default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
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;
/* TODO: only announce us as print server when we are a print server */
default_server_announce |= SV_TYPE_PRINTQ_SERVER;
}
/***********************************************************
If we are PDC then prefer us as DMB
************************************************************/
BOOL lp_domain_master(void)
{
return (lp_server_role() == ROLE_DOMAIN_PDC);
}
/***********************************************************
If we are PDC then prefer us as DMB
************************************************************/
BOOL lp_domain_logons(void)
{
return (lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC);
}
/***********************************************************
If we are DMB then prefer us as LMB
************************************************************/
BOOL lp_preferred_master(void)
{
return (lp_local_master() && lp_domain_master());
return (lp_server_role() == ROLE_DOMAIN_CONTROLLER);
}
/*******************************************************************
@ -2706,15 +2610,6 @@ void lp_copy_service(int snum, const char *new_name)
}
}
/*******************************************************************
Get the default server type we will announce as via nmbd.
********************************************************************/
int lp_default_server_announce(void)
{
return default_server_announce;
}
const char *lp_printername(int snum)
{
const char *ret = _lp_printername(snum);

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;

View File

@ -104,7 +104,7 @@ cat >$CONFFILE<<EOF
tls dh params file = $DHFILE
panic action = $SRCDIR/script/gdb_backtrace %PID% %PROG%
wins support = yes
server role = pdc
server role = domain controller
max xmit = 32K
server max protocol = SMB2
notify:inotify = false

View File

@ -2987,6 +2987,16 @@ static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
levels[i], r.out.info->info2.comment.string, domain_comment);
ret = False;
}
if (!r.out.info->info2.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = False;
} else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
}
}
break;
case 4:
if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
@ -2995,6 +3005,13 @@ static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
ret = False;
}
break;
case 6:
if (!r.out.info->info6.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = False;
}
break;
case 11:
if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",