s3:winbind: Convert InitConnection from struct based to NDR based
authorSamuel Cabrero <scabrero@samba.org>
Mon, 28 Feb 2022 16:16:23 +0000 (17:16 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 19 May 2022 17:51:33 +0000 (17:51 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
librpc/idl/winbind.idl
nsswitch/winbind_struct_protocol.h
source3/winbindd/winbindd_domain.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_dual_srv.c
source3/winbindd/winbindd_proto.h

index 2d209448841db19a6b6f25cd347d866e48c1f938..2adfc853835ca1ce15dba5c55d63ac2e40cf0cb8 100644 (file)
@@ -248,6 +248,22 @@ interface winbind
         [out,ref] samPwdChangeReason *reject_reason
         );
 
+    typedef [enum16bit] enum {
+        WB_DOMINFO_DOMAIN_UNKNOWN = 0x0000,
+        WB_DOMINFO_DOMAIN_NATIVE  = 0x0001,
+        WB_DOMINFO_DOMAIN_AD      = 0x0002,
+        WB_DOMINFO_DOMAIN_PRIMARY = 0x0004,
+        WB_DOMINFO_DOMAIN_OFFLINE = 0x0008
+    } DomainInfoFlags;
+
+    NTSTATUS wbint_InitConnection(
+        [in,string,charset(UTF8)] char *dcname,
+        [out,string,charset(UTF8)] char **name,
+        [out,string,charset(UTF8)] char **alt_name,
+        [out,ref] dom_sid *sid,
+        [out,ref] DomainInfoFlags *flags
+        );
+
   /* Public methods available via IRPC */
 
     typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
index ac0558c87c5c8585cbece572a1006f66d8ed0550..9365b312e3052ab3705a1b7fcd61f58f693e2a6b 100644 (file)
@@ -62,6 +62,7 @@ typedef char fstring[FSTRING_LEN];
  * 30: added "validation_level" and "info6" to response.data.auth
  * 31: added "client_name" to the request
  * 32: added "traceid" to the request
+ *     removed WINBINDD_INIT_CONNECTION
  */
 #define WINBIND_INTERFACE_VERSION 32
 
@@ -164,9 +165,6 @@ enum winbindd_cmd {
        /* lookup local groups */
        WINBINDD_GETSIDALIASES,
 
-       /* Initialize connection in a child */
-       WINBINDD_INIT_CONNECTION,
-
        /* Blocking calls that are not allowed on the main winbind pipe, only
         * between parent and children */
        WINBINDD_DUAL_SID2UID,
index c206b9589c988dc952d8cd4fad62bbdb96922285..e5d461261b09b94833ac4d5491a088ed07c28c28 100644 (file)
 
 static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
        {
-               .name           = "INIT_CONNECTION",
-               .struct_cmd     = WINBINDD_INIT_CONNECTION,
-               .struct_fn      = winbindd_dual_init_connection,
-       },{
                .name           = "NDRCMD",
                .struct_cmd     = WINBINDD_DUAL_NDRCMD,
                .struct_fn      = winbindd_dual_ndrcmd,
index 5394d992de2b474ff0d7853dd93230f8dce95e8b..bf90515509bbae375dc0b08e867cede29b423bc7 100644 (file)
@@ -47,6 +47,7 @@
 #include "idmap.h"
 #include "libcli/auth/netlogon_creds_cli.h"
 #include "../lib/util/pidfile.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -467,6 +468,7 @@ struct wb_domain_request_state {
        struct winbindd_request *init_req;
        struct winbindd_response *response;
        struct tevent_req *pending_subreq;
+       struct wbint_InitConnection r;
 };
 
 static void wb_domain_request_cleanup(struct tevent_req *req,
@@ -575,13 +577,15 @@ static void wb_domain_request_trigger(struct tevent_req *req,
 
        if (IS_DC || domain->primary || domain->internal) {
                /* The primary domain has to find the DC name itself */
-               state->init_req->cmd = WINBINDD_INIT_CONNECTION;
-               fstrcpy(state->init_req->domain_name, domain->name);
-               state->init_req->data.init_conn.is_primary = domain->primary;
-               fstrcpy(state->init_req->data.init_conn.dcname, "");
+               state->r.in.dcname = talloc_strdup(state, "");
+               if (tevent_req_nomem(state->r.in.dcname, req)) {
+                       return;
+               }
 
-               subreq = wb_child_request_send(state, state->ev, state->child,
-                                              state->init_req);
+               subreq = dcerpc_wbint_InitConnection_r_send(state,
+                                               state->ev,
+                                               state->child->binding_handle,
+                                               &state->r);
                if (tevent_req_nomem(subreq, req)) {
                        return;
                }
@@ -633,16 +637,18 @@ static void wb_domain_request_gotdc(struct tevent_req *subreq)
        while (dcname != NULL && *dcname == '\\') {
                dcname++;
        }
-       state->init_req->cmd = WINBINDD_INIT_CONNECTION;
-       fstrcpy(state->init_req->domain_name, state->domain->name);
-       state->init_req->data.init_conn.is_primary = False;
-       fstrcpy(state->init_req->data.init_conn.dcname,
-               dcname);
+
+       state->r.in.dcname = talloc_strdup(state, dcname);
+       if (tevent_req_nomem(state->r.in.dcname, req)) {
+               return;
+       }
 
        TALLOC_FREE(dcinfo);
 
-       subreq = wb_child_request_send(state, state->ev, state->child,
-                                      state->init_req);
+       subreq = dcerpc_wbint_InitConnection_r_send(state,
+                                               state->ev,
+                                               state->child->binding_handle,
+                                               &state->r);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -656,52 +662,50 @@ static void wb_domain_request_initialized(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct wb_domain_request_state *state = tevent_req_data(
                req, struct wb_domain_request_state);
-       struct winbindd_response *response;
-       int ret, err;
+       NTSTATUS status;
 
        state->pending_subreq = NULL;
 
-       ret = wb_child_request_recv(subreq, talloc_tos(), &response, &err);
+       status = dcerpc_wbint_InitConnection_r_recv(subreq, state);
        TALLOC_FREE(subreq);
-       if (ret == -1) {
-               tevent_req_error(req, err);
+       if (NT_STATUS_IS_ERR(status)) {
+               tevent_req_error(req, map_errno_from_nt_status(status));
                return;
        }
 
-       if (!string_to_sid(&state->domain->sid,
-                          response->data.domain_info.sid)) {
-               DEBUG(1,("init_child_recv: Could not convert sid %s "
-                       "from string\n", response->data.domain_info.sid));
-               tevent_req_error(req, EINVAL);
+       status = state->r.out.result;
+       if (NT_STATUS_IS_ERR(status)) {
+               tevent_req_error(req, map_errno_from_nt_status(status));
                return;
        }
 
+       state->domain->sid = *state->r.out.sid;
+
        talloc_free(state->domain->name);
-       state->domain->name = talloc_strdup(state->domain,
-                                           response->data.domain_info.name);
+       state->domain->name = talloc_strdup(state->domain, *state->r.out.name);
        if (state->domain->name == NULL) {
                tevent_req_error(req, ENOMEM);
                return;
        }
 
-       if (response->data.domain_info.alt_name[0] != '\0') {
+       if (*state->r.out.alt_name != NULL &&
+           strlen(*state->r.out.alt_name) > 0) {
                talloc_free(state->domain->alt_name);
 
                state->domain->alt_name = talloc_strdup(state->domain,
-                               response->data.domain_info.alt_name);
+                                                       *state->r.out.alt_name);
                if (state->domain->alt_name == NULL) {
                        tevent_req_error(req, ENOMEM);
                        return;
                }
        }
 
-       state->domain->native_mode = response->data.domain_info.native_mode;
+       state->domain->native_mode =
+                       (*state->r.out.flags & WB_DOMINFO_DOMAIN_NATIVE);
        state->domain->active_directory =
-               response->data.domain_info.active_directory;
+                       (*state->r.out.flags & WB_DOMINFO_DOMAIN_AD);
        state->domain->initialized = true;
 
-       TALLOC_FREE(response);
-
        subreq = wb_child_request_send(state, state->ev, state->child,
                                       state->request);
        if (tevent_req_nomem(subreq, req)) {
index 704df80a1a23df6dd2323d6670b3d563ed176fac..bb164d9914a876628bcb6527aa6a3b0216c26f76 100644 (file)
@@ -39,7 +39,6 @@
 #include "rpc_client/util_netlogon.h"
 #include "libsmb/dsgetdcname.h"
 #include "lib/global_contexts.h"
-#include "lib/util/string_wrappers.h"
 
 NTSTATUS _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r)
 {
@@ -47,21 +46,16 @@ NTSTATUS _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r)
        return NT_STATUS_OK;
 }
 
-enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
-                                                  struct winbindd_cli_state *state)
+NTSTATUS _wbint_InitConnection(struct pipes_struct *p,
+                              struct wbint_InitConnection *r)
 {
-       /* Ensure null termination */
-       state->request->domain_name
-               [sizeof(state->request->domain_name)-1]='\0';
-       state->request->data.init_conn.dcname
-               [sizeof(state->request->data.init_conn.dcname)-1]='\0';
+       struct winbindd_domain *domain = wb_child_domain();
 
-       if (strlen(state->request->data.init_conn.dcname) > 0) {
+       if (r->in.dcname != NULL && strlen(r->in.dcname) > 0) {
                TALLOC_FREE(domain->dcname);
-               domain->dcname = talloc_strdup(domain,
-                               state->request->data.init_conn.dcname);
+               domain->dcname = talloc_strdup(domain, r->in.dcname);
                if (domain->dcname == NULL) {
-                       return WINBINDD_ERROR;
+                       return NT_STATUS_NO_MEMORY;
                }
        }
 
@@ -79,18 +73,35 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai
                         domain->name, (int)domain->online);
        }
 
-       fstrcpy(state->response->data.domain_info.name, domain->name);
-       fstrcpy(state->response->data.domain_info.alt_name, domain->alt_name);
-       sid_to_fstring(state->response->data.domain_info.sid, &domain->sid);
+       *r->out.name = talloc_strdup(p->mem_ctx, domain->name);
+       if (*r->out.name == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
-       state->response->data.domain_info.native_mode
-               = domain->native_mode;
-       state->response->data.domain_info.active_directory
-               = domain->active_directory;
-       state->response->data.domain_info.primary
-               = domain->primary;
+       if (domain->alt_name != NULL) {
+               *r->out.alt_name = talloc_strdup(p->mem_ctx, domain->alt_name);
+               if (*r->out.alt_name == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
 
-       return WINBINDD_OK;
+       r->out.sid = dom_sid_dup(p->mem_ctx, &domain->sid);
+       if (r->out.sid == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *r->out.flags = 0;
+       if (domain->native_mode) {
+               *r->out.flags |= WB_DOMINFO_DOMAIN_NATIVE;
+       }
+       if (domain->active_directory) {
+               *r->out.flags |= WB_DOMINFO_DOMAIN_AD;
+       }
+       if (domain->primary) {
+               *r->out.flags |= WB_DOMINFO_DOMAIN_PRIMARY;
+       }
+
+       return NT_STATUS_OK;
 }
 
 bool reset_cm_connection_on_error(struct winbindd_domain *domain,
index 57f7cebd2cf30a76d1fb4af1756f34342d27e245..7774f2837aa422c4da2c132b9c8ce3b508f48ae0 100644 (file)
@@ -492,8 +492,6 @@ void winbindd_ping_offline_domains(struct tevent_context *ev,
                                   struct tevent_timer *te,
                                   struct timeval now,
                                   void *private_data);
-enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
-                                                  struct winbindd_cli_state *state);
 bool init_domain_list(void);
 struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name);
 struct winbindd_domain *find_trust_from_name_noinit(const char *domain_name);