wb-ndr: implement NDR_WINBIND_LOOKUP_LEVEL_RIDS2NAMES in winbindd_ndr_domain_child_lo...
[metze/samba/wb-ndr.git] / source / winbindd / winbindd_async.c
index ab32ee0c761d59bdbed61fdff201d847fb564c82..888c697aeaedbd69ac0b55ff5c228f9e7b61bbbe 100644 (file)
@@ -111,81 +111,178 @@ void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
                             &state->response, do_async_recv, state);
 }
 
-struct lookupsid_state {
-       DOM_SID sid;    
-       void *caller_private_data;
+struct do_async_ndr_state {
+       TALLOC_CTX *mem_ctx;
+       struct winbindd_ndr_call call;
+       void (*cont)(TALLOC_CTX *mem_ctx, bool success,
+                    struct winbindd_ndr_call *call,
+                    void *private_data,
+                    void *caller_cont,
+                    void *caller_private);
+       void *private_data;
+       void *caller_cont;
+       void *caller_private;
 };
 
+static void do_async_ndr_recv(void *private_data, bool success)
+{
+       struct do_async_ndr_state *state =
+               talloc_get_type_abort(private_data, struct do_async_ndr_state);
 
-static void lookupsid_recv2(TALLOC_CTX *mem_ctx, bool success,
-                          struct winbindd_response *response,
-                          void *c, void *private_data)
+       state->cont(state->mem_ctx, success,
+                   &state->call, state->private_data,
+                   state->caller_cont, state->caller_private);
+}
+
+void do_async_ndr(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
+                 uint32 opnum, void *r,
+                 void (*cont)(TALLOC_CTX *mem_ctx, bool success,
+                              struct winbindd_ndr_call *call,
+                              void *private_data,
+                              void *caller_cont,
+                              void *caller_private),
+                 void *private_data,
+                 void *caller_cont,
+                 void *caller_private)
+{
+       struct do_async_ndr_state *state;
+
+       SMB_ASSERT(opnum < ndr_table_winbind_protocol.num_calls);
+
+       state = TALLOC_ZERO_P(mem_ctx, struct do_async_ndr_state);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               cont(mem_ctx, False, NULL, private_data,
+                    caller_cont, caller_private);
+               return;
+       }
+
+       state->mem_ctx = mem_ctx;
+       state->call.ndr.call = &ndr_table_winbind_protocol.calls[opnum];
+       state->call.ndr.r = r;
+       state->cont = cont;
+       state->private_data = private_data;
+       state->caller_cont = caller_cont;
+       state->caller_private = caller_private;
+
+       async_ndr_call(mem_ctx, child, &state->call,
+                      do_async_ndr_recv, state);
+}
+
+void do_async_ndr_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
+                        uint32 opnum, void *r,
+                        void (*cont)(TALLOC_CTX *mem_ctx, bool success,
+                                     struct winbindd_ndr_call *call,
+                                     void *private_data,
+                                     void *caller_cont,
+                                     void *caller_private),
+                        void *private_data,
+                        void *caller_cont,
+                        void *caller_private)
+{
+       struct do_async_ndr_state *state;
+
+       SMB_ASSERT(opnum < ndr_table_winbind_protocol.num_calls);
+
+       state = TALLOC_ZERO_P(mem_ctx, struct do_async_ndr_state);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               cont(mem_ctx, False, NULL, private_data,
+                    caller_cont, caller_private);
+               return;
+       }
+
+       state->mem_ctx = mem_ctx;
+       state->call.ndr.call = &ndr_table_winbind_protocol.calls[opnum];
+       state->call.ndr.r = r;
+       state->cont = cont;
+       state->private_data = private_data;
+       state->caller_cont = caller_cont;
+       state->caller_private = caller_private;
+
+       async_ndr_domain_call(mem_ctx, domain, &state->call,
+                             do_async_ndr_recv, state);
+}
+
+static void winbindd_lookupsid_recv2(TALLOC_CTX *mem_ctx, bool success,
+                                    struct winbindd_ndr_call *c,
+                                    void *_private_data,
+                                    void *_cont,
+                                    void *cont_private)
 {
        void (*cont)(void *priv, bool succ, const char *dom_name,
                     const char *name, enum lsa_SidType type) =
                (void (*)(void *, bool, const char *, const char *,
-                         enum lsa_SidType))c;
-       struct lookupsid_state *s = talloc_get_type_abort(private_data, 
-                                                         struct lookupsid_state);
+                         enum lsa_SidType))_cont;
+       struct winbind_lookup *r =
+               talloc_get_type_abort(_private_data, struct winbind_lookup);
 
        if (!success) {
-               DEBUG(5, ("Could not trigger lookupsid\n"));
-               cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
+               DEBUG(5, ("Could not trigger lookup(sid2name)\n"));
+               TALLOC_FREE(r);
+               cont(cont_private, false, NULL, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       if (response->result != WINBINDD_OK) {
-               DEBUG(5, ("lookupsid (forest root) returned an error\n"));              
-               cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
+       if (r->out.result != WINBIND_STATUS_OK) {
+               DEBUG(5,("lookup(sid2name) returned an error:0x%08X\n"
+                        " (root domain)\n", r->out.result));
+               TALLOC_FREE(r);
+               cont(cont_private, false, NULL, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       cont(s->caller_private_data, True, response->data.name.dom_name,
-            response->data.name.name,
-            (enum lsa_SidType)response->data.name.type);
+       cont(cont_private, true,
+            r->out.rep->name_info.domain_name,
+            r->out.rep->name_info.account_name,
+            r->out.rep->name_info.type);
 }
 
-static void lookupsid_recv(TALLOC_CTX *mem_ctx, bool success,
-                          struct winbindd_response *response,
-                          void *c, void *private_data)
+static void winbindd_lookupsid_recv1(TALLOC_CTX *mem_ctx, bool success,
+                                    struct winbindd_ndr_call *c,
+                                    void *_private_data,
+                                    void *_cont,
+                                    void *cont_private)
 {
        void (*cont)(void *priv, bool succ, const char *dom_name,
                     const char *name, enum lsa_SidType type) =
                (void (*)(void *, bool, const char *, const char *,
-                         enum lsa_SidType))c;
-       struct lookupsid_state *s = talloc_get_type_abort(private_data, 
-                                                         struct lookupsid_state);
+                         enum lsa_SidType))_cont;
+       struct winbind_lookup *r =
+               talloc_get_type_abort(_private_data, struct winbind_lookup);
 
        if (!success) {
-               DEBUG(5, ("Could not trigger lookupsid\n"));
-               cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
+               DEBUG(5, ("Could not trigger lookup(sid2name)\n"));
+               TALLOC_FREE(r);
+               cont(cont_private, false, NULL, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       if (response->result != WINBINDD_OK) {
-               /* Try again using the forest root */
+       if (r->out.result != WINBIND_STATUS_OK) {
                struct winbindd_domain *root_domain = find_root_domain();
-               struct winbindd_request request;
-               
+
                if ( !root_domain ) {
-                       DEBUG(5,("lookupsid_recv: unable to determine forest root\n"));
-                       cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
+                       DEBUG(5,("lookup(sid2name) returned an error:0x%08X\n"
+                                " (no root domain as fallback)\n", r->out.result));
+
+                       TALLOC_FREE(r);
+                       cont(cont_private, false, NULL, NULL, SID_NAME_UNKNOWN);
                        return;
                }
+               DEBUG(5,("lookup(sid2name) returned an error:0x%08X"
+                        " (fallback to root domain)\n", r->out.result));
 
-               ZERO_STRUCT(request);
-               request.cmd = WINBINDD_LOOKUPSID;
-               sid_to_fstring(request.data.sid, &s->sid);
-
-               do_async_domain(mem_ctx, root_domain, &request, lookupsid_recv2,
-                               (void *)cont, s);
-
+               do_async_ndr_domain(mem_ctx, root_domain,
+                                   NDR_WINBIND_LOOKUP, r,
+                                   winbindd_lookupsid_recv2, r,
+                                   (void *)cont, cont_private);
                return;
        }
 
-       cont(s->caller_private_data, True, response->data.name.dom_name,
-            response->data.name.name,
-            (enum lsa_SidType)response->data.name.type);
+       cont(cont_private, true,
+            r->out.rep->name_info.domain_name,
+            r->out.rep->name_info.account_name,
+            r->out.rep->name_info.type);
 }
 
 void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
@@ -193,176 +290,273 @@ void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
                                           const char *dom_name,
                                           const char *name,
                                           enum lsa_SidType type),
-                             void *private_data)
+                             void *cont_private)
 {
        struct winbindd_domain *domain;
-       struct winbindd_request request;
-       struct lookupsid_state *s;      
+       struct winbind_lookup *r = NULL;
 
        domain = find_lookup_domain_from_sid(sid);
        if (domain == NULL) {
                DEBUG(5, ("Could not find domain for sid %s\n",
                          sid_string_dbg(sid)));
-               cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
+               cont(cont_private, false, NULL, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       ZERO_STRUCT(request);
-       request.cmd = WINBINDD_LOOKUPSID;
-       sid_to_fstring(request.data.sid, sid);
+       r = TALLOC_P(mem_ctx, struct winbind_lookup);
+       if (!r) goto nomem;
+       r->in.level = TALLOC_P(r, enum winbind_lookup_level);
+       if (!r->in.level) goto nomem;
+
+       *r->in.level    = WINBIND_LOOKUP_LEVEL_SID2NAME;
+       r->in.req.sid   = sid_dup_talloc(r, sid);
+       if (!r->in.req.sid) goto nomem;
+
+       do_async_ndr_domain(mem_ctx, domain,
+                           NDR_WINBIND_LOOKUP, r,
+                           winbindd_lookupsid_recv1, r,
+                           (void *)cont, cont_private);
+       return;
+nomem:
+       TALLOC_FREE(r);
+       cont(cont_private, false, NULL, NULL, SID_NAME_UNKNOWN);
+       return;
+}
 
-       if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupsid_state)) == NULL ) {
-               DEBUG(0, ("winbindd_lookupsid_async: talloc failed\n"));
-               cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN);
+static void ndr_child_lookup_sid2name(struct winbindd_domain *domain,
+                                     struct winbindd_cli_state *state,
+                                     struct winbind_lookup *r)
+{
+       bool ok;
+
+       DEBUG(3, ("lookup sid2name %s\n",
+                 sid_string_dbg(r->in.req.sid)));
+
+       /* Lookup the sid */
+
+       ok = winbindd_lookup_name_by_sid(r, domain,
+                                        r->in.req.sid,
+                                        (char **)&r->out.rep->name_info.domain_name,
+                                        (char **)&r->out.rep->name_info.account_name,
+                                        &r->out.rep->name_info.type);
+       if (!ok) {
+               DEBUG(1, ("Can't lookup name by sid\n"));
+               r->out.result = WINBIND_STATUS_FOOBAR;
                return;
        }
 
-       sid_copy( &s->sid, sid );       
-       s->caller_private_data = private_data;  
-
-       do_async_domain(mem_ctx, domain, &request, lookupsid_recv,
-                       (void *)cont, s);
+       r->out.result = WINBIND_STATUS_OK;
 }
 
-enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain,
-                                            struct winbindd_cli_state *state)
+static void ndr_child_lookup_name2sid(struct winbindd_domain *domain,
+                                     struct winbindd_cli_state *state,
+                                     struct winbind_lookup *r)
 {
-       enum lsa_SidType type;
-       DOM_SID sid;
-       char *name;
-       char *dom_name;
-
-       /* Ensure null termination */
-       state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+       bool ok;
+       char *name_domain;
+       char *name_user;
+       char *p;
 
-       DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, 
-                 state->request.data.sid));
+       DEBUG(3, ("lookup name2sid %s\n",
+                 r->in.req.name));
 
