r25026: Move param/param.h out of includes.h
[kai/samba-autobuild/.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
index fd394b2f05b0bcf628f889abbeb5abfa56c534e6..144e61cd75dedf4c35e947ca87fac0ce24e1558d 100644 (file)
@@ -8,7 +8,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -17,8 +17,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "lib/ldb/include/ldb_errors.h"
 #include "libcli/security/security.h"
 #include "libcli/auth/libcli_auth.h"
-#include "passdb/secrets.h"
+#include "param/secrets.h"
 #include "db_wrap.h"
+#include "librpc/gen_ndr/ndr_dssetup.h"
+#include "param/param.h"
 
 /*
   this type allows us to distinguish handle types
@@ -51,12 +52,17 @@ struct lsa_policy_state {
        struct ldb_context *sam_ldb;
        struct sidmap_context *sidmap;
        uint32_t access_mask;
-       const struct ldb_dn *domain_dn;
-       const struct ldb_dn *builtin_dn;
-       const struct ldb_dn *system_dn;
+       struct ldb_dn *domain_dn;
+       struct ldb_dn *forest_dn;
+       struct ldb_dn *builtin_dn;
+       struct ldb_dn *system_dn;
        const char *domain_name;
+       const char *domain_dns;
+       const char *forest_dns;
        struct dom_sid *domain_sid;
+       struct GUID domain_guid;
        struct dom_sid *builtin_sid;
+       int mixed_domain;
 };
 
 
@@ -76,7 +82,7 @@ struct lsa_account_state {
 struct lsa_secret_state {
        struct lsa_policy_state *policy;
        uint32_t access_mask;
-       const struct ldb_dn *secret_dn;
+       struct ldb_dn *secret_dn;
        struct ldb_context *sam_ldb;
        BOOL global;
 };
@@ -87,14 +93,14 @@ struct lsa_secret_state {
 struct lsa_trusted_domain_state {
        struct lsa_policy_state *policy;
        uint32_t access_mask;
-       const struct ldb_dn *trusted_domain_dn;
+       struct ldb_dn *trusted_domain_dn;
 };
 
-static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
                                      TALLOC_CTX *mem_ctx,
                                      struct lsa_EnumAccountRights *r);
 
-static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
                                           TALLOC_CTX *mem_ctx,
                                           struct lsa_policy_state *state,
                                           int ldb_flag,
@@ -104,7 +110,7 @@ static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
 /* 
   lsa_Close 
 */
-static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                          struct lsa_Close *r)
 {
        struct dcesrv_handle *h;
@@ -124,7 +130,7 @@ static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ct
 /* 
   lsa_Delete 
 */
-static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                           struct lsa_Delete *r)
 {
        struct dcesrv_handle *h;
@@ -166,7 +172,7 @@ static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_c
                r2.in.sid = astate->account_sid;
                r2.out.rights = rights;
 
-               status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
+               status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
                if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                        return NT_STATUS_OK;
                }
@@ -175,7 +181,7 @@ static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_c
                        return status;
                }
 
-               status = lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
+               status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
                                                    LDB_FLAG_MOD_DELETE, astate->account_sid,
                                                    r2.out.rights);
                if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
@@ -194,7 +200,7 @@ static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_c
 /* 
   lsa_EnumPrivs 
 */
