LSA Patch for User Manager
authorMatthias Dieter Wallnöfer <mwallnoefer@yahoo.de>
Mon, 20 Oct 2008 04:50:07 +0000 (15:50 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 20 Oct 2008 09:07:09 +0000 (20:07 +1100)
New (major) patch
=================
- Enhances the "lsa.idl" file in the sense that it adds more values to
"PolicyInformation" to improve the "lsa_QueryInfoPolicy*" calls.
- Adds a minimal implementation for "AuditEvents" (also lsa_QueryInfoPolicy*
calls) to enable the "Audit" option in the "User Manager for Domains" (at least
readable).
- Adds to the "lsa.idl" file the system access mode flags needed for the calls
"lsa_*SystemAccessAccount".
- Fill in the "lsa_GetSystemAccessAccount" for enabling the "User Rights"
option in the "User Manager for Domains" (at least readable).
- Merge the two similar torture tests of the "lsa_QueryInfoPolicy*" calls in
one using "if"'s for a few separations.
- Add a torture test for "lsa_GetSystemAccessAccount".
- Some cosmetic-only changes (unifications) in output strings in the "LSA"
torture test.

The work has been done using the Microsoft WSPP docs.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
source4/librpc/idl/lsa.idl
source4/rpc_server/lsa/dcesrv_lsa.c
source4/torture/rpc/lsa.c

index dd9791d894670dfe8c0b8c3b5cd80399dd6d4620..8745385a101bdda547133b984245e3bf89ae2d1d 100644 (file)
@@ -263,11 +263,12 @@ import "misc.idl", "security.idl";
                LSA_POLICY_INFO_ROLE=6,
                LSA_POLICY_INFO_REPLICA=7,
                LSA_POLICY_INFO_QUOTA=8,
-               LSA_POLICY_INFO_DB=9,
+               LSA_POLICY_INFO_MOD=9,
                LSA_POLICY_INFO_AUDIT_FULL_SET=10,
                LSA_POLICY_INFO_AUDIT_FULL_QUERY=11,
                LSA_POLICY_INFO_DNS=12,
-               LSA_POLICY_INFO_DNS_INT=13
+               LSA_POLICY_INFO_DNS_INT=13,
+               LSA_POLICY_INFO_L_ACCOUNT_DOMAIN=14
        } lsa_PolicyInfo;
 
        typedef [switch_type(uint16)] union {
@@ -279,11 +280,12 @@ import "misc.idl", "security.idl";
                [case(LSA_POLICY_INFO_ROLE)]             lsa_ServerRole         role;
                [case(LSA_POLICY_INFO_REPLICA)]          lsa_ReplicaSourceInfo  replica;
                [case(LSA_POLICY_INFO_QUOTA)]            lsa_DefaultQuotaInfo   quota;
-               [case(LSA_POLICY_INFO_DB)]               lsa_ModificationInfo   db;
+               [case(LSA_POLICY_INFO_MOD)]              lsa_ModificationInfo   mod;
                [case(LSA_POLICY_INFO_AUDIT_FULL_SET)]   lsa_AuditFullSetInfo   auditfullset;
                [case(LSA_POLICY_INFO_AUDIT_FULL_QUERY)] lsa_AuditFullQueryInfo auditfullquery;
                [case(LSA_POLICY_INFO_DNS)]              lsa_DnsDomainInfo      dns;
                [case(LSA_POLICY_INFO_DNS_INT)]          lsa_DnsDomainInfo      dns;
+               [case(LSA_POLICY_INFO_L_ACCOUNT_DOMAIN)] lsa_DomainInfo         l_account_domain;
        } lsa_PolicyInformation;
 
        NTSTATUS lsa_QueryInfoPolicy (
@@ -512,23 +514,39 @@ import "misc.idl", "security.idl";
        /* Function:           0x16 */
        [todo] NTSTATUS lsa_SetQuotasForAccount();
        
+       typedef [bitmap32bit] bitmap {
+               LSA_POLICY_MODE_INTERACTIVE             = 0x00000001,
+               LSA_POLICY_MODE_NETWORK                 = 0x00000002,
+               LSA_POLICY_MODE_BATCH                   = 0x00000004,
+               LSA_POLICY_MODE_SERVICE                 = 0x00000010,
+               LSA_POLICY_MODE_PROXY                   = 0x00000020,
+               LSA_POLICY_MODE_DENY_INTERACTIVE        = 0x00000040,
+               LSA_POLICY_MODE_DENY_NETWORK            = 0x00000080,
+               LSA_POLICY_MODE_DENY_BATCH              = 0x00000100,
+               LSA_POLICY_MODE_DENY_SERVICE            = 0x00000200,
+               LSA_POLICY_MODE_REMOTE_INTERACTIVE      = 0x00000400,
+               LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE = 0x00000800,
+               LSA_POLICY_MODE_ALL                     = 0x00000FF7,
+               LSA_POLICY_MODE_ALL_NT4                 = 0x00000037
+       } lsa_SystemAccessModeFlags;
+
        /* Function:    0x17 */
        NTSTATUS lsa_GetSystemAccessAccount(
-               [in]    policy_handle *handle,
+               [in]      policy_handle *handle,
                [out,ref] uint32 *access_mask
                );
 
        /* Function:    0x18 */
        NTSTATUS lsa_SetSystemAccessAccount(
-               [in]    policy_handle *handle,
-               [in]    uint32 access_mask
+               [in] policy_handle *handle,
+               [in] uint32 access_mask
                );
 
        /* Function:        0x19 */
        NTSTATUS lsa_OpenTrustedDomain(
                [in]     policy_handle *handle,
                [in]     dom_sid2      *sid,
-               [in]         uint32         access_mask,
+               [in]     uint32         access_mask,
                [out]    policy_handle *trustdom_handle
                );
 
index 4c596f1f0368899b554e7a873311aec009e54cc5..84f11ef3a8f7564b6c762acb9da88017004e8a0a 100644 (file)
@@ -399,7 +399,6 @@ static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_cal
        return WERR_INVALID_PARAM;
 }
 
