Fix include paths to new location of libutil.
[bbaumbach/samba-autobuild/.git] / source4 / winbind / wb_sid2domain.c
index 83e81e1cd06719711a00309c0163aff799bf2ea0..cb9fa3ada28d189158718a027c952ec6c7eda084 100644 (file)
@@ -7,7 +7,7 @@
    
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "libcli/composite/composite.h"
 #include "winbind/wb_server.h"
-#include "smbd/service_stream.h"
 #include "smbd/service_task.h"
-#include "lib/events/events.h"
-#include "librpc/gen_ndr/nbt.h"
-#include "librpc/gen_ndr/ndr_netlogon.h"
 #include "winbind/wb_async_helpers.h"
-#include "include/dlinklist.h"
-
-static const char *sam_name(void)
-{
-       if (lp_server_role() == ROLE_STANDALONE) {
-               return lp_netbios_name();
-       }
-       return lp_workgroup();
-}
-
-static struct wbsrv_domain *find_primary_domain(struct wbsrv_service *service)
-{
-       const char *my_domain_name = sam_name();
-       struct wbsrv_domain *domain;
-
-       for (domain = service->domains; domain!=NULL; domain = domain->next) {
-               if (strcasecmp(domain->name, my_domain_name) == 0) {
-                       break;
-               }
-       }
-       return domain;
-}
+#include "libcli/security/security.h"
+#include "../lib/util/dlinklist.h"
+#include "param/param.h"
 
 static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
                                                 const struct dom_sid *sid)