-static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                              struct lsa_EnumPrivs *r)
 {
        struct dcesrv_handle *h;
@@ -237,7 +243,7 @@ static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
 /* 
   lsa_QuerySecObj 
 */
-static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                  struct lsa_QuerySecurity *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -247,7 +253,7 @@ static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /* 
   lsa_SetSecObj 
 */
-static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                              struct lsa_SetSecObj *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -257,17 +263,33 @@ static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
 /* 
   lsa_ChangePassword 
 */
-static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                   struct lsa_ChangePassword *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
 
-static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                     struct lsa_policy_state **_state)
 {
        struct lsa_policy_state *state;
-       const struct ldb_dn *partitions_basedn = ldb_dn_string_compose(mem_ctx, samdb_base_dn(mem_ctx), "CN=Partitions,CN=Configuration");
+       struct ldb_dn *partitions_basedn;
+       struct ldb_result *dom_res;
+       const char *dom_attrs[] = {
+               "objectSid", 
+               "objectGUID", 
+               "nTMixedDomain",
+               "fSMORoleOwner",
+               NULL
+       };
+       struct ldb_result *ref_res;
+       struct ldb_result *forest_ref_res;
+       const char *ref_attrs[] = {
+               "nETBIOSName",
+               "dnsRoot",
+               NULL
+       };
+       int ret;
 
        state = talloc(mem_ctx, struct lsa_policy_state);
        if (!state) {
@@ -280,6 +302,8 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
+       partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
+
        state->sidmap = sidmap_open(state);
        if (state->sidmap == NULL) {
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
@@ -287,20 +311,95 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
 
        /* work out the domain_dn - useful for so many calls its worth
           fetching here */
-       state->domain_dn = samdb_base_dn(state);
+       state->domain_dn = samdb_base_dn(state->sam_ldb);
        if (!state->domain_dn) {
                return NT_STATUS_NO_MEMORY;             
        }
 
-       state->domain_name
-               = samdb_search_string(state->sam_ldb, state, partitions_basedn, "nETBIOSName", 
-                                     "(&(objectclass=crossRef)(ncName=%s))", ldb_dn_linearize(mem_ctx, state->domain_dn));
+       /* work out the forest root_dn - useful for so many calls its worth
+          fetching here */
+       state->forest_dn = samdb_root_dn(state->sam_ldb);
+       if (!state->forest_dn) {
+               return NT_STATUS_NO_MEMORY;             
+       }
+
+       ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
+       
+       if (ret != LDB_SUCCESS) {
+               return NT_STATUS_INVALID_SYSTEM_SERVICE;
+       }
+       talloc_steal(mem_ctx, dom_res);
+       if (dom_res->count != 1) {
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+
+       state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
+       if (!state->domain_sid) {
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+
+       state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
+       if (!state->domain_sid) {
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+
+       state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
        
+       talloc_free(dom_res);
+
+       ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
+                                partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
+                                "(&(objectclass=crossRef)(ncName=%s))",
+                                ldb_dn_get_linearized(state->domain_dn));
+       
+       if (ret != LDB_SUCCESS) {
+               talloc_free(ref_res);
+               return NT_STATUS_INVALID_SYSTEM_SERVICE;
+       }
+       if (ref_res->count != 1) {
+               talloc_free(ref_res);
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+
+       state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
        if (!state->domain_name) {
+               talloc_free(ref_res);
                return NT_STATUS_NO_SUCH_DOMAIN;                
        }
        talloc_steal(state, state->domain_name);
 
+       state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
+       if (!state->domain_dns) {
+               talloc_free(ref_res);
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+       talloc_steal(state, state->domain_dns);
+
+       talloc_free(ref_res);
+
+       ret = ldb_search_exp_fmt(state->sam_ldb, state, &forest_ref_res,
+                                partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
+                                "(&(objectclass=crossRef)(ncName=%s))",
+                                ldb_dn_get_linearized(state->forest_dn));
+       
+       if (ret != LDB_SUCCESS) {
+               talloc_free(forest_ref_res);
+               return NT_STATUS_INVALID_SYSTEM_SERVICE;
+       }
+       if (forest_ref_res->count != 1) {
+               talloc_free(forest_ref_res);
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+
+       state->forest_dns = ldb_msg_find_attr_as_string(forest_ref_res->msgs[0], "dnsRoot", NULL);
+       if (!state->forest_dns) {
+               talloc_free(forest_ref_res);
+               return NT_STATUS_NO_SUCH_DOMAIN;                
+       }
+       talloc_steal(state, state->forest_dns);
+
+       talloc_free(forest_ref_res);
+
        /* work out the builtin_dn - useful for so many calls its worth
           fetching here */
        state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
@@ -316,14 +415,6 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
                return NT_STATUS_NO_SUCH_DOMAIN;                
        }
 
-       state->domain_sid = samdb_search_dom_sid(state->sam_ldb, state,
-                                                state->domain_dn, "objectSid", NULL);
-       if (!state->domain_sid) {
-               return NT_STATUS_NO_SUCH_DOMAIN;                
-       }
-
-       talloc_steal(state, state->domain_sid);
-
        state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
        if (!state->builtin_sid) {
                return NT_STATUS_NO_SUCH_DOMAIN;                
@@ -334,10 +425,117 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_
        return NT_STATUS_OK;
 }
 
+/* 
+  dssetup_DsRoleGetPrimaryDomainInformation 
+
+  This is not an LSA call, but is the only call left on the DSSETUP
+  pipe (after the pipe was truncated), and needs lsa_get_policy_state
+*/
+static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, 
+                                                TALLOC_CTX *mem_ctx,
+                                                struct dssetup_DsRoleGetPrimaryDomainInformation *r)
+{
+       union dssetup_DsRoleInfo *info;
+
+       info = talloc(mem_ctx, union dssetup_DsRoleInfo);
+       W_ERROR_HAVE_NO_MEMORY(info);
+
+       switch (r->in.level) {
+       case DS_ROLE_BASIC_INFORMATION:
+       {
+               enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
+               uint32_t flags = 0;
+               const char *domain = NULL;
+               const char *dns_domain = NULL;
+               const char *forest = NULL;
+               struct GUID domain_guid;
+               struct lsa_policy_state *state;
+
+               NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return ntstatus_to_werror(status);
+               }
+
+               ZERO_STRUCT(domain_guid);
+
+               switch (lp_server_role()) {
+               case ROLE_STANDALONE:
+                       role            = DS_ROLE_STANDALONE_SERVER;
+                       break;
+               case ROLE_DOMAIN_MEMBER:
+                       role            = DS_ROLE_MEMBER_SERVER;
+                       break;
+               case ROLE_DOMAIN_CONTROLLER:
+                       if (samdb_is_pdc(state->sam_ldb)) {
+                               role    = DS_ROLE_PRIMARY_DC;
+                       } else {
+                               role    = DS_ROLE_BACKUP_DC;
+                       }
+                       break;
+               }
+
+               switch (lp_server_role()) {
+               case ROLE_STANDALONE:
+                       domain          = talloc_strdup(mem_ctx, lp_workgroup());
+                       W_ERROR_HAVE_NO_MEMORY(domain);
+                       break;
+               case ROLE_DOMAIN_MEMBER:
+                       domain          = talloc_strdup(mem_ctx, lp_workgroup());
+                       W_ERROR_HAVE_NO_MEMORY(domain);
+                       /* TODO: what is with dns_domain and forest and guid? */
+                       break;
+               case ROLE_DOMAIN_CONTROLLER:
+                       flags           = DS_ROLE_PRIMARY_DS_RUNNING;
+
+                       if (state->mixed_domain == 1) {
+                               flags   |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
+                       }
+                       
+                       domain          = state->domain_name;
+                       dns_domain      = state->domain_dns;
+                       forest          = state->forest_dns;
+
+                       domain_guid     = state->domain_guid;
+                       flags   |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
+                       break;
+               }
+
+               info->basic.role        = role; 
+               info->basic.flags       = flags;
+               info->basic.domain      = domain;
+               info->basic.dns_domain  = dns_domain;
+               info->basic.forest      = forest;
+               info->basic.domain_guid = domain_guid;
+
+               r->out.info = info;
+               return WERR_OK;
+       }
+       case DS_ROLE_UPGRADE_STATUS:
+       {
+               info->upgrade.upgrading     = DS_ROLE_NOT_UPGRADING;
+               info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
+
+               r->out.info = info;
+               return WERR_OK;
+       }
+       case DS_ROLE_OP_STATUS:
+       {
+               info->opstatus.status = DS_ROLE_OP_IDLE;
+
+               r->out.info = info;
+               return WERR_OK;
+       }
+       default:
+               return WERR_INVALID_PARAM;
+       }
+
+       return WERR_INVALID_PARAM;
+}
+
 /* 
   lsa_OpenPolicy2
 */
-static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                               struct lsa_OpenPolicy2 *r)
 {
        NTSTATUS status;
@@ -346,7 +544,7 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 
        ZERO_STRUCTP(r->out.handle);
 
-       status = lsa_get_policy_state(dce_call, mem_ctx, &state);
+       status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -373,7 +571,7 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
   lsa_OpenPolicy
   a wrapper around lsa_OpenPolicy2
 */
-static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                struct lsa_OpenPolicy *r)
 {
        struct lsa_OpenPolicy2 r2;
@@ -383,7 +581,7 @@ static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        r2.in.access_mask = r->in.access_mask;
        r2.out.handle = r->out.handle;
 
-       return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
+       return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
 }
 
 
@@ -392,7 +590,7 @@ static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 /*
   fill in the AccountDomain info
 */
-static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                                       struct lsa_DomainInfo *info)
 {
        info->name.string = state->domain_name;
@@ -404,23 +602,14 @@ static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CT
 /*
   fill in the DNS domain info
 */
-static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                             struct lsa_DnsDomainInfo *info)
 {
-       const char * const attrs[] = { "dnsDomain", "objectGUID", "objectSid", NULL };
-       int ret;
-       struct ldb_message **res;
-
-       ret = gendb_search_dn(state->sam_ldb, mem_ctx, state->domain_dn, &res, attrs);
-       if (ret != 1) {
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-
        info->name.string = state->domain_name;
        info->sid         = state->domain_sid;
-       info->dns_domain.string = samdb_result_string(res[0],           "dnsDomain", NULL);
-       info->dns_forest.string = samdb_result_string(res[0],           "dnsDomain", NULL);
-       info->domain_guid       = samdb_result_guid(res[0],             "objectGUID");
+       info->dns_domain.string = state->domain_dns;
+       info->dns_forest.string = state->forest_dns;
+       info->domain_guid       = state->domain_guid;
 
        return NT_STATUS_OK;
 }
@@ -428,7 +617,7 @@ static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx
 /* 
   lsa_QueryInfoPolicy2
 */
-static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                     struct lsa_QueryInfoPolicy2 *r)
 {
        struct lsa_policy_state *state;
@@ -450,10 +639,10 @@ static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_
        switch (r->in.level) {
        case LSA_POLICY_INFO_DOMAIN:
        case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
-               return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
+               return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
 
        case LSA_POLICY_INFO_DNS:
-               return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
+               return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
        }
 
        return NT_STATUS_INVALID_INFO_CLASS;
@@ -462,7 +651,7 @@ static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_
 /* 
   lsa_QueryInfoPolicy 
 */
-static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                    struct lsa_QueryInfoPolicy *r)
 {
        struct lsa_QueryInfoPolicy2 r2;
@@ -471,7 +660,7 @@ static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_C
        r2.in.handle = r->in.handle;
        r2.in.level = r->in.level;
        
-       status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
+       status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
 
        r->out.info = r2.out.info;
 
@@ -481,7 +670,7 @@ static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_C
 /* 
   lsa_SetInfoPolicy 
 */
-static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                  struct lsa_SetInfoPolicy *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -491,7 +680,7 @@ static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /* 
   lsa_ClearAuditLog 
 */
-static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                  struct lsa_ClearAuditLog *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -501,7 +690,7 @@ static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /* 
   lsa_CreateAccount 
 */
-static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                  struct lsa_CreateAccount *r)
 {
        struct lsa_account_state *astate;
@@ -546,7 +735,7 @@ static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /* 
   lsa_EnumAccounts 
 */
-static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                 struct lsa_EnumAccounts *r)
 {
        struct dcesrv_handle *h;
@@ -563,7 +752,7 @@ static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX
        /* NOTE: This call must only return accounts that have at least
           one privilege set 
        */
-       ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs, 
+       ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
                           "(&(objectSid=*)(privilege=*))");
        if (ret < 0) {
                return NT_STATUS_NO_SUCH_USER;
@@ -606,7 +795,7 @@ static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /*
   lsa_CreateTrustedDomainEx2
 */
-static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
                                           TALLOC_CTX *mem_ctx,
                                           struct lsa_CreateTrustedDomainEx2 *r)
 {
@@ -616,7 +805,7 @@ static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
 /*
   lsa_CreateTrustedDomainEx
 */
-static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
                                          TALLOC_CTX *mem_ctx,
                                          struct lsa_CreateTrustedDomainEx *r)
 {
@@ -626,7 +815,7 @@ static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
 /* 
   lsa_CreateTrustedDomain 
 */
-static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                        struct lsa_CreateTrustedDomain *r)
 {
        struct dcesrv_handle *policy_handle;
@@ -672,18 +861,15 @@ static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALL
        
        if (ret < 0 || ret > 1) {
                DEBUG(0,("Found %d records matching DN %s\n", ret,
-                        ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
+                        ldb_dn_get_linearized(policy_state->system_dn)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
        
-       msg->dn = ldb_dn_build_child(mem_ctx, "cn",
-                                    r->in.info->name.string, 
-                                    policy_state->system_dn);
-       if (!msg->dn) {
+       msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
+       if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {
                return NT_STATUS_NO_MEMORY;
        }
        
-       samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
        samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
 
        if (r->in.info->sid) {
@@ -700,10 +886,10 @@ static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALL
        trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
 
        /* create the trusted_domain */
-       ret = samdb_add(trusted_domain_state->policy->sam_ldb, mem_ctx, msg);
-       if (ret != 0) {
-               DEBUG(0,("Failed to create trusted_domain record %s\n",
-                        ldb_dn_linearize(mem_ctx, msg->dn)));
+       ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
+       if (ret != LDB_SUCCESS) {
+               DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
+                        ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
@@ -725,7 +911,7 @@ static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALL
 /* 
   lsa_OpenTrustedDomain
 */
-static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                      struct lsa_OpenTrustedDomain *r)
 {
        struct dcesrv_handle *policy_handle;
@@ -767,7 +953,7 @@ static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC
        
        if (ret != 1) {
                DEBUG(0,("Found %d records matching DN %s\n", ret,
-                        ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
+                        ldb_dn_get_linearized(policy_state->system_dn)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
@@ -792,7 +978,7 @@ static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC
 /*
   lsa_OpenTrustedDomainByName
 */
-static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
                                            TALLOC_CTX *mem_ctx,
                                            struct lsa_OpenTrustedDomainByName *r)
 {
@@ -833,7 +1019,7 @@ static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
        
        if (ret != 1) {
                DEBUG(0,("Found %d records matching DN %s\n", ret,
-                        ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
+                        ldb_dn_get_linearized(policy_state->system_dn)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
@@ -855,40 +1041,86 @@ static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
 }
 
 
+
 /* 
-  lsa_QueryTrustedDomainInfoBySid
+  lsa_SetTrustedDomainInfo
 */
-static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                                               struct lsa_QueryTrustedDomainInfoBySid *r)
+static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                        struct lsa_SetTrustedDomainInfo *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
 
 
+
 /* 
-  lsa_SetTrustDomainInfo
+  lsa_SetInfomrationTrustedDomain
 */
-static NTSTATUS lsa_SetTrustDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct lsa_SetTrustDomainInfo *r)
+static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, 
+                                               TALLOC_CTX *mem_ctx,
+                                               struct lsa_SetInformationTrustedDomain *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
 
 
 /* 
-  lsa_DeleteTrustDomain
+  lsa_DeleteTrustedDomain
 */
-static NTSTATUS lsa_DeleteTrustDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                                     struct lsa_DeleteTrustDomain *r)
+static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                     struct lsa_DeleteTrustedDomain *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       NTSTATUS status;
+       struct lsa_OpenTrustedDomain open;
+       struct lsa_Delete delete;
+       struct dcesrv_handle *h;
+
+       open.in.handle = r->in.handle;
+       open.in.sid = r->in.dom_sid;
+       open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
+       if (!open.out.trustdom_handle) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
+       talloc_steal(mem_ctx, h);
+
+       delete.in.handle = open.out.trustdom_handle;
+       status = dcesrv_lsa_Delete(dce_call, mem_ctx, &delete);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       return NT_STATUS_OK;
 }
 
+static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 
+                                    struct ldb_message *msg, 
+                                    struct lsa_TrustDomainInfoInfoEx *info_ex) 
+{
+       info_ex->domain_name.string
+               = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
+       info_ex->netbios_name.string
+               = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
+       info_ex->sid 
+               = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
+       info_ex->trust_direction
+               = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
+       info_ex->trust_type
+               = ldb_msg_find_attr_as_int(msg, "trustType", 0);
+       info_ex->trust_attributes
+               = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);  
+       return NT_STATUS_OK;
+}
 
 /* 
   lsa_QueryTrustedDomainInfo
 */
-static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                           struct lsa_QueryTrustedDomainInfo *r)
 {
        struct dcesrv_handle *h;
@@ -897,10 +1129,12 @@ static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, T
        int ret;
        struct ldb_message **res;
        const char *attrs[] = {
-               "cn",
-               "flatname",
-               "posixOffset",
+               "flatname", 
+               "trustPartner",
                "securityIdentifier",
+               "trustDirection",
+               "trustType",
+               "trustAttributes", 
                NULL
        };
 
@@ -929,6 +1163,31 @@ static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, T
                r->out.info->posix_offset.posix_offset
                        = samdb_result_uint(msg, "posixOffset", 0);                                        
                break;
+#if 0  /* Win2k3 doesn't implement this */
+       case LSA_TRUSTED_DOMAIN_INFO_BASIC:
+               r->out.info->info_basic.netbios_name.string 
+                       = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
+               r->out.info->info_basic.sid
+                       = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
+               break;
+#endif
+       case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
+               return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
+
+       case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
+               ZERO_STRUCT(r->out.info->full_info);
+               return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
+
+       case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
+               ZERO_STRUCT(r->out.info->info_all);
+               return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
+
+       case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
+       case LSA_TRUSTED_DOMAIN_INFO_11:
+               /* oops, we don't want to return the info after all */
+               talloc_free(r->out.info);
+               r->out.info = NULL;
+               return NT_STATUS_INVALID_PARAMETER;
        default:
                /* oops, we don't want to return the info after all */
                talloc_free(r->out.info);
@@ -941,72 +1200,120 @@ static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, T
 
 
 /* 
-  lsa_SetInformationTrustedDomain
+  lsa_QueryTrustedDomainInfoBySid
 */
-static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct lsa_SetInformationTrustedDomain *r)
+static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                               struct lsa_QueryTrustedDomainInfoBySid *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
-}
-
+       NTSTATUS status;
+       struct lsa_OpenTrustedDomain open;
+       struct lsa_QueryTrustedDomainInfo query;
+       struct dcesrv_handle *h;
+       open.in.handle = r->in.handle;
+       open.in.sid = r->in.dom_sid;
+       open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
+       if (!open.out.trustdom_handle) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-/*
-  lsa_QueryTrustedDomainInfoByName
-*/
-static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
-                                                TALLOC_CTX *mem_ctx,
-                                                struct lsa_QueryTrustedDomainInfoByName *r)
-{
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       /* Ensure this handle goes away at the end of this call */
+       DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
+       talloc_steal(mem_ctx, h);
+       
+       query.in.trustdom_handle = open.out.trustdom_handle;
+       query.in.level = r->in.level;
+       status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       
+       r->out.info = query.out.info;
+       return NT_STATUS_OK;
 }
 
 /*
   lsa_SetTrustedDomainInfoByName
 */
-static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
                                               TALLOC_CTX *mem_ctx,
                                               struct lsa_SetTrustedDomainInfoByName *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
 
-/*
-  lsa_EnumTrustedDomainsEx
+/* 
+   lsa_QueryTrustedDomainInfoByName
 */
-static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call,
-                                        TALLOC_CTX *mem_ctx,
-                                        struct lsa_EnumTrustedDomainsEx *r)
+static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
+                                                TALLOC_CTX *mem_ctx,
+                                                struct lsa_QueryTrustedDomainInfoByName *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       NTSTATUS status;
+       struct lsa_OpenTrustedDomainByName open;
+       struct lsa_QueryTrustedDomainInfo query;
+       struct dcesrv_handle *h;
+       open.in.handle = r->in.handle;
+       open.in.name = r->in.trusted_domain;
+       open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
+       if (!open.out.trustdom_handle) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       
+       /* Ensure this handle goes away at the end of this call */
+       DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
+       talloc_steal(mem_ctx, h);
+
+       query.in.trustdom_handle = open.out.trustdom_handle;
+       query.in.level = r->in.level;
+       status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       
+       r->out.info = query.out.info;
+       return NT_STATUS_OK;
 }
 
 /*
-  lsa_CloseTrustedDomainEx
+  lsa_CloseTrustedDomainEx 
 */
-static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
                                         TALLOC_CTX *mem_ctx,
                                         struct lsa_CloseTrustedDomainEx *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       /* The result of a bad hair day from an IDL programmer?  Not
+        * implmented in Win2k3.  You should always just lsa_Close
+        * anyway. */
+       return NT_STATUS_NOT_IMPLEMENTED;
 }
 
 
 /*
   comparison function for sorting lsa_DomainInformation array
 */
-static int compare_DomainInformation(struct lsa_DomainInformation *e1, struct lsa_DomainInformation *e2)
+static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
 {
-       return strcasecmp(e1->name.string, e2->name.string);
+       return strcasecmp_m(e1->name.string, e2->name.string);
 }
 
 /* 
   lsa_EnumTrustDom 
 */
-static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                 struct lsa_EnumTrustDom *r)
 {
        struct dcesrv_handle *policy_handle;
-       struct lsa_DomainInformation *entries;
+       struct lsa_DomainInfo *entries;
        struct lsa_policy_state *policy_state;
        struct ldb_message **domains;
        const char *attrs[] = {
@@ -1038,8 +1345,8 @@ static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX
                return NT_STATUS_OK;
        }
 
-       /* convert to lsa_DomainInformation format */
-       entries = talloc_array(mem_ctx, struct lsa_DomainInformation, count);
+       /* convert to lsa_TrustInformation format */
+       entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
        if (!entries) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1049,8 +1356,8 @@ static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX
        }
 
        /* sort the results by name */
-       qsort(entries, count, sizeof(struct lsa_DomainInformation), 
-             (comparison_fn_t)compare_DomainInformation);
+       qsort(entries, count, sizeof(*entries), 
+             (comparison_fn_t)compare_DomainInfo);
 
        if (*r->in.resume_handle >= count) {
                *r->out.resume_handle = -1;
@@ -1075,11 +1382,101 @@ static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX
        return NT_STATUS_OK;
 }
 
+/*
+  comparison function for sorting lsa_DomainInformation array
+*/
+static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
+{
+       return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
+}
+
+/* 
+  lsa_EnumTrustedDomainsEx 
+*/
+static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                       struct lsa_EnumTrustedDomainsEx *r)
+{
+       struct dcesrv_handle *policy_handle;
+       struct lsa_TrustDomainInfoInfoEx *entries;
+       struct lsa_policy_state *policy_state;
+       struct ldb_message **domains;
+       const char *attrs[] = {
+               "flatname", 
+               "trustPartner",
+               "securityIdentifier",
+               "trustDirection",
+               "trustType",
+               "trustAttributes", 
+               NULL
+       };
+       NTSTATUS nt_status;
+
+       int count, i;
+
+       *r->out.resume_handle = 0;
+
+       r->out.domains->domains = NULL;
+       r->out.domains->count = 0;
+
+       DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
+
+       policy_state = policy_handle->data;
+
+       /* search for all users in this domain. This could possibly be cached and 
+          resumed based on resume_key */
+       count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 
+                            "objectclass=trustedDomain");
+       if (count == -1) {
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+       if (count == 0 || r->in.max_size == 0) {
+               return NT_STATUS_OK;
+       }
+
+       /* convert to lsa_DomainInformation format */
+       entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
+       if (!entries) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       for (i=0;i<count;i++) {
+               nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       return nt_status;
+               }
+       }
+
+       /* sort the results by name */
+       qsort(entries, count, sizeof(*entries), 
+             (comparison_fn_t)compare_TrustDomainInfoInfoEx);
+
+       if (*r->in.resume_handle >= count) {
+               *r->out.resume_handle = -1;
+
+               return NT_STATUS_NO_MORE_ENTRIES;
+       }
+
+       /* return the rest, limit by max_size. Note that we 
+          use the w2k3 element size value of 60 */
+       r->out.domains->count = count - *r->in.resume_handle;
+       r->out.domains->count = MIN(r->out.domains->count, 
+                                1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
+
+       r->out.domains->domains = entries + *r->in.resume_handle;
+       r->out.domains->count = r->out.domains->count;
+
+       if (r->out.domains->count < count - *r->in.resume_handle) {
+               *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
+               return STATUS_MORE_ENTRIES;
+       }
+
+       return NT_STATUS_OK;
+}
+
 
 /*
   return the authority name and authority sid, given a sid
 */
-static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
+static NTSTATUS dcesrv_lsa_authority_name(struct lsa_policy_state *state,
                                   TALLOC_CTX *mem_ctx, struct dom_sid *sid,
                                   const char **authority_name,
                                   struct dom_sid **authority_sid)
@@ -1112,7 +1509,7 @@ static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
 /*
   add to the lsa_RefDomainList for LookupSids and LookupNames
 */
-static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
+static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
                                   struct dom_sid *sid, 
                                   struct lsa_RefDomainList *domains,
                                   uint32_t *sid_index)
@@ -1123,7 +1520,7 @@ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *m
        int i;
 
        /* work out the authority name */
-       status = lsa_authority_name(state, mem_ctx, sid, 
+       status = dcesrv_lsa_authority_name(state, mem_ctx, sid, 
                                    &authority_name, &authority_sid);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -1139,7 +1536,7 @@ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *m
 
        domains->domains = talloc_realloc(domains, 
                                          domains->domains,
-                                         struct lsa_TrustInformation,
+                                         struct lsa_DomainInfo,
                                          domains->count+1);
        if (domains->domains == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -1147,6 +1544,7 @@ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *m
        domains->domains[i].name.string = authority_name;
        domains->domains[i].sid         = authority_sid;
        domains->count++;
+       domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
        *sid_index = i;
        
        return NT_STATUS_OK;
@@ -1155,7 +1553,7 @@ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *m
 /*
   lookup a name for 1 SID
 */
-static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                               struct dom_sid *sid, const char *sid_str,
                               const char **name, uint32_t *atype)
 {
@@ -1188,11 +1586,11 @@ static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_c
 
 
 /*
-  lsa_LookupSids3
+  lsa_LookupSids2
 */
-static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call,
                                TALLOC_CTX *mem_ctx,
-                               struct lsa_LookupSids3 *r)
+                               struct lsa_LookupSids2 *r)
 {
        struct lsa_policy_state *state;
        int i;
@@ -1200,7 +1598,7 @@ static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
 
        r->out.domains = NULL;
 
-       status = lsa_get_policy_state(dce_call, mem_ctx, &state);
+       status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -1245,12 +1643,12 @@ static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
                }
 
                /* work out the authority name */
-               status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
+               status2 = dcesrv_lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
                        return status2;
                }
 
