Systemd/src/shared/user-record.h

445 lines
18 KiB
C

/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <inttypes.h>
#include <sys/types.h>
#include "sd-id128.h"
#include "json.h"
#include "missing_resource.h"
#include "time-util.h"
/* But some limits on disk sizes: not less than 5M, not more than 5T */
#define USER_DISK_SIZE_MIN (UINT64_C(5)*1024*1024)
#define USER_DISK_SIZE_MAX (UINT64_C(5)*1024*1024*1024*1024)
/* The default disk size to use when nothing else is specified, relative to free disk space */
#define USER_DISK_SIZE_DEFAULT_PERCENT 85
bool uid_is_system(uid_t uid);
bool gid_is_system(gid_t gid);
static inline bool uid_is_dynamic(uid_t uid) {
return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
}
static inline bool gid_is_dynamic(gid_t gid) {
return uid_is_dynamic((uid_t) gid);
}
static inline bool uid_is_container(uid_t uid) {
return CONTAINER_UID_BASE_MIN <= uid && uid <= CONTAINER_UID_BASE_MAX;
}
static inline bool gid_is_container(gid_t gid) {
return uid_is_container((uid_t) gid);
}
typedef struct UGIDAllocationRange {
uid_t system_alloc_uid_min;
uid_t system_uid_max;
gid_t system_alloc_gid_min;
gid_t system_gid_max;
} UGIDAllocationRange;
int read_login_defs(UGIDAllocationRange *ret_defs, const char *path, const char *root);
const UGIDAllocationRange *acquire_ugid_allocation_range(void);
typedef enum UserDisposition {
USER_INTRINSIC, /* root and nobody */
USER_SYSTEM, /* statically allocated users for system services */
USER_DYNAMIC, /* dynamically allocated users for system services */
USER_REGULAR, /* regular (typically human users) */
USER_CONTAINER, /* UID ranges allocated for container uses */
USER_RESERVED, /* Range above 2^31 */
_USER_DISPOSITION_MAX,
_USER_DISPOSITION_INVALID = -1,
} UserDisposition;
typedef enum UserHomeStorage {
USER_CLASSIC,
USER_LUKS,
USER_DIRECTORY, /* A directory, and a .identity file in it, which USER_CLASSIC lacks */
USER_SUBVOLUME,
USER_FSCRYPT,
USER_CIFS,
_USER_STORAGE_MAX,
_USER_STORAGE_INVALID = -1
} UserStorage;
typedef enum UserRecordMask {
/* The various sections an identity record may have, as bit mask */
USER_RECORD_REGULAR = 1U << 0,
USER_RECORD_SECRET = 1U << 1,
USER_RECORD_PRIVILEGED = 1U << 2,
USER_RECORD_PER_MACHINE = 1U << 3,
USER_RECORD_BINDING = 1U << 4,
USER_RECORD_STATUS = 1U << 5,
USER_RECORD_SIGNATURE = 1U << 6,
_USER_RECORD_MASK_MAX = (1U << 7)-1
} UserRecordMask;
typedef enum UserRecordLoadFlags {
/* A set of flags used while loading a user record from JSON data. We leave the lower 6 bits free,
* just as a safety precaution so that we can detect borked conversions between UserRecordMask and
* UserRecordLoadFlags. */
/* What to require */
USER_RECORD_REQUIRE_REGULAR = USER_RECORD_REGULAR << 7,
USER_RECORD_REQUIRE_SECRET = USER_RECORD_SECRET << 7,
USER_RECORD_REQUIRE_PRIVILEGED = USER_RECORD_PRIVILEGED << 7,
USER_RECORD_REQUIRE_PER_MACHINE = USER_RECORD_PER_MACHINE << 7,
USER_RECORD_REQUIRE_BINDING = USER_RECORD_BINDING << 7,
USER_RECORD_REQUIRE_STATUS = USER_RECORD_STATUS << 7,
USER_RECORD_REQUIRE_SIGNATURE = USER_RECORD_SIGNATURE << 7,
/* What to allow */
USER_RECORD_ALLOW_REGULAR = USER_RECORD_REGULAR << 14,
USER_RECORD_ALLOW_SECRET = USER_RECORD_SECRET << 14,
USER_RECORD_ALLOW_PRIVILEGED = USER_RECORD_PRIVILEGED << 14,
USER_RECORD_ALLOW_PER_MACHINE = USER_RECORD_PER_MACHINE << 14,
USER_RECORD_ALLOW_BINDING = USER_RECORD_BINDING << 14,
USER_RECORD_ALLOW_STATUS = USER_RECORD_STATUS << 14,
USER_RECORD_ALLOW_SIGNATURE = USER_RECORD_SIGNATURE << 14,
/* What to strip */
USER_RECORD_STRIP_REGULAR = USER_RECORD_REGULAR << 21,
USER_RECORD_STRIP_SECRET = USER_RECORD_SECRET << 21,
USER_RECORD_STRIP_PRIVILEGED = USER_RECORD_PRIVILEGED << 21,
USER_RECORD_STRIP_PER_MACHINE = USER_RECORD_PER_MACHINE << 21,
USER_RECORD_STRIP_BINDING = USER_RECORD_BINDING << 21,
USER_RECORD_STRIP_STATUS = USER_RECORD_STATUS << 21,
USER_RECORD_STRIP_SIGNATURE = USER_RECORD_SIGNATURE << 21,
/* Some special combinations that deserve explicit names */
USER_RECORD_LOAD_FULL = USER_RECORD_REQUIRE_REGULAR |
USER_RECORD_ALLOW_SECRET |
USER_RECORD_ALLOW_PRIVILEGED |
USER_RECORD_ALLOW_PER_MACHINE |
USER_RECORD_ALLOW_BINDING |
USER_RECORD_ALLOW_STATUS |
USER_RECORD_ALLOW_SIGNATURE,
USER_RECORD_LOAD_REFUSE_SECRET = USER_RECORD_REQUIRE_REGULAR |
USER_RECORD_ALLOW_PRIVILEGED |
USER_RECORD_ALLOW_PER_MACHINE |
USER_RECORD_ALLOW_BINDING |
USER_RECORD_ALLOW_STATUS |
USER_RECORD_ALLOW_SIGNATURE,
USER_RECORD_LOAD_MASK_SECRET = USER_RECORD_REQUIRE_REGULAR |
USER_RECORD_ALLOW_PRIVILEGED |
USER_RECORD_ALLOW_PER_MACHINE |
USER_RECORD_ALLOW_BINDING |
USER_RECORD_ALLOW_STATUS |
USER_RECORD_ALLOW_SIGNATURE |
USER_RECORD_STRIP_SECRET,
USER_RECORD_EXTRACT_SECRET = USER_RECORD_REQUIRE_SECRET |
USER_RECORD_STRIP_REGULAR |
USER_RECORD_STRIP_PRIVILEGED |
USER_RECORD_STRIP_PER_MACHINE |
USER_RECORD_STRIP_BINDING |
USER_RECORD_STRIP_STATUS |
USER_RECORD_STRIP_SIGNATURE,
USER_RECORD_LOAD_SIGNABLE = USER_RECORD_REQUIRE_REGULAR |
USER_RECORD_ALLOW_PRIVILEGED |
USER_RECORD_ALLOW_PER_MACHINE,
USER_RECORD_EXTRACT_SIGNABLE = USER_RECORD_LOAD_SIGNABLE |
USER_RECORD_STRIP_SECRET |
USER_RECORD_STRIP_BINDING |
USER_RECORD_STRIP_STATUS |
USER_RECORD_STRIP_SIGNATURE,
USER_RECORD_LOAD_EMBEDDED = USER_RECORD_REQUIRE_REGULAR |
USER_RECORD_ALLOW_PRIVILEGED |
USER_RECORD_ALLOW_PER_MACHINE |
USER_RECORD_ALLOW_SIGNATURE,
USER_RECORD_EXTRACT_EMBEDDED = USER_RECORD_LOAD_EMBEDDED |
USER_RECORD_STRIP_SECRET |
USER_RECORD_STRIP_BINDING |
USER_RECORD_STRIP_STATUS,
/* Whether to log about loader errors beyond LOG_DEBUG */
USER_RECORD_LOG = 1U << 28,
/* Whether to ignore errors and load what we can */
USER_RECORD_PERMISSIVE = 1U << 29,
} UserRecordLoadFlags;
static inline UserRecordLoadFlags USER_RECORD_REQUIRE(UserRecordMask m) {
assert((m & ~_USER_RECORD_MASK_MAX) == 0);
return m << 7;
}
static inline UserRecordLoadFlags USER_RECORD_ALLOW(UserRecordMask m) {
assert((m & ~_USER_RECORD_MASK_MAX) == 0);
return m << 14;
}
static inline UserRecordLoadFlags USER_RECORD_STRIP(UserRecordMask m) {
assert((m & ~_USER_RECORD_MASK_MAX) == 0);
return m << 21;
}
static inline UserRecordMask USER_RECORD_REQUIRE_MASK(UserRecordLoadFlags f) {
return (f >> 7) & _USER_RECORD_MASK_MAX;
}
static inline UserRecordMask USER_RECORD_ALLOW_MASK(UserRecordLoadFlags f) {
return ((f >> 14) & _USER_RECORD_MASK_MAX) | USER_RECORD_REQUIRE_MASK(f);
}
static inline UserRecordMask USER_RECORD_STRIP_MASK(UserRecordLoadFlags f) {
return (f >> 21) & _USER_RECORD_MASK_MAX;
}
static inline JsonDispatchFlags USER_RECORD_LOAD_FLAGS_TO_JSON_DISPATCH_FLAGS(UserRecordLoadFlags flags) {
return (FLAGS_SET(flags, USER_RECORD_LOG) ? JSON_LOG : 0) |
(FLAGS_SET(flags, USER_RECORD_PERMISSIVE) ? JSON_PERMISSIVE : 0);
}
typedef struct Pkcs11EncryptedKey {
/* The encrypted passphrase, which can be decrypted with the private key indicated below */
void *data;
size_t size;
/* Where to find the private key to decrypt the encrypted passphrase above */
char *uri;
/* What to test the decrypted passphrase against to allow access (classic UNIX password hash). Note
* that the decrypted passphrase is also used for unlocking LUKS and fscrypt, and if the account is
* backed by LUKS or fscrypt the hashed password is only an additional layer of authentication, not
* the only. */
char *hashed_password;
} Pkcs11EncryptedKey;
typedef struct Fido2HmacCredential {
void *id;
size_t size;
} Fido2HmacCredential;
typedef struct Fido2HmacSalt {
/* The FIDO2 Cridential ID to use */
Fido2HmacCredential credential;
/* The FIDO2 salt value */
void *salt;
size_t salt_size;
/* What to test the hashed salt value against, usually UNIX password hash here. */
char *hashed_password;
} Fido2HmacSalt;
typedef struct RecoveryKey {
/* The type of recovery key, must be "modhex64" right now */
char *type;
/* A UNIX password hash of the normalized form of modhex64 */
char *hashed_password;
} RecoveryKey;
typedef struct UserRecord {
/* The following three fields are not part of the JSON record */
unsigned n_ref;
UserRecordMask mask;
bool incomplete; /* incomplete due to security restrictions. */
char *user_name;
char *realm;
char *user_name_and_realm_auto; /* the user_name field concatenated with '@' and the realm, if the latter is defined */
char *real_name;
char *email_address;
char *password_hint;
char *icon_name;
char *location;
UserDisposition disposition;
uint64_t last_change_usec;
uint64_t last_password_change_usec;
char *shell;
mode_t umask;
char **environment;
char *time_zone;
char *preferred_language;
int nice_level;
struct rlimit *rlimits[_RLIMIT_MAX];
int locked; /* prohibit activation in general */
uint64_t not_before_usec; /* prohibit activation before this unix time */
uint64_t not_after_usec; /* prohibit activation after this unix time */
UserStorage storage;
uint64_t disk_size;
uint64_t disk_size_relative; /* Disk size, relative to the free bytes of the medium, normalized to UINT32_MAX = 100% */
char *skeleton_directory;
mode_t access_mode;
uint64_t tasks_max;
uint64_t memory_high;
uint64_t memory_max;
uint64_t cpu_weight;
uint64_t io_weight;
bool nosuid;
bool nodev;
bool noexec;
char **hashed_password;
char **ssh_authorized_keys;
char **password;
char **token_pin;
char *cifs_domain;
char *cifs_user_name;
char *cifs_service;
char *image_path;
char *image_path_auto; /* when none is configured explicitly, this is where we place the implicit image */
char *home_directory;
char *home_directory_auto; /* when none is set explicitly, this is where we place the implicit home directory */
uid_t uid;
gid_t gid;
char **member_of;
char *file_system_type;
sd_id128_t partition_uuid;
sd_id128_t luks_uuid;
sd_id128_t file_system_uuid;
int luks_discard;
int luks_offline_discard;
char *luks_cipher;
char *luks_cipher_mode;
uint64_t luks_volume_key_size;
char *luks_pbkdf_hash_algorithm;
char *luks_pbkdf_type;
uint64_t luks_pbkdf_time_cost_usec;
uint64_t luks_pbkdf_memory_cost;
uint64_t luks_pbkdf_parallel_threads;
uint64_t disk_usage;
uint64_t disk_free;
uint64_t disk_ceiling;
uint64_t disk_floor;
char *state;
char *service;
int signed_locally;
uint64_t good_authentication_counter;
uint64_t bad_authentication_counter;
uint64_t last_good_authentication_usec;
uint64_t last_bad_authentication_usec;
uint64_t ratelimit_begin_usec;
uint64_t ratelimit_count;
uint64_t ratelimit_interval_usec;
uint64_t ratelimit_burst;
int removable;
int enforce_password_policy;
int auto_login;
uint64_t stop_delay_usec; /* How long to leave systemd --user around on log-out */
int kill_processes; /* Whether to kill user processes forcibly on log-out */
/* The following exist mostly so that we can cover the full /etc/shadow set of fields */
uint64_t password_change_min_usec; /* maps to .sp_min */
uint64_t password_change_max_usec; /* maps to .sp_max */
uint64_t password_change_warn_usec; /* maps to .sp_warn */
uint64_t password_change_inactive_usec; /* maps to .sp_inact */
int password_change_now; /* Require a password change immediately on next login (.sp_lstchg = 0) */
char **pkcs11_token_uri;
Pkcs11EncryptedKey *pkcs11_encrypted_key;
size_t n_pkcs11_encrypted_key;
int pkcs11_protected_authentication_path_permitted;
Fido2HmacCredential *fido2_hmac_credential;
size_t n_fido2_hmac_credential;
Fido2HmacSalt *fido2_hmac_salt;
size_t n_fido2_hmac_salt;
int fido2_user_presence_permitted;
char **recovery_key_type;
RecoveryKey *recovery_key;
size_t n_recovery_key;
JsonVariant *json;
} UserRecord;
UserRecord* user_record_new(void);
UserRecord* user_record_ref(UserRecord *h);
UserRecord* user_record_unref(UserRecord *h);
DEFINE_TRIVIAL_CLEANUP_FUNC(UserRecord*, user_record_unref);
int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags flags);
int user_record_build(UserRecord **ret, ...);
const char *user_record_user_name_and_realm(UserRecord *h);
UserStorage user_record_storage(UserRecord *h);
const char *user_record_file_system_type(UserRecord *h);
const char *user_record_skeleton_directory(UserRecord *h);
mode_t user_record_access_mode(UserRecord *h);
const char *user_record_home_directory(UserRecord *h);
const char *user_record_image_path(UserRecord *h);
unsigned long user_record_mount_flags(UserRecord *h);
const char *user_record_cifs_user_name(UserRecord *h);
const char *user_record_shell(UserRecord *h);
const char *user_record_real_name(UserRecord *h);
bool user_record_luks_discard(UserRecord *h);
bool user_record_luks_offline_discard(UserRecord *h);
const char *user_record_luks_cipher(UserRecord *h);
const char *user_record_luks_cipher_mode(UserRecord *h);
uint64_t user_record_luks_volume_key_size(UserRecord *h);
const char* user_record_luks_pbkdf_type(UserRecord *h);
usec_t user_record_luks_pbkdf_time_cost_usec(UserRecord *h);
uint64_t user_record_luks_pbkdf_memory_cost(UserRecord *h);
uint64_t user_record_luks_pbkdf_parallel_threads(UserRecord *h);
const char *user_record_luks_pbkdf_hash_algorithm(UserRecord *h);
gid_t user_record_gid(UserRecord *h);
UserDisposition user_record_disposition(UserRecord *h);
int user_record_removable(UserRecord *h);
usec_t user_record_ratelimit_interval_usec(UserRecord *h);
uint64_t user_record_ratelimit_burst(UserRecord *h);
bool user_record_can_authenticate(UserRecord *h);
int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret);
bool user_record_equal(UserRecord *a, UserRecord *b);
bool user_record_compatible(UserRecord *a, UserRecord *b);
int user_record_compare_last_change(UserRecord *a, UserRecord *b);
usec_t user_record_ratelimit_next_try(UserRecord *h);
int user_record_clone(UserRecord *h, UserRecordLoadFlags flags, UserRecord **ret);
int user_record_masked_equal(UserRecord *a, UserRecord *b, UserRecordMask mask);
int user_record_test_blocked(UserRecord *h);
int user_record_test_password_change_required(UserRecord *h);
/* The following six are user by group-record.c, that's why we export them here */
int json_dispatch_realm(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
int json_dispatch_user_group_list(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
int json_dispatch_user_disposition(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
int per_machine_id_match(JsonVariant *ids, JsonDispatchFlags flags);
int per_machine_hostname_match(JsonVariant *hns, JsonDispatchFlags flags);
int user_group_record_mangle(JsonVariant *v, UserRecordLoadFlags load_flags, JsonVariant **ret_variant, UserRecordMask *ret_mask);
const char* user_storage_to_string(UserStorage t) _const_;
UserStorage user_storage_from_string(const char *s) _pure_;
const char* user_disposition_to_string(UserDisposition t) _const_;
UserDisposition user_disposition_from_string(const char *s) _pure_;