root/source4/torture/libnet/libnet_domain.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_opendomain_samr
  2. test_opendomain_lsa
  3. torture_domain_open_lsa
  4. torture_domain_close_lsa
  5. torture_domain_open_samr
  6. torture_domain_close_samr
  7. torture_domain_list

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    Test suite for libnet calls.
   4 
   5    Copyright (C) Rafal Szczesniak 2006
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 
  22 #include "includes.h"
  23 #include "lib/cmdline/popt_common.h"
  24 #include "lib/events/events.h"
  25 #include "auth/credentials/credentials.h"
  26 #include "libnet/libnet.h"
  27 #include "librpc/gen_ndr/ndr_samr_c.h"
  28 #include "librpc/gen_ndr/ndr_lsa_c.h"
  29 #include "libcli/security/security.h"
  30 #include "librpc/rpc/dcerpc.h"
  31 #include "torture/torture.h"
  32 #include "torture/rpc/rpc.h"
  33 #include "param/param.h"
  34 
  35 
  36 static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  37                                  struct policy_handle *handle, struct lsa_String *domname,
  38                                  uint32_t *access_mask, struct dom_sid **sid_p)
  39 {
  40         NTSTATUS status;
  41         struct policy_handle h, domain_handle;
  42         struct samr_Connect r1;
  43         struct samr_LookupDomain r2;
  44         struct dom_sid2 *sid = NULL;
  45         struct samr_OpenDomain r3;
  46         
  47         printf("connecting\n");
  48 
  49         *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
  50         
  51         r1.in.system_name = 0;
  52         r1.in.access_mask = *access_mask;
  53         r1.out.connect_handle = &h;
  54         
  55         status = dcerpc_samr_Connect(p, mem_ctx, &r1);
  56         if (!NT_STATUS_IS_OK(status)) {
  57                 printf("Connect failed - %s\n", nt_errstr(status));
  58                 return false;
  59         }
  60         
  61         r2.in.connect_handle = &h;
  62         r2.in.domain_name = domname;
  63         r2.out.sid = &sid;
  64 
  65         printf("domain lookup on %s\n", domname->string);
  66 
  67         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
  68         if (!NT_STATUS_IS_OK(status)) {
  69                 printf("LookupDomain failed - %s\n", nt_errstr(status));
  70                 return false;
  71         }
  72 
  73         r3.in.connect_handle = &h;
  74         r3.in.access_mask = *access_mask;
  75         r3.in.sid = *sid_p = *r2.out.sid;
  76         r3.out.domain_handle = &domain_handle;
  77 
  78         printf("opening domain\n");
  79 
  80         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
  81         if (!NT_STATUS_IS_OK(status)) {
  82                 printf("OpenDomain failed - %s\n", nt_errstr(status));
  83                 return false;
  84         } else {
  85                 *handle = domain_handle;
  86         }
  87 
  88         return true;
  89 }
  90 
  91 
  92 static bool test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  93                                 struct policy_handle *handle, struct lsa_String *domname,
  94                                 uint32_t *access_mask)
  95 {
  96         NTSTATUS status;
  97         struct lsa_OpenPolicy2 open;
  98         struct lsa_ObjectAttribute attr;
  99         struct lsa_QosInfo qos;
 100 
 101         *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 102 
 103         ZERO_STRUCT(attr);
 104         ZERO_STRUCT(qos);
 105 
 106         qos.len                 = 0;
 107         qos.impersonation_level = 2;
 108         qos.context_mode        = 1;
 109         qos.effective_only      = 0;
 110         
 111         attr.sec_qos = &qos;
 112 
 113         open.in.system_name = domname->string;
 114         open.in.attr        = &attr;
 115         open.in.access_mask = *access_mask;
 116         open.out.handle     = handle;
 117         
 118         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
 119         if (!NT_STATUS_IS_OK(status)) {
 120                 return false;
 121         }
 122 
 123         return true;
 124 }
 125 
 126 bool torture_domain_open_lsa(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 127 {
 128         NTSTATUS status;
 129         bool ret = true;
 130         struct libnet_context *ctx;
 131         struct libnet_DomainOpen r;
 132         struct lsa_Close lsa_close;
 133         struct policy_handle h;
 134         const char *domain_name;
 135 
 136         /* we're accessing domain controller so the domain name should be
 137            passed (it's going to be resolved to dc name and address) instead
 138            of specific server name. */
 139         domain_name = lp_workgroup(torture->lp_ctx);
 140 
 141         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
 142         if (ctx == NULL) {
 143                 d_printf("failed to create libnet context\n");
 144                 return false;
 145         }
 146 
 147         ctx->cred = cmdline_credentials;
 148 
 149         ZERO_STRUCT(r);
 150         r.in.type = DOMAIN_LSA;
 151         r.in.domain_name = domain_name;
 152         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 153 
 154         status = libnet_DomainOpen(ctx, torture, &r);
 155         if (!NT_STATUS_IS_OK(status)) {
 156                 d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status));
 157                 ret = false;
 158                 goto done;
 159         }
 160 
 161         ZERO_STRUCT(lsa_close);
 162         lsa_close.in.handle  = &ctx->lsa.handle;
 163         lsa_close.out.handle = &h;
 164         
 165         status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
 166         if (!NT_STATUS_IS_OK(status)) {
 167                 d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
 168                 ret = false;
 169         }
 170 
 171 done:
 172         talloc_free(ctx);
 173         return ret;
 174 }
 175 
 176 
 177 bool torture_domain_close_lsa(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179         bool ret = true;
 180         NTSTATUS status;
 181         TALLOC_CTX *mem_ctx=NULL;
 182         struct libnet_context *ctx;
 183         struct lsa_String domain_name;
 184         struct dcerpc_binding *binding;
 185         uint32_t access_mask;
 186         struct policy_handle h;
 187         struct dcerpc_pipe *p;
 188         struct libnet_DomainClose r;
 189 
 190         status = torture_rpc_binding(torture, &binding);
 191         if (!NT_STATUS_IS_OK(status)) {
 192                 return false;
 193         }
 194 
 195         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
 196         if (ctx == NULL) {
 197                 d_printf("failed to create libnet context\n");
 198                 ret = false;
 199                 goto done;
 200         }
 201 
 202         ctx->cred = cmdline_credentials;
 203 
 204         mem_ctx = talloc_init("torture_domain_close_lsa");
 205         status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_lsarpc,
 206                                      cmdline_credentials, torture->ev, torture->lp_ctx);
 207         if (!NT_STATUS_IS_OK(status)) {
 208                 d_printf("failed to connect to server: %s\n", nt_errstr(status));
 209                 ret = false;
 210                 goto done;
 211         }
 212 
 213         domain_name.string = lp_workgroup(torture->lp_ctx);
 214         
 215         if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
 216                 d_printf("failed to open domain on lsa service\n");
 217                 ret = false;
 218                 goto done;
 219         }
 220         
 221         ctx->lsa.pipe        = p;
 222         ctx->lsa.name        = domain_name.string;
 223         ctx->lsa.access_mask = access_mask;
 224         ctx->lsa.handle      = h;
 225         /* we have to use pipe's event context, otherwise the call will
 226            hang indefinitely */
 227         ctx->event_ctx       = p->conn->event_ctx;
 228 
 229         ZERO_STRUCT(r);
 230         r.in.type = DOMAIN_LSA;
 231         r.in.domain_name = domain_name.string;
 232         
 233         status = libnet_DomainClose(ctx, mem_ctx, &r);
 234         if (!NT_STATUS_IS_OK(status)) {
 235                 ret = false;
 236                 goto done;
 237         }
 238 
 239 done:
 240         talloc_free(mem_ctx);
 241         talloc_free(ctx);
 242         return ret;
 243 }
 244 
 245 
 246 bool torture_domain_open_samr(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 247 {
 248         NTSTATUS status;
 249         struct libnet_context *ctx;
 250         TALLOC_CTX *mem_ctx;
 251         struct policy_handle domain_handle, handle;
 252         struct libnet_DomainOpen io;
 253         struct samr_Close r;
 254         const char *domain_name;
 255         bool ret = true;
 256 
 257         mem_ctx = talloc_init("test_domainopen_lsa");
 258 
 259         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
 260         ctx->cred = cmdline_credentials;
 261 
 262         /* we're accessing domain controller so the domain name should be
 263            passed (it's going to be resolved to dc name and address) instead
 264            of specific server name. */
 265         domain_name = lp_workgroup(torture->lp_ctx);
 266 
 267         /*
 268          * Testing synchronous version
 269          */
 270         printf("opening domain\n");
 271         
 272         io.in.type         = DOMAIN_SAMR;
 273         io.in.domain_name  = domain_name;
 274         io.in.access_mask  = SEC_FLAG_MAXIMUM_ALLOWED;
 275 
 276         status = libnet_DomainOpen(ctx, mem_ctx, &io);
 277         if (!NT_STATUS_IS_OK(status)) {
 278                 printf("Composite domain open failed - %s\n", nt_errstr(status));
 279                 ret = false;
 280                 goto done;
 281         }
 282 
 283         domain_handle = ctx->samr.handle;
 284 
 285         r.in.handle   = &domain_handle;
 286         r.out.handle  = &handle;
 287         
 288         printf("closing domain handle\n");
 289         
 290         status = dcerpc_samr_Close(ctx->samr.pipe, mem_ctx, &r);
 291         if (!NT_STATUS_IS_OK(status)) {
 292                 printf("Close failed - %s\n", nt_errstr(status));
 293                 ret = false;
 294                 goto done;
 295         }
 296 
 297 done:
 298         talloc_free(mem_ctx);
 299         talloc_free(ctx);
 300 
 301         return ret;
 302 }
 303 
 304 
 305 bool torture_domain_close_samr(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 306 {
 307         bool ret = true;
 308         NTSTATUS status;
 309         TALLOC_CTX *mem_ctx = NULL;
 310         struct libnet_context *ctx;
 311         struct lsa_String domain_name;
 312         struct dcerpc_binding *binding;
 313         uint32_t access_mask;
 314         struct policy_handle h;
 315         struct dcerpc_pipe *p;
 316         struct libnet_DomainClose r;
 317         struct dom_sid *sid;
 318 
 319         status = torture_rpc_binding(torture, &binding);
 320         if (!NT_STATUS_IS_OK(status)) {
 321                 return false;
 322         }
 323 
 324         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
 325         if (ctx == NULL) {
 326                 d_printf("failed to create libnet context\n");
 327                 ret = false;
 328                 goto done;
 329         }
 330 
 331         ctx->cred = cmdline_credentials;
 332 
 333         mem_ctx = talloc_init("torture_domain_close_samr");
 334         status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_samr,
 335                                      ctx->cred, torture->ev, torture->lp_ctx);
 336         if (!NT_STATUS_IS_OK(status)) {
 337                 d_printf("failed to connect to server: %s\n", nt_errstr(status));
 338                 ret = false;
 339                 goto done;
 340         }
 341 
 342         domain_name.string = talloc_strdup(mem_ctx, lp_workgroup(torture->lp_ctx));
 343         
 344         if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask, &sid)) {
 345                 d_printf("failed to open domain on samr service\n");
 346                 ret = false;
 347                 goto done;
 348         }
 349         
 350         ctx->samr.pipe        = p;
 351         ctx->samr.name        = talloc_steal(ctx, domain_name.string);
 352         ctx->samr.access_mask = access_mask;
 353         ctx->samr.handle      = h;
 354         ctx->samr.sid         = talloc_steal(ctx, sid);
 355         /* we have to use pipe's event context, otherwise the call will
 356            hang indefinitely - this wouldn't be the case if pipe was opened
 357            by means of libnet call */
 358         ctx->event_ctx       = p->conn->event_ctx;
 359 
 360         ZERO_STRUCT(r);
 361         r.in.type = DOMAIN_SAMR;
 362         r.in.domain_name = domain_name.string;
 363         
 364         status = libnet_DomainClose(ctx, mem_ctx, &r);
 365         if (!NT_STATUS_IS_OK(status)) {
 366                 ret = false;
 367                 goto done;
 368         }
 369 
 370 done:
 371         talloc_free(mem_ctx);
 372         talloc_free(ctx);
 373         return ret;
 374 }
 375 
 376 
 377 bool torture_domain_list(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 378 {
 379         bool ret = true;
 380         NTSTATUS status;
 381         TALLOC_CTX *mem_ctx = NULL;
 382         struct dcerpc_binding *binding;
 383         struct libnet_context *ctx;
 384         struct libnet_DomainList r;
 385         int i;
 386 
 387         status = torture_rpc_binding(torture, &binding);
 388         if (!NT_STATUS_IS_OK(status)) {
 389                 return false;
 390         }
 391 
 392         ctx = libnet_context_init(torture->ev, torture->lp_ctx);
 393         if (ctx == NULL) {
 394                 d_printf("failed to create libnet context\n");
 395                 ret = false;
 396                 goto done;
 397         }
 398 
 399         ctx->cred = cmdline_credentials;
 400         
 401         mem_ctx = talloc_init("torture_domain_close_samr");
 402 
 403         /*
 404          * querying the domain list using default buffer size
 405          */
 406 
 407         ZERO_STRUCT(r);
 408         r.in.hostname = binding->host;
 409 
 410         status = libnet_DomainList(ctx, mem_ctx, &r);
 411         if (!NT_STATUS_IS_OK(status)) {
 412                 ret = false;
 413                 goto done;
 414         }
 415 
 416         d_printf("Received list or domains (everything in one piece):\n");
 417         
 418         for (i = 0; i < r.out.count; i++) {
 419                 d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
 420         }
 421 
 422         /*
 423          * querying the domain list using specified (much smaller) buffer size
 424          */
 425 
 426         ctx->samr.buf_size = 32;
 427 
 428         ZERO_STRUCT(r);
 429         r.in.hostname = binding->host;
 430 
 431         status = libnet_DomainList(ctx, mem_ctx, &r);
 432         if (!NT_STATUS_IS_OK(status)) {
 433                 ret = false;
 434                 goto done;
 435         }
 436 
 437         d_printf("Received list or domains (collected in more than one round):\n");
 438         
 439         for (i = 0; i < r.out.count; i++) {
 440                 d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
 441         }
 442 
 443 done:
 444         d_printf("\nStatus: %s\n", nt_errstr(status));
 445 
 446         talloc_free(mem_ctx);
 447         talloc_free(ctx);
 448         return ret;
 449 }

/* [<][>][^][v][top][bottom][index][help] */