-               status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
+               status2 = dcesrv_lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
                                         &name, &atype);
                if (!NT_STATUS_IS_OK(status2)) {
                        status = STATUS_SOME_UNMAPPED;
@@ -1274,32 +1672,56 @@ static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
 
 
 /*
-  lsa_LookupSids2
+  lsa_LookupSids3
+
+  Identical to LookupSids2, but doesn't take a policy handle
+  
 */
-static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_LookupSids3(struct dcesrv_call_state *dce_call,
                                TALLOC_CTX *mem_ctx,
-                               struct lsa_LookupSids2 *r)
+                               struct lsa_LookupSids3 *r)
 {
-       struct lsa_LookupSids3 r3;
+       struct lsa_LookupSids2 r2;
+       struct lsa_OpenPolicy2 pol;
        NTSTATUS status;
+       struct dcesrv_handle *h;
 
-       r3.in.sids     = r->in.sids;
-       r3.in.names    = r->in.names;
-       r3.in.level    = r->in.level;
-       r3.in.count    = r->in.count;
-       r3.in.unknown1 = r->in.unknown1;
-       r3.in.unknown2 = r->in.unknown2;
-       r3.out.count   = r->out.count;
-       r3.out.names   = r->out.names;
+       /* No policy handle on the wire, so make one up here */
+       r2.in.handle = talloc(mem_ctx, struct policy_handle);
+       if (!r2.in.handle) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       pol.out.handle = r2.in.handle;
+       pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       pol.in.attr = NULL;
+       pol.in.system_name = NULL;
+       status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-       status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
+       /* ensure this handle goes away at the end of this call */
+       DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
+       talloc_steal(mem_ctx, h);
+
+       r2.in.sids     = r->in.sids;
+       r2.in.names    = r->in.names;
+       r2.in.level    = r->in.level;
+       r2.in.count    = r->in.count;
+       r2.in.unknown1 = r->in.unknown1;
+       r2.in.unknown2 = r->in.unknown2;
+       r2.out.count   = r->out.count;
+       r2.out.names   = r->out.names;
+
+       status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
        if (dce_call->fault_code != 0) {
                return status;
        }
 
-       r->out.domains = r3.out.domains;
-       r->out.names   = r3.out.names;
-       r->out.count   = r3.out.count;
+       r->out.domains = r2.out.domains;
+       r->out.names   = r2.out.names;
+       r->out.count   = r2.out.count;
 
        return status;
 }
