static void client_connected(struct master_service_connection *conn) { const char *access_sockets = global_login_settings->login_access_sockets; struct login_access_lookup *lookup; master_service_client_connection_accept(conn); if (conn->remote_ip.family != 0) { /* log the connection's IP address in case we crash. it's of course possible that another earlier client causes the crash, but this is better than nothing. */ i_set_failure_send_ip(&conn->remote_ip); } /* make sure we're connected (or attempting to connect) to auth */ auth_client_connect(auth_client); if (*access_sockets == '\0') { /* no access checks */ client_connected_finish(conn); return; } lookup = i_new(struct login_access_lookup, 1); lookup->conn = *conn; lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup); lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " "); lookup->next_socket = lookup->sockets; login_access_lookup_next(lookup); }
static int cmd_id_handle_args(struct imap_client *client, const struct imap_arg *arg) { struct imap_client_cmd_id *id = client->cmd_id; const char *key, *value; switch (id->state) { case IMAP_CLIENT_ID_STATE_LIST: if (arg->type == IMAP_ARG_NIL) return 1; if (arg->type != IMAP_ARG_LIST) return -1; if (client->set->imap_id_log[0] == '\0') { /* no ID logging */ } else if (client->id_logged) { /* already logged the ID reply */ } else { id->log_reply = str_new(default_pool, 64); if (strcmp(client->set->imap_id_log, "*") == 0) { /* log all keys */ } else { /* log only specified keys */ id->log_keys = p_strsplit_spaces(default_pool, client->set->imap_id_log, " "); } } id->state = IMAP_CLIENT_ID_STATE_KEY; break; case IMAP_CLIENT_ID_STATE_KEY: if (!imap_arg_get_string(arg, &key)) return -1; if (i_strocpy(id->key, key, sizeof(id->key)) < 0) return -1; id->state = IMAP_CLIENT_ID_STATE_VALUE; break; case IMAP_CLIENT_ID_STATE_VALUE: if (!imap_arg_get_nstring(arg, &value)) return -1; cmd_id_handle_keyvalue(client, id->key, value); id->state = IMAP_CLIENT_ID_STATE_KEY; break; } return 0; }
/* <settings checks> */ static bool auth_settings_check(void *_set, pool_t pool, const char **error_r) { struct auth_settings *set = _set; const char *p; if (set->debug_passwords) set->debug = TRUE; if (set->debug) set->verbose = TRUE; if (set->cache_size > 0 && set->cache_size < 1024) { /* probably a configuration error. older versions used megabyte numbers */ *error_r = t_strdup_printf("auth_cache_size value is too small " "(%"PRIuUOFF_T" bytes)", set->cache_size); return FALSE; } if (*set->username_chars == '\0') { /* all chars are allowed */ memset(set->username_chars_map, 1, sizeof(set->username_chars_map)); } else { for (p = set->username_chars; *p != '\0'; p++) set->username_chars_map[(int)(uint8_t)*p] = 1; } if (*set->username_translation != '\0') { p = set->username_translation; for (; *p != '\0' && p[1] != '\0'; p += 2) set->username_translation_map[(int)(uint8_t)*p] = p[1]; } set->realms_arr = (const char *const *)p_strsplit_spaces(pool, set->realms, " "); return TRUE; }
static bool test_parse_header_line(struct test_parser *parser, struct test *test, const char *line, const char **error_r) { struct test_connection *test_conn; const char *key, *value; unsigned int idx; value = strchr(line, ':'); if (value == NULL) { *error_r = "Missing ':'"; return FALSE; } for (key = value; key[-1] == ' '; key--) ; key = t_str_lcase(t_strdup_until(line, key)); for (value++; *value == ' '; value++) ; if (strcmp(key, "capabilities") == 0) { test->required_capabilities = (const char *const *) p_strsplit_spaces(parser->pool, value, " "); return TRUE; } if (strcmp(key, "connections") == 0) { test->connection_count = strcmp(value, "n") == 0 ? 2 : strtoul(value, NULL, 10); return TRUE; } if (strncmp(key, "user ", 5) == 0 && str_to_uint(key+5, &idx) == 0 && idx != 0) { /* FIXME: kludgy kludgy */ if (strcmp(value, "$user2") == 0 || strcmp(value, "${user2}") == 0) { test->require_user2 = TRUE; value = conf.username2_template; } test_conn = array_idx_modifiable(&test->connections, idx-1); test_conn->username = p_strdup(parser->pool, value); return TRUE; } if (strcmp(key, "messages") == 0) { test->message_count = strcmp(value, "all") == 0 ? UINT_MAX : strtoul(value, NULL, 10); return TRUE; } if (strcmp(key, "state") == 0) { if (strcasecmp(value, "nonauth") == 0) test->startup_state = TEST_STARTUP_STATE_NONAUTH; else if (strcasecmp(value, "auth") == 0) test->startup_state = TEST_STARTUP_STATE_DELETED; else if (strcasecmp(value, "created") == 0) test->startup_state = TEST_STARTUP_STATE_CREATED; else if (strcasecmp(value, "appended") == 0) test->startup_state = TEST_STARTUP_STATE_APPENDED; else if (strcasecmp(value, "selected") == 0) test->startup_state = TEST_STARTUP_STATE_SELECTED; else { *error_r = "Unknown state value"; return FALSE; } return TRUE; } *error_r = "Unknown setting"; return FALSE; }
passwd_file_add(struct passwd_file *pw, const char *username, const char *pass, const char *const *args) { /* args = uid, gid, user info, home dir, shell, extra_fields */ struct passwd_user *pu; const char *extra_fields = NULL; char *user; size_t len; if (hash_table_lookup(pw->users, username) != NULL) { i_error("passwd-file %s: User %s exists more than once", pw->path, username); return; } pu = p_new(pw->pool, struct passwd_user, 1); user = p_strdup(pw->pool, username); len = pass == NULL ? 0 : strlen(pass); if (len > 4 && pass[0] != '{' && pass[0] != '$' && pass[len-1] == ']' && pass[len-4] == '[') { /* password[type] - we're being libpam-pwdfile compatible here. it uses 13 = DES and 34 = MD5. For backwards comaptibility with ourself, we have also 56 = Digest-MD5. */ int num = (pass[len-3] - '0') * 10 + (pass[len-2] - '0'); pass = t_strndup(pass, len-4); if (num == 34) { pu->password = p_strconcat(pw->pool, "{PLAIN-MD5}", pass, NULL); } else if (num == 56) { pu->password = p_strconcat(pw->pool, "{DIGEST-MD5}", pass, NULL); if (strlen(pu->password) != 32 + 12) { i_error("passwd-file %s: User %s " "has invalid password", pw->path, username); return; } } else { pu->password = p_strconcat(pw->pool, "{CRYPT}", pass, NULL); } } else { pu->password = p_strdup(pw->pool, pass); } pu->uid = (uid_t)-1; pu->gid = (gid_t)-1; if (*args == NULL) ; else if (!pw->db->userdb || **args == '\0') { args++; } else { pu->uid = userdb_parse_uid(NULL, *args); if (pu->uid == 0 || pu->uid == (uid_t)-1) { i_error("passwd-file %s: User %s has invalid UID '%s'", pw->path, username, *args); return; } args++; } if (*args == NULL) { if (pw->db->userdb_warn_missing) { i_error("passwd-file %s: User %s is missing " "userdb info", pw->path, username); } /* don't allow userdb lookups */ pu->uid = 0; pu->gid = 0; } else if (!pw->db->userdb || **args == '\0') args++; else { pu->gid = userdb_parse_gid(NULL, *args); if (pu->gid == 0 || pu->gid == (gid_t)-1) { i_error("passwd-file %s: User %s has invalid GID '%s'", pw->path, username, *args); return; } args++; } /* user info */ if (*args != NULL) args++; /* home */ if (*args != NULL) { if (pw->db->userdb) pu->home = p_strdup_empty(pw->pool, *args); args++; } /* shell */ if (*args != NULL) args++; if (*args != NULL && **args == '\0') { /* old format, this field is empty and next field may contain MAIL */ args++; if (*args != NULL && **args != '\0' && pw->db->userdb) { extra_fields = t_strconcat("userdb_mail=", t_strarray_join(args, ":"), NULL); } } else if (*args != NULL) { /* new format, contains a space separated list of extra fields */ extra_fields = t_strarray_join(args, ":"); } if (extra_fields != NULL) { pu->extra_fields = p_strsplit_spaces(pw->pool, extra_fields, " "); } hash_table_insert(pw->users, user, pu); }