*error_r = "PENALTY-INC: Not enough parameters";
return -1;
}
- checksum = strtoul(args[1], NULL, 10);
- value = strtoul(args[2], NULL, 10);
- if (value > PENALTY_MAX_VALUE ||
+ if (str_to_uint(args[1], &checksum) < 0 ||
+ str_to_uint(args[2], &value) < 0 ||
+ value > PENALTY_MAX_VALUE ||
(value == 0 && checksum != 0)) {
*error_r = "PENALTY-INC: Invalid parameters";
return -1;
}
penalty_inc(penalty, args[0], checksum, value);
} else if (strcmp(cmd, "PENALTY-SET-EXPIRE-SECS") == 0) {
- if (args[0] == NULL) {
+ if (args[0] == NULL || str_to_uint(args[0], &value) < 0) {
*error_r = "PENALTY-SET-EXPIRE-SECS: "
- "Not enough parameters";
+ "Invalid parameters";
return -1;
}
- penalty_set_expire_secs(penalty, atoi(args[0]));
+ penalty_set_expire_secs(penalty, value);
} else if (strcmp(cmd, "PENALTY-DUMP") == 0) {
penalty_dump(penalty, conn->output);
} else {
if (str_array_length(args) < 4 ||
strcmp(args[0], "VERSION") != 0 ||
strcmp(args[1], "anvil") != 0 ||
- atoi(args[2]) != ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(args[2], ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION)) {
i_error("Anvil client not compatible with this server "
"(mixed old and new binaries?)");
anvil_connection_destroy(conn);
i_assert(conn->pid == 0);
- pid = (unsigned int)strtoul(args, NULL, 10);
- if (pid == 0) {
+ if (str_to_uint(args, &pid) < 0 || pid == 0) {
i_error("BUG: Authentication client said it's PID 0");
return FALSE;
}
if (!conn->version_received) {
/* make sure the major version matches */
if (strncmp(line, "VERSION\t", 8) != 0 ||
- atoi(t_strcut(line + 8, '\t')) !=
- AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(t_strcut(line + 8, '\t'),
+ AUTH_CLIENT_PROTOCOL_MAJOR_VERSION)) {
i_error("Authentication client "
"not compatible with this server "
"(mixed old and new binaries?)");
/* <id> <client-pid> <client-id> <cookie> */
list = t_strsplit(args, "\t");
- if (str_array_length(list) < 4) {
+ if (str_array_length(list) < 4 ||
+ str_to_uint(list[0], &id) < 0 ||
+ str_to_uint(list[1], &client_pid) < 0 ||
+ str_to_uint(list[2], &client_id) < 0) {
i_error("BUG: Master sent broken REQUEST");
return FALSE;
}
- id = (unsigned int)strtoul(list[0], NULL, 10);
- client_pid = (unsigned int)strtoul(list[1], NULL, 10);
- client_id = (unsigned int)strtoul(list[2], NULL, 10);
buffer_create_data(&buf, cookie, sizeof(cookie));
if (hex_to_binary(list[3], &buf) < 0) {
i_error("BUG: Master sent broken REQUEST cookie");
{
struct auth_request *auth_request;
const char *const *list, *name, *arg;
+ unsigned int id;
/* <id> <userid> [<parameters>] */
list = t_strsplit(args, "\t");
- if (list[0] == NULL || list[1] == NULL) {
+ if (list[0] == NULL || list[1] == NULL ||
+ str_to_uint(list[0], &id) < 0) {
i_error("BUG: Master sent broken %s", cmd);
return -1;
}
auth_request = auth_request_new_dummy();
- auth_request->id = (unsigned int)strtoul(list[0], NULL, 10);
+ auth_request->id = id;
auth_request->context = conn;
auth_master_connection_ref(conn);
unsigned int id;
/* <id> */
- if (*args == '\0') {
+ if (str_to_uint(args, &id) < 0) {
i_error("BUG: Master sent broken LIST");
return FALSE;
}
- id = strtoul(args, NULL, 10);
while (userdb != NULL && userdb->userdb->iface->iterate_init == NULL)
userdb = userdb->next;
/* make sure the major version matches */
if (strncmp(line, "VERSION\t", 8) != 0 ||
- atoi(t_strcut(line + 8, '\t')) !=
- AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(t_strcut(line + 8, '\t'),
+ AUTH_MASTER_PROTOCOL_MAJOR_VERSION)) {
i_error("Master not compatible with this server "
"(mixed old and new binaries?)");
auth_master_connection_destroy(&conn);
/* <id> <mechanism> [...] */
list = t_strsplit(args, "\t");
- if (list[0] == NULL || list[1] == NULL) {
+ if (list[0] == NULL || list[1] == NULL ||
+\v str_to_uint(list[0], &id) < 0) {
i_error("BUG: Authentication client %u "
"sent broken AUTH request", handler->client_pid);
return FALSE;
}
- id = (unsigned int)strtoul(list[0], NULL, 10);
-
mech = mech_module_find(list[1]);
if (mech == NULL) {
/* unsupported mechanism */
unsigned int id;
data = strchr(args, '\t');
- if (data == NULL) {
+ if (data == NULL || str_to_uint(args, &id) < 0) {
i_error("BUG: Authentication client sent broken CONT request");
return FALSE;
}
data++;
- id = (unsigned int)strtoul(args, NULL, 10);
-
request = hash_table_lookup(handler->requests, POINTER_CAST(id));
if (request == NULL) {
struct auth_stream_reply *reply;
if (!net_ip_compare(&ip, &request->local_ip))
return FALSE;
- if (port != NULL && (unsigned int)atoi(port) != request->local_port)
+ if (port != NULL && !str_uint_equals(port, request->local_port))
return FALSE;
return destuser == NULL ||
strcmp(destuser, request->original_username) == 0;
unsigned int passdb_id;
/* <passdb id> <password> [<args>] */
- if (args[1] == NULL) {
+ if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
i_error("BUG: Auth worker server sent us invalid PASSV");
return FALSE;
}
- passdb_id = atoi(args[0]);
password = args[1];
auth_request = worker_auth_request_new(client, id, args + 2);
unsigned int passdb_id;
/* <passdb id> <scheme> [<args>] */
- if (args[1] == NULL) {
+ if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
i_error("BUG: Auth worker server sent us invalid PASSL");
return FALSE;
}
- passdb_id = atoi(args[0]);
scheme = args[1];
auth_request = worker_auth_request_new(client, id, args + 2);
const char *creds;
/* <passdb id> <credentials> [<args>] */
- if (args[1] == NULL) {
+ if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
i_error("BUG: Auth worker server sent us invalid SETCRED");
return FALSE;
}
- passdb_id = atoi(args[0]);
creds = args[1];
auth_request = worker_auth_request_new(client, id, args + 2);
unsigned int userdb_id;
/* <userdb id> [<args>] */
- userdb_id = atoi(args[0]);
+ if (str_to_uint(args[0], &userdb_id) < 0) {
+ i_error("BUG: Auth worker server sent us invalid USER");
+ return FALSE;
+ }
auth_request = worker_auth_request_new(client, id, args + 1);
if (auth_request->user == NULL || auth_request->service == NULL) {
{
struct auth_worker_list_context *ctx;
struct auth_userdb *userdb;
+ unsigned int userdb_id;
+
+ if (str_to_uint(args[0], &userdb_id) < 0) {
+ i_error("BUG: Auth worker server sent us invalid LIST");
+ return FALSE;
+ }
- userdb = auth_userdb_find_by_id(client->auth->userdbs, atoi(args[0]));
+ userdb = auth_userdb_find_by_id(client->auth->userdbs, userdb_id);
if (userdb == NULL) {
i_error("BUG: LIST had invalid userdb ID");
return FALSE;
bool ret = FALSE;
args = t_strsplit(line, "\t");
- if (args[0] == NULL || args[1] == NULL || args[2] == NULL) {
+ if (args[0] == NULL || args[1] == NULL || args[2] == NULL ||
+ str_to_uint(args[0], &id) < 0) {
i_error("BUG: Invalid input: %s", line);
return FALSE;
}
- id = (unsigned int)strtoul(args[0], NULL, 10);
if (strcmp(args[1], "PASSV") == 0)
ret = auth_worker_handle_passv(client, id, args + 2);
else if (strcmp(args[1], "PASSL") == 0)
return;
if (strncmp(line, "VERSION\tauth-worker\t", 20) != 0 ||
- atoi(t_strcut(line + 20, '\t')) !=
- AUTH_WORKER_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(t_strcut(line + 20, '\t'),
+ AUTH_WORKER_PROTOCOL_MAJOR_VERSION)) {
i_error("Auth worker not compatible with this server "
"(mixed old and new binaries?)");
auth_worker_client_destroy(&client);
}
id_str = line;
line = strchr(line, '\t');
- if (line == NULL)
+ if (line == NULL ||
+ str_to_uint(t_strdup_until(id_str, line), &id) < 0)
continue;
- id = (unsigned int)strtoul(t_strcut(id_str, '\t'),
- NULL, 10);
if (conn->request != NULL && id == conn->request->id) {
auth_worker_request_handle(conn, conn->request,
line + 1);
return FALSE;
}
- request->maxbuf = strtoul(value, NULL, 10);
- if (request->maxbuf == 0) {
+ if (str_to_ulong(value, &request->maxbuf) < 0 ||
+ request->maxbuf == 0) {
*error = "Invalid maxbuf value";
return FALSE;
}
/* for backwards compatibility */
module->service_name = "%Ls";
} else if (strncmp(t_args[i], "max_requests=", 13) == 0) {
- module->requests_left = atoi(t_args[i] + 13);
+ if (str_to_uint(t_args[i] + 13,
+ &module->requests_left) < 0) {
+ i_error("pam: Invalid requests_left value: %s",
+ t_args[i] + 13);
+ }
} else if (t_args[i+1] == NULL) {
module->service_name = p_strdup(pool, t_args[i]);
} else {
- i_fatal("passdb pam: Unknown setting: %s", t_args[i]);
+ i_fatal("pam: Unknown setting: %s", t_args[i]);
}
}
return &module->module;
{
struct passwd *pw;
uid_t uid;
- char *p;
if (str == NULL)
return (uid_t)-1;
- if (*str >= '0' && *str <= '9') {
- uid = (uid_t)strtoul(str, &p, 10);
- if (*p == '\0')
- return uid;
- }
+ if (str_to_uid(str, &uid) == 0)
+ return uid;
pw = getpwnam(str);
if (pw == NULL) {
{
struct group *gr;
gid_t gid;
- char *p;
if (str == NULL)
return (gid_t)-1;
- if (*str >= '0' && *str <= '9') {
- gid = (gid_t)strtoul(str, &p, 10);
- if (*p == '\0')
- return gid;
- }
+ if (str_to_gid(str, &gid) == 0)
+ return gid;
gr = getgrnam(str);
if (gr == NULL) {
return;
if (strncmp(line, "VERSION\tconfig\t", 15) != 0 ||
- atoi(t_strcut(line + 15, '\t')) !=
- CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(t_strcut(line + 15, '\t'),
+ CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION)) {
i_error("Config client not compatible with this server "
"(mixed old and new binaries?)");
config_connection_destroy(conn);
{
struct ip_addr *ips;
const char *p;
- unsigned int ip_count;
+ unsigned int ip_count, bits, max_bits;
int ret;
if (net_parse_range(value, ip_r, bits_r) == 0)
}
*host_r = p_strdup(ctx->pool, value);
*ip_r = ips[0];
- if (p != NULL && is_numeric(p, '\0'))
- *bits_r = atoi(p);
+
+ max_bits = IPADDR_IS_V4(&ips[0]) ? 32 : 128;
+ if (p == NULL || str_to_uint(p, &bits) < 0 || bits > max_bits)
+ *bits_r = max_bits;
else
- *bits_r = IPADDR_IS_V4(&ips[0]) ? 32 : 128;
+ *bits_r = bits;
return 0;
}
static int cmd_iterate(struct dict_connection *conn, const char *line)
{
const char *const *args;
+ unsigned int flags;
if (conn->iter_ctx != NULL) {
i_error("dict client: ITERATE: Already iterating");
}
args = t_strsplit(line, "\t");
- if (str_array_length(args) < 2) {
+ if (str_array_length(args) < 2 ||
+ str_to_uint(args[0], &flags) < 0) {
i_error("dict client: ITERATE: broken input");
return -1;
}
/* <flags> <path> */
- conn->iter_ctx = dict_iterate_init_multiple(conn->dict, args+1,
- atoi(args[0]));
+ conn->iter_ctx = dict_iterate_init_multiple(conn->dict, args+1, flags);
o_stream_set_flush_callback(conn->output, cmd_iterate_flush, conn);
cmd_iterate_flush(conn);
struct dict_connection_transaction *trans;
unsigned int id;
- if (!is_numeric(line, '\0')) {
+ if (str_to_uint(line, &id) < 0) {
i_error("dict client: Invalid transaction ID %s", line);
return -1;
}
-
- id = (unsigned int)strtoul(line, NULL, 10);
if (dict_connection_transaction_lookup(conn, id) != NULL) {
i_error("dict client: Transaction ID %u already exists", id);
return -1;
{
unsigned int id;
- if (!is_numeric(line, '\0')) {
+ if (str_to_uint(line, &id) < 0) {
i_error("dict client: Invalid transaction ID %s", line);
return -1;
}
-
- id = (unsigned int)strtoul(line, NULL, 10);
*trans_r = dict_connection_transaction_lookup(conn, id);
if (*trans_r == NULL) {
i_error("dict client: Transaction ID %u doesn't exist", id);
{
struct dict_connection_transaction *trans;
const char *const *args;
- long long arg;
+ long long diff;
/* <id> <key> <diff> */
args = t_strsplit(line, "\t");
- if (str_array_length(args) != 3) {
+ if (str_array_length(args) != 3 ||
+ str_to_llong(args[2], &diff) < 0) {
i_error("dict client: ATOMIC_INC: broken input");
return -1;
}
if (dict_connection_transaction_lookup_parse(conn, args[0], &trans) < 0)
return -1;
- if (*args[2] != '-')
- arg = (long long)strtoull(args[2], NULL, 10);
- else
- arg = -(long long)strtoull(args[2]+1, NULL, 10);
- dict_atomic_inc(trans->ctx, args[1], arg);
+ dict_atomic_inc(trans->ctx, args[1], diff);
return 0;
}
const char *name, const struct imap_arg **args)
{
const char *str;
- unsigned long long num;
+ uint64_t modseq;
if (strcmp(name, "CHANGEDSINCE") == 0) {
- if (!imap_arg_get_atom(*args, &str)) {
+ if (!imap_arg_get_atom(*args, &str) ||
+ str_to_uint64(str, &modseq) < 0) {
client_send_command_error(ctx->cmd,
"Invalid CHANGEDSINCE modseq.");
return FALSE;
}
- num = strtoull(str, NULL, 10);
*args += 1;
- return imap_fetch_add_changed_since(ctx, num);
+ return imap_fetch_add_changed_since(ctx, modseq);
}
if (strcmp(name, "VANISHED") == 0 && ctx->cmd->uid) {
if ((ctx->client->enabled_features &
const struct imap_arg *args)
{
const struct imap_arg *list_args;
- const char *arg1, *arg2;
+ const char *str;
unsigned int count;
if ((ctx->cmd->client->enabled_features &
return FALSE;
}
- if (!imap_arg_get_atom(&args[0], &arg1) ||
- !imap_arg_get_atom(&args[1], &arg2)) {
+ if (!imap_arg_get_atom(&args[0], &str) ||
+ str_to_uint32(str, &ctx->qresync_uid_validity) < 0 ||
+ !imap_arg_get_atom(&args[1], &str) ||
+ str_to_uint64(str, &ctx->qresync_modseq) < 0) {
client_send_command_error(ctx->cmd,
"Invalid QRESYNC parameters");
return FALSE;
}
args += 2;
- ctx->qresync_uid_validity = strtoul(arg1, NULL, 10);
- ctx->qresync_modseq = strtoull(arg2, NULL, 10);
- if (!imap_arg_get_atom(args, &arg1)) {
+ if (!imap_arg_get_atom(args, &str)) {
i_array_init(&ctx->qresync_known_uids, 64);
seq_range_array_add_range(&ctx->qresync_known_uids,
1, (uint32_t)-1);
} else {
i_array_init(&ctx->qresync_known_uids, 64);
- if (imap_seq_set_parse(arg1, &ctx->qresync_known_uids) < 0) {
+ if (imap_seq_set_parse(str, &ctx->qresync_known_uids) < 0) {
client_send_command_error(ctx->cmd,
"Invalid QRESYNC known-uids");
return FALSE;
}
if (strcasecmp(name, "UNCHANGEDSINCE") == 0) {
- ctx->max_modseq = strtoull(value, NULL, 10);
+ if (str_to_uint64(value, &ctx->max_modseq) < 0) {
+ client_send_command_error(ctx->cmd,
+ "Invalid modseq");
+ return FALSE;
+ }
client_enable(ctx->cmd->client,
MAILBOX_FEATURE_CONDSTORE);
} else {
p_array_init(&reply_r->extra_fields, pool, 64);
for (; *fields != NULL; fields++) {
- if (strncmp(*fields, "uid=", 4) == 0)
- reply_r->uid = strtoul(*fields + 4, NULL, 10);
- else if (strncmp(*fields, "gid=", 4) == 0)
- reply_r->gid = strtoul(*fields + 4, NULL, 10);
- else if (strncmp(*fields, "home=", 5) == 0)
+ if (strncmp(*fields, "uid=", 4) == 0) {
+ if (str_to_uid(*fields + 4, &reply_r->uid) < 0)
+ i_error("Invalid uid in reply");
+ } else if (strncmp(*fields, "gid=", 4) == 0) {
+ if (str_to_gid(*fields + 4, &reply_r->gid) < 0)
+ i_error("Invalid gid in reply");
+ } else if (strncmp(*fields, "home=", 5) == 0)
reply_r->home = p_strdup(pool, *fields + 5);
else if (strncmp(*fields, "chroot=", 7) == 0)
reply_r->chroot = p_strdup(pool, *fields + 7);
return -1;
}
- conn->server_pid = (unsigned int)strtoul(args[0], NULL, 10);
+ if (str_to_uint(args[0], &conn->server_pid) < 0) {
+ i_error("BUG: Authentication server sent invalid PID");
+ return -1;
+ }
return 0;
}
i_error("BUG: Authentication server already sent handshake");
return -1;
}
- if (args[0] == NULL) {
+ if (args[0] == NULL ||
+ str_to_uint(args[0], &conn->connect_uid) < 0) {
i_error("BUG: Authentication server sent broken CUID line");
return -1;
}
-
- conn->connect_uid = (unsigned int)strtoul(args[0], NULL, 10);
return 0;
}
struct auth_client_request *request;
unsigned int id;
- if (id_arg == NULL) {
+ if (id_arg == NULL || str_to_uint(id_arg, &id) < 0) {
i_error("BUG: Authentication server input missing ID");
return -1;
}
- id = (unsigned int)strtoul(id_arg, NULL, 10);
request = hash_table_lookup(conn->requests, POINTER_CAST(id));
if (request == NULL) {
/* make sure the major version matches */
if (strncmp(line, "VERSION\t", 8) != 0 ||
- atoi(t_strcut(line + 8, '\t')) !=
- AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(t_strcut(line + 8, '\t'),
+ AUTH_CLIENT_PROTOCOL_MAJOR_VERSION)) {
i_error("Authentication server not compatible with "
"this client (mixed old and new binaries?)");
auth_server_connection_disconnect(conn);
line);
return 0;
}
- id = strtoul(line+2, NULL, 10);
+ if (str_to_uint(line+2, &id) < 0) {
+ i_error("dict-client: Invalid ID");
+ return 0;
+ }
client_dict_finish_transaction(dict, id, ret);
return 0;
}
dkey.size = strlen(key);
if (dict->value_type == DICT_DATA_TYPE_UINT32) {
- uint32_t ivalue = (uint32_t)strtoul(value, NULL, 10);
+ uint32_t ivalue;
+ if (str_to_uint32(value, &ivalue) < 0) {
+ i_error("db: Value not uint32: %s", value);
+ ivalue = 0;
+ }
ddata.data = &ivalue;
ddata.size = sizeof(ivalue);
} else {
/* <id> <userid> [..] */
list = t_strsplit(args, "\t");
- if (list[0] == NULL || list[1] == NULL) {
+ if (list[0] == NULL || list[1] == NULL ||
+ str_to_uint(list[0], &id) < 0) {
i_error("Auth server sent corrupted USER line");
return FALSE;
}
- id = (unsigned int)strtoul(list[0], NULL, 10);
request = master_login_auth_lookup_request(auth, id);
if (request != NULL) {
struct master_login_auth_request *request;
unsigned int id;
- id = (unsigned int)strtoul(args, NULL, 10);
+ if (str_to_uint(args, &id) < 0) {
+ i_error("Auth server sent corrupted NOTFOUND line");
+ return FALSE;
+ }
+
request = master_login_auth_lookup_request(auth, id);
if (request != NULL) {
i_error("Authenticated user not found from userdb");
unsigned int i, id;
args = t_strsplit(args_line, "\t");
- if (args[0] == NULL) {
+ if (args[0] == NULL || str_to_uint(args[0], &id) < 0) {
i_error("Auth server sent broken FAIL line");
return FALSE;
}
error = args[i] + 7;
}
- id = (unsigned int)strtoul(args[0], NULL, 10);
request = master_login_auth_lookup_request(auth, id);
if (request != NULL) {
if (error != NULL)
/* make sure the major version matches */
if (strncmp(line, "VERSION\t", 8) != 0 ||
- atoi(t_strcut(line + 8, '\t')) !=
- AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
+ !str_uint_equals(t_strcut(line + 8, '\t'),
+ AUTH_MASTER_PROTOCOL_MAJOR_VERSION)) {
i_error("Authentication server not compatible with "
"master process (mixed old and new binaries?)");
master_login_auth_disconnect(auth);
bool master_service_parse_option(struct master_service *service,
int opt, const char *arg)
{
- int i;
-
switch (opt) {
case 'c':
service->config_path = arg;
service->flags |= MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS;
break;
case 's':
- if ((i = atoi(arg)) < 0)
+ if (str_to_uint(arg, &service->socket_count) < 0)
i_fatal("Invalid socket count: %s", arg);
- service->socket_count = i;
break;
case 'L':
service->log_directly = TRUE;
/* initialize master_status structure */
value = getenv(MASTER_UID_ENV);
- if (value == NULL)
- i_fatal(MASTER_UID_ENV" not set");
+ if (value == NULL ||
+ str_to_uint(value, &service->master_status.uid) < 0)
+ i_fatal(MASTER_UID_ENV" missing");
service->master_status.pid = getpid();
- service->master_status.uid =
- (unsigned int)strtoul(value, NULL, 10);
/* set the default limit */
value = getenv(MASTER_CLIENT_LIMIT_ENV);
- count = value == NULL ? 0 :
- (unsigned int)strtoul(value, NULL, 10);
- if (count == 0)
- i_fatal(MASTER_CLIENT_LIMIT_ENV" not set");
+ if (value == NULL || str_to_uint(value, &count) < 0 ||
+ count == 0)
+ i_fatal(MASTER_CLIENT_LIMIT_ENV" missing");
master_service_set_client_limit(service, count);
/* set the default service count */
value = getenv(MASTER_SERVICE_COUNT_ENV);
- count = value == NULL ? 0 :
- (unsigned int)strtoul(value, NULL, 10);
- if (count > 0)
+ if (value != NULL && str_to_uint(value, &count) == 0 &&
+ count > 0)
master_service_set_service_count(service, count);
/* start listening errors for status fd, it means master died */
get_uint(struct setting_parser_context *ctx, const char *value,
unsigned int *result_r)
{
- int num;
+ if (str_to_uint(value, result_r) < 0) {
+ ctx->error = p_strdup_printf(ctx->parser_pool,
+ "Invalid number %s: %s", value,
+ str_num_error(value));
+ return -1;
+ }
+ return 0;
+}
- /* use %i so we can handle eg. 0600 as octal value with umasks */
- if (!sscanf(value, "%i", &num) || num < 0) {
+static int
+get_octal(struct setting_parser_context *ctx, const char *value,
+ unsigned int *result_r)
+{
+ unsigned long long octal;
+ char *p;
+
+ if (*value != '0')
+ return get_uint(ctx, value, result_r);
+
+ octal = strtoull(value + 1, &p, 4);
+ if (*p != '\0' || octal > UINT_MAX) {
ctx->error = p_strconcat(ctx->parser_pool, "Invalid number: ",
value, NULL);
- return -1;
}
- *result_r = num;
+ *result_r = (unsigned int)octal;
return 0;
}
return -1;
break;
case SET_UINT:
- case SET_UINT_OCT:
if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
return -1;
break;
+ case SET_UINT_OCT:
+ if (get_octal(ctx, value, (unsigned int *)ptr) < 0)
+ return -1;
+ break;
case SET_TIME:
if (settings_get_time(value, (unsigned int *)ptr, &error) < 0) {
ctx->error = p_strdup(ctx->parser_pool, error);
break;
}
case SQL_TYPE_UINT: {
- if (value != NULL) {
- *((unsigned int *)ptr) =
- strtoul(value, NULL, 10);
- }
+ if (value != NULL &&
+ str_to_uint(value, (unsigned int *)ptr) < 0)
+ i_error("sql: Value not uint: %s", value);
break;
}
case SQL_TYPE_ULLONG: {
- if (value != NULL) {
- *((unsigned long long *)ptr) =
- strtoull(value, NULL, 10);
- }
+ if (value != NULL &&
+ str_to_ullong(value, (unsigned long long *)ptr) < 0)
+ i_error("sql: Value not ullong: %s", value);
break;
}
case SQL_TYPE_BOOL: {
if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX,
strlen(MDBOX_MAIL_FILE_PREFIX)) != 0)
continue;
+ if (str_to_uint32(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
+ &file_id) < 0)
+ continue;
- file_id = strtoul(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
- NULL, 10);
if (min_file_id > file_id)
min_file_id = file_id;
}
i_assert(fname != NULL);
fname += strlen(MDBOX_MAIL_FILE_PREFIX) + 1;
- file_id = strtoul(fname, NULL, 10);
- if (!is_numeric(fname, '\0') || file_id == 0) {
+ if (str_to_uint32(fname, &file_id) < 0 || file_id == 0) {
len = strlen(fname);
if (len > 7 && strcmp(fname + len - 7, ".broken") != 0) {
i_warning("dbox rebuild: File name is missing ID: %s",
if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX,
strlen(MDBOX_MAIL_FILE_PREFIX)) != 0)
continue;
+ if (str_to_uint32(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
+ &file_id) < 0)
+ continue;
str_truncate(path, dir_len);
str_append(path, d->d_name);
- file_id = strtoul(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
- NULL, 10);
-
if (stat(str_c(path), &st) < 0) {
mail_storage_set_critical(storage,
"stat(%s) failed: %m", str_c(path));
{
struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)ctx->box;
struct dbox_file *file;
- unsigned long uid;
- char *p;
+ uint32_t uid;
int ret;
if (strncmp(fname, SDBOX_MAIL_FILE_PREFIX,
return 0;
fname += strlen(SDBOX_MAIL_FILE_PREFIX);
- uid = strtoul(fname, &p, 10);
- if (*p != '\0' || uid == 0 || uid >= (uint32_t)-1) {
+ if (str_to_uint32(fname, &uid) < 0 || uid == 0) {
i_warning("dbox %s: Ignoring invalid filename %s",
ctx->box->path, fname);
return 0;
struct stat st;
char *line, *p, *new_name;
const char **strp;
- int fd, idx;
+ unsigned int idx;
+ int fd;
/* Remember that we rely on uidlist file locking in here. That's why
we rely on stat()'s timestamp and don't bother handling ESTALE
}
*p++ = '\0';
- idx = atoi(line);
- if (idx < 0 || idx >= MAILDIR_MAX_KEYWORDS || *p == '\0') {
+ if (str_to_uint(line, &idx) < 0 ||
+ idx >= MAILDIR_MAX_KEYWORDS || *p == '\0') {
/* shouldn't happen */
continue;
}
struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
enum maildir_uidlist_rec_ext_key key;
const char *path, *fname, *value;
- uoff_t size;
- char *p;
if (_mail->uid != 0) {
if (maildir_mail_get_fname(mbox, _mail, &fname) <= 0)
MAILDIR_UIDLIST_REC_EXT_PSIZE;
value = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
key);
- if (value != NULL) {
- size = strtoull(value, &p, 10);
- if (*p == '\0') {
- *size_r = size;
- return 1;
- }
- }
+ if (value != NULL && str_to_uoff(value, size_r) == 0)
+ return 1;
}
return 0;
}
{
struct mail_search_arg *sarg;
const char *value;
- char *p;
*next_sarg = sarg = search_arg_new(data->pool, type);
if (!arg_get_next(data, args, &value))
return FALSE;
- sarg->value.size = strtoull(value, &p, 10);
- if (*p != '\0') {
+ if (str_to_uoff(value, &sarg->value.size) < 0) {
data->error = "Invalid search size parameter";
return FALSE;
}
{
struct mail_search_arg *sarg;
const char *value;
- unsigned long interval;
- char *p;
+ uint32_t interval;
*next_sarg = sarg = search_arg_new(data->pool, type);
if (!arg_get_next(data, args, &value))
return FALSE;
- interval = strtoul(value, &p, 10);
- if (interval == 0 || *p != '\0') {
+ if (str_to_uint32(value, &interval) < 0 || interval == 0) {
data->error = "Invalid search interval parameter";
return FALSE;
}
if (!arg_get_next(data, args, &value))
return FALSE;
}
- if (!is_numeric(value, '\0')) {
+ if (str_to_uint64(value, &sarg->value.modseq->modseq) < 0) {
data->error = "Invalid MODSEQ value";
return FALSE;
}
- sarg->value.modseq->modseq = strtoull(value, NULL, 10);
return TRUE;
}
static bool parse_uid(const char *str, uid_t *uid_r)
{
struct passwd *pw;
- char *p;
- if (*str >= '0' && *str <= '9') {
- *uid_r = (uid_t)strtoul(str, &p, 10);
- if (*p == '\0')
- return TRUE;
- }
+ if (str_to_uid(str, uid_r) == 0)
+ return TRUE;
pw = getpwnam(str);
if (pw == NULL)
static bool parse_gid(const char *str, gid_t *gid_r)
{
struct group *gr;
- char *p;
- if (*str >= '0' && *str <= '9') {
- *gid_r = (gid_t)strtoul(str, &p, 10);
- if (*p == '\0')
- return TRUE;
- }
+ if (str_to_gid(str, gid_r) == 0)
+ return TRUE;
gr = getgrnam(str);
if (gr == NULL)
if (strcmp(host, my_hostname) != 0)
return -1;
- if (!is_numeric(buf, '\0'))
+ if (str_to_pid(buf, &pid) < 0)
return -1;
- pid = (pid_t)strtoul(buf, NULL, 0);
if (pid <= 0)
return -1;
return pid;
unsigned int *bits_r)
{
const char *p;
- int bits, max_bits;
+ unsigned int bits, max_bits;
p = strchr(network, '/');
if (p != NULL)
bits = max_bits;
} else {
/* get the network mask */
- bits = atoi(p);
- if (bits < 0 || bits > max_bits)
+ if (str_to_uint(p, &bits) < 0 || bits > max_bits)
return -1;
}
*bits_r = bits;
static gid_t get_group_id(const char *name)
{
struct group *group;
+ gid_t gid;
- if (is_numeric(name, '\0'))
- return (gid_t)strtoul(name, NULL, 10);
+ if (str_to_gid(name, &gid) == 0)
+ return gid;
group = getgrnam(name);
if (group == NULL)
restrict_access_init(&set);
- if ((value = getenv("RESTRICT_SETUID")) != NULL)
- set.uid = (uid_t)strtol(value, NULL, 10);
- if ((value = getenv("RESTRICT_SETGID")) != NULL)
- set.gid = (gid_t)strtol(value, NULL, 10);
- if ((value = getenv("RESTRICT_SETGID_PRIV")) != NULL)
- set.privileged_gid = (gid_t)strtol(value, NULL, 10);
- if ((value = getenv("RESTRICT_GID_FIRST")) != NULL)
- set.first_valid_gid = (gid_t)strtol(value, NULL, 10);
- if ((value = getenv("RESTRICT_GID_LAST")) != NULL)
- set.last_valid_gid = (gid_t)strtol(value, NULL, 10);
+ if ((value = getenv("RESTRICT_SETUID")) != NULL) {
+ if (str_to_uid(value, &set.uid) < 0)
+ i_fatal("Invalid uid: %s", value);
+ }
+ if ((value = getenv("RESTRICT_SETGID")) != NULL) {
+ if (str_to_gid(value, &set.gid) < 0)
+ i_fatal("Invalid gid: %s", value);
+ }
+ if ((value = getenv("RESTRICT_SETGID_PRIV")) != NULL) {
+ if (str_to_gid(value, &set.privileged_gid) < 0)
+ i_fatal("Invalid privileged_gid: %s", value);
+ }
+ if ((value = getenv("RESTRICT_GID_FIRST")) != NULL) {
+ if (str_to_gid(value, &set.first_valid_gid) < 0)
+ i_fatal("Invalid first_valid_gid: %s", value);
+ }
+ if ((value = getenv("RESTRICT_GID_LAST")) != NULL) {
+ if (str_to_gid(value, &set.last_valid_gid) < 0)
+ i_fatal("Invalid last_value_gid: %s", value);
+ }
set.extra_groups = null_if_empty(getenv("RESTRICT_SETEXTRAGROUPS"));
set.system_groups_user = null_if_empty(getenv("RESTRICT_USER"));
if (*tmp != NULL)
tmp++;
for (; *tmp != NULL; tmp++) {
- if (strncmp(*tmp, "cache_secs=", 11) == 0)
- backend->cache_secs = atoi(*tmp + 11);
- else {
+ if (strncmp(*tmp, "cache_secs=", 11) == 0) {
+ if (str_to_uint(*tmp + 11, &backend->cache_secs) < 0) {
+ i_error("acl vfile: Invalid cache_secs value: %s",
+ *tmp + 11);
+ return -1;
+ }
+ } else {
i_error("acl vfile: Unknown parameter: %s", *tmp);
return -1;
}
i_fatal("expire: Missing expire time for mailbox '%s'",
rule.pattern);
}
- if (is_numeric(args[0], '\0')) {
+ if (str_is_numeric(args[0], '\0')) {
i_fatal("expire: Missing expire time specifier for mailbox "
"'%s': %s (add e.g. 'days')", rule.pattern, args[0]);
}
fts_backend_squat_set(struct squat_fts_backend *backend, const char *str)
{
const char *const *tmp;
- int len;
+ unsigned int len;
for (tmp = t_strsplit_spaces(str, " "); *tmp != NULL; tmp++) {
if (strncmp(*tmp, "partial=", 8) == 0) {
- len = atoi(*tmp + 8);
- if (len <= 0) {
+ if (str_to_uint(*tmp + 8, &len) < 0 || len == 0) {
i_fatal("fts_squat: Invalid partial len: %s",
*tmp + 8);
}
squat_trie_set_partial_len(backend->trie, len);
} else if (strncmp(*tmp, "full=", 5) == 0) {
- len = atoi(*tmp + 5);
- if (len <= 0) {
+ if (str_to_uint(*tmp + 5, &len) < 0 || len == 0) {
i_fatal("fts_squat: Invalid full len: %s",
*tmp + 5);
}
for (; !IMAP_ARG_IS_EOL(list_args); list_args += 2) {
if (!imap_arg_get_atom(&list_args[0], &name) ||
!imap_arg_get_atom(&list_args[1], &value_str) ||
- !is_numeric(value_str, '\0')) {
+ str_to_uint64(value_str, &value) < 0) {
client_send_command_error(cmd, "Invalid arguments.");
return TRUE;
}
- value = strtoull(value_str, NULL, 10);
if (quota_set_resource(root, name, value, &error) < 0) {
client_send_command_error(cmd, error);
return TRUE;
value = mail_user_plugin_getenv(client->user,
"imap_zlib_compress_level");
- level = value == NULL ? 0 : atoi(value);
- if (level <= 0 || level > 9)
+ if (str_to_uint(value, &level) < 0 ||
+ level <= 0 || level > 9)
level = IMAP_COMPRESS_DEFAULT_LEVEL;
old_input = client->input;
trash = array_append_space(&tuser->trash_boxes);
trash->name = p_strdup(user->pool, name+1);
- trash->priority = atoi(t_strdup_until(line, name));
+ if (str_to_int(t_strdup_until(line, name),
+ &trash->priority) < 0) {
+ i_error("trash: Invalid priority for mailbox '%s'",
+ trash->name);
+ ret = -1;
+ }
if (!trash_find_storage(user, trash)) {
i_error("trash: Namespace not found for mailbox '%s'",
union mail_user_module_context module_ctx;
const struct zlib_handler *save_handler;
- int save_level;
+ unsigned int save_level;
};
const char *zlib_plugin_version = DOVECOT_VERSION;
}
name = mail_user_plugin_getenv(user, "zlib_save_level");
if (name != NULL) {
- zuser->save_level = atoi(name);
- if (zuser->save_level < 1 || zuser->save_level > 9) {
+ if (str_to_uint(name, &zuser->save_level) < 0 ||
+ zuser->save_level < 1 || zuser->save_level > 9) {
i_error("zlib_save_level: Level must be between 1..9");
zuser->save_level = 0;
}