@@ -1308,29 +1730,30 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
 /* 
   lsa_LookupSids 
 */
-static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                               struct lsa_LookupSids *r)
 {
-       struct lsa_LookupSids3 r3;
+       struct lsa_LookupSids2 r2;
        NTSTATUS status;
        int i;
 
-       r3.in.sids     = r->in.sids;
-       r3.in.names    = NULL;
-       r3.in.level    = r->in.level;
-       r3.in.count    = r->in.count;
-       r3.in.unknown1 = 0;
-       r3.in.unknown2 = 0;
-       r3.out.count   = r->out.count;
-       r3.out.names   = NULL;
-
-       status = lsa_LookupSids3(dce_call, mem_ctx, &r3);
+       r2.in.handle   = r->in.handle;
+       r2.in.sids     = r->in.sids;
+       r2.in.names    = NULL;
+       r2.in.level    = r->in.level;
+       r2.in.count    = r->in.count;
+       r2.in.unknown1 = 0;
+       r2.in.unknown2 = 0;
+       r2.out.count   = r->out.count;
+       r2.out.names   = NULL;
+
+       status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2);
        if (dce_call->fault_code != 0) {
                return status;
        }
 
-       r->out.domains = r3.out.domains;
-       if (!r3.out.names) {
+       r->out.domains = r2.out.domains;
+       if (!r2.out.names) {
                r->out.names = NULL;
                return status;
        }
@@ -1339,16 +1762,16 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        if (r->out.names == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       r->out.names->count = r3.out.names->count;
+       r->out.names->count = r2.out.names->count;
        r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName, 
                                             r->out.names->count);
        if (r->out.names->names == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
        for (i=0;i<r->out.names->count;i++) {
-               r->out.names->names[i].sid_type    = r3.out.names->names[i].sid_type;
-               r->out.names->names[i].name.string = r3.out.names->names[i].name.string;
-               r->out.names->names[i].sid_index   = r3.out.names->names[i].sid_index;
+               r->out.names->names[i].sid_type    = r2.out.names->names[i].sid_type;
+               r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
+               r->out.names->names[i].sid_index   = r2.out.names->names[i].sid_index;
        }
 
        return status;
@@ -1358,7 +1781,7 @@ static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 /* 
   lsa_OpenAccount 
 */
-static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                struct lsa_OpenAccount *r)
 {
        struct dcesrv_handle *h, *ah;
@@ -1402,7 +1825,7 @@ static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 /* 
   lsa_EnumPrivsAccount 
 */
-static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
                                     TALLOC_CTX *mem_ctx,
                                     struct lsa_EnumPrivsAccount *r)
 {
@@ -1428,7 +1851,7 @@ static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
                return NT_STATUS_NO_MEMORY;
        }
 
-       ret = gendb_search(astate->policy->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs, 
+       ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, 
                           "objectSid=%s", sidstr);
        if (ret != 1) {
                return NT_STATUS_OK;
@@ -1463,7 +1886,7 @@ static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
 /* 
   lsa_EnumAccountRights 
 */
-static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
                                      TALLOC_CTX *mem_ctx,
                                      struct lsa_EnumAccountRights *r)
 {
@@ -1484,7 +1907,7 @@ static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
                return NT_STATUS_NO_MEMORY;
        }
 
-       ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs, 
+       ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
                           "(&(objectSid=%s)(privilege=*))", sidstr);
        if (ret == 0) {
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1523,7 +1946,7 @@ static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
 /* 
   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
 */
-static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
                                           TALLOC_CTX *mem_ctx,
                                           struct lsa_policy_state *state,
                                           int ldb_flag,
@@ -1547,7 +1970,7 @@ static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
        }
 
        msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, 
