Implement the LIST_INFO_FOR_SERVER input format
authorMatthieu Patou <mat@matws.net>
Tue, 25 Sep 2012 04:34:02 +0000 (21:34 -0700)
committerMatthieu Patou <mat@matws.net>
Mon, 8 Oct 2012 04:51:01 +0000 (21:51 -0700)
source4/dsdb/samdb/cracknames.c
source4/rpc_server/drsuapi/dcesrv_drsuapi.c

index 504f1b2deb4ba75c3c3a2f5d0f0204c364345969..9fc377da42802f07a944497fdb0dfae585f4adab 100644 (file)
@@ -1494,3 +1494,110 @@ WERROR dcesrv_drsuapi_CrackNamesByNameFormat(struct ldb_context *sam_ctx, TALLOC
 
        return WERR_OK;
 }
+
+WERROR dcesrv_drsuapi_ListInfoServer(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
+                                    const struct drsuapi_DsNameRequest1 *req1,
+                                    struct drsuapi_DsNameCtr1 **_ctr1)
+{
+       struct drsuapi_DsNameInfo1 *names;
+       struct ldb_result *res;
+       struct ldb_dn *server_dn, *dn;
+       struct drsuapi_DsNameCtr1 *ctr1;
+       int ret, i;
+       const char *str;
+       const char *attrs[] = {
+               "dn",
+               "dNSHostName",
+               "serverReference",
+               NULL
+       };
+
+       *_ctr1 = NULL;
+
+       ctr1 = talloc_zero(mem_ctx, struct drsuapi_DsNameCtr1);
+       W_ERROR_HAVE_NO_MEMORY(ctr1);
+
+       /*
+        * No magic value here, we have to return 3 entries according to the
+        * MS-DRSR.pdf
+        */
+       ctr1->count = 3;
+       names = talloc_zero_array(ctr1, struct drsuapi_DsNameInfo1,
+                                 ctr1->count);
+       W_ERROR_HAVE_NO_MEMORY(names);
+       ctr1->array = names;
+
+       for (i=0; i < ctr1->count; i++) {
+               names[i].status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+       }
+       *_ctr1 = ctr1;
+
+       if (req1->count != 1) {
+               DEBUG(1, ("Expected a count of 1 for the ListInfoServer crackname \n"));
+               return WERR_OK;
+       }
+
+       if (req1->names[0].str == NULL) {
+               return WERR_OK;
+       }
+
+       server_dn = ldb_dn_new(mem_ctx, sam_ctx, req1->names[0].str);
+       W_ERROR_HAVE_NO_MEMORY(server_dn);
+
+       ret = ldb_search(sam_ctx, mem_ctx, &res, server_dn, LDB_SCOPE_ONELEVEL,
+                        NULL, "(objectClass=nTDSDSA)");
+
+       if (ret != LDB_SUCCESS) {
+               DEBUG(1, ("Search for objectClass=nTDSDSA "
+                         "returned less than 1 objects\n"));
+               return WERR_OK;
+       }
+
+       if (res->count != 1) {
+               DEBUG(1, ("Search for objectClass=nTDSDSA "
+                         "returned less than 1 objects\n"));
+               return WERR_OK;
+       }
+
+       if (res->msgs[0]->dn) {
+               names[0].result_name = ldb_dn_alloc_linearized(names, res->msgs[0]->dn);
+               W_ERROR_HAVE_NO_MEMORY(names[0].result_name);
+               names[0].status = DRSUAPI_DS_NAME_STATUS_OK;
+       }
+
+       talloc_free(res);
+
+       ret = ldb_search(sam_ctx, mem_ctx, &res, server_dn, LDB_SCOPE_BASE,
+                        attrs, "(objectClass=*)");
+       if (ret != LDB_SUCCESS) {
+               DEBUG(1, ("Search for objectClass=* on dn %s"
+                         "returned %s\n", req1->names[0].str,
+                         ldb_strerror(ret)));
+               return WERR_OK;
+       }
+
+       if (res->count != 1) {
+               DEBUG(1, ("Search for objectClass=* on dn %s"
+                         "returned less than 1 objects\n", req1->names[0].str));
+               return WERR_OK;
+       }
+
+       str = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
+       if (str != NULL) {
+               names[1].result_name = talloc_strdup(names, str);
+               W_ERROR_HAVE_NO_MEMORY(names[1].result_name);
+               names[1].status = DRSUAPI_DS_NAME_STATUS_OK;
+       }
+
+       dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, res->msgs[0], "serverReference");
+       if (dn != NULL) {
+               names[2].result_name = ldb_dn_alloc_linearized(names, dn);
+               W_ERROR_HAVE_NO_MEMORY(names[2].result_name);
+               names[2].status = DRSUAPI_DS_NAME_STATUS_OK;
+       }
+
+       talloc_free(dn);
+       talloc_free(res);
+
+       return WERR_OK;
+}
index b294e4644efd10370e4366bb78d3d013f1b8d3c7..1f0ea9c8d622b4d2c6bd41f3165ccc53afb5939d 100644 (file)
@@ -441,7 +441,6 @@ static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TA
                        case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS:
                        case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID:
                        case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN:
-                       case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER:
                        case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE:
                        case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE:
                        case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE:
@@ -449,6 +448,8 @@ static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TA
                                DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X",
                                          r->in.req->req1.format_offered));
                                return WERR_OK;
+                       case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER:
+                               return dcesrv_drsuapi_ListInfoServer(b_state->sam_ctx, mem_ctx, &r->in.req->req1, &r->out.ctr->ctr1);
                        case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES:
                                return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx,
                                                                &r->in.req->req1, &r->out.ctr->ctr1);