int mail_session_connect_parse(const char *const *args, const char **error_r) { struct mail_session *session; const char *session_id; pid_t pid; struct ip_addr ip; unsigned int i; /* <session id> <username> <service> <pid> [key=value ..] */ if (str_array_length(args) < 4) { *error_r = "CONNECT: Too few parameters"; return -1; } session_id = args[0]; if (str_to_pid(args[3], &pid) < 0) { *error_r = t_strdup_printf("CONNECT: Invalid pid %s for session ID %s", args[3], session_id); return -1; } session = hash_table_lookup(mail_sessions_hash, session_id); if (session != NULL) { *error_r = t_strdup_printf( "CONNECT: Duplicate session ID %s for user %s service %s", session_id, args[1], args[2]); return -1; } session = i_malloc(sizeof(struct mail_session) + stats_alloc_size()); session->stats = (void *)(session + 1); session->refcount = 1; /* unrefed at disconnect */ session->id = i_strdup(session_id); session->service = str_table_ref(services, args[2]); session->pid = pid; session->last_update = ioloop_timeval; session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS, mail_session_idle_timeout, session); session->user = mail_user_login(args[1]); for (i = 3; args[i] != NULL; i++) { if (strncmp(args[i], "rip=", 4) == 0 && net_addr2ip(args[i] + 4, &ip) == 0) session->ip = mail_ip_login(&ip); } hash_table_insert(mail_sessions_hash, session->id, session); DLLIST_PREPEND_FULL(&stable_mail_sessions, session, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session, sorted_prev, sorted_next); DLLIST_PREPEND_FULL(&session->user->sessions, session, user_prev, user_next); mail_user_ref(session->user); if (session->ip != NULL) { DLLIST_PREPEND_FULL(&session->ip->sessions, session, ip_prev, ip_next); mail_ip_ref(session->ip); } global_memory_alloc(mail_session_memsize(session)); return 0; }
struct mail_user *mail_user_login(const char *username) { struct mail_user *user; const char *domain; user = hash_table_lookup(mail_users_hash, username); if (user != NULL) { user->num_logins++; mail_user_refresh(user, NULL); mail_domain_login(user->domain); return user; } domain = strchr(username, '@'); if (domain != NULL) domain++; else domain = ""; user = i_malloc(sizeof(struct mail_user) + stats_alloc_size()); user->stats = (void *)(user + 1); user->name = i_strdup(username); user->reset_timestamp = ioloop_time; user->domain = mail_domain_login_create(domain); hash_table_insert(mail_users_hash, user->name, user); DLLIST_PREPEND_FULL(&stable_mail_users, user, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_users_head, &mail_users_tail, user, sorted_prev, sorted_next); DLLIST_PREPEND_FULL(&user->domain->users, user, domain_prev, domain_next); mail_domain_ref(user->domain); user->num_logins++; user->last_update = ioloop_timeval; global_memory_alloc(mail_user_memsize(user)); return user; }
static struct mail_command * mail_command_add(struct mail_session *session, const char *name, const char *args) { struct mail_command *cmd; cmd = i_malloc(MALLOC_ADD(sizeof(struct mail_command), stats_alloc_size())); cmd->stats = (void *)(cmd + 1); cmd->refcount = 1; /* unrefed at "done" */ cmd->session = session; cmd->name = i_strdup(name); cmd->args = i_strdup(args); cmd->last_update = ioloop_timeval; DLLIST2_APPEND_FULL(&stable_mail_commands_head, &stable_mail_commands_tail, cmd, stable_prev, stable_next); DLLIST_PREPEND_FULL(&session->commands, cmd, session_prev, session_next); mail_session_ref(cmd->session); global_memory_alloc(mail_command_memsize(cmd)); return cmd; }
struct mail_ip *mail_ip_login(const struct ip_addr *ip_addr) { struct mail_ip *ip; ip = hash_table_lookup(mail_ips_hash, ip_addr); if (ip != NULL) { ip->num_logins++; mail_ip_refresh(ip, NULL); return ip; } ip = i_new(struct mail_ip, 1); ip->ip = *ip_addr; ip->reset_timestamp = ioloop_time; hash_table_insert(mail_ips_hash, &ip->ip, ip); DLLIST_PREPEND_FULL(&stable_mail_ips, ip, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_ips_head, &mail_ips_tail, ip, sorted_prev, sorted_next); ip->num_logins++; ip->last_update = ioloop_timeval; global_memory_alloc(mail_ip_memsize(ip)); return ip; }
int mail_session_connect_parse(const char *const *args, const char **error_r) { struct mail_session *session; guid_128_t session_guid; uint8_t *guid_p; pid_t pid; struct ip_addr ip; unsigned int i; /* <session guid> <username> <service> <pid> [key=value ..] */ if (str_array_length(args) < 4) { *error_r = "CONNECT: Too few parameters"; return -1; } if (guid_128_from_string(args[0], session_guid) < 0) { *error_r = "CONNECT: Invalid GUID"; return -1; } if (str_to_pid(args[3], &pid) < 0) { *error_r = "CONNECT: Invalid pid"; return -1; } guid_p = session_guid; session = hash_table_lookup(mail_sessions_hash, guid_p); if (session != NULL) { *error_r = "CONNECT: Duplicate session GUID"; return -1; } session = i_new(struct mail_session, 1); session->refcount = 1; /* unrefed at disconnect */ session->service = i_strdup(args[2]); memcpy(session->guid, session_guid, sizeof(session->guid)); session->pid = pid; session->last_update = ioloop_timeval; session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS, mail_session_idle_timeout, session); session->user = mail_user_login(args[1]); for (i = 3; args[i] != NULL; i++) { if (strncmp(args[i], "rip=", 4) == 0 && net_addr2ip(args[i] + 4, &ip) == 0) session->ip = mail_ip_login(&ip); } guid_p = session->guid; hash_table_insert(mail_sessions_hash, guid_p, session); DLLIST_PREPEND_FULL(&stable_mail_sessions, session, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session, sorted_prev, sorted_next); DLLIST_PREPEND_FULL(&session->user->sessions, session, user_prev, user_next); mail_user_ref(session->user); if (session->ip != NULL) { DLLIST_PREPEND_FULL(&session->ip->sessions, session, ip_prev, ip_next); mail_ip_ref(session->ip); } global_memory_alloc(mail_session_memsize(session)); return 0; }