r14175: More comments and my copyright.
authorRafal Szczesniak <mimir@samba.org>
Fri, 10 Mar 2006 21:40:47 +0000 (21:40 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:56:58 +0000 (13:56 -0500)
rafal

source/librpc/rpc/dcerpc_schannel.c

index 64dc6d3ad9d7852ef1935e00b33b5a3e9181d1a3..e868a8081c8eaf7fc9ebdcbaf8c8d8ef31b03852 100644 (file)
@@ -5,6 +5,7 @@
 
    Copyright (C) Andrew Tridgell 2004
    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
+   Copyright (C) Rafal Szczesniak 2006
 
    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
@@ -49,6 +50,10 @@ static void continue_srv_challenge(struct rpc_request *req);
 static void continue_srv_auth2(struct rpc_request *req);
 
 
+/*
+  Stage 2 of schannel_key: Receive endpoint mapping and request secondary
+  rpc connection
+*/
 static void continue_epm_map_binding(struct composite_context *ctx)
 {
        struct composite_context *c;
@@ -58,6 +63,7 @@ static void continue_epm_map_binding(struct composite_context *ctx)
        c = talloc_get_type(ctx->async.private_data, struct composite_context);
        s = talloc_get_type(c->private_data, struct schannel_key_state);
 
+       /* receive endpoint mapping */
        c->status = dcerpc_epm_map_binding_recv(ctx);
        if (!composite_is_ok(c)) {
                DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n",
@@ -65,6 +71,7 @@ static void continue_epm_map_binding(struct composite_context *ctx)
                return;
        }
 
+       /* send a request for secondary rpc connection */
        sec_conn_req = dcerpc_secondary_connection_send(s->pipe,
                                                        s->binding);
        if (composite_nomem(sec_conn_req, c)) return;
@@ -73,6 +80,10 @@ static void continue_epm_map_binding(struct composite_context *ctx)
 }
 
 
+/*
+  Stage 3 of schannel_key: Receive secondary rpc connection and perform
+  non-authenticated bind request
+*/
 static void continue_secondary_connection(struct composite_context *ctx)
 {
        struct composite_context *c;
@@ -82,9 +93,11 @@ static void continue_secondary_connection(struct composite_context *ctx)
        c = talloc_get_type(ctx->async.private_data, struct composite_context);
        s = talloc_get_type(c->private_data, struct schannel_key_state);
 
+       /* receive secondary rpc connection */
        c->status = dcerpc_secondary_connection_recv(ctx, &s->pipe2);
        if (!composite_is_ok(c)) return;
 
+       /* initiate a non-authenticated bind */
        auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe2, &dcerpc_table_netlogon);
        if (composite_nomem(auth_none_req, c)) return;
 
@@ -92,6 +105,10 @@ static void continue_secondary_connection(struct composite_context *ctx)
 }
 
 
+/*
+  Stage 4 of schannel_key: Receive non-authenticated bind and get
+  a netlogon challenge
+*/
 static void continue_bind_auth_none(struct composite_context *ctx)
 {
        struct composite_context *c;
@@ -100,25 +117,26 @@ static void continue_bind_auth_none(struct composite_context *ctx)
 
        c = talloc_get_type(ctx->async.private_data, struct composite_context);
        s = talloc_get_type(c->private_data, struct schannel_key_state);
-       
+
+       /* receive result of non-authenticated bind request */
        c->status = dcerpc_bind_auth_none_recv(ctx);
        if (!composite_is_ok(c)) {
                talloc_free(s->pipe2);
                return;
        }
-
+       
+       /* prepare a challenge request */
        s->r.in.server_name   = talloc_asprintf(c, "\\\\%s", dcerpc_server_name(s->pipe));
        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;
-
+       
        generate_random_buffer(s->credentials1.data, sizeof(s->credentials1.data));
 
        /*
-         request a netlogon challenge
+         request a netlogon challenge - a rpc request over opened secondary pipe
        */
-
        srv_challenge_req = dcerpc_netr_ServerReqChallenge_send(s->pipe2, c, &s->r);
        if (composite_nomem(srv_challenge_req, c)) return;
 
@@ -126,6 +144,10 @@ static void continue_bind_auth_none(struct composite_context *ctx)
 }
 
 
+/*
+  Stage 5 of schannel_key: Receive a challenge and perform authentication
+  on the netlogon pipe
+*/
 static void continue_srv_challenge(struct rpc_request *req)
 {
        struct composite_context *c;
@@ -135,18 +157,17 @@ static void continue_srv_challenge(struct rpc_request *req)
        c = talloc_get_type(req->async.private, struct composite_context);
        s = talloc_get_type(c->private_data, struct schannel_key_state);
 
+       /* receive rpc request result - netlogon challenge */
        c->status = dcerpc_ndr_request_recv(req);
        if (!composite_is_ok(c)) return;
 
-       /*
-         authenticate on the netlogon pipe
-       */
-
+       /* 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);
        s->a.in.secure_channel_type =
@@ -157,6 +178,9 @@ static void continue_srv_challenge(struct rpc_request *req)
        s->a.out.negotiate_flags = &s->negotiate_flags;
        s->a.out.credentials     = &s->credentials3;
 
+       /*
+         authenticate on the netlogon pipe - a rpc request over secondary pipe
+       */
        srv_auth2_req = dcerpc_netr_ServerAuthenticate2_send(s->pipe2, c, &s->a);
        if (composite_nomem(srv_auth2_req, c)) return;
 
@@ -164,6 +188,10 @@ static void continue_srv_challenge(struct rpc_request *req)
 }
 
 
