r2970: - give somefields names and typdef enums for the possible values
authorStefan Metzmacher <metze@samba.org>
Thu, 14 Oct 2004 09:56:04 +0000 (09:56 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:59:53 +0000 (12:59 -0500)
- do more crackname tests in the torture test

- move server code for cracknames to a different file

metze
(This used to be commit 18050ea6037b3c0c7cfe975eb9c872368b9e3328)

source4/librpc/idl/drsuapi.idl
source4/rpc_server/config.mk
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/rpc_server/drsuapi/drsuapi_cracknames.c [new file with mode: 0644]
source4/torture/rpc/drsuapi.c

index fc9aee6b7f80fb869ad35892a4728a081e72b7e6..d49f3d294aa4a2ce2ff0b0a2587214616e968915 100644 (file)
@@ -72,44 +72,77 @@ interface drsuapi
 
        /*****************/
        /* Function 0x0c */
+       typedef enum {
+               DRSUAPI_DS_NAME_STATUS_OK                       = 0,
+               DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR            = 1,
+               DRSUAPI_DS_NAME_STATUS_NOT_FOUND                = 2,
+               DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE               = 3,
+               DRSUAPI_DS_NAME_STATUS_NO_MAPPING               = 4,
+               DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY              = 5,
+               DRSUAPI_DS_NAME_STATUS_NO_SYNTACTICAL_MAPPING   = 6,
+               DRSUAPI_DS_NAME_STATUS_TRUST_REFERRAL           = 7
+       } drsuapi_DsNameStatus;
+
+       typedef enum {
+               DRSUAPI_DS_NAME_FLAG_NO_FLAGS                   = 0x0,
+               DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY           = 0x1,
+               DRSUAPI_DS_NAME_FLAG_EVAL_AT_DC                 = 0x2,
+               DRSUAPI_DS_NAME_FLAG_GCVERIFY                   = 0x4,
+               DRSUAPI_DS_NAME_FLAG_TRUST_REFERRAL             = 0x8
+       } drsuapi_DsNameFlags;
+
+       typedef enum {
+               DRSUAPI_DS_NAME_FORMAT_UKNOWN                   = 0,
+               DRSUAPI_DS_NAME_FORMAT_FQDN_1779                = 1,
+               DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT              = 2,
+               DRSUAPI_DS_NAME_FORMAT_DISPLAY                  = 3,
+               DRSUAPI_DS_NAME_FORMAT_GUID                     = 6,
+               DRSUAPI_DS_NAME_FORMAT_CANONICAL                = 7,
+               DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL           = 8,
+               DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX             = 9,
+               DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL        = 10,
+               DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY       = 11,
+               DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN               = 12
+       } drsuapi_DsNameFormat;
+
        typedef struct {
                unistr *str;
-       } drsuapi_DsCrackNamesInInfo1Names;
+       } drsuapi_DsNameString;
 
        typedef struct {
-               uint32 unknown1;
-               uint32 unknown2;
-               uint32 unknown3;
-               uint32 unknown4;
-               uint32 unknown5;
+               uint32 unknown1; /* 0x000004e4 */
+               uint32 unknown2; /* 0x00000407 */
+               uint32 format_flags;
+               uint32 format_offered;
+               uint32 format_desired;
                [range(1,10000)] uint32 count;
-               [size_is(count)] drsuapi_DsCrackNamesInInfo1Names *names;
-       } drsuapi_DsCrackNamesInInfo1;
+               [size_is(count)] drsuapi_DsNameString *names;
+       } drsuapi_DsNameRequest1;
 
        typedef union {
-               [case(1)] drsuapi_DsCrackNamesInInfo1 info1;
-       } drsuapi_DsCrackNamesInInfo;
+               [case(1)] drsuapi_DsNameRequest1 req1;
+       } drsuapi_DsNameRequest;
 
        typedef struct {
-               uint32 unknown1;
-               unistr *name1;
-               unistr *name2;
-       } drsuapi_DsCrackNamesOutInfo1Names;
+               uint32 status;
+               unistr *dns_domain_name;
+               unistr *result_name;
+       } drsuapi_DsNameInfo1;
 
        typedef struct {
                uint32 count;
-               [size_is(count)] drsuapi_DsCrackNamesOutInfo1Names *names;
-       } drsuapi_DsCrackNamesOutInfo1;
+               [size_is(count)] drsuapi_DsNameInfo1 *array;
+       } drsuapi_DsNameCtr1;
 
        typedef union {
-               [case(1)] drsuapi_DsCrackNamesOutInfo1 *info1;
-       } drsuapi_DsCrackNamesOutInfo;
+               [case(1)] drsuapi_DsNameCtr1 *ctr1;
+       } drsuapi_DsNameCtr;
 
        NTSTATUS drsuapi_DsCrackNames(
                [in,ref] policy_handle *bind_handle,
                [in, out] uint32 level,
-               [in,switch_is(level)] drsuapi_DsCrackNamesInInfo in,
-               [out,switch_is(level)] drsuapi_DsCrackNamesOutInfo out
+               [in,switch_is(level)] drsuapi_DsNameRequest req,
+               [out,switch_is(level)] drsuapi_DsNameCtr ctr
                );
 
        /*****************/
