r3784: do a samdb lookup for the DsCrackNames server
authorStefan Metzmacher <metze@samba.org>
Tue, 16 Nov 2004 10:56:51 +0000 (10:56 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:05:53 +0000 (13:05 -0500)
metze
(This used to be commit a2776eca83117131f8316ca222a2f385ffa5d7d5)

source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/rpc_server/drsuapi/dcesrv_drsuapi.h
source4/rpc_server/drsuapi/drsuapi_cracknames.c

index 468d608f4ff4f702ccd9974a66f325ca120ce1c1..c758f70da79f89f90fdc7fbc231d795e385cd634 100644 (file)
@@ -50,6 +50,11 @@ static WERROR drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
        WERR_TALLOC_CHECK(b_state);
 
        /* TODO: fill b_state here */
+       b_state->sam_ctx = samdb_connect(b_state);
+       if (!b_state->sam_ctx) {
+               talloc_free(b_state);
+               return WERR_FOOBAR;
+       }
 
        handle = dcesrv_handle_new(dce_call->conn, DRSUAPI_BIND_HANDLE);
        if (!handle) {
index 4c31d4d71045a3cff21def343c7d65ef2a2908ab..15eace70e18b58bf642c9857b7dddd5f4ea486a2 100644 (file)
@@ -31,5 +31,5 @@ enum drsuapi_handle {
   state asscoiated with a drsuapi_DsBind*() operation
 */
 struct drsuapi_bind_state {
-       uint8_t __dummy;
+       void *sam_ctx;
 };
index 72b3da17339c4bde481fa9acbc001ed8e7c62a0e..a0802d0dcd0323573ed64c40455adb713fce9175 100644 (file)
 #include "rpc_server/dcerpc_server.h"
 #include "rpc_server/common/common.h"
 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
-
+#include "lib/ldb/include/ldb.h"
 
 static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx,
                        uint32 format_offered, uint32 format_desired, const char *name,
                        struct drsuapi_DsNameInfo1 *info1)
 {
+       int ret;
+       const char *domain_filter;
+       const char * const *domain_attrs;
+       struct ldb_message **domain_res;
+       const char *result_basedn;
+       const char *result_filter = NULL;
+       const char * const *result_attrs;
+       struct ldb_message **result_res;
+
        info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
        info1->dns_domain_name = NULL;
        info1->result_name = NULL;
@@ -39,7 +48,6 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX
        /* 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());
@@ -52,20 +60,43 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX
                                return WERR_OK;
                        }
 
-                       info1->status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
-                       info1->dns_domain_name = talloc_asprintf(mem_ctx, "%s", lp_realm());
-                       WERR_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());
-                                       WERR_TALLOC_CHECK(info1->result_name);
-                                       return WERR_OK;
-                               default:
-                                       return WERR_OK;
+                       domain_filter = talloc_asprintf(mem_ctx, "(&(objectClass=domainDNS)(name=%s))",
+                                                               lp_workgroup());
+                       WERR_TALLOC_CHECK(domain_filter);
+
+                       break;
+               }
+               case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: {
+                       char *p;
+                       char *domain;
+                       const char *account = NULL;
+
+                       domain = talloc_strdup(mem_ctx, name);
+                       WERR_TALLOC_CHECK(domain);
+
+                       p = strchr(domain, '\\');
+                       if (!p) {
+                               /* invalid input format */
+                               info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+                               return WERR_OK;
+                       }
+                       p[0] = '\0';
+
+                       if (p[1]) {
+                               account = &p[1];
+                       }
+
+                       domain_filter = talloc_asprintf(mem_ctx, "(&(objectClass=domainDNS)(name=%s))",
+                                                               domain);
+                       WERR_TALLOC_CHECK(domain_filter);
+                       if (account) {
+                               result_filter = talloc_asprintf(mem_ctx, "(sAMAccountName=%s)",
+                                                               account);
+                               WERR_TALLOC_CHECK(result_filter);
                        }
-                       return WERR_INVALID_PARAM;
+
+                       talloc_free(domain);
+                       break;
                }
                default: {
                        info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
@@ -73,6 +104,108 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX
                }
        }
 
