From 49004af3ca88f0107cdbd7f7e882931d6a1d04d2 Mon Sep 17 00:00:00 2001 From: Michael Spang Date: Sat, 31 Jan 2009 17:34:59 -0500 Subject: [PATCH] Free everything before exiting This cleans up valgrind --show-reachable. --- src/addclub.c | 14 ++++++++-- src/addmember.c | 14 ++++++++-- src/ceoc.c | 14 ++++++++-- src/config.c | 11 +++++++- src/config.h | 3 ++- src/dmaster.c | 14 ++++++++-- src/dslave.c | 7 +++++ src/gss.c | 69 +++++++++++++++++++++++++++++++++++++----------- src/gss.h | 1 + src/net.c | 4 +++ src/net.h | 1 + src/op-adduser.c | 5 +++- src/ops.c | 11 ++++++++ src/ops.h | 1 + 14 files changed, 142 insertions(+), 27 deletions(-) diff --git a/src/addclub.c b/src/addclub.c index 1442b03..27b4f94 100644 --- a/src/addclub.c +++ b/src/addclub.c @@ -69,13 +69,18 @@ int addclub(void) { notice("%s", ret->messages[i]->message); } + ceo__add_user_response__free_unpacked(ret, &protobuf_c_default_allocator); + strbuf_release(&preq); + strbuf_release(&pret); + return 0; } int main(int argc, char *argv[]) { int opt; + int ret; - prog = basename(argv[0]); + prog = xstrdup(basename(argv[0])); init_log(prog, 0, LOG_AUTHPRIV); configure(); @@ -98,5 +103,10 @@ int main(int argc, char *argv[]) { lib_dir = getenv("CEO_LIB_DIR") ?: default_lib_dir; - return addclub(); + ret = addclub(); + + free_config(); + free(prog); + + return ret; } diff --git a/src/addmember.c b/src/addmember.c index 183ccdd..138a356 100644 --- a/src/addmember.c +++ b/src/addmember.c @@ -79,13 +79,18 @@ int addmember(void) { notice("%s", ret->messages[i]->message); } + ceo__add_user_response__free_unpacked(ret, &protobuf_c_default_allocator); + strbuf_release(&preq); + strbuf_release(&pret); + return 0; } int main(int argc, char *argv[]) { int opt; + int ret; - prog = basename(argv[0]); + prog = xstrdup(basename(argv[0])); init_log(prog, 0, LOG_AUTHPRIV); configure(); @@ -114,5 +119,10 @@ int main(int argc, char *argv[]) { lib_dir = getenv("CEO_LIB_DIR") ?: default_lib_dir; - return addmember(); + ret = addmember(); + + free_config(); + free(prog); + + return ret; } diff --git a/src/ceoc.c b/src/ceoc.c index a4899f7..1eb6d78 100644 --- a/src/ceoc.c +++ b/src/ceoc.c @@ -136,13 +136,15 @@ int client_main(char *op_name) { int main(int argc, char *argv[]) { int opt; + int ret; char *op; - prog = basename(argv[0]); + prog = xstrdup(basename(argv[0])); init_log(prog, 0, LOG_USER); configure(); setup_ops(); + setup_fqdn(); while ((opt = getopt_long(argc, argv, "", opts, NULL)) != -1) { switch (opt) { @@ -159,5 +161,13 @@ int main(int argc, char *argv[]) { op = argv[optind++]; - return client_main(op); + ret = client_main(op); + + free_gss(); + free_fqdn(); + free_config(); + free_ops(); + free(prog); + + return ret; } diff --git a/src/config.c b/src/config.c index d08b260..7dffe9e 100644 --- a/src/config.c +++ b/src/config.c @@ -54,7 +54,7 @@ void config_var(char *var, char *val) { } } -void configure() { +void configure(void) { int i; char conffile[1024]; @@ -80,3 +80,12 @@ void configure() { } } } + +void free_config(void) { + for (int i = 0; i < sizeof(config_vars)/sizeof(*config_vars); i++) { + if (config_vars[i].type == CONFIG_TYPE_STR) { + free(*(char **)config_vars[i].p); + *(char **)config_vars[i].p = NULL; + } + } +} diff --git a/src/config.h b/src/config.h index 789843f..57527c5 100644 --- a/src/config.h +++ b/src/config.h @@ -4,6 +4,7 @@ #undef CONFIG_STR #undef CONFIG_INT -void configure(); +void configure(void); +void free_config(void); extern const char *config_dir; diff --git a/src/dmaster.c b/src/dmaster.c index d2d40f3..e621ade 100644 --- a/src/dmaster.c +++ b/src/dmaster.c @@ -142,13 +142,18 @@ static int master_main(void) { while (!terminate) accept_one_client(sock); + free_gss(); + free_fqdn(); + free_ops(); + return 0; } int main(int argc, char *argv[]) { int opt; + int ret; - prog = basename(argv[0]); + prog = xstrdup(basename(argv[0])); init_log(prog, LOG_PID, LOG_DAEMON); configure(); @@ -169,5 +174,10 @@ int main(int argc, char *argv[]) { if (argc != optind) usage(); - return master_main(); + ret = master_main(); + + free_config(); + free(prog); + + return ret; } diff --git a/src/dslave.c b/src/dslave.c index 0001372..f62e0a5 100644 --- a/src/dslave.c +++ b/src/dslave.c @@ -142,5 +142,12 @@ void slave_main(int sock, struct sockaddr *addr) { notice("connection closed by peer %s", addrstr); strbuf_release(&msg); + + /* stuff allocated by dmaster */ + free_gss(); + free_config(); + free_fqdn(); + free_ops(); + free(prog); } diff --git a/src/gss.c b/src/gss.c index 9305ce6..13d0c6d 100644 --- a/src/gss.c +++ b/src/gss.c @@ -12,13 +12,43 @@ static gss_cred_id_t my_creds = GSS_C_NO_CREDENTIAL; static gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; static gss_name_t peer_name = GSS_C_NO_NAME; static gss_name_t imported_service = GSS_C_NO_NAME; -static gss_OID mech_type = GSS_C_NO_OID; -static gss_buffer_desc peer_principal; +static char *peer_principal; static char *peer_username; static OM_uint32 ret_flags; static int complete; char service_name[128]; +void free_gss(void) { + OM_uint32 maj_stat, min_stat; + + if (peer_name) { + maj_stat = gss_release_name(&min_stat, &peer_name); + if (maj_stat != GSS_S_COMPLETE) + gss_fatal("gss_release_name", maj_stat, min_stat); + } + + if (imported_service) { + maj_stat = gss_release_name(&min_stat, &imported_service); + if (maj_stat != GSS_S_COMPLETE) + gss_fatal("gss_release_name", maj_stat, min_stat); + } + + if (context_handle) { + maj_stat = gss_delete_sec_context(&min_stat, &context_handle, GSS_C_NO_BUFFER); + if (maj_stat != GSS_S_COMPLETE) + gss_fatal("gss_delete_sec_context", maj_stat, min_stat); + } + + if (my_creds) { + maj_stat = gss_release_cred(&min_stat, &my_creds); + if (maj_stat != GSS_S_COMPLETE) + gss_fatal("gss_release_creds", maj_stat, min_stat); + } + + free(peer_principal); + free(peer_username); +} + static void display_status(char *prefix, OM_uint32 code, int type) { OM_uint32 maj_stat, min_stat; gss_buffer_desc msg; @@ -101,28 +131,44 @@ void client_acquire_creds(const char *service, const char *hostname) { import_service(service, hostname); } +static char *princ_to_username(char *princ) { + char *ret = xstrdup(princ); + char *c = strchr(ret, '@'); + if (c) + *c = '\0'; + return ret; +} + int process_server_token(gss_buffer_t incoming_tok, gss_buffer_t outgoing_tok) { OM_uint32 maj_stat, min_stat; OM_uint32 time_rec; gss_OID name_type; + gss_buffer_desc peer_princ; if (complete) fatal("unexpected %zd-byte token from peer", incoming_tok->length); maj_stat = gss_accept_sec_context(&min_stat, &context_handle, my_creds, - incoming_tok, GSS_C_NO_CHANNEL_BINDINGS, &peer_name, &mech_type, + incoming_tok, GSS_C_NO_CHANNEL_BINDINGS, &peer_name, NULL, outgoing_tok, &ret_flags, &time_rec, NULL); if (maj_stat == GSS_S_COMPLETE) { check_services(ret_flags); complete = 1; - maj_stat = gss_display_name(&min_stat, peer_name, &peer_principal, &name_type); + maj_stat = gss_display_name(&min_stat, peer_name, &peer_princ, &name_type); if (maj_stat != GSS_S_COMPLETE) gss_fatal("gss_display_name", maj_stat, min_stat); - notice("client authenticated as %s", (char *)peer_principal.value); - debug("context expires in %d seconds",time_rec); + peer_principal = xstrdup((char *)peer_princ.value); + peer_username = princ_to_username((char *)peer_princ.value); + + notice("client authenticated as %s", peer_principal); + debug("context expires in %d seconds", time_rec); + + maj_stat = gss_release_buffer(&min_stat, &peer_princ); + if (maj_stat != GSS_S_COMPLETE) + gss_fatal("gss_release_buffer", maj_stat, min_stat); } else if (maj_stat != GSS_S_CONTINUE_NEEDED) { gss_fatal("gss_accept_sec_context", maj_stat, min_stat); @@ -165,19 +211,10 @@ int initial_client_token(gss_buffer_t outgoing_tok) { } char *client_principal(void) { - return complete ? (char *)peer_principal.value : NULL; + return peer_principal; } char *client_username(void) { - if (!peer_username) { - char *princ = client_principal(); - if (princ) { - peer_username = xstrdup(princ); - char *c = strchr(peer_username, '@'); - if (c) - *c = '\0'; - } - } return peer_username; } diff --git a/src/gss.h b/src/gss.h index 7e7c290..9a14a61 100644 --- a/src/gss.h +++ b/src/gss.h @@ -9,3 +9,4 @@ int process_client_token(gss_buffer_t incoming_tok, gss_buffer_t outgoing_tok); int initial_client_token(gss_buffer_t outgoing_tok); char *client_principal(void); char *client_username(void); +void free_gss(void); diff --git a/src/net.c b/src/net.c index 825c917..f46e5c1 100644 --- a/src/net.c +++ b/src/net.c @@ -26,6 +26,10 @@ void setup_fqdn(void) { strbuf_addstr(&fqdn, lo->h_name); } +void free_fqdn(void) { + strbuf_release(&fqdn); +} + static size_t recv_one_message(int sock, struct sctp_meta *msg_meta, struct strbuf *msg, int *notification) { size_t len = 0; int flags; diff --git a/src/net.h b/src/net.h index 0e6ac9f..45a4a06 100644 --- a/src/net.h +++ b/src/net.h @@ -22,6 +22,7 @@ typedef struct sockaddr sa; extern struct strbuf fqdn; extern void setup_fqdn(void); +extern void free_fqdn(void); struct sctp_meta { struct sockaddr_storage from; diff --git a/src/op-adduser.c b/src/op-adduser.c index 5e1990e..0d54508 100644 --- a/src/op-adduser.c +++ b/src/op-adduser.c @@ -261,7 +261,7 @@ void cmd_adduser(void) { } int main(int argc, char *argv[]) { - prog = basename(argv[0]); + prog = xstrdup(basename(argv[0])); init_log(prog, LOG_PID, LOG_AUTHPRIV); configure(); @@ -279,5 +279,8 @@ int main(int argc, char *argv[]) { ceo_ldap_cleanup(); ceo_krb5_cleanup(); + free_config(); + free(prog); + return 0; } diff --git a/src/ops.c b/src/ops.c index 9cf53c3..857f633 100644 --- a/src/ops.c +++ b/src/ops.c @@ -102,9 +102,20 @@ void setup_ops(void) { strbuf_list_free(words); } + fclose(fp); } closedir(dp); strbuf_release(&line); } +void free_ops(void) { + while (ops) { + struct op *next = ops->next; + free(ops->name); + free(ops->hostname); + free(ops->path); + free(ops); + ops = next; + } +} diff --git a/src/ops.h b/src/ops.h index 21ee45a..3e7465c 100644 --- a/src/ops.h +++ b/src/ops.h @@ -9,5 +9,6 @@ struct op { }; void setup_ops(void); +void free_ops(void); struct op *find_op(const char *name); struct op *get_local_op(uint32_t id);