service.c revision b203ee2724dbe50332502a6d9521a7cdae38380f
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesvoid service_error(struct service *service, const char *format, ...)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesservice_create_file_listener(struct service *service,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char **error_r)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes l = p_new(service->list->pool, struct service_listener, 1);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (get_uidgid(set->user, &l->set.fileset.uid, &gid, error_r) < 0)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes else if (get_gid(set->group, &l->set.fileset.gid, error_r) < 0)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "%s (See service %s { %s_listener %s { %s } } setting)",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesresolve_ip(const char *address, const struct ip_addr **ips_r,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes unsigned int ips_count;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (address == NULL || strcmp(address, "*") == 0) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* IPv4 any */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (strcmp(address, "::") == 0 || strcmp(address, "[::]") == 0) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* IPv6 any */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* Return the first IP if there happens to be multiple. */
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg ret = net_gethostbyname(address, &ip_list, &ips_count);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ret != 0) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *error_r = t_strdup_printf("Can't resolve address %s: %s",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *error_r = t_strdup_printf("No IPs for address: %s", address);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesservice_create_one_inet_listener(struct service *service,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char **error_r)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes l = p_new(service->list->pool, struct service_listener, 1);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes l->inet_address = p_strdup(service->list->pool, address);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *error_r = t_strdup_printf("Invalid port: %u", set->port);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesservice_create_inet_listeners(struct service *service,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char **error_r)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes static struct service_listener *l;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes unsigned int i, ips_count;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes bool ssl_disabled = strcmp(service->set->master_set->ssl, "no") == 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* disabled */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* use the default listen address */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (resolve_ip(address, &ips, &ips_count, error_r) < 0)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes for (i = 0; i < ips_count; i++) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes l = service_create_one_inet_listener(service, set,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic int service_get_groups(const char *groups, pool_t pool,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes const char *const *tmp;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes for (tmp = t_strsplit(groups, ","); *tmp != NULL; tmp++) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic struct service *
ac7985784d08a3655291f24f711812b4d8b1cbcffuankgservice_create(pool_t pool, const struct service_settings *set,
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg struct service_list *service_list, const char **error_r)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct file_listener_settings *const *unix_listeners;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct file_listener_settings *const *fifo_listeners;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct inet_listener_settings *const *inet_listeners;
ac7985784d08a3655291f24f711812b4d8b1cbcffuankg service->throttle_secs = SERVICE_STARTUP_FAILURE_THROTTLE_MIN_SECS;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes service->client_limit = set->client_limit != 0 ? set->client_limit :
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes service->vsz_limit = set->vsz_limit != (uoff_t)-1 ? set->vsz_limit :
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes service->idle_kill = set->idle_kill != 0 ? set->idle_kill :
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* use default */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes /* default gid to user's primary group */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (get_uidgid(set->user, &service->uid, &service->gid, error_r) < 0) {
return NULL;
return NULL;
error_r) < 0) {
return NULL;
return NULL;
unix_count = 0;
fifo_count = 0;
inet_count = 0;
return NULL;
for (i = 0; i < unix_count; i++) {
if (l == NULL)
return NULL;
for (i = 0; i < fifo_count; i++) {
if (l == NULL)
return NULL;
for (i = 0; i < inet_count; i++) {
error_r) < 0)
return NULL;
return NULL;
return service;
struct service *
return service;
return NULL;
struct service *
return service;
return NULL;
char *const *proto;
return TRUE;
return TRUE;
return FALSE;
const char *error;
unsigned int i, count;
for (i = 0; i < count; i++) {
case SERVICE_TYPE_LOG:
case SERVICE_TYPE_CONFIG:
case SERVICE_TYPE_ANVIL:
int diff;
service);
bool sigterm_log;
int sig;
unsigned int count;
int fd;
case SERVICE_LISTENER_UNIX:
case SERVICE_LISTENER_INET:
case SERVICE_LISTENER_FIFO:
unsigned int secs)
void service_pids_init(void)
void service_pids_deinit(void)
void *key;