r3920: - it seem that we need to send a magic bind_guid in DsBind()
authorStefan Metzmacher <metze@samba.org>
Tue, 23 Nov 2004 08:57:42 +0000 (08:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:06:06 +0000 (13:06 -0500)
  to make DsWriteAccountSpn() work

- add idl and torture test for DsWriteAccountSpn()

metze
(This used to be commit 625826ad9050c68407ae5e8abfee13699986303c)

source4/librpc/idl/drsuapi.idl
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/torture/rpc/drsuapi.c

index 17e84fffab619cde1cb446fe922e34a51459b7bb..481c1a1de13d6f2077bff4303247ab0697a8c8b8 100644 (file)
@@ -17,8 +17,11 @@ interface drsuapi
                [size_is(length)] uint8 data[];
        } drsuapi_DsBindInfo;
 
+       /* this is a magic guid you need to pass to DsBind to make drsuapi_DsWriteAccountSpn() work */
+       const string DRSUAPI_DS_BIND_GUID = "e24d201a-4fd6-11d1-a3da-0000f875ae0d";
+
        WERROR drsuapi_DsBind(
-               [in]        GUID *server_guid,
+               [in]        GUID *bind_guid,
                [in,out]    drsuapi_DsBindInfo *bind_info,
                [out,ref]   policy_handle *bind_handle
                );
@@ -145,8 +148,39 @@ interface drsuapi
                );
 
        /*****************/
-        /* Function 0x0d */
-       WERROR DRSUAPI_WRITE_SPN();
+       /* Function 0x0d */
+       typedef enum {
+               DRSUAPI_DS_SPN_OPERATION_ADD    = 0,
+               DRSUAPI_DS_SPN_OPERATION_REPLACE= 1,
+               DRSUAPI_DS_SPN_OPERATION_DELETE = 2
+       } drsuapi_DsSpnOperation;
+
+       typedef struct {
+               int32 operation;
+               int32 unknown1;
+               unistr *object_dn;
+               [range(0,10000)] uint32 count;
+               [size_is(count)] drsuapi_DsNameString *spn_names;
+       } drsuapi_DsWriteAccountSpnRequest1;
+
+       typedef union {
+               [case(1)] drsuapi_DsWriteAccountSpnRequest1 req1;
+       } drsuapi_DsWriteAccountSpnRequest;
+
+       typedef struct {
+               WERROR status;
+       } drsuapi_DsWriteAccountSpnResult1;
+
+       typedef union {
+               [case(1)] drsuapi_DsWriteAccountSpnResult1 res1;
+       } drsuapi_DsWriteAccountSpnResult;
+
+       WERROR drsuapi_DsWriteAccountSpn(
+               [in,ref] policy_handle *bind_handle,
+               [in, out] uint32 level,
+               [in,switch_is(level)] drsuapi_DsWriteAccountSpnRequest req,
+               [out,switch_is(level)] drsuapi_DsWriteAccountSpnResult res
+               );
 
        /*****************/
         /* Function 0x0e */
index 617bc027424e962ddaee73ee37b1d2b20e5cdf29..eb38a22f43e55db8fb74b23cc966d6a8b5c465aa 100644 (file)
@@ -200,10 +200,10 @@ static WERROR (*drsuapi_DsCrackNames)(struct dcesrv_call_state *dce_call, TALLOC
                       struct drsuapi_DsCrackNames *r) = dcesrv_drsuapi_DsCrackNames;
 
 /* 
-  DRSUAPI_WRITE_SPN 
+  drsuapi_DsWriteAccountSpn 
 */
-static WERROR DRSUAPI_WRITE_SPN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct DRSUAPI_WRITE_SPN *r)
+static WERROR drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                      struct drsuapi_DsWriteAccountSpn *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
index 6696d12136855b0c5281f7c2da20616e9e508a52..b6b1ddf6dcfa20e4a6704cd478f300da75465afa 100644 (file)
@@ -26,6 +26,7 @@
 
 struct DsPrivate {
        struct policy_handle bind_handle;
+       struct GUID bind_guid;
        const char *domain_guid_str;
        struct drsuapi_DsGetDCInfo2 dcinfo;
 };
@@ -37,7 +38,9 @@ static BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct drsuapi_DsBind r;
        BOOL ret = True;
 
-       r.in.server_guid = NULL;
+       GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
+
+       r.in.bind_guid = &priv->bind_guid;
        r.in.bind_info = NULL;
        r.out.bind_handle = &priv->bind_handle;
 
@@ -366,6 +369,8 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return ret;
        }
 
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid);
 
        printf("testing DsCrackNames with Server GUID '%s' desired format:%d\n",
@@ -388,6 +393,8 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return ret;
        }
 
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid);
 
        printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
@@ -410,6 +417,30 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return ret;
        }
 
+       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
+       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
+
+       printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
+                       names[0].str, r.in.req.req1.format_desired);
+
+       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("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
+               ret = False;
+       } else if (!W_ERROR_IS_OK(r.out.result)) {
+               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
+               ret = False;
+       }
+
+       if (!ret) {
+               return ret;
+       }
+
        return ret;
 }
 
@@ -543,6 +574,59 @@ static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        return ret;
 }
 
+static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+                       struct DsPrivate *priv)
+{
+       NTSTATUS status;
+       struct drsuapi_DsWriteAccountSpn r;
+       struct drsuapi_DsNameString names[2];
+       BOOL ret = True;
+
+       r.in.bind_handle                = &priv->bind_handle;
+       r.in.level                      = 1;
+
+       printf("testing DsWriteAccountSpn\n");
+
+       r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
+       r.in.req.req1.unknown1  = 0;
+       r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
+       r.in.req.req1.count     = 2;
+       r.in.req.req1.spn_names = names;
+       names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
+       names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
+
+       status = dcerpc_drsuapi_DsWriteAccountSpn(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("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
+               ret = False;
+       } else if (!W_ERROR_IS_OK(r.out.result)) {
+               printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
+               ret = False;
+       }
+
+       r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
+       r.in.req.req1.unknown1  = 0;
+
+       status = dcerpc_drsuapi_DsWriteAccountSpn(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("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
+               ret = False;
+       } else if (!W_ERROR_IS_OK(r.out.result)) {
+               printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
+               ret = False;
+       }
+
+       return ret;
+}
+
 static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
                        struct DsPrivate *priv)
 {
@@ -605,6 +689,10 @@ BOOL torture_rpc_drsuapi(void)
                ret = False;
        }
 
+       if (!test_DsWriteAccountSpn(p, mem_ctx, &priv)) {
+               ret = False;
+       }
+
        if (!test_DsUnbind(p, mem_ctx, &priv)) {
                ret = False;
        }