-                                 samdb_base_dn(mem_ctx), "objectSid=%s", sidstr);
+                                 NULL, "objectSid=%s", sidstr);
        if (msg->dn == NULL) {
                NTSTATUS status;
                if (ldb_flag == LDB_FLAG_MOD_DELETE) {
@@ -1561,7 +1984,7 @@ static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       if (ldb_msg_add_empty(msg, "privilege", ldb_flag)) {
+       if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -1572,7 +1995,7 @@ static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
                r2.in.sid = sid;
                r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
 
-               status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
+               status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
                if (!NT_STATUS_IS_OK(status)) {
                        ZERO_STRUCTP(r2.out.rights);
                }
@@ -1612,7 +2035,7 @@ static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
                }
                DEBUG(3, ("Could not %s attributes from %s: %s", 
                          ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
-                         ldb_dn_linearize(mem_ctx, msg->dn), ldb_errstring(state->sam_ldb)));
+                         ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
                return NT_STATUS_UNEXPECTED_IO_ERROR;
        }
 
@@ -1622,7 +2045,7 @@ static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
 /* 
   lsa_AddPrivilegesToAccount
 */
-static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                           struct lsa_AddPrivilegesToAccount *r)
 {
        struct lsa_RightSet rights;
@@ -1650,7 +2073,7 @@ static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, T
                }
        }
 
