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:
parent
5cc44027dc
commit
d471e52d23
@ -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;
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,6 +75,8 @@ struct nbtd_server {
|
||||
struct wins_server *winssrv;
|
||||
|
||||
struct nbtd_statistics stats;
|
||||
|
||||
struct ldb_context *sam_ctx;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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! */
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user