Free everything before exiting
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Sat, 31 Jan 2009 22:34:59 +0000 (17:34 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Sat, 31 Jan 2009 22:39:37 +0000 (17:39 -0500)
This cleans up valgrind --show-reachable.

14 files changed:
src/addclub.c
src/addmember.c
src/ceoc.c
src/config.c
src/config.h
src/dmaster.c
src/dslave.c
src/gss.c
src/gss.h
src/net.c
src/net.h
src/op-adduser.c
src/ops.c
src/ops.h

index 1442b03..27b4f94 100644 (file)
@@ -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;
 }
index 183ccdd..138a356 100644 (file)
@@ -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;
 }
index a4899f7..1eb6d78 100644 (file)
@@ -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;
 }
index d08b260..7dffe9e 100644 (file)
@@ -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;
+        }
+    }
+}
index 789843f..57527c5 100644 (file)
@@ -4,6 +4,7 @@
 #undef CONFIG_STR
 #undef CONFIG_INT
 
-void configure();
+void configure(void);
+void free_config(void);
 
 extern const char *config_dir;
index d2d40f3..e621ade 100644 (file)
@@ -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;
 }
index 0001372..f62e0a5 100644 (file)
@@ -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);
 }
 
index 9305ce6..13d0c6d 100644 (file)
--- 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;
 }
 
index 7e7c290..9a14a61 100644 (file)
--- 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);
index 825c917..f46e5c1 100644 (file)
--- 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;
index 0e6ac9f..45a4a06 100644 (file)
--- 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;
index 5e1990e..0d54508 100644 (file)
@@ -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;
 }
index 9cf53c3..857f633 100644 (file)
--- 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;
+    }
+}
index 21ee45a..3e7465c 100644 (file)
--- 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);