-       return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
+       return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
                                          LDB_FLAG_MOD_ADD, astate->account_sid,
                                          &rights);
 }
@@ -1659,7 +2082,7 @@ static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, T
 /* 
   lsa_RemovePrivilegesFromAccount
 */
-static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                                struct lsa_RemovePrivilegesFromAccount *r)
 {
        struct lsa_RightSet *rights;
@@ -1682,12 +2105,12 @@ static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_ca
                r2.in.sid = astate->account_sid;
                r2.out.rights = rights;
 
-               status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
+               status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
 
-               return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
+               return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
                                                  LDB_FLAG_MOD_DELETE, astate->account_sid,
                                                  r2.out.rights);
        }
@@ -1712,7 +2135,7 @@ static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_ca
                }
        }
 
-       return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
+       return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
                                          LDB_FLAG_MOD_DELETE, astate->account_sid,
                                          rights);
 }
@@ -1721,7 +2144,7 @@ static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_ca
 /* 
   lsa_GetQuotasForAccount
 */
-static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_GetQuotasForAccount *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -1731,7 +2154,7 @@ static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALL
 /* 
   lsa_SetQuotasForAccount
 */
-static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_SetQuotasForAccount *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -1741,7 +2164,7 @@ static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALL
 /* 
   lsa_GetSystemAccessAccount
 */
-static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_GetSystemAccessAccount *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -1751,7 +2174,7 @@ static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, T
 /* 
   lsa_SetSystemAccessAccount
 */
-static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_SetSystemAccessAccount *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -1761,7 +2184,7 @@ static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, T
 /* 
   lsa_CreateSecret 
 */
-static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                 struct lsa_CreateSecret *r)
 {
        struct dcesrv_handle *policy_handle;
@@ -1769,7 +2192,7 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
        struct lsa_secret_state *secret_state;
        struct dcesrv_handle *handle;
        struct ldb_message **msgs, *msg;
-       char *errstr;
+       const char *errstr;
        const char *attrs[] = {
                NULL
        };
@@ -1824,8 +2247,8 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
 
-               msg->dn = ldb_dn_build_child(mem_ctx, "cn", name2, policy_state->system_dn);
-               if (!name2 || !msg->dn) {
+               msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
+               if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
                        return NT_STATUS_NO_MEMORY;
                }
                
@@ -1842,7 +2265,7 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
                secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
                /* search for the secret record */
                ret = gendb_search(secret_state->sam_ldb, mem_ctx,
-                                  ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
+                                  ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
                                   &msgs, attrs,
                                   "(&(cn=%s)(objectclass=secret))", 
                                   ldb_binary_encode_string(mem_ctx, name));
@@ -1856,13 +2279,13 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
 
-               msg->dn = ldb_dn_string_compose(mem_ctx, NULL, "cn=%s,cn=LSA Secrets", name);
+               msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
                samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
        } 
 
        /* pull in all the template attributes.  Note this is always from the global samdb */
        ret = samdb_copy_template(secret_state->policy->sam_ldb, msg, 
-                                 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
+                                 "secret", &errstr);
        if (ret != 0) {
                DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
                         errstr));
@@ -1877,9 +2300,9 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
        ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
        if (ret != 0) {
                DEBUG(0,("Failed to create secret record %s: %s\n",
-                        ldb_dn_linearize(mem_ctx, msg->dn), 
+                        ldb_dn_get_linearized(msg->dn), 
                         ldb_errstring(secret_state->sam_ldb)));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+               return NT_STATUS_ACCESS_DENIED;
        }
 
        handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
@@ -1901,7 +2324,7 @@ static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /* 
   lsa_OpenSecret 
 */
-static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                               struct lsa_OpenSecret *r)
 {
        struct dcesrv_handle *policy_handle;
@@ -1952,7 +2375,7 @@ static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
                
                if (ret != 1) {
                        DEBUG(0,("Found %d records matching DN %s\n", ret,
-                                ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
+                                ldb_dn_get_linearized(policy_state->system_dn)));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
        
@@ -1967,7 +2390,7 @@ static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 
                /* search for the secret record */
                ret = gendb_search(secret_state->sam_ldb, mem_ctx,
-                                  ldb_dn_explode(mem_ctx, "cn=LSA Secrets"),
+                                  ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
                                   &msgs, attrs,
                                   "(&(cn=%s)(objectclass=secret))", 
                                   ldb_binary_encode_string(mem_ctx, name));
@@ -1976,8 +2399,8 @@ static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
                }
                
                if (ret != 1) {
-                       DEBUG(0,("Found %d records matching DN %s\n", ret,
-                                ldb_dn_linearize(mem_ctx, policy_state->system_dn)));
+                       DEBUG(0,("Found %d records matching CN=%s\n", 
+                                ret, ldb_binary_encode_string(mem_ctx, name)));
                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
        } 
@@ -2003,7 +2426,7 @@ static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 /* 
   lsa_SetSecret 
 */
-static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                              struct lsa_SetSecret *r)
 {
 
@@ -2052,7 +2475,7 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
                
                /* set value */
                if (samdb_msg_add_value(secret_state->sam_ldb, 
-                                       mem_ctx, msg, "priorSecret", &val) != 0) {
+                                       mem_ctx, msg, "priorValue", &val) != 0) {
                        return NT_STATUS_NO_MEMORY; 
                }
                
@@ -2072,7 +2495,7 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
                                }
                        } else {
                                if (samdb_msg_add_delete(secret_state->sam_ldb, 
-                                                        mem_ctx, msg, "secret")) {
+                                                        mem_ctx, msg, "currentValue")) {
                                        return NT_STATUS_NO_MEMORY;
                                }
                                if (samdb_msg_add_delete(secret_state->sam_ldb, 
@@ -2098,7 +2521,7 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
                
                /* set value */
                if (samdb_msg_add_value(secret_state->sam_ldb, 
-                                       mem_ctx, msg, "secret", &val) != 0) {
+                                       mem_ctx, msg, "currentValue", &val) != 0) {
                        return NT_STATUS_NO_MEMORY; 
                }
                
@@ -2115,7 +2538,7 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
                        NTTIME last_set_time;
                        struct ldb_message **res;
                        const char *attrs[] = {
-                               "secret",
+                               "currentValue",
                                "lastSetTime",
                                NULL
                        };
@@ -2129,17 +2552,17 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
                        
                        if (ret != 1) {
                                DEBUG(0,("Found %d records matching dn=%s\n", ret,
-                                        ldb_dn_linearize(mem_ctx, secret_state->secret_dn)));
+                                        ldb_dn_get_linearized(secret_state->secret_dn)));
                                return NT_STATUS_INTERNAL_DB_CORRUPTION;
                        }
 
