r2648: - use a destructor on struct server_connection to simplify the
authorAndrew Tridgell <tridge@samba.org>
Sun, 26 Sep 2004 03:50:24 +0000 (03:50 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:59:16 +0000 (12:59 -0500)
  connection termination cleanup, and to ensure that the event
  contexts are properly removed for every process model

- gave auth_context the new talloc treatment, which removes another
  source of memory leaks.
(This used to be commit 230e1cd777b0fba82dffcbd656cfa23c155d0560)

source4/auth/auth.c
source4/auth/auth.h
source4/auth/auth_util.c
source4/libcli/auth/gensec_ntlmssp.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/smb_server/negprot.c
source4/smb_server/sesssetup.c
source4/smbd/process_single.c
source4/smbd/process_standard.c
source4/smbd/process_thread.c
source4/smbd/service.c

index 0697cee1aca6556b4d928f36d81eddc23375fdea..62e2b93ecb9f0f6bde12a446befc533972e6c967 100644 (file)
@@ -78,7 +78,7 @@ static const uint8_t *get_ntlm_challenge(struct auth_context *auth_context)
                uint8_t chal[8];
                
                generate_random_buffer(chal, sizeof(chal));
-               auth_context->challenge = data_blob_talloc(auth_context->mem_ctx
+               auth_context->challenge = data_blob_talloc(auth_context, 
                                                           chal, sizeof(chal));
                
                challenge_set_by = "random";
@@ -269,7 +269,7 @@ void free_auth_context(struct auth_context **auth_context)
                        }
                }
 
-               talloc_destroy((*auth_context)->mem_ctx);
+               talloc_free(*auth_context);
                *auth_context = NULL;
        }
 }
@@ -278,21 +278,15 @@ void free_auth_context(struct auth_context **auth_context)
  Make a auth_info struct
 ***************************************************************************/
 
-static NTSTATUS make_auth_context(struct auth_context **auth_context) 
+static NTSTATUS make_auth_context(TALLOC_CTX *mem_ctx, struct auth_context **auth_context) 
 {
-       TALLOC_CTX *mem_ctx;
-
-       mem_ctx = talloc_init("authentication context");
-       
-       *auth_context = talloc(mem_ctx, sizeof(**auth_context));
+       *auth_context = talloc_p(mem_ctx, struct auth_context);
        if (!*auth_context) {
                DEBUG(0,("make_auth_context: talloc failed!\n"));
-               talloc_destroy(mem_ctx);
                return NT_STATUS_NO_MEMORY;
        }
        ZERO_STRUCTP(*auth_context);
 
-       (*auth_context)->mem_ctx = mem_ctx;
        (*auth_context)->check_ntlm_password = check_ntlm_password;
        (*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
        
@@ -303,7 +297,8 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context)
  Make a auth_info struct for the auth subsystem
 ***************************************************************************/
 
-static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list) 
+static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx, 
+                                           struct auth_context **auth_context, char **text_list) 
 {
        struct auth_methods *list = NULL;
        struct auth_methods *t = NULL;
@@ -314,7 +309,7 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context,
                return NT_STATUS_UNSUCCESSFUL;
        }
        
-       if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context)))
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context(mem_ctx, auth_context)))
                return nt_status;
        
        for (;*text_list; text_list++) {
@@ -362,7 +357,7 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context,
  Make a auth_context struct for the auth subsystem
 ***************************************************************************/
 
-NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) 
+NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx, struct auth_context **auth_context) 
 {
        char **auth_method_list = NULL; 
        NTSTATUS nt_status;
@@ -371,7 +366,8 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_text_list(auth_context, auth_method_list))) {
+       nt_status = make_auth_context_text_list(mem_ctx, auth_context, auth_method_list);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                str_list_free(&auth_method_list);
                return nt_status;
        }
@@ -384,14 +380,15 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
  Make a auth_info struct with a fixed challenge
 ***************************************************************************/
 
-NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uint8_t chal[8]) 
+NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx, 
+                                struct auth_context **auth_context, uint8_t chal[8]) 
 {
        NTSTATUS nt_status;
-       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(mem_ctx, auth_context))) {
                return nt_status;
        }
        