-
 /*
   fill in the AccountDomain info
 */
@@ -462,9 +461,15 @@ static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call,
                /* we don't need to fill in any of this */
                ZERO_STRUCT(r->out.info->pd);
                return NT_STATUS_OK;
+
        case LSA_POLICY_INFO_DOMAIN:
+               return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->domain);
        case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
                return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
+       case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
+               return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->l_account_domain);
+
+
        case LSA_POLICY_INFO_ROLE:
                r->out.info->role.role = LSA_ROLE_PRIMARY;
                return NT_STATUS_OK;
@@ -481,9 +486,8 @@ static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call,
                ZERO_STRUCT(r->out.info->quota);
                return NT_STATUS_OK;
 
+       case LSA_POLICY_INFO_MOD:
        case LSA_POLICY_INFO_AUDIT_FULL_SET:
-       case LSA_POLICY_INFO_DB:
-       case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
                /* windows gives INVALID_PARAMETER */
                r->out.info = NULL;
                return NT_STATUS_INVALID_PARAMETER;
@@ -2050,7 +2054,36 @@ static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_cal
 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);
+       int i;
+       NTSTATUS status;
+       struct lsa_EnumPrivsAccount enumPrivs;
+
+       enumPrivs.in.handle = r->in.handle;
+
+       status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }       
+
+       *(r->out.access_mask) = 0x00000000;
+
+       for (i = 0; i < enumPrivs.out.privs->count; i++) {
+               int priv = enumPrivs.out.privs->set[i].luid.low;
+
+               switch (priv) {
+               case SEC_PRIV_INTERACTIVE_LOGON:
+                       *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE;
+                       break;
+               case SEC_PRIV_NETWORK_LOGON:
+                       *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK;
+                       break;
+               case SEC_PRIV_REMOTE_INTERACTIVE_LOGON:
+                       *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE;
+                       break;
+               }
+       }
+
+       return NT_STATUS_OK;
 }
 
 
index 245ed1e41bb197ed7d993fdffe3727fd9c721a3b..875a85752225dfda1040060775361a145ae2e646 100644 (file)
@@ -46,7 +46,7 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
        NTSTATUS status;
        uint16_t system_name = '\\';
 