-                       new_val = ldb_msg_find_ldb_val(res[0], "secret");
+                       new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
                        last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
                        
                        if (new_val) {
                                /* set value */
                                if (samdb_msg_add_value(secret_state->sam_ldb, 
-                                                       mem_ctx, msg, "priorSecret", 
+                                                       mem_ctx, msg, "priorValue", 
                                                        new_val) != 0) {
                                        return NT_STATUS_NO_MEMORY; 
                                }
@@ -2169,7 +2592,7 @@ static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
 /* 
   lsa_QuerySecret 
 */
-static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                struct lsa_QuerySecret *r)
 {
        struct dcesrv_handle *h;
@@ -2180,8 +2603,8 @@ static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        int ret;
        struct ldb_message **res;
        const char *attrs[] = {
-               "secret",
-               "priorSecret",
+               "currentValue",
+               "priorValue",
                "lastSetTime",
                "priorSetTime", 
                NULL
@@ -2212,13 +2635,13 @@ static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *
                if (!r->out.old_val) {
                        return NT_STATUS_NO_MEMORY;
                }
-               /* Decrypt */
-               prior_val = ldb_msg_find_ldb_val(res[0], "priorSecret");
+               prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
                
                if (prior_val && prior_val->length) {
                        secret.data = prior_val->data;
                        secret.length = prior_val->length;
                
+                       /* Encrypt */
                        crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
                        if (!crypt_secret.length) {
                                return NT_STATUS_NO_MEMORY;
@@ -2248,13 +2671,13 @@ static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *
                        return NT_STATUS_NO_MEMORY;
                }
 
-               /* Decrypt */
-               new_val = ldb_msg_find_ldb_val(res[0], "secret");
+               new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
                
                if (new_val && new_val->length) {
                        secret.data = new_val->data;
                        secret.length = new_val->length;
                
+                       /* Encrypt */
                        crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
                        if (!crypt_secret.length) {
                                return NT_STATUS_NO_MEMORY;
@@ -2284,7 +2707,7 @@ static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 /* 
   lsa_LookupPrivValue
 */
-static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
                                    TALLOC_CTX *mem_ctx,
                                    struct lsa_LookupPrivValue *r)
 {
@@ -2311,7 +2734,7 @@ static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
 /* 
   lsa_LookupPrivName 
 */
-static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 
                                   TALLOC_CTX *mem_ctx,
                                   struct lsa_LookupPrivName *r)
 {
@@ -2345,7 +2768,7 @@ static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
 /* 
   lsa_LookupPrivDisplayName
 */
-static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
                                          TALLOC_CTX *mem_ctx,
                                          struct lsa_LookupPrivDisplayName *r)
 {
@@ -2379,7 +2802,7 @@ static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
 /* 
   lsa_DeleteObject
 */
-static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_DeleteObject *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2389,7 +2812,7 @@ static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /* 
   lsa_EnumAccountsWithUserRight
 */
-static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
                                              TALLOC_CTX *mem_ctx,
                                              struct lsa_EnumAccountsWithUserRight *r)
 {
@@ -2413,7 +2836,7 @@ static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call
                return NT_STATUS_NO_SUCH_PRIVILEGE;
        }
 
-       ret = gendb_search(state->sam_ldb, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs, 
+       ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 
                           "privilege=%s", privname);
        if (ret == -1) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -2440,7 +2863,7 @@ static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call
 /* 
   lsa_AddAccountRights
 */
-static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
                                     TALLOC_CTX *mem_ctx,
                                     struct lsa_AddAccountRights *r)
 {
@@ -2451,7 +2874,7 @@ static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
 
        state = h->data;
 
-       return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
+       return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
                                          LDB_FLAG_MOD_ADD,
                                          r->in.sid, r->in.rights);
 }
@@ -2460,7 +2883,7 @@ static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
 /* 
   lsa_RemoveAccountRights
 */
-static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
+static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
                                        TALLOC_CTX *mem_ctx,
                                        struct lsa_RemoveAccountRights *r)
 {
@@ -2471,7 +2894,7 @@ static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
 
        state = h->data;
 
-       return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
+       return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
                                          LDB_FLAG_MOD_DELETE,
                                          r->in.sid, r->in.rights);
 }
@@ -2480,7 +2903,7 @@ static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
 /* 
   lsa_StorePrivateData
 */
-static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_StorePrivateData *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2490,7 +2913,7 @@ static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_
 /* 
   lsa_RetrievePrivateData
 */
-static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_RetrievePrivateData *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2500,7 +2923,7 @@ static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALL
 /* 
   lsa_GetUserName
 */
-static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                struct lsa_GetUserName *r)
 {
        NTSTATUS status = NT_STATUS_OK;
@@ -2547,7 +2970,7 @@ static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 /*
   lsa_SetInfoPolicy2
 */
-static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
                                   TALLOC_CTX *mem_ctx,
                                   struct lsa_SetInfoPolicy2 *r)
 {
@@ -2557,7 +2980,7 @@ static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
 /*
   lsa_QueryDomainInformationPolicy
 */
-static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
                                                 TALLOC_CTX *mem_ctx,
                                                 struct lsa_QueryDomainInformationPolicy *r)
 {
@@ -2567,7 +2990,7 @@ static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_c
 /*
   lsa_SetDomInfoPolicy
 */
-static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
                                              TALLOC_CTX *mem_ctx,
                                              struct lsa_SetDomainInformationPolicy *r)
 {
@@ -2577,7 +3000,7 @@ static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_cal
 /*
   lsa_TestCall
 */
-static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
                             TALLOC_CTX *mem_ctx,
                             struct lsa_TestCall *r)
 {
@@ -2587,7 +3010,7 @@ static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
 /*
   lookup a SID for 1 name
 */
-static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                                const char *name, struct dom_sid **sid, uint32_t *atype)
 {
        int ret;
@@ -2621,20 +3044,20 @@ static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_
 
 
 /*
-  lsa_LookupNames4
+  lsa_LookupNames3
 */
-static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
                                 TALLOC_CTX *mem_ctx,
-                                struct lsa_LookupNames4 *r)
+                                struct lsa_LookupNames3 *r)
 {
-       struct lsa_policy_state *state;
+       struct lsa_policy_state *policy_state;
+       struct dcesrv_handle *policy_handle;
        int i;
        NTSTATUS status = NT_STATUS_OK;
 
-       status = lsa_get_policy_state(dce_call, mem_ctx, &state);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
+       DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
+
+       policy_state = policy_handle->data;
 
        r->out.domains = NULL;
 
@@ -2670,7 +3093,7 @@ static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
                r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
                r->out.sids->sids[i].unknown     = 0;
 
-               status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
+               status2 = dcesrv_lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
                if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
                        status = STATUS_SOME_UNMAPPED;
                        continue;
@@ -2682,7 +3105,7 @@ static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
                        continue;
                }
 
-               status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
+               status2 = dcesrv_lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
                        return status2;
                }