-       (*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8);
+       (*auth_context)->challenge = data_blob_talloc(*auth_context, chal, 8);
        (*auth_context)->challenge_set_by = "fixed";
        return nt_status;
 }
index 6f2c7134e7902e210f763da59f0f492882194972..2f35b36a1542282b089d708a4415464e084387f2 100644 (file)
@@ -119,7 +119,6 @@ struct auth_context {
        /* methods, in the order they should be called */
        struct auth_methods *auth_method_list;  
 
-       TALLOC_CTX *mem_ctx;
        const uint8_t *(*get_ntlm_challenge)(struct auth_context *auth_context);
        NTSTATUS (*check_ntlm_password)(struct auth_context *auth_context,
                                        const struct auth_usersupplied_info *user_info, 
index ab725249c77043bdb76ba88f3622937e0f6d66d8..f508cff35e0e04eed8b6990b9bcb94c682671c5e 100644 (file)
@@ -512,7 +512,7 @@ BOOL make_auth_methods(struct auth_context *auth_context, struct auth_methods **
                smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
        }
 
-       *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
+       *auth_method = talloc_p(auth_context, struct auth_methods);
        if (!*auth_method) {
                DEBUG(0,("make_auth_method: malloc failed!\n"));
                return False;
index 7270797f52b00c5c18281ee2e5f60cae1c0b517c..40f3e605eb2bbf9b3789f713e93229b8462b8285 100644 (file)
@@ -65,7 +65,7 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state,
 
        SMB_ASSERT(challenge->length == 8);
 
-       auth_context->challenge = data_blob_talloc(auth_context->mem_ctx
+       auth_context->challenge = data_blob_talloc(auth_context, 
                                                   challenge->data, challenge->length);
 
        auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
@@ -189,7 +189,8 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur
        }
 
        ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
-       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) {
+       nt_status = make_auth_context_subsystem(gensec_security, &gensec_ntlmssp_state->auth_context);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
 
index fdd5ead660d15c5a6d35a88dd6646325f3f1bd74..d35a8476df52e02e3516492dc27313662a97aab1 100644 (file)
@@ -498,7 +498,7 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call,
                                    r->in.logon.password->ntpassword.hash, 
                                    sizeof(r->in.logon.password->ntpassword.hash));
 
-               nt_status = make_auth_context_subsystem(&auth_context);
+               nt_status = make_auth_context_subsystem(pipe_state, &auth_context);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        return nt_status;
                }
@@ -515,7 +515,8 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call,
                
        case 2:
        case 6:
-               nt_status = make_auth_context_fixed(&auth_context, r->in.logon.network->challenge);
+               nt_status = make_auth_context_fixed(pipe_state,
+                                                   &auth_context, r->in.logon.network->challenge);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        return nt_status;
                }
index 576fcc22bf30e047c734932e55c5d0c986bc928a..2baf1cf0f1624aafd97d2e15ea100926bbf119ae 100644 (file)
@@ -34,7 +34,7 @@ static void get_challenge(struct smbsrv_connection *smb_conn, char buff[8])
 
        DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
 
-       nt_status = make_auth_context_subsystem(&smb_conn->negotiate.auth_context);
+       nt_status = make_auth_context_subsystem(smb_conn, &smb_conn->negotiate.auth_context);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
index 4cb0447d3222bddae9407fd631d991257c7aa55c..2af4d2237f50ae4cf708628b72e1b48d146881e0 100644 (file)
@@ -118,7 +118,7 @@ static NTSTATUS sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *s
                        make_user_info_guest(&user_info);
                }
                
-               status = make_auth_context_subsystem(&auth_context);
+               status = make_auth_context_subsystem(req->smb_conn, &auth_context);
 
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
index 62d780277cdd35edac2106e051376d04f5026700..12a265b62f1213338e7004cf30274bb4434d0c4d 100644 (file)
@@ -71,15 +71,7 @@ static void single_terminate_connection(struct server_connection *conn, const ch
        DEBUG(2,("single_terminate_connection: reason[%s]\n",reason));
 
        if (conn) {
-               if (conn->service) {
-                       conn->service->ops->close_connection(conn,reason);
-               }
-
-               if (conn->server_socket) {
-                       DLIST_REMOVE(conn->server_socket->connection_list,conn);
-               }
-
-               server_destroy_connection(conn);
+               talloc_free(conn);
        }
 }
 
