r11193: Implement wbinfo -m
authorVolker Lendecke <vlendec@samba.org>
Wed, 19 Oct 2005 21:53:03 +0000 (21:53 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:44:59 +0000 (13:44 -0500)
(This used to be commit 12a800bc8541c4160a534d1edcaeb6774776e18d)

source4/include/structs.h
source4/winbind/config.mk
source4/winbind/wb_cmd_list_trustdom.c
source4/winbind/wb_samba3_cmd.c
source4/winbind/wb_samba3_protocol.c
source4/winbind/wb_sid2domain.c

index 2925d4fec92f97bc29b00930e10a7cd89ad0694e..b61ada237bd3b6a7a2544b2715a31741ce240152 100644 (file)
@@ -265,6 +265,7 @@ struct wins_server;
 
 struct nbt_dc_name;
 struct wb_sid_object;
+struct wb_dom_info;
 
 struct cldap_socket;
 struct cldapd_server;
index 551f5c47bb4e47258da5c3eaa77f9189bfc915bc..6d63acb1155a4a9a8ee9a70e436c7b95e9246ba5 100644 (file)
@@ -19,6 +19,7 @@ INIT_OBJ_FILES = \
                winbind/wb_cmd_getdcname.o \
                winbind/wb_cmd_userdomgroups.o \
                winbind/wb_cmd_usersids.o \
+               winbind/wb_cmd_list_trustdom.o \
                winbind/wb_pam_auth.o \
                winbind/wb_async_helpers.o
 REQUIRED_SUBSYSTEMS = RPC_NDR_LSA
index 1f3ba267d0b5aea6a423b71248ff0ade4877f3c8..af93ea0643e7a32ed3ecbad1b4ee7036f2f308e2 100644 (file)
 
 #include "includes.h"
 #include "libcli/composite/composite.h"
+#include "winbind/wb_async_helpers.h"
 #include "winbind/wb_server.h"
 #include "smbd/service_stream.h"
 #include "smbd/service_task.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
 
 /* List trusted domains. To avoid the trouble with having to wait for other
  * conflicting requests waiting for the lsa pipe we're opening our own lsa
@@ -35,10 +37,10 @@ struct cmd_list_trustdom_state {
        struct dcerpc_pipe *lsa_pipe;
        struct policy_handle *lsa_policy;
        int num_domains;
-       struct wb_dom_info *domains;
+       struct wb_dom_info **domains;
 
        uint32_t resume_handle;
-       struct lsa_DomainList domains;
+       struct lsa_DomainList domainlist;
        struct lsa_EnumTrustDom r;
 };
 
@@ -62,8 +64,6 @@ struct composite_context *wb_cmd_list_trustdoms_send(struct wbsrv_service *servi
        state->ctx = result;
        result->private_data = state;
 
-       state->service = service;
-
        ctx = wb_sid2domain_send(service, service->primary_sid);
        if (ctx == NULL) goto failed;
        ctx->async.fn = cmd_list_trustdoms_recv_domain;
@@ -86,8 +86,8 @@ static void cmd_list_trustdoms_recv_domain(struct composite_context *ctx)
        state->ctx->status = wb_sid2domain_recv(ctx, &domain);
        if (!composite_is_ok(state->ctx)) return;
 
-       tree = dcerpc_smb_tree(domain->lsa_pipe);
-       if (composite_nomem(tree, state->tree)) return;
+       tree = dcerpc_smb_tree(domain->lsa_pipe->conn);
+       if (composite_nomem(tree, state->ctx)) return;
 
        ctx = wb_init_lsa_send(tree, domain->lsa_auth_type,
                               domain->schannel_creds);
@@ -107,11 +107,18 @@ static void cmd_list_trustdoms_recv_lsa(struct composite_context *ctx)
                                              &state->lsa_policy);
        if (!composite_is_ok(state->ctx)) return;
 
+       state->num_domains = 0;
+       state->domains = NULL;
+
+       state->domainlist.count = 0;
+       state->domainlist.domains = NULL;
+
        state->resume_handle = 0;
-       state->r.in.policy_handle = state->lsa_policy;
+       state->r.in.handle = state->lsa_policy;
        state->r.in.resume_handle = &state->resume_handle;
        state->r.in.max_size = 1000;
        state->r.out.resume_handle = &state->resume_handle;
+       state->r.out.domains = &state->domainlist;
 
        req = dcerpc_lsa_EnumTrustDom_send(state->lsa_pipe, state, &state->r);
        composite_continue_rpc(state->ctx, req, cmd_list_trustdoms_recv_doms,
@@ -120,5 +127,74 @@ static void cmd_list_trustdoms_recv_lsa(struct composite_context *ctx)
 
 static void cmd_list_trustdoms_recv_doms(struct rpc_request *req)
 {
+       struct cmd_list_trustdom_state *state =
+               talloc_get_type(req->async.private,
+                               struct cmd_list_trustdom_state);
+       int i, old_num_domains;
+
+       state->ctx->status = dcerpc_ndr_request_recv(req);
+       if (!composite_is_ok(state->ctx)) return;
+       state->ctx->status = state->r.out.result;
+
+       if (!NT_STATUS_IS_OK(state->ctx->status) &&
+           !NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_NO_MORE_ENTRIES) &&
+           !NT_STATUS_EQUAL(state->ctx->status, STATUS_MORE_ENTRIES)) {
+               composite_error(state->ctx, state->ctx->status);
+               return;
+       }
+
+       old_num_domains = state->num_domains;
+
+       state->num_domains += state->r.out.domains->count;
+       state->domains = talloc_realloc(state, state->domains,
+                                       struct wb_dom_info *,
+                                       state->num_domains);
+       if (composite_nomem(state->domains, state->ctx)) return;
+
+       for (i=0; i<state->r.out.domains->count; i++) {
+               int j = i+old_num_domains;
+               state->domains[j] = talloc(state->domains,
+                                          struct wb_dom_info);
+               if (composite_nomem(state->domains[i], state->ctx)) return;
+               state->domains[j]->name = talloc_steal(
+                       state->domains[j],
+                       state->r.out.domains->domains[i].name.string);
+               state->domains[j]->sid = talloc_steal(
+                       state->domains[j],
+                       state->r.out.domains->domains[i].sid);
+       }
+
+       if (NT_STATUS_IS_OK(state->ctx->status)) {
+               composite_done(state->ctx);
+               return;
+       }
+
+       state->domainlist.count = 0;
+       state->domainlist.domains = NULL;
+       state->r.in.handle = state->lsa_policy;
+       state->r.in.resume_handle = &state->resume_handle;
+       state->r.in.max_size = 1000;
+       state->r.out.resume_handle = &state->resume_handle;
+       state->r.out.domains = &state->domainlist;
        
+       req = dcerpc_lsa_EnumTrustDom_send(state->lsa_pipe, state, &state->r);
+       composite_continue_rpc(state->ctx, req, cmd_list_trustdoms_recv_doms,
+                              state);
+}
+
+NTSTATUS wb_cmd_list_trustdoms_recv(struct composite_context *ctx,
+                                   TALLOC_CTX *mem_ctx,
+                                   int *num_domains,
+                                   struct wb_dom_info ***domains)
+{
+       NTSTATUS status = composite_wait(ctx);
+       if (NT_STATUS_IS_OK(status)) {
+               struct cmd_list_trustdom_state *state =
+                       talloc_get_type(ctx->private_data,
+                                       struct cmd_list_trustdom_state);
+               *num_domains = state->num_domains;
+               *domains = talloc_steal(mem_ctx, state->domains);
+       }
+       talloc_free(ctx);
+       return status;
 }
index 2eb1c1f5a376978612571a716a998a7b4d94b3a3..7eec57255b4b953bd309cc4f821d72e5ffcfd374 100644 (file)
@@ -192,7 +192,6 @@ NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
                return NT_STATUS_NO_MEMORY;
        }
 
-       ;
        ctx = wb_cmd_userdomgroups_send(
                s3call->call->wbconn->listen_socket->service, sid);
        NT_STATUS_HAVE_NO_MEMORY(ctx);
@@ -573,3 +572,79 @@ static void pam_auth_crap_recv(struct composite_context *ctx)
                return;
        }
 }
+
+static void list_trustdom_recv_doms(struct composite_context *ctx);
+
+NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
+{
+       struct composite_context *ctx;
+       struct wbsrv_service *service =
+               s3call->call->wbconn->listen_socket->service;
+
+       DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
+
+       ctx = wb_cmd_list_trustdoms_send(service);
+       NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+       ctx->async.fn = list_trustdom_recv_doms;
+       ctx->async.private_data = s3call;
+       s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+       return NT_STATUS_OK;
+}
+
+static void list_trustdom_recv_doms(struct composite_context *ctx)
+{
+       struct wbsrv_samba3_call *s3call =
+               talloc_get_type(ctx->async.private_data,
+                               struct wbsrv_samba3_call);
+       int i, num_domains;
+       struct wb_dom_info **domains;
+       NTSTATUS status;
+       char *result;
+
+       status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
+                                           &domains);
+       if (!NT_STATUS_IS_OK(status)) goto done;
+
+       result = talloc_strdup(s3call, "");
+       if (result == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       for (i=0; i<num_domains; i++) {
+               result = talloc_asprintf_append(
+                       result, "%s\\%s\\%s",
+                       domains[i]->name, domains[i]->name,
+                       dom_sid_string(s3call, domains[i]->sid));
+       }
+
+       if (result == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+
+       s3call->response.result = WINBINDD_OK;
+       if (num_domains > 0) {
+               s3call->response.extra_data = result;
+               s3call->response.length += strlen(result)+1;
+       }
+
+ done:
+       if (!NT_STATUS_IS_OK(status)) {
+               struct winbindd_response *resp = &s3call->response;
+               resp->result = WINBINDD_ERROR;
+               WBSRV_SAMBA3_SET_STRING(resp->data.auth.nt_status_string,
+                                       nt_errstr(status));
+               WBSRV_SAMBA3_SET_STRING(resp->data.auth.error_string,
+                                       nt_errstr(status));
+               resp->data.auth.pam_error = nt_status_to_pam(status);
+       }
+
+       status = wbsrv_send_reply(s3call->call);
+       if (!NT_STATUS_IS_OK(status)) {
+               wbsrv_terminate_connection(s3call->call->wbconn,
+                                          "wbsrv_queue_reply() failed");
+               return;
+       }
+}
index fa2225a5c31d38fbb19d8840f991ae21d71cee5d..f9e4c54ce2102bafc3d56359efd6738a61425899 100644 (file)
@@ -113,6 +113,9 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_call *call)
 
        case WINBINDD_GETUSERSIDS:
                return wbsrv_samba3_usersids(s3call);
+
+       case WINBINDD_LIST_TRUSTDOM:
+               return wbsrv_samba3_list_trustdom(s3call);
        }
 
        s3call->response.result = WINBINDD_ERROR;
index af3add42fe2c32056134e6617cbb5a1c641dc097..8249d6c7d32f5129cf2b9e8fc15ab8c27b464e30 100644 (file)
@@ -109,6 +109,15 @@ struct composite_context *wb_sid2domain_send(struct wbsrv_service *service,
        state->result = find_domain_from_sid(service, sid);
        if (state->result != NULL) {
                result->status = NT_STATUS_OK;
+               if (!state->result->initialized) {
+                       ctx = wb_init_domain_send(state->result,
+                                                 service->task->event_ctx,
+                                                 service->task->msg_ctx);
+                       if (ctx == NULL) goto failed;
+                       ctx->async.fn = sid2domain_recv_init;
+                       ctx->async.private_data = state;
+                       return result;
+               }
                composite_trigger_done(result);
                return result;
        }