return false;
}
+int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range) {
+ uid_t uid_base, uid_shift, uid_range;
+ int r;
+
+ assert(f);
+ assert(ret_base);
+ assert(ret_shift);
+ assert(ret_range);
+
+ errno = 0;
+ r = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
+ if (r == EOF)
+ return errno_or_else(ENOMSG);
+ assert(r >= 0);
+ if (r != 3)
+ return -EBADMSG;
+
+ *ret_base = uid_base;
+ *ret_shift = uid_shift;
+ *ret_range = uid_range;
+
+ return 0;
+}
+
int uid_range_load_userns(UidRange **ret, const char *path) {
_cleanup_(uid_range_freep) UidRange *range = NULL;
_cleanup_fclose_ FILE *f = NULL;
for (;;) {
uid_t uid_base, uid_shift, uid_range;
- int k;
-
- errno = 0;
- k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
- if (k == EOF) {
- if (ferror(f))
- return errno_or_else(EIO);
+ r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
+ if (r == -ENOMSG)
break;
- }
- if (k != 3)
- return -EBADMSG;
+ if (r < 0)
+ return r;
r = uid_range_add_internal(&range, uid_base, uid_range, /* coalesce = */ false);
if (r < 0)
return uid_range_covers(range, uid, 1);
}
+int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range);
+
int uid_range_load_userns(UidRange **ret, const char *path);
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "uid-range.h"
#include "virt.h"
enum {
static int userns_has_mapping(const char *name) {
_cleanup_fclose_ FILE *f = NULL;
- uid_t a, b, c;
+ uid_t base, shift, range;
int r;
f = fopen(name, "re");
return errno == ENOENT ? false : -errno;
}
- errno = 0;
- r = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &a, &b, &c);
- if (r == EOF) {
- if (ferror(f))
- return log_debug_errno(errno_or_else(EIO), "Failed to read %s: %m", name);
-
- log_debug("%s is empty, we're in an uninitialized user namespace", name);
+ r = uid_map_read_one(f, &base, &shift, &range);
+ if (r == -ENOMSG) {
+ log_debug("%s is empty, we're in an uninitialized user namespace.", name);
return true;
}
- if (r != 3)
- return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse %s: %m", name);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to read %s: %m", name);
- if (a == 0 && b == 0 && c == UINT32_MAX) {
+ if (base == 0 && shift == 0 && range == UINT32_MAX) {
/* The kernel calls mappings_overlap() and does not allow overlaps */
log_debug("%s has a full 1:1 mapping", name);
return false;
}
/* Anything else implies that we are in a user namespace */
- log_debug("Mapping found in %s, we're in a user namespace", name);
+ log_debug("Mapping found in %s, we're in a user namespace.", name);
return true;
}
#include "string-table.h"
#include "terminal-util.h"
#include "tmpfile-util.h"
+#include "uid-range.h"
#include "unit-name.h"
#include "user-util.h"
}
/* Read the first line. There's at least one. */
- errno = 0;
- k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
- if (k != 3) {
- if (ferror(f))
- return errno_or_else(EIO);
-
- return -EBADMSG;
- }
+ r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
+ if (r < 0)
+ return r;
/* Not a mapping starting at 0? Then it's a complex mapping we can't expose here. */
if (uid_base != 0)
_cleanup_fclose_ FILE *f = NULL;
const char *p;
+ int r;
/* This is a generic implementation for both uids and gids, under the assumptions they have the same types and semantics. */
assert_cc(sizeof(uid_t) == sizeof(gid_t));
for (;;) {
uid_t uid_base, uid_shift, uid_range, converted;
- int k;
- errno = 0;
- k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
- if (k < 0 && feof(f))
+ r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
+ if (r == -ENOMSG)
break;
- if (k != 3) {
- if (ferror(f))
- return errno_or_else(EIO);
-
- return -EIO;
- }
+ if (r < 0)
+ return r;
/* The private user namespace is disabled, ignoring. */
if (uid_shift == 0)
_cleanup_fclose_ FILE *f = NULL;
const char *p;
+ int r;
/* This is a generic implementation for both uids and gids, under the assumptions they have the same types and semantics. */
assert_cc(sizeof(uid_t) == sizeof(gid_t));
for (;;) {
uid_t uid_base, uid_shift, uid_range, converted;
- int k;
- errno = 0;
- k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
- if (k < 0 && feof(f))
+ r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
+ if (r == -ENOMSG)
break;
- if (k != 3) {
- if (ferror(f))
- return errno_or_else(EIO);
-
- return -EIO;
- }
+ if (r < 0)
+ return r;
if (uid < uid_base || uid >= uid_base + uid_range)
continue;
if (ret_host_uid)
*ret_host_uid = converted;
+
return 0;
}