r20149: Remove the smb.conf distinction between PDC and BDC. Now the correct
authorAndrew Bartlett <abartlet@samba.org>
Wed, 13 Dec 2006 11:19:51 +0000 (11:19 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:29:15 +0000 (14:29 -0500)
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 67d8365e831adf3eaecd8b34dcc481fc82565893)

14 files changed:
source4/auth/auth_sam.c
source4/dsdb/samdb/samdb.c
source4/include/core.h
source4/ldap_server/ldap_server.c
source4/librpc/idl/samr.idl
source4/nbt_server/nbt_server.c
source4/nbt_server/nbt_server.h
source4/nbt_server/register.c
source4/param/loadparm.c
source4/rpc_server/common/server_info.c
source4/rpc_server/lsa/dcesrv_lsa.c
source4/rpc_server/samr/dcesrv_samr.c
source4/script/tests/mktestsetup.sh
source4/torture/rpc/samr.c

index 6b290360ec49077e0cb8625f139bf5a3fa66274e..56187a6d546488aee170aa95b2434ee71424e171 100644 (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;
 
index da04be1dbbbcc8d5319af287672314b53ad8be82..9296352b0bc09487e33133632095a8f9e190a2b2 100644 (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,51 +1078,153 @@ const struct dom_sid *samdb_domain_sid(struct ldb_context *ldb)
                goto failed;
        }
 
-       basedn = ldb_dn_new(tmp_ctx, ldb, NULL);
-       if (basedn == NULL) {
+       /* find the domain_sid */
+       domain_sid = samdb_search_dom_sid(ldb, tmp_ctx, ldb_get_default_basedn(ldb),
+                                         "objectSid", "objectClass=domainDNS");
+       if (domain_sid == 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) {
+
+       /* cache the domain_sid in the ldb */
+       if (ldb_set_opaque(ldb, "cache.domain_sid", domain_sid) != LDB_SUCCESS) {
                goto failed;
        }
 
-       basedn_s = ldb_msg_find_attr_as_string(res->msgs[0], "rootDomainNamingContext", NULL);
-       if (basedn_s == NULL) {
+       talloc_steal(ldb, domain_sid);
+       talloc_free(tmp_ctx);
+
+       return domain_sid;
+
+failed:
+       DEBUG(1,("Failed to find domain_sid for open ldb\n"));
+       talloc_free(tmp_ctx);
+       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;
        }
+       
 
-       basedn = ldb_dn_new(tmp_ctx, ldb, basedn_s);
-       if ( ! ldb_dn_validate(basedn)) {
+       ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, ""), LDB_SCOPE_BASE, NULL, root_attrs, &root_res);
+       if (ret) {
                goto failed;
        }
 
-       /* find the domain_sid */
-       domain_sid = samdb_search_dom_sid(ldb, tmp_ctx, basedn, 
-                                         "objectSid", "objectClass=domainDNS");
-       if (domain_sid == NULL) {
+       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.domain_sid", domain_sid) != LDB_SUCCESS) {
+       if (ldb_set_opaque(ldb, "cache.settings_dn", settings_dn) != LDB_SUCCESS) {
                goto failed;
        }
 
-       talloc_steal(ldb, domain_sid);
+       talloc_steal(ldb, settings_dn);
        talloc_free(tmp_ctx);
 
-       return domain_sid;
+       return settings_dn;
 
 failed:
-       DEBUG(1,("Failed to find domain_sid for open ldb\n"));
+       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
 */
index f334c3df42f39090707e220944dbae699db95076..40452e6034a7170a99b50133894ede3fe5566ae3 100644 (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 */
index 82fc1d966011d0c89234e4bde0f69e7aa8b49942..c459c27961e36e457475c9de47fb0f15f3aae827 100644 (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);
index 9989c821f0ff9712c08fcdbca2054e46da3a9526..5c73bfa76ccf364d995fec29435db959bb6a9405 100644 (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 */
index d8f6a83e9457b7b916412d43bf509242ab377ce6..a2b95d76c486d837cb3d96202ba3c8ac2c38145d 100644 (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");
+
+
 }
 
 
index ebf1edb81fc0c6abe4bf3a6c5be5d235ecc59c3f..e5a33ca5f15b4d6f3d8e637c341f823d989f3e21 100644 (file)
@@ -75,6 +75,8 @@ struct nbtd_server {
        struct wins_server *winssrv;
 
        struct nbtd_statistics stats;
+
+       struct ldb_context *sam_ctx;
 };
 
 
index 64ceaffd9c437ba77a7522dcc506da07fabffd7c..6e65b753b1442f0f0a07331babdb59e9596e7934 100644 (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;
index c781a00ae5c6c31be0454d2b8aac3a7f2d231096..5094a7f565056483728ec1fa6d8b90469d3ec60e 100644 (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);
index 12f5c90e8dfcc0a9ecad4a0f201e1ecb4570ce7d..26667edc69ed9b2a80087d7c06c7fdf3a8e0509d 100644 (file)
 
 #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! */
index 0b2c5a0cfb93b53530b66827dc4ff43537145a84..4a207645b4944eec11eee6d1c5e99fb0729ab551 100644 (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) {
index bc85e4e665469d72b739c46cab62097646014b59..8183c10f120fff042f1133431c4ef5be51f1e98a 100644 (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;
index d6102e9d434491fab89e4606ee265f8e8017e42b..5264885a64c361c5d6aedb4db2c2c4a6b86e9e5b 100755 (executable)
@@ -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
index 25db0228c59dff9c52c32b0f3e7ddd8c76f7ff73..28dd03e803c4d4cb0c1c0902b830f4a3143a0b25 100644 (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",