@@ -58,10 +34,10 @@ static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
        struct wbsrv_domain *domain;
 
        for (domain = service->domains; domain!=NULL; domain = domain->next) {
-               if (dom_sid_equal(domain->sid, sid)) {
+               if (dom_sid_equal(domain->info->sid, sid)) {
                        break;
                }
-               if (dom_sid_in_domain(domain->sid, sid)) {
+               if (dom_sid_in_domain(domain->info->sid, sid)) {
                        break;
                }
        }
@@ -71,31 +47,25 @@ static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
 struct sid2domain_state {
        struct composite_context *ctx;
        struct wbsrv_service *service;
-       const struct dom_sid *sid;
+       struct dom_sid *sid;
 
-       const char *domain_name;
-       const char *dc_name;
-       struct dom_sid *domain_sid;
-
-       struct wbsrv_domain *my_domain;
-       struct wbsrv_domain *result;
+       struct wbsrv_domain *domain;
 };
 
+static void sid2domain_recv_dom_info(struct composite_context *ctx);
 static void sid2domain_recv_name(struct composite_context *ctx);
-static void sid2domain_recv_dcname(struct composite_context *ctx);
+static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx);
 static void sid2domain_recv_init(struct composite_context *ctx);
 
-struct composite_context *wb_sid2domain_send(struct wbsrv_service *service,
+struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
+                                            struct wbsrv_service *service,
                                             const struct dom_sid *sid)
 {
        struct composite_context *result, *ctx;
        struct sid2domain_state *state;
 
-       result = talloc_zero(NULL, struct composite_context);
+       result = composite_create(mem_ctx, service->task->event_ctx);
        if (result == NULL) goto failed;
-       result->state = COMPOSITE_STATE_IN_PROGRESS;
-       result->async.fn = NULL;
-       result->event_ctx = service->task->event_ctx;
 
        state = talloc(result, struct sid2domain_state);
        if (state == NULL) goto failed;
@@ -106,36 +76,48 @@ struct composite_context *wb_sid2domain_send(struct wbsrv_service *service,
        state->sid = dom_sid_dup(state, sid);
        if (state->sid == NULL) goto failed;
 
-       state->result = find_domain_from_sid(service, sid);
-       if (state->result != NULL) {
+       state->domain = find_domain_from_sid(service, sid);
+       if (state->domain != NULL) {
                result->status = NT_STATUS_OK;
-               if (!state->result->initialized) {
-                       ctx = wb_init_domain_send(service, state->result);
-                       if (ctx == NULL) goto failed;
-                       ctx->async.fn = sid2domain_recv_init;
-                       ctx->async.private_data = state;
-                       return result;
-               }
-               composite_trigger_done(result);
+               composite_done(result);
                return result;
        }
 
-       state->my_domain = find_primary_domain(service);
-       if (state->my_domain == NULL) {
-               result->status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
-               composite_trigger_error(result);
+       if (dom_sid_equal(service->primary_sid, sid) ||
+           dom_sid_in_domain(service->primary_sid, sid)) {
+               ctx = wb_get_dom_info_send(state, service, lp_workgroup(service->task->lp_ctx),
+                                          service->primary_sid);
+               if (ctx == NULL) goto failed;
+               ctx->async.fn = sid2domain_recv_dom_info;
+               ctx->async.private_data = state;
                return result;
        }
 
-       ctx = wb_cmd_lookupsid_send(service, state->my_domain, state->sid);
+       ctx = wb_cmd_lookupsid_send(state, service, state->sid);
        if (ctx == NULL) goto failed;
-       ctx->async.fn = sid2domain_recv_name;
-       ctx->async.private_data = state;
+       composite_continue(result, ctx, sid2domain_recv_name, state);
+
        return result;
 
  failed:
        talloc_free(result);
        return NULL;
+
+}
+
+static void sid2domain_recv_dom_info(struct composite_context *ctx)
+{
+       struct sid2domain_state *state =
+               talloc_get_type(ctx->async.private_data,
+                               struct sid2domain_state);
+       struct wb_dom_info *info;
+
+       state->ctx->status = wb_get_dom_info_recv(ctx, state, &info);
+       if (!composite_is_ok(state->ctx)) return;
+
+       ctx = wb_init_domain_send(state, state->service, info);
+
+       composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
 }
 
 static void sid2domain_recv_name(struct composite_context *ctx)
@@ -153,43 +135,29 @@ static void sid2domain_recv_name(struct composite_context *ctx)
                return;
        }
 
-       state->domain_name = name->domain;
-       state->domain_sid = dom_sid_dup(state, state->sid);
        if (name->type != SID_NAME_DOMAIN) {
-               state->domain_sid->num_auths -= 1;
+               state->sid->num_auths -= 1;
        }
-       
-       ctx = wb_cmd_getdcname_send(state->service, state->my_domain,
-                                   state->domain_name);
-       composite_continue(state->ctx, ctx, sid2domain_recv_dcname, state);
+
+       ctx = wb_trusted_dom_info_send(state, state->service, name->domain,
+                                      state->sid);
+
+       composite_continue(state->ctx, ctx, sid2domain_recv_trusted_dom_info,
+                          state);
 }
 
-static void sid2domain_recv_dcname(struct composite_context *ctx)
+static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx)
 {
        struct sid2domain_state *state =
                talloc_get_type(ctx->async.private_data,
                                struct sid2domain_state);
+       struct wb_dom_info *info;
 
-       state->ctx->status = wb_cmd_getdcname_recv(ctx, state,
-                                                  &state->dc_name);
+       state->ctx->status = wb_trusted_dom_info_recv(ctx, state, &info);
        if (!composite_is_ok(state->ctx)) return;
 
-       state->result = talloc_zero(state, struct wbsrv_domain);
-       if (composite_nomem(state->result, state->ctx)) return;
-
-       state->result->name = talloc_steal(state->result, state->domain_name);
-       state->result->sid = talloc_steal(state->result, state->domain_sid);
-       state->result->dcname = talloc_steal(state->result, state->dc_name);
-
-       state->result->schannel_creds = cli_credentials_init(state->result);
-       if (composite_nomem(state->result->schannel_creds, state->ctx)) return;
-       cli_credentials_set_conf(state->result->schannel_creds);
-       cli_credentials_set_machine_account(state->result->schannel_creds);
+       ctx = wb_init_domain_send(state, state->service, info);
 
-       talloc_steal(state->service, state->result);
-       DLIST_ADD(state->service->domains, state->result);
-
-       ctx = wb_init_domain_send(state->service, state->result);
        composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
 }
 
@@ -198,9 +166,24 @@ static void sid2domain_recv_init(struct composite_context *ctx)
        struct sid2domain_state *state =
                talloc_get_type(ctx->async.private_data,
                                struct sid2domain_state);
+       struct wbsrv_domain *existing;
 
-       state->ctx->status = wb_init_domain_recv(ctx);
-       if (!composite_is_ok(state->ctx)) return;
+       state->ctx->status = wb_init_domain_recv(ctx, state,
+                                                &state->domain);
+       if (!composite_is_ok(state->ctx)) {
+               DEBUG(10, ("Could not init domain\n"));
+               return;
+       }
+
+       existing = find_domain_from_sid(state->service, state->sid);
+       if (existing != NULL) {
+               DEBUG(5, ("Initialized domain twice, dropping second one\n"));
+               talloc_free(state->domain);
+               state->domain = existing;
+       }
+
+       talloc_steal(state->service, state->domain);
+       DLIST_ADD(state->service->domains, state->domain);
 
        composite_done(state->ctx);
 }
@@ -213,16 +196,17 @@ NTSTATUS wb_sid2domain_recv(struct composite_context *ctx,
                struct sid2domain_state *state =
                        talloc_get_type(ctx->private_data,
                                        struct sid2domain_state);
-               *result = state->result;
+               *result = state->domain;
        }
        talloc_free(ctx);
        return status;
 }
 
-NTSTATUS wb_sid2domain(struct wbsrv_service *service,
+NTSTATUS wb_sid2domain(TALLOC_CTX *mem_ctx, struct wbsrv_service *service,
                       const struct dom_sid *sid,
                       struct wbsrv_domain **result)
 {
-       struct composite_context *c = wb_sid2domain_send(service, sid);
+       struct composite_context *c = wb_sid2domain_send(mem_ctx, service,
+                                                        sid);
        return wb_sid2domain_recv(c, result);
 }