/*!
- * Free and cleanup all linked DSI objects from config
+ * Free and cleanup config and DSI
*
- * Preserve object pointed to by "dsi".
- * "dsi" can be NULL in which case all DSI objects _and_ the options object are freed
+ * "dsi" can be NULL in which case all DSI objects and the config object is freed,
+ * otherwise its an afpd session child and only any unneeded DSI objects are freed
*/
void configfree(AFPObj *obj, DSI *dsi)
{
DSI *p, *q;
- /* the master loaded the volumes for zeroconf, get rid of that */
- unload_volumes(obj);
+ if (!dsi) {
+ /* Master afpd reloading config */
+ auth_unload();
+ if (! (obj->options.flags & OPTION_NOZEROCONF)) {
+ unload_volumes(obj);
+ zeroconf_deregister();
+ }
+ }
+ /* Master and child releasing unneeded DSI handles */
for (p = obj->dsi; p; p = q) {
q = p->next;
if (p == dsi)
continue;
- close(p->socket);
+ dsi_free(p);
free(p);
}
+ obj->dsi = NULL;
+ /* afpd session child passes dsi handle to obj handle */
if (dsi) {
dsi->next = NULL;
obj->dsi = dsi;
- } else {
- afp_options_free(&obj->options);
}
}
auth_load(obj->options.uampath, obj->options.uamlist);
set_signature(&obj->options);
+#ifdef HAVE_LDAP
+ acl_ldap_freeconfig();
+#endif /* HAVE_LDAP */
LOG(log_debug, logtype_afpd, "DSIConfigInit: hostname: %s, listen: %s, port: %s",
obj->options.hostname,
free(str); free(key); \
}
+static struct pollfd *fds;
/*
* This is the thread that polls the filehandles
*/
-void *polling_thread(void *arg) {
+static void *polling_thread(void *arg) {
// First we loop through getting the filehandles and adding them to our poll, we
// need to allocate our pollfd's
DNSServiceErrorType error;
- struct pollfd *fds = calloc(svc_ref_count, sizeof(struct pollfd));
+ fds = calloc(svc_ref_count, sizeof(struct pollfd));
assert(fds);
for(int i=0; i < svc_ref_count; i++) {
return(NULL);
}
-
/*
* This is the callback for the service register function ... actually there isn't a lot
* we can do if we get problems, so we don't really need to do anything other than report
* the issue.
*/
-void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
- const char *name, const char *regtype, const char *domain, void *context) {
-
- if(errorCode != kDNSServiceErr_NoError) {
+static void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
+ const char *name, const char *regtype, const char *domain, void *context)
+{
+ if (errorCode != kDNSServiceErr_NoError) {
LOG(log_error, logtype_afpd, "Failed to register mDNS service: %s%s%s: code=%d",
name, regtype, domain, errorCode);
}
}
-
/*
* This function unregisters anything we have already
* registered and frees associated memory
*/
static void unregister_stuff() {
- pthread_kill(poller, SIGKILL);
+ pthread_cancel(poller);
+
+ for (int i = 0; i < svc_ref_count; i++)
+ close(fds[i].fd);
+ free(fds);
+ fds = NULL;
+
if(svc_refs) {
for(int i=0; i < svc_ref_count; i++) {
DNSServiceRefDeallocate(svc_refs[i]);
#define LENGTH 512
-/* get rid of any allocated afp_option buffers. */
-void afp_options_free(struct afp_options *opt)
-{
- if (opt->hostname)
- free(opt->hostname);
- if (opt->adminauthuser)
- free(opt->adminauthuser);
- if (opt->configfile)
- free(opt->configfile);
- if (opt->fqdn)
- free(opt->fqdn);
- if (opt->guest)
- free(opt->guest);
- if (opt->listen)
- free(opt->listen);
- if (opt->k5realm)
- free(opt->k5realm);
- if (opt->k5keytab)
- free(opt->k5keytab);
- if (opt->k5service)
- free(opt->k5service);
- if (opt->logconfig)
- free(opt->logconfig);
- if (opt->logfile)
- free(opt->logfile);
- if (opt->loginmesg)
- free(opt->loginmesg);
- if (opt->maccodepage)
- free(opt->maccodepage);
- if (opt->mimicmodel)
- free(opt->mimicmodel);
- if (opt->ntdomain)
- free(opt->ntdomain);
- if (opt->ntseparator)
- free(opt->ntseparator);
- if (opt->passwdfile)
- free(opt->passwdfile);
- if (opt->port)
- free(opt->port);
- if (opt->signatureopt)
- free(opt->signatureopt);
- if (opt->uamlist)
- free(opt->uamlist);
- if (opt->uampath)
- free(opt->uampath);
- if (opt->unixcodepage)
- free(opt->unixcodepage);
-}
-
/*
* Show version information about afpd.
* Used by "afp -v".
if (reloadconfig) {
nologin++;
- auth_unload();
+
fd_reset_listening_sockets(&obj);
LOG(log_info, logtype_afpd, "re-reading configuration file");
configfree(&obj, NULL);
+ afp_config_free(&obj);
+
+ if (afp_config_parse(&obj, "afpd") != 0)
+ afp_exit(EXITERR_CONF);
+
if (configinit(&obj) != 0) {
LOG(log_error, logtype_afpd, "config re-read: no servers configured");
afp_exit(EXITERR_CONF);
kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, NULL);
}
+/* SIGQUIT callback */
+static void sighup_cb(evutil_socket_t fd, short what, void *arg)
+{
+ LOG(log_note, logtype_afpd, "Received SIGHUP, sending all processes signal to reload config");
+ kill_childs(SIGHUP, &afpd_pid, &cnid_metad_pid, NULL);
+}
+
/* SIGCHLD callback */
static void sigchld_cb(evutil_socket_t fd, short what, void *arg)
{
sigterm_ev = event_new(base, SIGTERM, EV_SIGNAL, sigterm_cb, NULL);
sigquit_ev = event_new(base, SIGQUIT, EV_SIGNAL | EV_PERSIST, sigquit_cb, NULL);
+ sigquit_ev = event_new(base, SIGHUP, EV_SIGNAL | EV_PERSIST, sighup_cb, NULL);
sigchld_ev = event_new(base, SIGCHLD, EV_SIGNAL | EV_PERSIST, sigchld_cb, NULL);
timer_ev = event_new(base, -1, EV_PERSIST, timer_cb, NULL);
sigdelset(&blocksigs, SIGTERM);
sigdelset(&blocksigs, SIGQUIT);
sigdelset(&blocksigs, SIGCHLD);
+ sigdelset(&blocksigs, SIGHUP);
sigprocmask(SIG_SETMASK, &blocksigs, NULL);
/* run the event loop */
if (uam_register(UAM_SERVER_CHANGEPW, path, "DHX2", dhx2_changepw) < 0)
return -1;
- p = gcry_mpi_new(0);
- g = gcry_mpi_new(0);
-
LOG(log_debug, logtype_uams, "DHX2: generating mersenne primes");
/* Generate p and g for DH */
if (dh_params_generate(PRIMEBITS) != 0) {
uam_unregister(UAM_SERVER_LOGIN, "DHX2");
uam_unregister(UAM_SERVER_CHANGEPW, "DHX2");
+ LOG(log_debug, logtype_uams, "DHX2: uam_cleanup");
+
gcry_mpi_release(p);
gcry_mpi_release(g);
}
extern DSI *dsi_init(AFPObj *obj, const char *hostname, const char *address, const char *port);
extern void dsi_setstatus (DSI *, char *, const size_t);
extern int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address, const char *port);
+extern void dsi_free(DSI *dsi);
/* in dsi_getsess.c */
extern int dsi_getsession (DSI *, server_child *, const int, afp_child_t **);
extern int get_afp_errno (const int param);
extern void afp_options_init (struct afp_options *);
extern void afp_options_parse_cmdline(AFPObj *obj, int ac, char **av);
-extern void afp_options_free(struct afp_options *);
extern void setmessage (const char *);
extern void readmessage (AFPObj *);
/* One function does the whole job */
extern int acl_ldap_readconfig(dictionary *iniconfig);
+extern void acl_ldap_freeconfig(void);
/* These are the prefvalues */
extern char *ldap_server;
int strorint; /* string to just store in char * or convert to int ? */
int intfromarray; /* convert to int, but use string to int mapping array pref_array[] */
int valid; /* -1 = mandatory, 0 = omittable/valid */
+ int valid_save; /* copy of 'valid', used when resettting config */
};
struct pref_array {
#include <atalk/volume.h>
extern int afp_config_parse(AFPObj *obj, char *processname);
-
+extern void afp_config_free(AFPObj *obj);
extern int load_charset(struct vol *vol);
extern int load_volumes(AFPObj *obj);
extern void unload_volumes(AFPObj *obj);
/* from charcnv.c */
extern int set_charset_name(charset_t, const char *);
+extern void free_charset_names(void);
extern void init_iconv (void);
extern size_t convert_string (charset_t, charset_t, void const *, size_t, void *, size_t);
extern size_t convert_string_allocate (charset_t, charset_t, void const *, size_t, char **);
#include <sys/time.h>
#include <string.h>
#include <errno.h>
+#include <ctype.h>
#define LDAP_DEPRECATED 1
#include <ldap.h>
int ldap_uuid_encoding;
struct ldap_pref ldap_prefs[] = {
- {&ldap_server, "ldap server", 0, 0, -1},
- {&ldap_auth_method,"ldap auth method", 1, 1, -1},
- {&ldap_auth_dn, "ldap auth dn", 0, 0, 0},
- {&ldap_auth_pw, "ldap auth pw", 0, 0, 0},
- {&ldap_userbase, "ldap userbase", 0, 0, -1},
- {&ldap_userscope, "ldap userscope", 1 ,1, -1},
- {&ldap_groupbase, "ldap groupbase", 0, 0, -1},
- {&ldap_groupscope, "ldap groupscope", 1 ,1, -1},
- {&ldap_uuid_attr, "ldap uuid attr", 0, 0, -1},
- {&ldap_uuid_string,"ldap uuid string", 0, 0, 0},
- {&ldap_name_attr, "ldap name attr", 0, 0, -1},
- {&ldap_group_attr, "ldap group attr", 0, 0, -1},
- {&ldap_uid_attr, "ldap uid attr", 0, 0, 0},
- {&ldap_uuid_encoding,"ldap uuid encoding", 1, 1, 0},
- {NULL, NULL, 0, 0, -1}
+ /* pointer to pref, prefname, strorint, intfromarray, valid, valid_save */
+ {&ldap_server, "ldap server", 0, 0, -1, -1},
+ {&ldap_auth_method, "ldap auth method", 1, 1, -1, -1},
+ {&ldap_auth_dn, "ldap auth dn", 0, 0, 0, 0},
+ {&ldap_auth_pw, "ldap auth pw", 0, 0, 0, 0},
+ {&ldap_userbase, "ldap userbase", 0, 0, -1, -1},
+ {&ldap_userscope, "ldap userscope", 1 ,1, -1, -1},
+ {&ldap_groupbase, "ldap groupbase", 0, 0, -1, -1},
+ {&ldap_groupscope, "ldap groupscope", 1 ,1, -1, -1},
+ {&ldap_uuid_attr, "ldap uuid attr", 0, 0, -1, -1},
+ {&ldap_uuid_string, "ldap uuid string", 0, 0, 0, 0},
+ {&ldap_name_attr, "ldap name attr", 0, 0, -1, -1},
+ {&ldap_group_attr, "ldap group attr", 0, 0, -1, -1},
+ {&ldap_uid_attr, "ldap uid attr", 0, 0, 0, 0},
+ {&ldap_uuid_encoding, "ldap uuid encoding", 1, 1, 0, 0},
+ {NULL, NULL, 0, 0, 0, 0}
};
struct pref_array prefs_array[] = {
#include <atalk/logger.h>
#include <atalk/iniparser.h>
+void acl_ldap_freeconfig(void)
+{
+ for (int i = 0; ldap_prefs[i].name != NULL; i++) {
+ if (ldap_prefs[i].intfromarray == 0 && ldap_prefs[i].strorint == 0) {
+ free(*((char **)(ldap_prefs[i].pref)));
+ *((char **)(ldap_prefs[i].pref)) = NULL;
+ }
+ ldap_prefs[i].valid = ldap_prefs[i].valid_save;
+ }
+}
+
int acl_ldap_readconfig(dictionary *iniconfig)
{
int i, j;
dsi->end = dsi->buffer + (dsi->dsireadbuf * dsi->server_quantum);
}
+/*!
+ * Free any allocated ressources of the master afpd DSI objects and close server socket
+ */
+void dsi_free(DSI *dsi)
+{
+ close(dsi->serversock);
+ dsi->serversock = -1;
+
+ free(dsi->commands);
+ dsi->commands = NULL;
+
+ free(dsi->buffer);
+ dsi->buffer = NULL;
+
+ free(dsi->bonjourname);
+ dsi->bonjourname = NULL;
+}
+
static struct itimerval itimer;
/* accept the socket and do a little sanity checking */
static int dsi_tcp_open(DSI *dsi)
return 0;
}
+void free_charset_names(void)
+{
+ for (int ch = 0; ch < MAX_CHARSETS; ch++) {
+ if (charset_names[ch]) {
+ free(charset_names[ch]);
+ charset_names[ch] = NULL;
+ }
+ }
+}
+
static struct charset_functions* get_charset_functions (charset_t ch)
{
if (charsets[ch] != NULL)
LOG(log_debug, logtype_afpd, "Locale charset is '%s'", p);
#else /* system doesn't have LOCALE support */
LOG(log_warning, logtype_afpd, "system doesn't have LOCALE support");
- p = strdup("UTF8");
+ p = "UTF8";
#endif
}
if (strcasecmp(p, "UTF-8") == 0) {
- p = strdup("UTF8");
+ p = "UTF8";
}
options->unixcodepage = strdup(p);
set_charset_name(CH_UNIX, p);
options->volcodepage = strdup(options->unixcodepage);
} else {
if (strcasecmp(p, "UTF-8") == 0) {
- p = strdup("UTF8");
+ p = "UTF8";
}
options->volcodepage = strdup(p);
}
EC_CLEANUP:
EC_EXIT;
}
+
+#define CONFIG_ARG_FREE(a) do { \
+ free(a); \
+ a = NULL; \
+ } while (0);
+
+/* get rid of any allocated afp_option buffers. */
+void afp_config_free(AFPObj *obj)
+{
+ if (obj->options.configfile)
+ CONFIG_ARG_FREE(obj->options.configfile);
+ if (obj->options.sigconffile)
+ CONFIG_ARG_FREE(obj->options.sigconffile);
+ if (obj->options.uuidconf)
+ CONFIG_ARG_FREE(obj->options.uuidconf);
+ if (obj->options.logconfig)
+ CONFIG_ARG_FREE(obj->options.logconfig);
+ if (obj->options.logfile)
+ CONFIG_ARG_FREE(obj->options.logfile);
+ if (obj->options.loginmesg)
+ CONFIG_ARG_FREE(obj->options.loginmesg);
+ if (obj->options.guest)
+ CONFIG_ARG_FREE(obj->options.guest);
+ if (obj->options.extmapfile)
+ CONFIG_ARG_FREE(obj->options.extmapfile);
+ if (obj->options.passwdfile)
+ CONFIG_ARG_FREE(obj->options.passwdfile);
+ if (obj->options.uampath)
+ CONFIG_ARG_FREE(obj->options.uampath);
+ if (obj->options.uamlist)
+ CONFIG_ARG_FREE(obj->options.uamlist);
+ if (obj->options.port)
+ CONFIG_ARG_FREE(obj->options.port);
+ if (obj->options.signatureopt)
+ CONFIG_ARG_FREE(obj->options.signatureopt);
+ if (obj->options.k5service)
+ CONFIG_ARG_FREE(obj->options.k5service);
+ if (obj->options.k5realm)
+ CONFIG_ARG_FREE(obj->options.k5realm);
+ if (obj->options.listen)
+ CONFIG_ARG_FREE(obj->options.listen);
+ if (obj->options.ntdomain)
+ CONFIG_ARG_FREE(obj->options.ntdomain);
+ if (obj->options.ntseparator)
+ CONFIG_ARG_FREE(obj->options.ntseparator);
+ if (obj->options.mimicmodel)
+ CONFIG_ARG_FREE(obj->options.mimicmodel);
+ if (obj->options.adminauthuser)
+ CONFIG_ARG_FREE(obj->options.adminauthuser);
+ if (obj->options.hostname)
+ CONFIG_ARG_FREE(obj->options.hostname);
+ if (obj->options.k5keytab)
+ CONFIG_ARG_FREE(obj->options.k5keytab);
+ if (obj->options.Cnid_srv)
+ CONFIG_ARG_FREE(obj->options.Cnid_srv);
+ if (obj->options.Cnid_port)
+ CONFIG_ARG_FREE(obj->options.Cnid_port);
+ if (obj->options.fqdn)
+ CONFIG_ARG_FREE(obj->options.fqdn);
+
+ if (obj->options.unixcodepage)
+ CONFIG_ARG_FREE(obj->options.unixcodepage);
+ if (obj->options.maccodepage)
+ CONFIG_ARG_FREE(obj->options.maccodepage);
+ if (obj->options.volcodepage)
+ CONFIG_ARG_FREE(obj->options.volcodepage);
+
+ obj->options.flags = 0;
+ obj->options.passwdbits = 0;
+
+ /* Free everything called from afp_config_parse() */
+ free_extmap();
+ iniparser_freedict(obj->iniconfig);
+ free_charset_names();
+}