index 1bb30c2ef09648f6795fdc4827bd25541b0d693b..194c6d24cc1b275f347771e4e45be674214221ac 100644 (file)
@@ -94,15 +94,7 @@ static void standard_terminate_connection(struct server_connection *conn, const
        DEBUG(2,("single_terminate_connection: reason[%s]\n",reason));
 
        if (conn) {
-               if (conn->service) {
-                       conn->service->ops->close_connection(conn,reason);
-               }
-
-               if (conn->server_socket) {
-                       DLIST_REMOVE(conn->server_socket->connection_list,conn);
-               }
-
-               server_destroy_connection(conn);
+               talloc_free(conn->service->srv_ctx);
        }
 
        /* terminate this process */
index 4e11137f37ca89e422988e031403f6981bdc11e3..55688f85e86bc25147321b2493eafe06d2436b2d 100644 (file)
@@ -117,17 +117,7 @@ static void thread_terminate_connection(struct server_connection *conn, const ch
        DEBUG(0,("thread_terminate_connection: reason[%s]\n",reason));
 
        if (conn) {
-               if (conn->service) {
-                       conn->service->ops->close_connection(conn,reason);
-               }
-
-               if (conn->server_socket) {
-                       MUTEX_LOCK_BY_ID(MUTEX_SMBD);
-                       DLIST_REMOVE(conn->server_socket->connection_list,conn);
-                       MUTEX_UNLOCK_BY_ID(MUTEX_SMBD);
-               }
-
-               server_destroy_connection(conn);
+               talloc_free(conn);
        }
 
        /* terminate this thread */
index e3eb4a02c14c0372466419d59720b7ede8b93cae..1f6033c238dc23ca7229aa6a8fd4488d2a75a088 100644 (file)
@@ -172,6 +172,29 @@ struct server_socket *service_setup_socket(struct server_service *service,
        return srv_sock;
 }
 
+/*
+  destructor that handles necessary event context changes
+ */
+static int server_destructor(void *ptr)
+{
+       struct server_connection *conn = ptr;
+
+       if (conn->service) {
+               conn->service->ops->close_connection(conn, "shutdown");
+       }
+
+       socket_destroy(conn->socket);
+
+       event_remove_fd(conn->event.ctx, conn->event.fde);
+       conn->event.fde = NULL;
+       event_remove_timed(conn->event.ctx, conn->event.idle);
+       conn->event.idle = NULL;
+
+       DLIST_REMOVE(conn->server_socket->connection_list, conn);
+
+       return 0;
+}
+
 struct server_connection *server_setup_connection(struct event_context *ev, 
                                                  struct server_socket *server_socket, 
                                                  struct socket_context *sock, 
@@ -215,6 +238,8 @@ struct server_connection *server_setup_connection(struct event_context *ev,
        srv_conn->event.fde     = event_add_fd(ev,&fde);
        srv_conn->event.idle    = event_add_timed(ev,&idle);
 
+       talloc_set_destructor(srv_conn, server_destructor);
+
        if (!socket_check_access(sock, "smbd", lp_hostsallow(-1), lp_hostsdeny(-1))) {
                server_terminate_connection(srv_conn, "denied by access rules");
                return NULL;
@@ -232,18 +257,6 @@ void server_terminate_connection(struct server_connection *srv_conn, const char
        srv_conn->service->model_ops->terminate_connection(srv_conn, reason);
 }
 
-void server_destroy_connection(struct server_connection *srv_conn)
-{
-       socket_destroy(srv_conn->socket);
-
-       event_remove_fd(srv_conn->event.ctx, srv_conn->event.fde);
-       srv_conn->event.fde = NULL;
-       event_remove_timed(srv_conn->event.ctx, srv_conn->event.idle);
-       srv_conn->event.idle = NULL;
-
-       talloc_free(srv_conn);
-}
-
 void server_io_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags)
 {
        struct server_connection *conn = fde->private;