+/*
+  Stage 6 of schannel_key: Receive authentication request result and verify
+  received credentials
+*/
 static void continue_srv_auth2(struct rpc_request *req)
 {
        struct composite_context *c;
@@ -172,14 +200,17 @@ static void continue_srv_auth2(struct rpc_request *req)
        c = talloc_get_type(req->async.private, struct composite_context);
        s = talloc_get_type(c->private_data, struct schannel_key_state);
 
+       /* receive rpc request result - auth2 credentials */ 
        c->status = dcerpc_ndr_request_recv(req);
        if (!composite_is_ok(c)) return;
 
+       /* verify credentials */
        if (!creds_client_check(s->creds, s->a.out.credentials)) {
                composite_error(c, NT_STATUS_UNSUCCESSFUL);
                return;
        }
 
+       /* setup current netlogon credentials */
        cli_credentials_set_netlogon_creds(s->credentials, s->creds);
        talloc_free(s->pipe2);
        
@@ -188,7 +219,8 @@ static void continue_srv_auth2(struct rpc_request *req)
 
 
 /*
-  initiate getting a schannel key using a netlogon challenge on a secondary pipe
+  Initiate establishing a schannel key using netlogon challenge
+  on a secondary pipe
 */
 struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
                                                   struct dcerpc_pipe *p,
@@ -198,6 +230,7 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
        struct schannel_key_state *s;
        struct composite_context *epm_map_req;
        
+       /* composite context allocation and setup */
        c = talloc_zero(mem_ctx, struct composite_context);
        if (c == NULL) return NULL;
 
@@ -208,23 +241,28 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
        c->private_data = s;
        c->event_ctx = p->conn->event_ctx;
 
+       /* store parameters in the state structure */
        s->pipe        = p;
        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;
        } else {
                s->negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
        }
 
+       /* allocate binding structure */
        s->binding = talloc(c, struct dcerpc_binding);
        if (composite_nomem(s->binding, c)) return c;
 
        *s->binding = *s->pipe->binding;
 
+       /* request the netlogon endpoint mapping */
        epm_map_req = dcerpc_epm_map_binding_send(c, s->binding,
                                                  &dcerpc_table_netlogon,
                                                  s->pipe->conn->event_ctx);
@@ -235,6 +273,9 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
 }
 
 
+/*
+  Receive result of schannel key request
+ */
 NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c)
 {
        NTSTATUS status = composite_wait(c);
@@ -255,6 +296,10 @@ struct auth_schannel_state {
 static void continue_bind_auth(struct composite_context *ctx);
 
 
+/*
+  Stage 2 of auth_schannel: Receive schannel key and intitiate an
+  authenticated bind using received credentials
+ */
 static void continue_schannel_key(struct composite_context *ctx)
 {
        struct composite_context *auth_req;
@@ -263,6 +308,7 @@ static void continue_schannel_key(struct composite_context *ctx)
        struct auth_schannel_state *s = talloc_get_type(c->private_data,
                                                        struct auth_schannel_state);
 
+       /* 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",
@@ -270,6 +316,7 @@ static void continue_schannel_key(struct composite_context *ctx)
                return;
        }
 
+       /* send bind auth request with received creds */
        auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, s->credentials, 
                                         DCERPC_AUTH_TYPE_SCHANNEL, s->auth_level,
                                         NULL);
@@ -279,6 +326,10 @@ static void continue_schannel_key(struct composite_context *ctx)
 }
 
 
+/*
+  Stage 3 of auth_schannel: Receivce result of authenticated bind
+  and say if we're done ok.
+*/
 static void continue_bind_auth(struct composite_context *ctx)
 {
        struct composite_context *c = talloc_get_type(ctx->async.private_data,
@@ -291,6 +342,9 @@ static void continue_bind_auth(struct composite_context *ctx)
 }
 
 
+/*
+  Initiate schannel authentication request
+*/
 struct composite_context *dcerpc_bind_auth_schannel_send(TALLOC_CTX *tmp_ctx, 
                                                         struct dcerpc_pipe *p,
                                                         const struct dcerpc_interface_table *table,
@@ -301,6 +355,7 @@ struct composite_context *dcerpc_bind_auth_schannel_send(TALLOC_CTX *tmp_ctx,
        struct auth_schannel_state *s;
        struct composite_context *schan_key_req;
 
+       /* composite context allocation and setup */
        c = talloc_zero(tmp_ctx, struct composite_context);
        if (c == NULL) return NULL;
        
@@ -310,12 +365,14 @@ struct composite_context *dcerpc_bind_auth_schannel_send(TALLOC_CTX *tmp_ctx,
        c->state = COMPOSITE_STATE_IN_PROGRESS;
        c->private_data = s;
        c->event_ctx = p->conn->event_ctx;
-
+       
+       /* store parameters in the state structure */
        s->pipe        = p;
        s->credentials = credentials;
        s->table       = table;
        s->auth_level  = auth_level;
 
+       /* start getting schannel key first */
        schan_key_req = dcerpc_schannel_key_send(c, p, credentials);
        if (composite_nomem(schan_key_req, c)) return c;
 
@@ -324,6 +381,9 @@ struct composite_context *dcerpc_bind_auth_schannel_send(TALLOC_CTX *tmp_ctx,
 }
 
 
+/*
+  Receive result of schannel authentication request
+*/
 NTSTATUS dcerpc_bind_auth_schannel_recv(struct composite_context *c)
 {
        NTSTATUS status = composite_wait(c);
@@ -333,6 +393,9 @@ NTSTATUS dcerpc_bind_auth_schannel_recv(struct composite_context *c)
 }
 
 
+/*
+  Perform schannel authenticated bind - sync version
+ */
 NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx, 
                                   struct dcerpc_pipe *p,
                                   const struct dcerpc_interface_table *table,