-       printf("\ntesting OpenPolicy\n");
+       printf("\nTesting OpenPolicy\n");
 
        qos.len = 0;
        qos.impersonation_level = 2;
@@ -88,7 +88,7 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct lsa_OpenPolicy2 r;
        NTSTATUS status;
 
-       printf("\ntesting OpenPolicy2\n");
+       printf("\nTesting OpenPolicy2\n");
 
        *handle = talloc(mem_ctx, struct policy_handle);
        if (!*handle) {
@@ -781,7 +781,7 @@ static bool test_LookupPrivName(struct dcerpc_pipe *p,
 }
 
 static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 
-                                            TALLOC_CTX *mem_ctx,                                 
+                                            TALLOC_CTX *mem_ctx,
                                             struct policy_handle *handle,
                                             struct policy_handle *acct_handle,
                                             struct lsa_LUID *luid)
@@ -791,7 +791,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
        struct lsa_PrivilegeSet privs;
        bool ret = true;
 
-       printf("Testing RemovePrivilegesFromAccount\n");
+       printf("\nTesting RemovePrivilegesFromAccount\n");
 
        r.in.handle = acct_handle;
        r.in.remove_all = 0;
@@ -831,7 +831,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
 }
 
 static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 
-                                       TALLOC_CTX *mem_ctx,                              
+                                       TALLOC_CTX *mem_ctx,
                                        struct policy_handle *acct_handle,
                                        struct lsa_LUID *luid)
 {
@@ -840,7 +840,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
        struct lsa_PrivilegeSet privs;
        bool ret = true;
 
-       printf("Testing AddPrivilegesToAccount\n");
+       printf("\nTesting AddPrivilegesToAccount\n");
 
        r.in.handle = acct_handle;
        r.in.privs = &privs;
@@ -861,7 +861,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
 }
 
 static bool test_EnumPrivsAccount(struct dcerpc_pipe *p, 
-                                 TALLOC_CTX *mem_ctx,                            
+                                 TALLOC_CTX *mem_ctx,
                                  struct policy_handle *handle,
                                  struct policy_handle *acct_handle)
 {
@@ -869,7 +869,7 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p,
        struct lsa_EnumPrivsAccount r;
        bool ret = true;
 
-       printf("Testing EnumPrivsAccount\n");
+       printf("\nTesting EnumPrivsAccount\n");
 
        r.in.handle = acct_handle;
 
@@ -895,6 +895,60 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p,
        return ret;
 }
 
