void fd_debug_verify_leaks(int first_fd, int last_fd) { struct ip_addr addr, raddr; in_port_t port, rport; struct stat st; int old_errno; for (; first_fd <= last_fd; first_fd++) { if (fcntl(first_fd, F_GETFD, 0) == -1 && errno == EBADF) continue; old_errno = errno; if (net_getsockname(first_fd, &addr, &port) == 0) { if (addr.family == AF_UNIX) { struct sockaddr_un sa; socklen_t socklen = sizeof(sa); if (getsockname(first_fd, (void *)&sa, &socklen) < 0) sa.sun_path[0] = '\0'; i_panic("Leaked UNIX socket fd %d: %s", first_fd, sa.sun_path); } if (net_getpeername(first_fd, &raddr, &rport) < 0) { memset(&raddr, 0, sizeof(raddr)); rport = 0; } i_panic("Leaked socket fd %d: %s:%u -> %s:%u", first_fd, net_ip2addr(&addr), port, net_ip2addr(&raddr), rport); } if (fstat(first_fd, &st) == 0) { #ifdef __APPLE__ /* OSX workaround: gettimeofday() calls shm_open() internally and the fd won't get closed on exec. We'll just skip all ino/dev=0 files and hope they weren't anything else. */ if (st.st_ino == 0 && st.st_dev == 0) continue; #endif #ifdef HAVE_SYS_SYSMACROS_H i_panic("Leaked file fd %d: dev %s.%s inode %s", first_fd, dec2str(major(st.st_dev)), dec2str(minor(st.st_dev)), dec2str(st.st_ino)); #else i_panic("Leaked file fd %d: dev %s inode %s", first_fd, dec2str(st.st_dev), dec2str(st.st_ino)); #endif } i_panic("Leaked unknown fd %d (errno = %s)", first_fd, strerror(old_errno)); } }
static int imap_master_client_verify(const struct imap_master_input *master_input, int fd_client, const char **error_r) { struct stat peer_st; if (master_input->peer_ino == 0) return 0; /* make sure we have the right fd */ if (fstat(fd_client, &peer_st) < 0) { *error_r = t_strdup_printf("fstat(peer) failed: %m"); return -1; } if (peer_st.st_ino != master_input->peer_ino || !CMP_DEV_T(peer_st.st_dev, master_input->peer_dev)) { *error_r = t_strdup_printf( "BUG: Expected peer device=%lu,%lu inode=%s doesn't match " "client fd's actual device=%lu,%lu inode=%s", (unsigned long)major(peer_st.st_dev), (unsigned long)minor(peer_st.st_dev), dec2str(peer_st.st_ino), (unsigned long)major(master_input->peer_dev), (unsigned long)minor(master_input->peer_dev), dec2str(master_input->peer_ino)); return -1; } return 0; }
static int user_verify_restricted_uid(struct auth_request *auth_request) { struct auth_master_connection *conn = auth_request->master; struct auth_fields *reply = auth_request->userdb_reply; const char *value, *reason; uid_t uid; if (conn->userdb_restricted_uid == 0) return 0; value = auth_fields_find(reply, "uid"); if (value == NULL) reason = "userdb reply doesn't contain uid"; else if (str_to_uid(value, &uid) < 0) reason = "userdb reply contains invalid uid"; else if (uid != conn->userdb_restricted_uid) { reason = t_strdup_printf( "userdb uid (%s) doesn't match peer uid (%s)", dec2str(uid), dec2str(conn->userdb_restricted_uid)); } else { return 0; } auth_request_log_error(auth_request, "userdb", "client doesn't have lookup permissions for this user: %s " "(to bypass this check, set: service auth { unix_listener %s { mode=0777 } })", reason, conn->path); return -1; }
static void sig_die(const siginfo_t *si, void *context) { struct master_service *service = context; /* SIGINT comes either from master process or from keyboard. we don't want to log it in either case.*/ if (si->si_signo != SIGINT) { i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)", si->si_signo, dec2str(si->si_pid), dec2str(si->si_uid), lib_signal_code_to_str(si->si_signo, si->si_code)); } else if ((service->flags & MASTER_SERVICE_FLAG_NO_IDLE_DIE) != 0) { /* never die when idling */ return; } else if ((service->flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) { /* SIGINT came from master. die only if we're not handling any clients currently. */ if (service->master_status.available_count != service->total_available_count) return; if (service->idle_die_callback != NULL && !service->idle_die_callback()) { /* we don't want to die - send a notification to master so it doesn't think we're ignoring it completely. */ master_status_send(service, FALSE); return; } } service->killed = TRUE; io_loop_stop(service->ioloop); }
int unix_socket_create(const char *path, int mode, uid_t uid, gid_t gid, int backlog) { mode_t old_umask; int fd; old_umask = umask(0777 ^ mode); fd = net_listen_unix_unlink_stale(path, backlog); umask(old_umask); if (fd < 0) { i_error("net_listen_unix(%s) failed: %m", path); return -1; } if (uid != (uid_t)-1 || gid != (gid_t)-1) { /* set correct permissions */ if (chown(path, uid, gid) < 0) { i_error("chown(%s, %s, %s) failed: %m", path, dec2str(uid), dec2str(gid)); i_close_fd(&fd); return -1; } } return fd; }
enum checkpassword_sigchld_handler_result checkpassword_sigchld_handler(const struct child_wait_status *child_wait_status, struct chkpw_auth_request *request) { int status = child_wait_status->status; pid_t pid = child_wait_status->pid; if (request == NULL) { i_error("checkpassword: sighandler called for unknown child %s", dec2str(pid)); return SIGCHLD_RESULT_UNKNOWN_CHILD; } if (WIFSIGNALED(status)) { i_error("checkpassword: Child %s died with signal %d", dec2str(pid), WTERMSIG(status)); return SIGCHLD_RESULT_DEAD_CHILD; } else if (WIFEXITED(status)) { request->exited = TRUE; request->exit_status = WEXITSTATUS(status); auth_request_log_debug(request->request, "checkpassword", "exit_status=%d", request->exit_status); return SIGCHLD_RESULT_OK; } else { /* shouldn't happen */ auth_request_log_debug(request->request, "checkpassword", "Child exited with status=%d", status); return SIGCHLD_RESULT_UNKNOWN_ERROR; } }
static const char *sieve_generate_tmp_filename(const char *scriptname) { static struct timeval last_tv = { 0, 0 }; struct timeval tv; /* use secs + usecs to guarantee uniqueness within this process. */ if (ioloop_timeval.tv_sec > last_tv.tv_sec || (ioloop_timeval.tv_sec == last_tv.tv_sec && ioloop_timeval.tv_usec > last_tv.tv_usec)) { tv = ioloop_timeval; } else { tv = last_tv; if (++tv.tv_usec == 1000000) { tv.tv_sec++; tv.tv_usec = 0; } } last_tv = tv; if ( scriptname == NULL ) { return t_strdup_printf("%s.M%sP%s.%s.tmp", dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); } scriptname = t_strdup_printf("%s_%s.M%sP%s.%s", scriptname, dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); return sieve_script_file_from_name(scriptname); }
static const struct var_expand_table * get_var_expand_table(struct client *client) { struct var_expand_table *tab; tab = t_malloc(sizeof(login_var_expand_empty_tab)); memcpy(tab, login_var_expand_empty_tab, sizeof(login_var_expand_empty_tab)); if (client->virtual_user != NULL) get_var_expand_users(tab, client->virtual_user); tab[3].value = login_binary->protocol; tab[4].value = getenv("HOME"); tab[5].value = net_ip2addr(&client->local_ip); tab[6].value = net_ip2addr(&client->ip); tab[7].value = my_pid; tab[8].value = client->auth_mech_name == NULL ? NULL : str_sanitize(client->auth_mech_name, MAX_MECH_NAME); tab[9].value = dec2str(client->local_port); tab[10].value = dec2str(client->remote_port); if (!client->tls) { tab[11].value = client->secured ? "secured" : NULL; tab[12].value = ""; } else { const char *ssl_state = ssl_proxy_is_handshaked(client->ssl_proxy) ? "TLS" : "TLS handshaking"; const char *ssl_error = ssl_proxy_get_last_error(client->ssl_proxy); tab[11].value = ssl_error == NULL ? ssl_state : t_strdup_printf("%s: %s", ssl_state, ssl_error); tab[12].value = ssl_proxy_get_security_string(client->ssl_proxy); } tab[13].value = client->mail_pid == 0 ? "" : dec2str(client->mail_pid); tab[14].value = client_get_session_id(client); tab[15].value = net_ip2addr(&client->real_local_ip); tab[16].value = net_ip2addr(&client->real_remote_ip); tab[17].value = dec2str(client->real_local_port); tab[18].value = dec2str(client->real_remote_port); if (client->virtual_user_orig != NULL) get_var_expand_users(tab+19, client->virtual_user_orig); else { tab[19].value = tab[0].value; tab[20].value = tab[1].value; tab[21].value = tab[2].value; } if (client->virtual_auth_user != NULL) get_var_expand_users(tab+22, client->virtual_auth_user); else { tab[22].value = tab[19].value; tab[23].value = tab[20].value; tab[24].value = tab[21].value; } tab[25].value = client->listener_name; return tab; }
static int service_parse_privileges(struct mail_storage_service_ctx *ctx, struct mail_storage_service_user *user, struct mail_storage_service_privileges *priv_r, const char **error_r) { const struct mail_user_settings *set = user->user_set; uid_t uid = (uid_t)-1; gid_t gid = (gid_t)-1; memset(priv_r, 0, sizeof(*priv_r)); if (*set->mail_uid != '\0') { if (!parse_uid(set->mail_uid, &uid, error_r)) { *error_r = t_strdup_printf("%s (from %s)", *error_r, user->uid_source); return -1; } if (uid < (uid_t)set->first_valid_uid || (set->last_valid_uid != 0 && uid > (uid_t)set->last_valid_uid)) { *error_r = t_strdup_printf( "Mail access for users with UID %s not permitted " "(see first_valid_uid in config file, uid from %s).", dec2str(uid), user->uid_source); return -1; } } priv_r->uid = uid; priv_r->uid_source = user->uid_source; if (*set->mail_gid != '\0') { if (!parse_gid(set->mail_gid, &gid, error_r)) { *error_r = t_strdup_printf("%s (from %s)", *error_r, user->gid_source); return -1; } if (gid < (gid_t)set->first_valid_gid || (set->last_valid_gid != 0 && gid > (gid_t)set->last_valid_gid)) { *error_r = t_strdup_printf( "Mail access for users with GID %s not permitted " "(see first_valid_gid in config file, gid from %s).", dec2str(gid), user->gid_source); return -1; } } priv_r->gid = gid; priv_r->gid_source = user->gid_source; /* variable strings are expanded in mail_user_init(), but we need the home and chroot sooner so do them separately here. */ priv_r->home = user_expand_varstr(ctx, user, priv_r, user->user_set->mail_home); priv_r->chroot = user_expand_varstr(ctx, user, priv_r, user->user_set->mail_chroot); return 0; }
static char *cydir_generate_tmp_filename(void) { static unsigned int create_count = 0; return i_strdup_printf("temp.%s.P%sQ%uM%s.%s", dec2str(ioloop_timeval.tv_sec), my_pid, create_count++, dec2str(ioloop_timeval.tv_usec), my_hostname); }
static void passwd_file_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct passwd_file_userdb_module *module = (struct passwd_file_userdb_module *)_module; struct passwd_user *pu; const struct var_expand_table *table; string_t *str; const char *key, *value; char **p; pu = db_passwd_file_lookup(module->pwf, auth_request, module->username_format); if (pu == NULL || pu->uid == 0) { callback(USERDB_RESULT_USER_UNKNOWN, auth_request); return; } if (pu->uid != (uid_t)-1) { auth_request_set_userdb_field(auth_request, "uid", dec2str(pu->uid)); } if (pu->gid != (gid_t)-1) { auth_request_set_userdb_field(auth_request, "gid", dec2str(pu->gid)); } if (pu->home != NULL) auth_request_set_userdb_field(auth_request, "home", pu->home); if (pu->extra_fields != NULL) { str = t_str_new(512); table = auth_request_get_var_expand_table(auth_request, NULL); for (p = pu->extra_fields; *p != NULL; p++) { if (strncmp(*p, "userdb_", 7) != 0) continue; key = *p + 7; value = strchr(key, '='); if (value != NULL) { key = t_strdup_until(key, value); str_truncate(str, 0); auth_request_var_expand_with_table(str, value + 1, auth_request, table, NULL); value = str_c(str); } else { value = ""; } auth_request_set_userdb_field(auth_request, key, value); } } callback(USERDB_RESULT_OK, auth_request); }
static void testsuite_tmp_dir_init(void) { testsuite_tmp_dir = i_strdup_printf ("/tmp/dsieve-testsuite.%s.%s", dec2str(time(NULL)), dec2str(getpid())); if ( mkdir(testsuite_tmp_dir, 0700) < 0 ) { i_fatal("failed to create temporary directory '%s': %m.", testsuite_tmp_dir); } }
static void userdb_nss_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct nss_userdb_module *module = (struct nss_userdb_module *)_module; struct passwd pw; enum nss_status status; enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE; int err; auth_request_log_debug(auth_request, "nss", "lookup"); status = module->getpwnam_r(auth_request->user, &pw, module->buf, module->bufsize, &err); switch (status) { case NSS_STATUS_TRYAGAIN: auth_request_log_error(auth_request, "nss", "returned tryagain (err=%d)", err); break; case NSS_STATUS_UNAVAIL: auth_request_log_error(auth_request, "nss", "unavailable (err=%d)", err); break; case NSS_STATUS_NOTFOUND: auth_request_log_info(auth_request, "nss", "unknown user"); result = USERDB_RESULT_USER_UNKNOWN; break; case NSS_STATUS_SUCCESS: result = USERDB_RESULT_OK; break; default: auth_request_log_info(auth_request, "nss", "returned %d (err=%d)", status, err); break; } if (result != USERDB_RESULT_OK) { callback(result, auth_request); return; } auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); auth_request_set_userdb_field(auth_request, "system_groups_user", pw.pw_name); auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); callback(USERDB_RESULT_OK, auth_request); }
static void imap_hibernate_write_cmd(struct client *client, string_t *cmd, const buffer_t *state, int fd_notify) { struct stat peer_st; str_append_tabescaped(cmd, client->user->username); str_append_c(cmd, '\t'); str_append_tabescaped(cmd, client->user->set->mail_log_prefix); str_printfa(cmd, "\tidle_notify_interval=%u", client->set->imap_idle_notify_interval); if (fstat(client->fd_in, &peer_st) == 0) { str_printfa(cmd, "\tpeer_dev_major=%lu\tpeer_dev_minor=%lu\tpeer_ino=%llu", (unsigned long)major(peer_st.st_dev), (unsigned long)minor(peer_st.st_dev), (unsigned long long)peer_st.st_ino); } if (client->session_id != NULL) { str_append(cmd, "\tsession="); str_append_tabescaped(cmd, client->session_id); } if (client->user->local_ip != NULL) str_printfa(cmd, "\tlip=%s", net_ip2addr(client->user->local_ip)); if (client->user->remote_ip != NULL) str_printfa(cmd, "\trip=%s", net_ip2addr(client->user->remote_ip)); if (client->userdb_fields != NULL) { string_t *userdb_fields = t_str_new(256); unsigned int i; for (i = 0; client->userdb_fields[i] != NULL; i++) { if (i > 0) str_append_c(userdb_fields, '\t'); str_append_tabescaped(userdb_fields, client->userdb_fields[i]); } str_append(cmd, "\tuserdb_fields="); str_append_tabescaped(cmd, str_c(userdb_fields)); } if (client->user->uid != (uid_t)-1) str_printfa(cmd, "\tuid=%s", dec2str(client->user->uid)); if (client->user->gid != (gid_t)-1) str_printfa(cmd, "\tgid=%s", dec2str(client->user->gid)); str_append(cmd, "\tstats="); str_append_tabescaped(cmd, client_stats(client)); if (client->command_queue != NULL && strcasecmp(client->command_queue->name, "IDLE") == 0) str_append(cmd, "\tidle-cmd"); if (fd_notify != -1) str_append(cmd, "\tnotify_fd"); str_append(cmd, "\tstate="); base64_encode(state->data, state->used, cmd); str_append_c(cmd, '\n'); }
static const struct var_expand_table * get_var_expand_table(struct master_service *service, struct mail_storage_service_user *user, const struct mail_storage_service_input *input, const struct mail_storage_service_privileges *priv) { static struct var_expand_table static_tab[] = { { 'u', NULL, "user" }, { 'n', NULL, "username" }, { 'd', NULL, "domain" }, { 's', NULL, "service" }, { 'l', NULL, "lip" }, { 'r', NULL, "rip" }, { 'p', NULL, "pid" }, { 'i', NULL, "uid" }, { '\0', NULL, "gid" }, { '\0', NULL, "session" }, { '\0', NULL, "auth_user" }, { '\0', NULL, "auth_username" }, { '\0', NULL, "auth_domain" }, { '\0', NULL, NULL } }; struct var_expand_table *tab; tab = t_malloc(sizeof(static_tab)); memcpy(tab, static_tab, sizeof(static_tab)); tab[0].value = input->username; tab[1].value = t_strcut(input->username, '@'); tab[2].value = strchr(input->username, '@'); if (tab[2].value != NULL) tab[2].value++; tab[3].value = service->name; tab[4].value = net_ip2addr(&input->local_ip); tab[5].value = net_ip2addr(&input->remote_ip); tab[6].value = my_pid; tab[7].value = priv == NULL ? NULL : dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid); tab[8].value = priv == NULL ? NULL : dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid); tab[9].value = input->session_id; if (user == NULL || user->auth_user == NULL) { tab[10].value = tab[0].value; tab[11].value = tab[1].value; tab[12].value = tab[2].value; } else { tab[10].value = user->auth_user; tab[11].value = t_strcut(user->auth_user, '@'); tab[12].value = strchr(user->auth_user, '@'); } return tab; }
static int process_io_open(void) { uid_t uid; if (proc_io_fd != -1) return proc_io_fd; if (proc_io_disabled) return -1; proc_io_fd = open(PROC_IO_PATH, O_RDONLY); if (proc_io_fd == -1 && errno == EACCES) { /* kludge: if we're running with permissions temporarily dropped, get them temporarily back so we can open /proc/self/io. */ uid = geteuid(); if (seteuid(0) == 0) { proc_io_fd = open(PROC_IO_PATH, O_RDONLY); if (seteuid(uid) < 0) { /* oops, this is bad */ i_fatal("stats: seteuid(%s) failed", dec2str(uid)); } } errno = EACCES; } if (proc_io_fd == -1) { if (errno != ENOENT) i_error("open(%s) failed: %m", PROC_IO_PATH); proc_io_disabled = TRUE; return -1; } return proc_io_fd; }
static void sieve_tool_get_user_data (const char **username_r, const char **homedir_r) { uid_t process_euid = geteuid(); struct passwd *pw; const char *user = NULL, *home = NULL; user = getenv("USER"); home = getenv("HOME"); if ( user == NULL || *user == '\0' || home == NULL || *home == '\0' ) { if ((pw = getpwuid(process_euid)) != NULL) { user = pw->pw_name; home = pw->pw_dir; } } if ( username_r != NULL ) { if ( user == NULL || *user == '\0' ) { i_fatal("couldn't lookup our username (uid=%s)", dec2str(process_euid)); } *username_r = t_strdup(user); } if ( homedir_r != NULL ) *homedir_r = t_strdup(home); }
void doveadm_master_send_signal(int signo) { const char *pidfile_path; unsigned int i; pid_t pid; pidfile_path = t_strconcat(doveadm_settings->base_dir, "/"MASTER_PID_FILE_NAME, NULL); if (!pid_file_read(pidfile_path, &pid)) i_fatal("Dovecot is not running (read from %s)", pidfile_path); if (kill(pid, signo) < 0) i_fatal("kill(%s, %d) failed: %m", dec2str(pid), signo); if (signo == SIGTERM) { /* wait for a while for the process to die */ usleep(1000); for (i = 0; i < 30; i++) { if (kill(pid, 0) < 0) { if (errno != ESRCH) i_error("kill() failed: %m"); break; } usleep(100000); } } }
static void service_process_get_status_error(string_t *str, struct service_process *process, int status, bool *default_fatal_r) { struct service *service = process->service; const char *msg; *default_fatal_r = FALSE; str_printfa(str, "service(%s): child %s ", service->set->name, dec2str(process->pid)); if (WIFSIGNALED(status)) { str_printfa(str, "killed with signal %d", WTERMSIG(status)); log_coredump(service, str, status); return; } if (!WIFEXITED(status)) { str_printfa(str, "died with status %d", status); return; } status = WEXITSTATUS(status); if (status == 0) { str_truncate(str, 0); return; } str_printfa(str, "returned error %d", status); msg = get_exit_status_message(service, status); if (msg != NULL) str_printfa(str, " (%s)", msg); if (status == FATAL_DEFAULT) *default_fatal_r = TRUE; }
static void checkpassword_request_half_finish(struct chkpw_auth_request *request) { if (!request->exited || request->fd_in != -1) return; switch (request->exit_status) { case 3: /* User does not exist. */ auth_request_log_info(request->request, "userdb-checkpassword", "User unknown"); checkpassword_request_finish(request, USERDB_RESULT_USER_UNKNOWN); break; case 2: /* This is intentionally not 0. checkpassword-reply exits with 2 on success when AUTHORIZED is set. */ if (request->input_buf != NULL) { checkpassword_request_finish(request, USERDB_RESULT_OK); break; } /* missing input - fall through */ default: /* whatever error... */ auth_request_log_error(request->request, "userdb-checkpassword", "Child %s exited with status %d", dec2str(request->pid), request->exit_status); checkpassword_request_finish(request, USERDB_RESULT_INTERNAL_FAILURE); break; } }
struct userdb_template * userdb_template_build(pool_t pool, const char *userdb_name, const char *args) { struct userdb_template *tmpl; const char *const *tmp, *key, *value, *nonull_value; uid_t uid; gid_t gid; tmpl = p_new(pool, struct userdb_template, 1); tmp = t_strsplit_spaces(args, " "); p_array_init(&tmpl->args, pool, str_array_length(tmp)); for (; *tmp != NULL; tmp++) { value = strchr(*tmp, '='); if (value == NULL) key = *tmp; else key = t_strdup_until(*tmp, value++); nonull_value = value == NULL ? "" : value; if (strcasecmp(key, "uid") == 0) { uid = userdb_parse_uid(NULL, nonull_value); if (uid == (uid_t)-1) { i_fatal("%s userdb: Invalid uid: %s", userdb_name, nonull_value); } value = dec2str(uid); } else if (strcasecmp(key, "gid") == 0) { gid = userdb_parse_gid(NULL, nonull_value); if (gid == (gid_t)-1) { i_fatal("%s userdb: Invalid gid: %s", userdb_name, nonull_value); } value = dec2str(gid); } else if (*key == '\0') { i_fatal("%s userdb: Empty key (=%s)", userdb_name, nonull_value); } key = p_strdup(pool, key); value = p_strdup(pool, value); array_append(&tmpl->args, &key, 1); array_append(&tmpl->args, &value, 1); } return tmpl; }
static void passwd_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct passwd_userdb_module *module = (struct passwd_userdb_module *)_module; struct passwd pw; struct timeval start_tv; int ret; auth_request_log_debug(auth_request, "passwd", "lookup"); if (gettimeofday(&start_tv, NULL) < 0) start_tv.tv_sec = 0; ret = i_getpwnam(auth_request->user, &pw); if (start_tv.tv_sec != 0) passwd_check_warnings(auth_request, module, &start_tv); switch (ret) { case -1: auth_request_log_error(auth_request, "passwd", "getpwnam() failed: %m"); callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request); return; case 0: auth_request_log_info(auth_request, "passwd", "unknown user"); callback(USERDB_RESULT_USER_UNKNOWN, auth_request); return; } auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); auth_request_set_userdb_field(auth_request, "system_groups_user", pw.pw_name); auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); userdb_template_export(module->tmpl, auth_request); callback(USERDB_RESULT_OK, auth_request); }
const char *maildir_filename_generate(void) { static struct timeval last_tv = { 0, 0 }; struct timeval tv; /* use secs + usecs to guarantee uniqueness within this process. */ if (timeval_cmp(&ioloop_timeval, &last_tv) > 0) tv = ioloop_timeval; else { tv = last_tv; if (++tv.tv_usec == 1000000) { tv.tv_sec++; tv.tv_usec = 0; } } last_tv = tv; return t_strdup_printf("%s.M%sP%s.%s", dec2str(tv.tv_sec), dec2str(tv.tv_usec), my_pid, my_hostname); }
// Show 4 digits prec for dec, 5 for ra void HMS::print_extra_precise_( char *buf ) const { char lbuf[32]; if ( show_sign_ ) { dec2str( lbuf, 32, val_, 4 ); } else { ra2str( lbuf, 32, val_ * 15.0, 5 ); } strncpy( buf, lbuf, 32 ); }
static void service_process_status_timeout(struct service_process *process) { service_error(process->service, "Initial status notification not received in %d " "seconds, killing the process", SERVICE_FIRST_STATUS_TIMEOUT_SECS); if (kill(process->pid, SIGKILL) < 0 && errno != ESRCH) { service_error(process->service, "kill(%s, SIGKILL) failed: %m", dec2str(process->pid)); } timeout_remove(&process->to_status); }
static int service_process_write_anvil_kill(int fd, struct service_process *process) { const char *data; data = t_strdup_printf("KILL\t%s\n", dec2str(process->pid)); if (write(fd, data, strlen(data)) < 0) { if (errno != EAGAIN) i_error("write(anvil process) failed: %m"); return -1; } return 0; }
static void maildir_handle_size_caching(struct index_mail *mail, bool quick_check, bool vsize) { struct mailbox *box = mail->mail.mail.box; struct maildir_mailbox *mbox = (struct maildir_mailbox *)box; enum mail_fetch_field field; uoff_t size; int pop3_state; field = vsize ? MAIL_FETCH_VIRTUAL_SIZE : MAIL_FETCH_PHYSICAL_SIZE; if ((mail->data.dont_cache_fetch_fields & field) != 0) return; if (quick_check && maildir_quick_size_lookup(mail, vsize, &size) > 0) { /* already in filename / uidlist. don't add it anywhere, including to the uidlist if it's already in filename. do some extra checks here to catch potential cache bugs. */ if (vsize && mail->data.virtual_size != size) { mail_cache_set_corrupted(box->cache, "Corrupted virtual size for uid=%u: " "%"PRIuUOFF_T" != %"PRIuUOFF_T, mail->mail.mail.uid, mail->data.virtual_size, size); mail->data.virtual_size = size; } else if (!vsize && mail->data.physical_size != size) { mail_cache_set_corrupted(box->cache, "Corrupted physical size for uid=%u: " "%"PRIuUOFF_T" != %"PRIuUOFF_T, mail->mail.mail.uid, mail->data.physical_size, size); mail->data.physical_size = size; } mail->data.dont_cache_fetch_fields |= field; return; } /* 1 = pop3-only, 0 = mixed, -1 = no pop3 */ pop3_state = maildir_get_pop3_state(mail); if (pop3_state >= 0 && mail->mail.mail.uid != 0) { /* if size is wanted permanently, store it to uidlist so that in case cache file gets lost we can get it quickly */ mail->data.dont_cache_fetch_fields |= field; size = vsize ? mail->data.virtual_size : mail->data.physical_size; maildir_uidlist_set_ext(mbox->uidlist, mail->mail.mail.uid, vsize ? MAILDIR_UIDLIST_REC_EXT_VSIZE : MAILDIR_UIDLIST_REC_EXT_PSIZE, dec2str(size)); } }
static const char *get_cram_challenge(void) { unsigned char buf[17]; size_t i; random_fill(buf, sizeof(buf)-1); for (i = 0; i < sizeof(buf)-1; i++) buf[i] = (buf[i] % 10) + '0'; buf[sizeof(buf)-1] = '\0'; return t_strdup_printf("<%s.%s@%s>", (const char *)buf, dec2str(ioloop_time), my_hostname); }
static void lookup_credentials_callback(enum passdb_result result, const unsigned char *credentials, size_t size, struct auth_request *request) { struct auth_worker_client *client = request->context; struct auth_stream_reply *reply; string_t *str; if (request->passdb_failure && result == PASSDB_RESULT_OK) result = PASSDB_RESULT_PASSWORD_MISMATCH; reply = auth_stream_reply_init(pool_datastack_create()); auth_stream_reply_add(reply, NULL, dec2str(request->id)); if (result != PASSDB_RESULT_OK) { auth_stream_reply_add(reply, "FAIL", NULL); auth_stream_reply_add(reply, NULL, t_strdup_printf("%d", result)); } else { auth_stream_reply_add(reply, "OK", NULL); auth_stream_reply_add(reply, NULL, request->user); str = t_str_new(64); str_printfa(str, "{%s.b64}", request->credentials_scheme); base64_encode(credentials, size, str); auth_stream_reply_add(reply, NULL, str_c(str)); if (request->extra_fields != NULL) { const char *fields = auth_stream_reply_export(request->extra_fields); auth_stream_reply_import(reply, fields); } if (request->extra_cache_fields != NULL) { const char *fields = auth_stream_reply_export(request->extra_cache_fields); auth_stream_reply_import(reply, fields); } } str = auth_stream_reply_get_str(reply); str_append_c(str, '\n'); auth_worker_send_reply(client, str); auth_request_unref(&request); auth_worker_client_check_throttle(client); auth_worker_client_unref(&client); }
void hostpid_init(void) { static char hostname[256], pid[MAX_INT_STRLEN]; if (gethostname(hostname, sizeof(hostname)-1) == -1) i_strocpy(hostname, "unknown", sizeof(hostname)); hostname[sizeof(hostname)-1] = '\0'; my_hostname = hostname; if (strchr(hostname, '/') != NULL) i_fatal("Invalid system hostname: %s", hostname); /* allow calling hostpid_init() multiple times to reset hostname */ i_free_and_null(my_domain); i_strocpy(pid, dec2str(getpid()), sizeof(pid)); my_pid = pid; }