s4-rpc: don't use s->credentials after it is freed
[ira/wip.git] / source4 / librpc / rpc / dcerpc_schannel.c
index 5588b43dcdf3d7e6236bab073c254dcd015bfacf..4927e203cdd7b644c81da49b4c1032fd0420e31e 100644 (file)
 #include "librpc/gen_ndr/ndr_netlogon_c.h"
 #include "auth/credentials/credentials.h"
 #include "librpc/rpc/dcerpc_proto.h"
+#include "param/param.h"
 
 struct schannel_key_state {
        struct dcerpc_pipe *pipe;
        struct dcerpc_pipe *pipe2;
        struct dcerpc_binding *binding;
        struct cli_credentials *credentials;
-       struct creds_CredentialState *creds;
+       struct netlogon_creds_CredentialState *creds;
        uint32_t negotiate_flags;
        struct netr_Credential credentials1;
        struct netr_Credential credentials2;
@@ -132,7 +133,7 @@ static void continue_bind_auth_none(struct composite_context *ctx)
        if (composite_nomem(s->r.in.server_name, c)) return;
        s->r.in.computer_name = cli_credentials_get_workstation(s->credentials);
        s->r.in.credentials   = &s->credentials1;
-       s->r.out.credentials  = &s->credentials2;
+       s->r.out.return_credentials  = &s->credentials2;
        
        generate_random_buffer(s->credentials1.data, sizeof(s->credentials1.data));
 
@@ -160,15 +161,12 @@ static void continue_srv_challenge(struct rpc_request *req)
        s = talloc_get_type(c->private_data, struct schannel_key_state);
 
        /* receive rpc request result - netlogon challenge */
-       c->status = dcerpc_ndr_request_recv(req);
+       c->status = dcerpc_netr_ServerReqChallenge_recv(req);
        if (!composite_is_ok(c)) return;
 
        /* prepare credentials for auth2 request */
        s->mach_pwd = cli_credentials_get_nt_hash(s->credentials, c);
 
-       creds_client_init(s->creds, &s->credentials1, &s->credentials2,
-                         s->mach_pwd, &s->credentials3, s->negotiate_flags);
-
        /* auth2 request arguments */
        s->a.in.server_name      = s->r.in.server_name;
        s->a.in.account_name     = cli_credentials_get_username(s->credentials);
@@ -178,8 +176,16 @@ static void continue_srv_challenge(struct rpc_request *req)
        s->a.in.negotiate_flags  = &s->negotiate_flags;
        s->a.in.credentials      = &s->credentials3;
        s->a.out.negotiate_flags = &s->negotiate_flags;
-       s->a.out.credentials     = &s->credentials3;
-
+       s->a.out.return_credentials     = &s->credentials3;
+
+       s->creds = netlogon_creds_client_init(s, 
+                                             s->a.in.account_name, 
+                                             s->a.in.computer_name,
+                                             &s->credentials1, &s->credentials2,
+                                             s->mach_pwd, &s->credentials3, s->negotiate_flags);
+       if (composite_nomem(s->creds, c)) {
+               return;
+       }
        /*
          authenticate on the netlogon pipe - a rpc request over secondary pipe
        */
@@ -203,11 +209,11 @@ static void continue_srv_auth2(struct rpc_request *req)
        s = talloc_get_type(c->private_data, struct schannel_key_state);
 
        /* receive rpc request result - auth2 credentials */ 
-       c->status = dcerpc_ndr_request_recv(req);
+       c->status = dcerpc_netr_ServerAuthenticate2_recv(req);
        if (!composite_is_ok(c)) return;
 
        /* verify credentials */
-       if (!creds_client_check(s->creds, s->a.out.credentials)) {
+       if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) {
                composite_error(c, NT_STATUS_UNSUCCESSFUL);
                return;
        }
@@ -245,9 +251,6 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
        s->credentials = credentials;
 
        /* allocate credentials */
-       s->creds = talloc(c, struct creds_CredentialState);
-       if (composite_nomem(s->creds, c)) return c;
-
        /* type of authentication depends on schannel type */
        if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
                s->negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
@@ -312,14 +315,13 @@ static void continue_schannel_key(struct composite_context *ctx)
        /* receive schannel key */
        c->status = dcerpc_schannel_key_recv(ctx);
        if (!composite_is_ok(c)) {
-               DEBUG(1, ("Failed to setup credentials for account %s: %s\n",
-                         cli_credentials_get_username(s->credentials), nt_errstr(c->status)));
+               DEBUG(1, ("Failed to setup credentials: %s\n", nt_errstr(c->status)));
                return;
        }
 
        /* send bind auth request with received creds */
        auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, s->credentials, 
-                                        s->lp_ctx,
+                                        lp_gensec_settings(c, s->lp_ctx),
                                         DCERPC_AUTH_TYPE_SCHANNEL, s->auth_level,
                                         NULL);
        if (composite_nomem(auth_req, c)) return;