index 350803afd972e83b8618f17f8ebc2d468180bd9a..9c0751a1b90d8c3bc0e168ceb1943e7528e55e58 100644 (file)
@@ -153,6 +153,8 @@ REQUIRED_SUBSYSTEMS = \
 [MODULE::dcerpc_drsuapi]
 INIT_OBJ_FILES = \
                rpc_server/drsuapi/dcesrv_drsuapi.o
+ADD_OBJ_FILES = \
+               rpc_server/drsuapi/drsuapi_cracknames.o
 REQUIRED_SUBSYSTEMS = \
                SAMDB \
                DCERPC_COMMON
index 06fa1bba95c2a4be844f83f1c85a694a9ca725f1..503a54b6b3ddba596690d9ca74b4a2850b941988 100644 (file)
@@ -190,54 +190,10 @@ static NTSTATUS DRSUAPI_GET_NT4_CHANGELOG(struct dcesrv_call_state *dce_call, TA
 
 
 /* 
-  drsuapi_DsCrackNames 
+  drsuapi_DsCrackNames => drsuapip_cracknames.c
 */
-static NTSTATUS drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct drsuapi_DsCrackNames *r)
-{
-       struct dcesrv_handle *h;
-
-       r->out.level = r->in.level;
-       ZERO_STRUCT(r->out.out);
-
-       DCESRV_PULL_HANDLE(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
-
-       switch (r->in.level) {
-               case 1: {
-                       int i;
-
-                       r->out.out.info1 = talloc_p(mem_ctx, struct drsuapi_DsCrackNamesOutInfo1);
-                       NTSTATUS_TALLOC_CHECK(r->out.out.info1);
-
-                       r->out.out.info1->names = talloc_array_p(mem_ctx,
-                                                       struct drsuapi_DsCrackNamesOutInfo1Names,
-                                                       r->in.in.info1.count);
-                       NTSTATUS_TALLOC_CHECK(r->out.out.info1->names);
-
-                       r->out.out.info1->count = r->in.in.info1.count;
-
-                       for (i=0; i < r->out.out.info1->count; i++) {
-                               const char *name;
-                               r->out.out.info1->names[i].unknown1 = 2;
-                               r->out.out.info1->names[i].name1 = NULL;
-                               r->out.out.info1->names[i].name2 = NULL;
-
-                               /* TODO: fill crack the right names! */
-                               name = talloc_asprintf(mem_ctx, "%s/", lp_realm());
-                               if (strcmp(name, r->in.in.info1.names[i].str) != 0) {
-                                       continue;
-                               }
-                               r->out.out.info1->names[i].unknown1 = 0;
-                               r->out.out.info1->names[i].name1 = talloc_asprintf(mem_ctx, "%s", lp_realm());
-                               r->out.out.info1->names[i].name2 = talloc_asprintf(mem_ctx, "%s\\", lp_workgroup());
-                       }
-                       return NT_STATUS_OK;
-               }
-       }
-       
-       return NT_STATUS_INVALID_LEVEL;
-}
-
+static NTSTATUS (*drsuapi_DsCrackNames)(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                      struct drsuapi_DsCrackNames *r) = dcesrv_drsuapi_DsCrackNames;
 
 /* 
   DRSUAPI_WRITE_SPN 
diff --git a/source4/rpc_server/drsuapi/drsuapi_cracknames.c b/source4/rpc_server/drsuapi/drsuapi_cracknames.c
new file mode 100644 (file)
index 0000000..1a31d54
--- /dev/null
@@ -0,0 +1,128 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   endpoint server for the drsuapi pipe
+   DsCrackNames()
+
+   Copyright (C) Stefan Metzmacher 2004
+   
+   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
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.
+*/
+
+#include "includes.h"
+#include "rpc_server/common/common.h"
+#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
+
+
+static NTSTATUS DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx,
+                       uint32 format_offered, uint32 format_desired, const char *name,
+                       struct drsuapi_DsNameInfo1 *info1)
+{
+       info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+       info1->dns_domain_name = NULL;
+       info1->result_name = NULL;
+
+       /* TODO: fill crack the correct names in all cases! */
+       switch (format_offered) {
+               case DRSUAPI_DS_NAME_FORMAT_CANONICAL: {
+                       int ret;
+                       char *str;
+
+                       str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
+                       NTSTATUS_TALLOC_CHECK(str);
+
+                       ret = strcasecmp(str, name);
+                       talloc_free(str);
+                       if (ret != 0) {
+                               info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+                               return NT_STATUS_OK;
+                       }
+
+                       info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
+                       info1->dns_domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
+                       NTSTATUS_TALLOC_CHECK(info1->dns_domain_name);
+                       switch (format_desired) {
+                               case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT:
+                                       info1->status = DRSUAPI_DS_NAME_STATUS_OK;
+                                       info1->result_name = talloc_asprintf(mem_ctx, "%s\\",
+                                                                               lp_workgroup());
+                                       NTSTATUS_TALLOC_CHECK(info1->result_name);
+                                       return NT_STATUS_OK;
+                               default:
+                                       return NT_STATUS_OK;
+                       }
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               default: {
+                       info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+                       return NT_STATUS_OK;
+               }
+       }
+
+       return NT_STATUS_INVALID_PARAMETER;
+}
+
+/* 
+  drsuapi_DsCrackNames 
+*/
+NTSTATUS dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                      struct drsuapi_DsCrackNames *r)
+{
+       NTSTATUS status;
+       struct drsuapi_bind_state *b_state;
+       struct dcesrv_handle *h;
+
+       r->out.level = r->in.level;
+       ZERO_STRUCT(r->out.ctr);
+
+       DCESRV_PULL_HANDLE(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
+       b_state = h->data;
+
+       switch (r->in.level) {
+               case 1: {
+                       struct drsuapi_DsNameInfo1 *names;
+                       int count;
+                       int i;
+
+                       r->out.ctr.ctr1 = talloc_p(mem_ctx, struct drsuapi_DsNameCtr1);
+                       NTSTATUS_TALLOC_CHECK(r->out.ctr.ctr1);
+
+                       r->out.ctr.ctr1->count = 0;
+                       r->out.ctr.ctr1->array = NULL;
+
+                       count = r->in.req.req1.count;
+                       names = talloc_array_p(mem_ctx, struct drsuapi_DsNameInfo1, count);
+                       NTSTATUS_TALLOC_CHECK(names);
+
+                       for (i=0; i < count; i++) {
+                               status = DsCrackNameOneName(b_state, mem_ctx,
+                                                           r->in.req.req1.format_offered,
+                                                           r->in.req.req1.format_desired,
+                                                           r->in.req.req1.names[i].str,
+                                                           &names[i]);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       return status;
+                               }
+                       }
+
+                       r->out.ctr.ctr1->count = count;
+                       r->out.ctr.ctr1->array = names;
+
+                       return NT_STATUS_OK;
+               }
+       }
+       
+       return NT_STATUS_INVALID_LEVEL;
+}
index aed7f884d2f1b8777f923b3d6ffdf84143d0a449..562291c6de37b48537568b242604f054c7da4c65 100644 (file)
@@ -53,20 +53,24 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct drsuapi_DsCrackNames r;
-       struct drsuapi_DsCrackNamesInInfo1Names names[1];
+       struct drsuapi_DsNameString names[1];
        BOOL ret = True;