+static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle,
+                                       struct policy_handle *acct_handle)
+{
+       NTSTATUS status;
+       uint32_t access_mask;
+       struct lsa_GetSystemAccessAccount r;
+
+       printf("\nTesting GetSystemAccessAccount\n");
+
+       r.in.handle = acct_handle;
+       r.out.access_mask = &access_mask;
+
+       status = dcerpc_lsa_GetSystemAccessAccount(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("GetSystemAccessAccount failed - %s\n", nt_errstr(status));
+               return false;
+       }
+
+       if (r.out.access_mask != NULL) {
+               printf("Rights:");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
+                       printf(" LSA_POLICY_MODE_INTERACTIVE");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
+                       printf(" LSA_POLICY_MODE_NETWORK");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
+                       printf(" LSA_POLICY_MODE_BATCH");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
+                       printf(" LSA_POLICY_MODE_SERVICE");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
+                       printf(" LSA_POLICY_MODE_PROXY");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
+                       printf(" LSA_POLICY_MODE_DENY_INTERACTIVE");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
+                       printf(" LSA_POLICY_MODE_DENY_NETWORK");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
+                       printf(" LSA_POLICY_MODE_DENY_BATCH");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
+                       printf(" LSA_POLICY_MODE_DENY_SERVICE");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
+                       printf(" LSA_POLICY_MODE_REMOTE_INTERACTIVE");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
+                       printf(" LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
+                       printf(" LSA_POLICY_MODE_ALL");
+               if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
+                       printf(" LSA_POLICY_MODE_ALL_NT4");
+               printf("\n");
+       }
+
+       return true;
+}
+
 static bool test_Delete(struct dcerpc_pipe *p, 
                       TALLOC_CTX *mem_ctx, 
                       struct policy_handle *handle)
@@ -902,7 +956,7 @@ static bool test_Delete(struct dcerpc_pipe *p,
        NTSTATUS status;
        struct lsa_Delete r;
 
-       printf("testing Delete\n");
+       printf("\nTesting Delete\n");
 
        r.in.handle = handle;
        status = dcerpc_lsa_Delete(p, mem_ctx, &r);
@@ -921,13 +975,13 @@ static bool test_DeleteObject(struct dcerpc_pipe *p,
        NTSTATUS status;
        struct lsa_DeleteObject r;
 
-       printf("testing DeleteObject\n");
+       printf("\nTesting DeleteObject\n");
 
        r.in.handle = handle;
        r.out.handle = handle;
        status = dcerpc_lsa_DeleteObject(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("Delete failed - %s\n", nt_errstr(status));
+               printf("DeleteObject failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -946,7 +1000,7 @@ static bool test_CreateAccount(struct dcerpc_pipe *p,
 
        newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
 
-       printf("Testing CreateAccount\n");
+       printf("\nTesting CreateAccount\n");
 
        r.in.handle = handle;
        r.in.sid = newsid;
@@ -998,7 +1052,7 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("lsa_OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+               printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1026,7 +1080,7 @@ static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_DeleteTrustedDomain(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("lsa_DeleteTrustedDomain failed - %s\n", nt_errstr(status));
+               printf("DeleteTrustedDomain failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1072,7 +1126,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
        secname[GLOBAL] = talloc_asprintf(mem_ctx, "G$torturesecret-%u", (uint_t)random());
 
        for (i=0; i< 2; i++) {
-               printf("Testing CreateSecret of %s\n", secname[i]);
+               printf("\nTesting CreateSecret of %s\n", secname[i]);
                
                init_lsa_String(&r.in.name, secname[i]);
                
@@ -1384,7 +1438,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p,
        struct lsa_EnumAccountRights r;
        struct lsa_RightSet rights;
 
-       printf("Testing EnumAccountRights\n");
+       printf("\nTesting EnumAccountRights\n");
 
        r.in.handle = acct_handle;
        r.in.sid = sid;
@@ -1410,11 +1464,11 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
        struct lsa_QuerySecurity r;
 
        if (torture_setting_bool(tctx, "samba4", false)) {
-               printf("skipping QuerySecurity test against Samba4\n");
+               printf("\nskipping QuerySecurity test against Samba4\n");
                return true;
        }
 
-       printf("Testing QuerySecurity\n");
+       printf("\nTesting QuerySecurity\n");
 
        r.in.handle = acct_handle;
        r.in.sec_info = 7;
@@ -1437,7 +1491,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p,
        struct lsa_OpenAccount r;
        struct policy_handle acct_handle;
 
-       printf("Testing OpenAccount\n");
+       printf("\nTesting OpenAccount\n");
 
        r.in.handle = handle;
        r.in.sid = sid;
@@ -1454,6 +1508,10 @@ static bool test_OpenAccount(struct dcerpc_pipe *p,
                return false;
        }
 
+       if (!test_GetSystemAccessAccount(p, mem_ctx, handle, &acct_handle)) {
+               return false;
+       }
+
        if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
                return false;
        }
@@ -1472,7 +1530,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
        int i;
        bool ret = true;
 
-       printf("\ntesting EnumAccounts\n");
+       printf("\nTesting EnumAccounts\n");
 
        r.in.handle = handle;
        r.in.resume_handle = &resume_handle;
@@ -1503,7 +1561,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
                 * be on schannel, or we would not be able to do the
                 * rest */
 
-               printf("testing all accounts\n");
+               printf("Testing all accounts\n");
                for (i=0;i<sids1.num_sids;i++) {
                        ret &= test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
                        ret &= test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
@@ -1515,7 +1573,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
                return ret;
        }
        
-       printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
+       printf("Trying EnumAccounts partial listing (asking for 1 at 2)\n");
        resume_handle = 2;
        r.in.num_entries = 1;
        r.out.sids = &sids2;
@@ -1545,7 +1603,7 @@ static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p,
           terminals */
        uint16_t language_id = (random() % 4) + 0x409;
 
-       printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
+       printf("\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
        
        r.in.handle = handle;
        r.in.name = priv_name;
@@ -1576,7 +1634,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p,
 
        ZERO_STRUCT(sids);
        
-       printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
+       printf("\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
        
        r.in.handle = handle;
        r.in.name = priv_name;
@@ -1609,7 +1667,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p,
        int i;
        bool ret = true;
 
-       printf("\ntesting EnumPrivs\n");
+       printf("\nTesting EnumPrivs\n");
 
        r.in.handle = handle;
        r.in.resume_handle = &resume_handle;
@@ -1999,7 +2057,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
        struct lsa_QueryTrustedDomainInfo q;
        int i;
 
-       printf("Testing CreateTrustedDomain for 12 domains\n");
+       printf("\nTesting CreateTrustedDomain for 12 domains\n");
 
        if (!test_EnumTrustDom(p, mem_ctx, handle)) {
                ret = false;
@@ -2095,7 +2153,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
        enum ndr_err_code ndr_err;
        int i;
 
-       printf("Testing CreateTrustedDomainEx2 for 12 domains\n");
+       printf("\nTesting CreateTrustedDomainEx2 for 12 domains\n");
 
        status = dcerpc_fetch_session_key(p, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2226,7 +2284,7 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
                r.in.handle = handle;
                r.in.level = i;
 
-               printf("\ntrying QueryDomainInformationPolicy level %d\n", i);
+               printf("\nTrying QueryDomainInformationPolicy level %d\n", i);
 
                status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r);
 
@@ -2244,35 +2302,49 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
 }
 
 
-static bool test_QueryInfoPolicy(struct dcerpc_pipe *p, 
-                                struct torture_context *tctx, 
-                                struct policy_handle *handle)
+static bool test_QueryInfoPolicyCalls( bool version2,
+                                       struct dcerpc_pipe *p,
+                                       struct torture_context *tctx,
+                                       struct policy_handle *handle)
 {
        struct lsa_QueryInfoPolicy r;
        NTSTATUS status;
        int i;
        bool ret = true;
-       printf("\nTesting QueryInfoPolicy\n");
 
-       for (i=1;i<=13;i++) {
+       if (version2)
+               printf("\nTesting QueryInfoPolicy2\n");
+       else
+               printf("\nTesting QueryInfoPolicy\n");
+
+       for (i=1;i<=14;i++) {
                r.in.handle = handle;
                r.in.level = i;
 
-               printf("\ntrying QueryInfoPolicy level %d\n", i);
+               if (version2)
+                       printf("\nTrying QueryInfoPolicy2 level %d\n", i);
+               else
+                       printf("\nTrying QueryInfoPolicy level %d\n", i);
 
-               status = dcerpc_lsa_QueryInfoPolicy(p, tctx, &r);
+               if (version2)
+                       /* We can perform the cast, because both types are
+                          structurally equal */
+                       status = dcerpc_lsa_QueryInfoPolicy2(p, tctx,
+                                (struct lsa_QueryInfoPolicy2*) &r);
+               else
+                       status = dcerpc_lsa_QueryInfoPolicy(p, tctx, &r);
 
                switch (i) {
-               case LSA_POLICY_INFO_DB:
+               case LSA_POLICY_INFO_MOD:
                case LSA_POLICY_INFO_AUDIT_FULL_SET:
-               case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
                        if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
-                               printf("server should have failed level %u: %s\n", i, nt_errstr(status));
+                               printf("Server should have failed level %u: %s\n", i, nt_errstr(status));
                                ret = false;
                        }
                        break;
                case LSA_POLICY_INFO_DOMAIN:
                case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
+               case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
                case LSA_POLICY_INFO_DNS_INT:
                case LSA_POLICY_INFO_DNS:
                case LSA_POLICY_INFO_REPLICA:
@@ -2282,7 +2354,10 @@ static bool test_QueryInfoPolicy(struct dcerpc_pipe *p,
                case LSA_POLICY_INFO_AUDIT_EVENTS:
                case LSA_POLICY_INFO_PD:
                        if (!NT_STATUS_IS_OK(status)) {
-                               printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+                               if (version2)
+                                       printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+                               else
+                                       printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
                                ret = false;
                        }
                        break;
@@ -2290,17 +2365,24 @@ static bool test_QueryInfoPolicy(struct dcerpc_pipe *p,
                        if (torture_setting_bool(tctx, "samba4", false)) {
                                /* Other levels not implemented yet */
                                if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
-                                       printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+                                       if (version2)
+                                               printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+                                       else
+                                               printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
                                        ret = false;
                                }
                        } else if (!NT_STATUS_IS_OK(status)) {
-                               printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+                               if (version2)
+                                       printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+                               else
+                                       printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
                                ret = false;
                        }
                        break;
                }
 
-               if (NT_STATUS_IS_OK(status) && i == LSA_POLICY_INFO_DNS) {
+               if (NT_STATUS_IS_OK(status) && (i == LSA_POLICY_INFO_DNS
+                       || i == LSA_POLICY_INFO_DNS_INT)) {
                        /* Let's look up some of these names */
 
                        struct lsa_TransNameArray tnames;
@@ -2342,63 +2424,18 @@ static bool test_QueryInfoPolicy(struct dcerpc_pipe *p,
        return ret;
 }
 
+static bool test_QueryInfoPolicy(struct dcerpc_pipe *p, 
+                                struct torture_context *tctx, 
+                                struct policy_handle *handle)
+{
+       return test_QueryInfoPolicyCalls(false, p, tctx, handle);
+}
+
 static bool test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
                                  struct torture_context *tctx, 
                                  struct policy_handle *handle)
 {
-       struct lsa_QueryInfoPolicy2 r;
-       NTSTATUS status;
-       int i;
-       bool ret = true;
-       printf("\nTesting QueryInfoPolicy2\n");
-       for (i=1;i<13;i++) {
-               r.in.handle = handle;
-               r.in.level = i;
-
-               printf("\ntrying QueryInfoPolicy2 level %d\n", i);
-
-               status = dcerpc_lsa_QueryInfoPolicy2(p, tctx, &r);
-               
-               switch (i) {
-               case LSA_POLICY_INFO_DB:
-               case LSA_POLICY_INFO_AUDIT_FULL_SET:
-               case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
-                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
-                               printf("server should have failed level %u: %s\n", i, nt_errstr(status));
-                               ret = false;
-                       }
-                       break;
-               case LSA_POLICY_INFO_DOMAIN:
-               case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
-               case LSA_POLICY_INFO_DNS_INT:
-               case LSA_POLICY_INFO_DNS:
-               case LSA_POLICY_INFO_REPLICA:
-               case LSA_POLICY_INFO_QUOTA:
-               case LSA_POLICY_INFO_ROLE:
-               case LSA_POLICY_INFO_AUDIT_LOG:
-               case LSA_POLICY_INFO_AUDIT_EVENTS:
-               case LSA_POLICY_INFO_PD:
-                       if (!NT_STATUS_IS_OK(status)) {
-                               printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
-                               ret = false;
-                       }
-                       break;
-               default:
-                       if (torture_setting_bool(tctx, "samba4", false)) {
-                               /* Other levels not implemented yet */
-                               if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
-                                       printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
-                                       ret = false;
-                               }
-                       } else if (!NT_STATUS_IS_OK(status)) {
-                               printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
-                               ret = false;
-                       }
-                       break;
-               }
-       }
-
-       return ret;
+       return test_QueryInfoPolicyCalls(true, p, tctx, handle);
 }
 
 static bool test_GetUserName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
@@ -2433,7 +2470,7 @@ bool test_lsa_Close(struct dcerpc_pipe *p,
        struct lsa_Close r;
        struct policy_handle handle2;
 
-       printf("\ntesting Close\n");
+       printf("\nTesting Close\n");
 
        r.in.handle = handle;
        r.out.handle = &handle2;