r23792: convert Samba4 to GPLv3
[kai/samba-autobuild/.git] / source4 / torture / libnet / libnet_domain.c
index 11c99b7c92ca392a70320e1f5479f8c82f086ebf..c337514aa6c1558abe88937d4e743fb840b14436 100644 (file)
@@ -6,7 +6,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,
@@ -15,8 +15,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/>.
 */
 
 
@@ -34,7 +33,8 @@
 
 
 static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                                struct policy_handle *handle, struct lsa_String *domname)
+                                struct policy_handle *handle, struct lsa_String *domname,
+                                uint32_t *access_mask)
 {
        NTSTATUS status;
        struct policy_handle h, domain_handle;
@@ -43,9 +43,11 @@ static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct samr_OpenDomain r3;
        
        printf("connecting\n");
+
+       *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        
        r1.in.system_name = 0;
-       r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       r1.in.access_mask = *access_mask;
        r1.out.connect_handle = &h;
        
        status = dcerpc_samr_Connect(p, mem_ctx, &r1);
@@ -66,7 +68,7 @@ static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        }
 
        r3.in.connect_handle = &h;
-       r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       r3.in.access_mask = *access_mask;
        r3.in.sid = r2.out.sid;
        r3.out.domain_handle = &domain_handle;
 
@@ -85,17 +87,15 @@ static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
 
 static BOOL test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                               struct policy_handle **handle, struct lsa_String *domname)
+                               struct policy_handle *handle, struct lsa_String *domname,
+                               uint32_t *access_mask)
 {
        NTSTATUS status;
        struct lsa_OpenPolicy2 open;
        struct lsa_ObjectAttribute attr;
        struct lsa_QosInfo qos;
 
-       *handle = talloc_zero(mem_ctx, struct policy_handle);
-       if (*handle == NULL) {
-               return False;
-       }
+       *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
        ZERO_STRUCT(attr);
        ZERO_STRUCT(qos);
@@ -109,8 +109,8 @@ static BOOL test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        open.in.system_name = domname->string;
        open.in.attr        = &attr;
-       open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
-       open.out.handle     = *handle;
+       open.in.access_mask = *access_mask;
+       open.out.handle     = handle;
        
        status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
        if (!NT_STATUS_IS_OK(status)) {
@@ -124,17 +124,17 @@ static BOOL test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 BOOL torture_domain_open_lsa(struct torture_context *torture)
 {
        NTSTATUS status;
+       BOOL ret = True;
        struct libnet_context *ctx;
        struct libnet_DomainOpen r;
-       struct dcerpc_binding *binding;
-       const char *bindstr;
-       
-       bindstr = lp_parm_string(-1, "torture", "binding");
-       status = dcerpc_parse_binding(torture, bindstr, &binding);
-       if (!NT_STATUS_IS_OK(status)) {
-               d_printf("failed to parse binding string\n");
-               return False;
-       }
+       struct lsa_Close lsa_close;
+       struct policy_handle h;
+       const char *domain_name;
+
+       /* we're accessing domain controller so the domain name should be
+          passed (it's going to be resolved to dc name and address) instead
+          of specific server name. */
+       domain_name = lp_workgroup();
 
        ctx = libnet_context_init(NULL);
        if (ctx == NULL) {
@@ -144,44 +144,55 @@ BOOL torture_domain_open_lsa(struct torture_context *torture)
 
        ctx->cred = cmdline_credentials;
 
+       ZERO_STRUCT(r);
        r.in.type = DOMAIN_LSA;
-       r.in.domain_name = binding->host;
+       r.in.domain_name = domain_name;
        r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
        status = libnet_DomainOpen(ctx, torture, &r);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status));
-               return False;
+               ret = False;
+               goto done;
        }
 
-       talloc_free(ctx);
+       ZERO_STRUCT(lsa_close);
+       lsa_close.in.handle  = &ctx->lsa.handle;
+       lsa_close.out.handle = &h;
+       
+       status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
+               ret = False;
+       }
 
-       return True;
+done:
+       talloc_free(ctx);
+       return ret;
 }
 
 
 BOOL torture_domain_close_lsa(struct torture_context *torture)
 {
-       BOOL ret;
+       BOOL ret = True;
        NTSTATUS status;
-       TALLOC_CTX *mem_ctx;
+       TALLOC_CTX *mem_ctx=NULL;
        struct libnet_context *ctx;
        struct lsa_String domain_name;
        struct dcerpc_binding *binding;
        const char *bindstr;
-       struct policy_handle *h;
+       uint32_t access_mask;
+       struct policy_handle h;
        struct dcerpc_pipe *p;
        struct libnet_DomainClose r;
-       struct lsa_QueryInfoPolicy2 r2;
 
-       bindstr = lp_parm_string(-1, "torture", "binding");
+       bindstr = torture_setting_string(torture, "binding", NULL);
        status = dcerpc_parse_binding(torture, bindstr, &binding);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("failed to parse binding string\n");
                return False;
        }
 