-       /* Lookup sid from PDC using lsa_lookup_sids() */
+       name_domain = talloc_strdup(r, r->in.req.name);
+       if (!name_domain) {
+               r->out.result = WINBIND_STATUS_NO_MEMORY;
+               return;
+       }
 
-       if (!string_to_sid(&sid, state->request.data.sid)) {
-               DEBUG(5, ("%s not a SID\n", state->request.data.sid));
-               return WINBINDD_ERROR;
+       /* the name must be a fully qualified name */
+       p = strstr(name_domain, lp_winbind_separator());
+       if (!p) {
+               r->out.result = WINBIND_STATUS_INVALID_PARAMETER;
+               return;
        }
 
-       /* Lookup the sid */
+       *p = 0;
+       name_user = p+1;
 
-       if (!winbindd_lookup_name_by_sid(state->mem_ctx, domain, &sid, 
-                                        &dom_name, &name, &type)) 
-       {
-               TALLOC_FREE(dom_name);
-               TALLOC_FREE(name);
-               return WINBINDD_ERROR;
+       r->out.rep->sid_info.sid = TALLOC_ZERO_P(r, struct dom_sid);
+       if (!r->out.rep->sid_info.sid) {
+               r->out.result = WINBIND_STATUS_NO_MEMORY;
+               return;
        }
 
-       fstrcpy(state->response.data.name.dom_name, dom_name);
-       fstrcpy(state->response.data.name.name, name);
-       state->response.data.name.type = type;
+       /* Lookup name from DC using lsa_lookup_names() */
+/* TODO: */    ok = winbindd_lookup_sid_by_name(state->mem_ctx, WINBINDD_LOOKUPNAME,
+                                        domain, name_domain, name_user,
+                                        r->out.rep->sid_info.sid,
+                                        &r->out.rep->sid_info.type);
+       if (!ok) {
+               DEBUG(1, ("Can't lookup name by sid\n"));
+               r->out.result = WINBIND_STATUS_FOOBAR;
+               return;
+       }
 
-       TALLOC_FREE(dom_name);
-       TALLOC_FREE(name);
-       return WINBINDD_OK;
+       r->out.result = WINBIND_STATUS_OK;
 }
 
-/********************************************************************
- This is the second callback after contacting the forest root
-********************************************************************/
+static void ndr_child_lookup_rids2names(struct winbindd_domain *domain,
+                                       struct winbindd_cli_state *state,
+                                       struct winbind_lookup *r)
+{
+       char *domain_name;
+       char **names;
+       enum lsa_SidType *types;
+       NTSTATUS status;
+       uint32_t i;
+       struct winbind_lookup_name_info *n;
 
-struct lookupname_state {
-       char *dom_name;
-       char *name;
-       void *caller_private_data;
-};
+       DEBUG(3, ("lookup rids2name domain:%s  num %u\n",
+                 sid_string_dbg(r->in.req.rids.domain_sid),
+                 r->in.req.rids.num_rids));
 
 
-static void lookupname_recv2(TALLOC_CTX *mem_ctx, bool success,
-                           struct winbindd_response *response,
-                           void *c, void *private_data)
-{
-       void (*cont)(void *priv, bool succ, const DOM_SID *sid,
-                    enum lsa_SidType type) =
-               (void (*)(void *, bool, const DOM_SID *, enum lsa_SidType))c;
-       DOM_SID sid;
-       struct lookupname_state *s = talloc_get_type_abort( private_data, 
-                                                           struct lookupname_state );
-       
+       status = domain->methods->rids_to_names(domain, state->mem_ctx,
+                                               r->in.req.rids.domain_sid,
+                                               r->in.req.rids.rids,
+                                               r->in.req.rids.num_rids,
+                                               &domain_name,
+                                               &names, &types);
 
-       if (!success) {
-               DEBUG(5, ("Could not trigger lookup_name\n"));
-               cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
+       if (!NT_STATUS_IS_OK(status) &&
+           !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
+               DEBUG(1, ("Can't lookup names by rids: %s\n",
+                         nt_errstr(status)));
+               r->out.result = WINBIND_STATUS_FOOBAR;
                return;
        }
 
-       if (response->result != WINBINDD_OK) {
-               DEBUG(5, ("lookup_name returned an error\n"));
-               cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
+       r->out.rep->name_array.num_names = r->in.req.rids.num_rids;
+       n = talloc_array(r,
+                        struct winbind_lookup_name_info,
+                        r->out.rep->name_array.num_names);
+       if (!n) {
+               r->out.result = WINBIND_STATUS_NO_MEMORY;
                return;
        }
+       r->out.rep->name_array.names = n;
+
+       for (i=0; i < r->out.rep->name_array.num_names; i++) {
+               n[i].domain_name        = domain_name;
+               n[i].account_name       = names[i];
+               n[i].type               = types[i];
+       }
+
+       r->out.result = WINBIND_STATUS_OK;
+}
+
+void winbindd_ndr_domain_child_lookup(struct winbindd_domain *domain,
+                                     struct winbindd_cli_state *state)
+{
+       struct winbind_lookup *r;
+
+       r = talloc_get_type_abort(state->c.ndr.r,
+                                 struct winbind_lookup);
 
-       if (!string_to_sid(&sid, response->data.sid.sid)) {
-               DEBUG(0, ("Could not convert string %s to sid\n",
-                         response->data.sid.sid));
-               cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
+       switch (*r->in.level) {
+       case WINBIND_LOOKUP_LEVEL_SID2NAME:
+               ndr_child_lookup_sid2name(domain, state, r);
+               return;
+
+       case WINBIND_LOOKUP_LEVEL_NAME2SID:
+               ndr_child_lookup_name2sid(domain, state, r);
+               return;
+
+       case WINBIND_LOOKUP_LEVEL_RIDS2NAMES:
+               ndr_child_lookup_rids2names(domain, state, r);
                return;
        }
 
-       cont(s->caller_private_data, True, &sid,
-            (enum lsa_SidType)response->data.sid.type);
+       r->out.result = WINBIND_STATUS_UNKNOWN_LEVEL;
+       return;
 }
 
 /********************************************************************
- This is the first callback after contacting our own domain 
+ This is the second callback after contacting the forest root
 ********************************************************************/
 
-static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success,
-                           struct winbindd_response *response,
-                           void *c, void *private_data)
+static void winbindd_lookupname_recv2(TALLOC_CTX *mem_ctx, bool success,
+                                     struct winbindd_ndr_call *c,
+                                     void *_private_data,
+                                     void *_cont,
+                                     void *cont_private)
 {
-       void (*cont)(void *priv, bool succ, const DOM_SID *sid,
-                    enum lsa_SidType type) =
-               (void (*)(void *, bool, const DOM_SID *, enum lsa_SidType))c;
-       DOM_SID sid;
-       struct lookupname_state *s = talloc_get_type_abort( private_data, 
-                                                           struct lookupname_state );  
+       void (*cont)(void *priv, bool succ,
+                    const DOM_SID *sid, enum lsa_SidType type) =
+               (void (*)(void *, bool, const DOM_SID *,
+                         enum lsa_SidType))_cont;
+       struct winbind_lookup *r =
+               talloc_get_type_abort(_private_data, struct winbind_lookup);
 
        if (!success) {
-               DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
-               cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
+               DEBUG(5, ("Could not trigger lookup(name2sid)\n"));
+               TALLOC_FREE(r);
+               cont(cont_private, false, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       if (response->result != WINBINDD_OK) {
-               /* Try again using the forest root */
-               struct winbindd_domain *root_domain = find_root_domain();
-               struct winbindd_request request;                
-               
-               if ( !root_domain ) {
-                       DEBUG(5,("lookupname_recv: unable to determine forest root\n"));
-                       cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
-                       return;
-               }
+       if (r->out.result != WINBIND_STATUS_OK) {
+               DEBUG(5,("lookup(name2sid) returned an error:0x%08X\n"
+                        " (root domain)\n", r->out.result));
+               TALLOC_FREE(r);
+               cont(cont_private, false, NULL, SID_NAME_UNKNOWN);
+               return;
+       }
 
-               ZERO_STRUCT(request);
-               request.cmd = WINBINDD_LOOKUPNAME;
+       cont(cont_private, true,
+            r->out.rep->sid_info.sid,
+            r->out.rep->sid_info.type);
+}
 
-               fstrcpy( request.data.name.dom_name, s->dom_name );
-               fstrcpy( request.data.name.name, s->name );             
+/********************************************************************
+ This is the first callback after contacting our own domain
+********************************************************************/
 
-               do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
-                               (void *)cont, s);
+static void winbindd_lookupname_recv1(TALLOC_CTX *mem_ctx, bool success,
+                                     struct winbindd_ndr_call *c,
+                                     void *_private_data,
+                                     void *_cont,
+                                     void *cont_private)
+{
+       void (*cont)(void *priv, bool succ,
+                    const DOM_SID *sid, enum lsa_SidType type) =
+               (void (*)(void *, bool, const DOM_SID *,
+                         enum lsa_SidType))_cont;
+       struct winbind_lookup *r =
+               talloc_get_type_abort(_private_data, struct winbind_lookup);
 
+       if (!success) {
+               DEBUG(5, ("Could not trigger lookup(name2sid)\n"));
+               TALLOC_FREE(r);
+               cont(cont_private, false, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       if (!string_to_sid(&sid, response->data.sid.sid)) {
-               DEBUG(0, ("Could not convert string %s to sid\n",
-                         response->data.sid.sid));
-               cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
+       if (r->out.result != WINBIND_STATUS_OK) {
+               struct winbindd_domain *root_domain = find_root_domain();
+
+               if ( !root_domain ) {
+                       DEBUG(5,("lookup(name2sid) returned an error:0x%08X\n"
+                                " (no root domain as fallback)\n", r->out.result));
+
+                       TALLOC_FREE(r);
+                       cont(cont_private, false, NULL, SID_NAME_UNKNOWN);
+                       return;
+               }
+               DEBUG(5,("lookup(name2sid) returned an error:0x%08X"
+                        " (fallback to root domain)\n", r->out.result));
+
+               do_async_ndr_domain(mem_ctx, root_domain,
+                                   NDR_WINBIND_LOOKUP, r,
+                                   winbindd_lookupname_recv2, r,
+                                   (void *)cont, cont_private);
                return;
        }
 
-       cont(s->caller_private_data, True, &sid,
-            (enum lsa_SidType)response->data.sid.type);
+       cont(cont_private, true,
+            r->out.rep->sid_info.sid,
+            r->out.rep->sid_info.type);
 }
 
 /********************************************************************
@@ -377,76 +571,38 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
                                            const DOM_SID *sid,
                                            enum lsa_SidType type),
                               enum winbindd_cmd orig_cmd,
-                              void *private_data)
+                              void *cont_private)
 {
-       struct winbindd_request request;
        struct winbindd_domain *domain;
-       struct lookupname_state *s;     
+       struct winbind_lookup *r = NULL;
 
        if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
                DEBUG(5, ("Could not find domain for name '%s'\n", dom_name));
-               cont(private_data, False, NULL, SID_NAME_UNKNOWN);
-               return;
-       }
-
-       ZERO_STRUCT(request);
-       request.cmd = WINBINDD_LOOKUPNAME;
-       request.original_cmd = orig_cmd;
-       fstrcpy(request.data.name.dom_name, dom_name);
-       fstrcpy(request.data.name.name, name);
-
-       if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupname_state)) == NULL ) {
-               DEBUG(0, ("winbindd_lookupname_async: talloc failed\n"));
-               cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+               cont(cont_private, false, NULL, SID_NAME_UNKNOWN);
                return;
        }
 
-       s->dom_name = talloc_strdup( s, dom_name );
-       s->name     = talloc_strdup( s, name );
-       s->caller_private_data = private_data;
-
-       do_async_domain(mem_ctx, domain, &request, lookupname_recv,
-                       (void *)cont, s);
-}
-
-enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
-                                             struct winbindd_cli_state *state)
-{
-       enum lsa_SidType type;
-       char *name_domain, *name_user;
-       DOM_SID sid;
-       char *p;
-
-       /* Ensure null termination */
-       state->request.data.name.dom_name[sizeof(state->request.data.name.dom_name)-1]='\0';
-
-       /* Ensure null termination */
-       state->request.data.name.name[sizeof(state->request.data.name.name)-1]='\0';
-
-       /* cope with the name being a fully qualified name */
-       p = strstr(state->request.data.name.name, lp_winbind_separator());
-       if (p) {
-               *p = 0;
-               name_domain = state->request.data.name.name;
-               name_user = p+1;
-       } else {
-               name_domain = state->request.data.name.dom_name;
-               name_user = state->request.data.name.name;
-       }
-
-       DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
-                 name_domain, lp_winbind_separator(), name_user));
-
-       /* Lookup name from DC using lsa_lookup_names() */
-       if (!winbindd_lookup_sid_by_name(state->mem_ctx, state->request.original_cmd, domain, name_domain,
-                                        name_user, &sid, &type)) {
-               return WINBINDD_ERROR;
-       }
-
-       sid_to_fstring(state->response.data.sid.sid, &sid);
-       state->response.data.sid.type = type;
-
-       return WINBINDD_OK;
+       r = TALLOC_P(mem_ctx, struct winbind_lookup);
+       if (!r) goto nomem;
+       r->in.level = TALLOC_P(r, enum winbind_lookup_level);
+       if (!r->in.level) goto nomem;
+
+       *r->in.level    = WINBIND_LOOKUP_LEVEL_NAME2SID;
+       r->in.req.name  = talloc_asprintf(r, "%s%s%s",
+                                         dom_name,
+                                         lp_winbind_separator(),
+                                         name);
+       if (!r->in.req.name) goto nomem;
+/*TODO: pass down orig_cmd */
+       do_async_ndr_domain(mem_ctx, domain,
+                           NDR_WINBIND_LOOKUP, r,
+                           winbindd_lookupname_recv1, r,
+                           (void *)cont, cont_private);
+       return;
+nomem:
+       TALLOC_FREE(r);
+       cont(cont_private, false, NULL, SID_NAME_UNKNOWN);
+       return;
 }
 
 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,