+       const char *dns_domain;
+       const char *nt4_domain;
+       const char *FQDN_1779_domain;
+       const char *FQDN_1779_name;
 
        ZERO_STRUCT(r);
-       r.in.bind_handle = bind_handle;
-       r.in.level = 1;
-       r.in.in.info1.unknown1 = 0x000004e4;
-       r.in.in.info1.unknown2 = 0x00000407;
-       r.in.in.info1.unknown3 = 0x00000000;
-       r.in.in.info1.unknown4 = 0x00000007;
-       r.in.in.info1.unknown5 = 0x00000002;
-       r.in.in.info1.count = 1;
-       r.in.in.info1.names = names;
-       
+       r.in.bind_handle                = bind_handle;
+       r.in.level                      = 1;
+       r.in.req.req1.unknown1          = 0x000004e4;
+       r.in.req.req1.unknown2          = 0x00000407;
+       r.in.req.req1.count             = 1;
+       r.in.req.req1.names             = names;
+       r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
+
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
        names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
 
        status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
@@ -79,6 +83,135 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                ret = False;
        }
 
+       if (!ret) {
+               return ret;
+       }
+
+       dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
+       nt4_domain = r.out.ctr.ctr1->array[0].result_name;
+
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       names[0].str = nt4_domain;
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
+       FQDN_1779_domain = r.out.ctr.ctr1->array[0].result_name;
+
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, dcerpc_server_name(p));
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
+       FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
+
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
+       names[0].str = FQDN_1779_name;
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_DISPLAY;
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
+
+       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               const char *errstr = nt_errstr(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+                       errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+               }
+               printf("drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
        return ret;
 }