+       switch (format_desired) {
+               case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: {
+                       const char * const _domain_attrs[] = { "dn", "dnsDomain", NULL};
+                       const char * const _result_attrs[] = { "dn", NULL};
+                       
+                       domain_attrs = _domain_attrs;
+                       result_attrs = _result_attrs;
+                       break;
+               }
+               case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: {
+                       const char * const _domain_attrs[] = { "name", "dnsDomain", "dn", NULL};
+                       const char * const _result_attrs[] = { "sAMAccountName", NULL};
+                       
+                       domain_attrs = _domain_attrs;
+                       result_attrs = _result_attrs;
+                       break;
+               }
+               case DRSUAPI_DS_NAME_FORMAT_GUID: {
+                       const char * const _domain_attrs[] = { "objectGUID", "dnsDomain", "dn", NULL};
+                       const char * const _result_attrs[] = { "objectGUID", NULL};
+                       
+                       domain_attrs = _domain_attrs;
+                       result_attrs = _result_attrs;
+                       break;
+               }
+               default:
+                       return WERR_OK;
+       }
+
+       ret = samdb_search(b_state->sam_ctx, mem_ctx, NULL, &domain_res, domain_attrs,
+                               "%s", domain_filter);
+       switch (ret) {
+               case 1: 
+                       break;
+               case 0: 
+                       info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
+                       return WERR_OK;
+               case -1: 
+                       info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+                       return WERR_OK;
+               default:
+                       info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+                       return WERR_OK;
+       }
+
+       info1->dns_domain_name  = samdb_result_string(domain_res[0], "dnsDomain", NULL);
+       WERR_TALLOC_CHECK(info1->dns_domain_name);
+       info1->status           = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY;
+
+       if (result_filter) {
+               result_basedn = samdb_result_string(domain_res[0], "dn", NULL);
+               
+               ret = samdb_search(b_state->sam_ctx, mem_ctx, result_basedn, &result_res,
+                                       result_attrs, "%s", result_filter);
+               switch (ret) {
+                       case 1:
+                               break;
+                       case 0:
+                               return WERR_OK;
+                       case -1:
+                               info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR;
+                               return WERR_OK;
+                       default:
+                               info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE;
+                               return WERR_OK;
+               }
+       } else {
+               result_res = domain_res;
+       }
+
+       switch (format_desired) {
+               case DRSUAPI_DS_NAME_FORMAT_FQDN_1779: {
+                       info1->result_name      = samdb_result_string(result_res[0], "dn", NULL);
+                       WERR_TALLOC_CHECK(info1->result_name);
+                       info1->status           = DRSUAPI_DS_NAME_STATUS_OK;
+                       return WERR_OK;
+               }
+               case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT: {
+                       const char *_dom = samdb_result_string(domain_res[0], "name", NULL);
+                       const char *_acc = "";
+                       WERR_TALLOC_CHECK(_dom);
+                       if (result_filter) {
+                               _acc = samdb_result_string(result_res[0], "sAMAccountName", NULL);
+                               WERR_TALLOC_CHECK(_acc);
+                       }
+                       info1->result_name      = talloc_asprintf(mem_ctx, "%s\\%s", _dom, _acc);
+                       WERR_TALLOC_CHECK(info1->result_name);
+                       info1->status           = DRSUAPI_DS_NAME_STATUS_OK;
+                       return WERR_OK;
+               }
+               case DRSUAPI_DS_NAME_FORMAT_GUID: {
+                       const char *result = samdb_result_string(result_res[0], "objectGUID", NULL);
+                       WERR_TALLOC_CHECK(result);
+                       info1->result_name      = talloc_asprintf(mem_ctx, "{%s}", result);
+                       WERR_TALLOC_CHECK(info1->result_name);
+                       info1->status           = DRSUAPI_DS_NAME_STATUS_OK;
+                       return WERR_OK;
+               }
+               default:
+                       return WERR_OK;
+       }
+
        return WERR_INVALID_PARAM;
 }