@@ -2697,16 +3120,38 @@ static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call,
 }
 
 /* 
-  lsa_LookupNames3
+  lsa_LookupNames4
+
+  Identical to LookupNames3, but doesn't take a policy handle
+  
 */
-static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                                struct lsa_LookupNames3 *r)
+static NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                struct lsa_LookupNames4 *r)
 {
-       struct lsa_LookupNames4 r2;
+       struct lsa_LookupNames3 r2;
+       struct lsa_OpenPolicy2 pol;
        NTSTATUS status;
        struct dcesrv_handle *h;
-       DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
-       
+
+       /* No policy handle on the wire, so make one up here */
+       r2.in.handle = talloc(mem_ctx, struct policy_handle);
+       if (!r2.in.handle) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       pol.out.handle = r2.in.handle;
+       pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       pol.in.attr = NULL;
+       pol.in.system_name = NULL;
+       status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /* ensure this handle goes away at the end of this call */
+       DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
+       talloc_steal(mem_ctx, h);
+
        r2.in.num_names = r->in.num_names;
        r2.in.names = r->in.names;
        r2.in.sids = r->in.sids;
@@ -2717,7 +3162,7 @@ static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX
        r2.out.sids = r->out.sids;
        r2.out.count = r->out.count;
        
-       status = lsa_LookupNames4(dce_call, mem_ctx, &r2);
+       status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
        if (dce_call->fault_code != 0) {
                return status;
        }
@@ -2731,7 +3176,7 @@ static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call, TALLOC_CTX
 /*
   lsa_LookupNames2
 */
-static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
+static NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                                 TALLOC_CTX *mem_ctx,
                                 struct lsa_LookupNames2 *r)
 {
@@ -2778,7 +3223,7 @@ static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
                r->out.sids->sids[i].unknown     = 0;
 
-               status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
+               status2 = dcesrv_lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
                if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
                        status = STATUS_SOME_UNMAPPED;
                        continue;
@@ -2790,7 +3235,7 @@ static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                        continue;
                }
 
-               status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
+               status2 = dcesrv_lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
                if (!NT_STATUS_IS_OK(status2)) {
                        return status2;
                }
@@ -2807,7 +3252,7 @@ static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
 /* 
   lsa_LookupNames 
 */
-static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LookupNames *r)
 {
        struct lsa_LookupNames2 r2;
@@ -2824,7 +3269,7 @@ static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        r2.in.unknown2  = 0;
        r2.out.count    = r->out.count;
 
-       status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
+       status = dcesrv_lsa_LookupNames2(dce_call, mem_ctx, &r2);
        if (dce_call->fault_code != 0) {
                return status;
        }
@@ -2852,7 +3297,7 @@ static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 /* 
   lsa_CREDRWRITE 
 */
-static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRWRITE *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2862,7 +3307,7 @@ static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 /* 
   lsa_CREDRREAD 
 */
-static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRREAD *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2872,7 +3317,7 @@ static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
 /* 
   lsa_CREDRENUMERATE 
 */
-static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRENUMERATE *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2882,7 +3327,7 @@ static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CT
 /* 
   lsa_CREDRWRITEDOMAINCREDENTIALS 
 */
-static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2892,7 +3337,7 @@ static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_ca
 /* 
   lsa_CREDRREADDOMAINCREDENTIALS 
 */
-static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRREADDOMAINCREDENTIALS *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2902,7 +3347,7 @@ static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_cal
 /* 
   lsa_CREDRDELETE 
 */
-static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRDELETE *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2912,7 +3357,7 @@ static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 /* 
   lsa_CREDRGETTARGETINFO 
 */
-static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRGETTARGETINFO *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2922,7 +3367,7 @@ static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLO
 /* 
   lsa_CREDRPROFILELOADED 
 */
-static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRPROFILELOADED *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2932,7 +3377,7 @@ static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLO
 /* 
   lsa_CREDRGETSESSIONTYPES 
 */
-static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRGETSESSIONTYPES *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2942,7 +3387,7 @@ static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TAL
 /* 
   lsa_LSARREGISTERAUDITEVENT 
 */
-static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARREGISTERAUDITEVENT *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2952,7 +3397,7 @@ static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, T
 /* 
   lsa_LSARGENAUDITEVENT 
 */
-static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARGENAUDITEVENT *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2962,7 +3407,7 @@ static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC
 /* 
   lsa_LSARUNREGISTERAUDITEVENT 
 */
-static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARUNREGISTERAUDITEVENT *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2970,10 +3415,10 @@ static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call,
 
 
 /* 
-  lsa_LSARQUERYFORESTTRUSTINFORMATION 
+  lsa_lsaRQueryForestTrustInformation 
 */
-static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
+static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                      struct lsa_lsaRQueryForestTrustInformation *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
@@ -2982,7 +3427,7 @@ static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dc
 /* 
   lsa_LSARSETFORESTTRUSTINFORMATION 
 */
-static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -2992,7 +3437,7 @@ static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_
 /* 
   lsa_CREDRRENAME 
 */
-static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_CREDRRENAME *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -3003,7 +3448,7 @@ static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *
 /* 
   lsa_LSAROPENPOLICYSCE 
 */
-static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSAROPENPOLICYSCE *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -3013,7 +3458,7 @@ static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC
 /* 
   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
 */
-static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -3023,7 +3468,7 @@ static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state
 /* 
   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
 */
-static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -3033,7 +3478,7 @@ static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_stat
 /* 
   lsa_LSARADTREPORTSECURITYEVENT 
 */
-static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_LSARADTREPORTSECURITYEVENT *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
@@ -3042,3 +3487,130 @@ static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_cal
 
 /* include the generated boilerplate */
 #include "librpc/gen_ndr/ndr_lsa_s.c"
+
+
+
+/*****************************************
+NOTE! The remaining calls below were
+removed in w2k3, so the DCESRV_FAULT()
+replies are the correct implementation. Do
+not try and fill these in with anything else
+******************************************/
+
+/* 
+  dssetup_DsRoleDnsNameToFlatName 
+*/
+static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                       struct dssetup_DsRoleDnsNameToFlatName *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleDcAsDc 
+*/
+static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                            struct dssetup_DsRoleDcAsDc *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleDcAsReplica 
+*/
+static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                 struct dssetup_DsRoleDcAsReplica *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleDemoteDc 
+*/
+static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                              struct dssetup_DsRoleDemoteDc *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleGetDcOperationProgress 
+*/
+static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                            struct dssetup_DsRoleGetDcOperationProgress *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleGetDcOperationResults 
+*/
+static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                           struct dssetup_DsRoleGetDcOperationResults *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleCancel 
+*/
+static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                            struct dssetup_DsRoleCancel *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleServerSaveStateForUpgrade 
+*/
+static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                               struct dssetup_DsRoleServerSaveStateForUpgrade *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleUpgradeDownlevelServer 
+*/
+static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                            struct dssetup_DsRoleUpgradeDownlevelServer *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  dssetup_DsRoleAbortDownlevelServerUpgrade 
+*/
+static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                                                 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
+{
+       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* include the generated boilerplate */
+#include "librpc/gen_ndr/ndr_dssetup_s.c"
+
+NTSTATUS dcerpc_server_lsa_init(void)
+{
+       NTSTATUS ret;
+       
+       ret = dcerpc_server_dssetup_init();
+       if (!NT_STATUS_IS_OK(ret)) {
+               return ret;
+       }
+       ret = dcerpc_server_lsarpc_init();
+       if (!NT_STATUS_IS_OK(ret)) {
+               return ret;
+       }
+       return ret;
+}