-       mem_ctx = talloc_init("torture_domain_close_lsa");
        ctx = libnet_context_init(NULL);
        if (ctx == NULL) {
                d_printf("failed to create libnet context\n");
@@ -191,37 +202,40 @@ BOOL torture_domain_close_lsa(struct torture_context *torture)
 
        ctx->cred = cmdline_credentials;
 
-       status = torture_rpc_connection(mem_ctx,
-                                       &p,
-                                       &dcerpc_table_lsarpc);
+       mem_ctx = talloc_init("torture_domain_close_lsa");
+       status = dcerpc_pipe_connect(mem_ctx, &p, bindstr, &dcerpc_table_lsarpc,
+                                    cmdline_credentials, NULL);
        if (!NT_STATUS_IS_OK(status)) {
+               d_printf("failed to connect to server %s: %s\n", bindstr,
+                        nt_errstr(status));
                ret = False;
                goto done;
        }
 
        domain_name.string = lp_workgroup();
-       if (!test_opendomain_lsa(p, mem_ctx, &h, &domain_name)) {
+       
+       if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
+               d_printf("failed to open domain on lsa service\n");
                ret = False;
                goto done;
        }
        
-       /* simulate opening by means of libnet api functions */
-       ctx->lsa.pipe   = p;
-       ctx->lsa.name   = domain_name.string;
-       ctx->lsa.handle = *h;
-
-       r2.in.handle = &ctx->lsa.handle;
-       r2.in.level  = 1;
-       
-       status = dcerpc_lsa_QueryInfoPolicy2(ctx->lsa.pipe, mem_ctx, &r2);
-       
+       ctx->lsa.pipe        = p;
+       ctx->lsa.name        = domain_name.string;
+       ctx->lsa.access_mask = access_mask;
+       ctx->lsa.handle      = h;
+       /* we have to use pipe's event context, otherwise the call will
+          hang indefinitely */
+       ctx->event_ctx       = p->conn->event_ctx;
+
+       ZERO_STRUCT(r);
        r.in.type = DOMAIN_LSA;
        r.in.domain_name = domain_name.string;
        
        status = libnet_DomainClose(ctx, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               goto done;
                ret = False;
+               goto done;
        }
 
 done:
@@ -236,21 +250,24 @@ BOOL torture_domain_open_samr(struct torture_context *torture)
        NTSTATUS status;
        const char *binding;
        struct libnet_context *ctx;
-       struct event_context *evt_ctx;
+       struct event_context *evt_ctx=NULL;
        TALLOC_CTX *mem_ctx;
        struct policy_handle domain_handle, handle;
-       struct lsa_String name;
        struct libnet_DomainOpen io;
        struct samr_Close r;
+       const char *domain_name;
        BOOL ret = True;
 
        mem_ctx = talloc_init("test_domainopen_lsa");
-       binding = lp_parm_string(-1, "torture", "binding");
+       binding = torture_setting_string(torture, "binding", NULL);
 
-       evt_ctx = event_context_find(torture);
        ctx = libnet_context_init(evt_ctx);
+       ctx->cred = cmdline_credentials;
 
-       name.string = lp_workgroup();
+       /* we're accessing domain controller so the domain name should be
+          passed (it's going to be resolved to dc name and address) instead
+          of specific server name. */
+       domain_name = lp_workgroup();
 
        /*
         * Testing synchronous version
@@ -258,7 +275,7 @@ BOOL torture_domain_open_samr(struct torture_context *torture)
        printf("opening domain\n");
        
        io.in.type         = DOMAIN_SAMR;
-       io.in.domain_name  = name.string;
+       io.in.domain_name  = domain_name;
        io.in.access_mask  = SEC_FLAG_MAXIMUM_ALLOWED;
 
        status = libnet_DomainOpen(ctx, mem_ctx, &io);
@@ -268,7 +285,7 @@ BOOL torture_domain_open_samr(struct torture_context *torture)
                goto done;
        }
 
-       domain_handle = io.out.domain_handle;
+       domain_handle = ctx->samr.handle;
 
        r.in.handle   = &domain_handle;
        r.out.handle  = &handle;
@@ -284,6 +301,159 @@ BOOL torture_domain_open_samr(struct torture_context *torture)
 
 done:
        talloc_free(mem_ctx);
+       talloc_free(ctx);
+
+       return ret;
+}
+
+
+BOOL torture_domain_close_samr(struct torture_context *torture)
+{
+       BOOL ret = True;
+       NTSTATUS status;
+       TALLOC_CTX *mem_ctx = NULL;
+       struct libnet_context *ctx;
+       struct lsa_String domain_name;
+       struct dcerpc_binding *binding;
+       const char *bindstr;
+       uint32_t access_mask;
+       struct policy_handle h;
+       struct dcerpc_pipe *p;
+       struct libnet_DomainClose r;
+
+       bindstr = torture_setting_string(torture, "binding", NULL);
+       status = dcerpc_parse_binding(torture, bindstr, &binding);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("failed to parse binding string\n");
+               return False;
+       }
+
+       ctx = libnet_context_init(NULL);
+       if (ctx == NULL) {
+               d_printf("failed to create libnet context\n");
+               ret = False;
+               goto done;
+       }
+
+       ctx->cred = cmdline_credentials;
+
+       mem_ctx = talloc_init("torture_domain_close_samr");
+       status = dcerpc_pipe_connect(mem_ctx, &p, bindstr, &dcerpc_table_samr,
+                                    ctx->cred, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("failed to connect to server %s: %s\n", bindstr,
+                        nt_errstr(status));
+               ret = False;
+               goto done;
+       }
+
+       domain_name.string = lp_workgroup();
+       
+       if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask)) {
+               d_printf("failed to open domain on samr service\n");
+               ret = False;
+               goto done;
+       }
+       
+       ctx->samr.pipe        = p;
+       ctx->samr.name        = domain_name.string;
+       ctx->samr.access_mask = access_mask;
+       ctx->samr.handle      = h;
+       /* we have to use pipe's event context, otherwise the call will
+          hang indefinitely - this wouldn't be the case if pipe was opened
+          by means of libnet call */
+       ctx->event_ctx       = p->conn->event_ctx;
+
+       ZERO_STRUCT(r);
+       r.in.type = DOMAIN_SAMR;
+       r.in.domain_name = domain_name.string;
+       
+       status = libnet_DomainClose(ctx, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               ret = False;
+               goto done;
+       }
+
+done:
+       talloc_free(mem_ctx);
+       talloc_free(ctx);
+       return ret;
+}
+
+
+BOOL torture_domain_list(struct torture_context *torture)
+{
+       BOOL ret = True;
+       NTSTATUS status;
+       TALLOC_CTX *mem_ctx = NULL;
+       const char *bindstr;
+       struct dcerpc_binding *binding;
+       struct libnet_context *ctx;
+       struct libnet_DomainList r;
+       int i;
+
+       bindstr = torture_setting_string(torture, "binding", NULL);
+       status = dcerpc_parse_binding(torture, bindstr, &binding);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("failed to parse binding string\n");
+               return False;
+       }
+
+       ctx = libnet_context_init(NULL);
+       if (ctx == NULL) {
+               d_printf("failed to create libnet context\n");
+               ret = False;
+               goto done;
+       }
+
+       ctx->cred = cmdline_credentials;
+       
+       mem_ctx = talloc_init("torture_domain_close_samr");
+
+       /*
+        * querying the domain list using default buffer size
+        */
+
+       ZERO_STRUCT(r);
+       r.in.hostname = binding->host;
+
+       status = libnet_DomainList(ctx, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               ret = False;
+               goto done;
+       }
+
+       d_printf("Received list or domains (everything in one piece):\n");
+       
+       for (i = 0; i < r.out.count; i++) {
+               d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
+       }
+
+       /*
+        * querying the domain list using specified (much smaller) buffer size
+        */
+
+       ctx->samr.buf_size = 32;
+
+       ZERO_STRUCT(r);
+       r.in.hostname = binding->host;
+
+       status = libnet_DomainList(ctx, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               ret = False;
+               goto done;
+       }
+
+       d_printf("Received list or domains (collected in more than one round):\n");
+       
+       for (i = 0; i < r.out.count; i++) {
+               d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
+       }
 
+done:
+       d_printf("\nStatus: %s\n", nt_errstr(status));
+
+       talloc_free(mem_ctx);
+       talloc_free(ctx);
        return ret;
 }