Merge pull request #8058 from keszybz/sysusers-inline
Extend sysusers for package installation scripts
This commit is contained in:
@@ -154,6 +154,70 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conf_files_insert(char ***strv, const char *root, const char *dirs, const char *path) {
|
||||
/* Insert a path into strv, at the place honouring the usual sorting rules:
|
||||
* - we first compare by the basename
|
||||
* - and then we compare by dirname, allowing just one file with the given
|
||||
* basename.
|
||||
* This means that we will
|
||||
* - add a new entry if basename(path) was not on the list,
|
||||
* - do nothing if an entry with higher priority was already present,
|
||||
* - do nothing if our new entry matches the existing entry,
|
||||
* - replace the existing entry if our new entry has higher priority.
|
||||
*/
|
||||
char *t;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < strv_length(*strv); i++) {
|
||||
int c;
|
||||
|
||||
c = base_cmp(*strv + i, &path);
|
||||
if (c == 0) {
|
||||
const char *dir;
|
||||
|
||||
/* Oh, we found our spot and it already contains something. */
|
||||
NULSTR_FOREACH(dir, dirs) {
|
||||
char *p1, *p2;
|
||||
|
||||
p1 = path_startswith((*strv)[i], root);
|
||||
if (p1)
|
||||
/* Skip "/" in dir, because p1 is without "/" too */
|
||||
p1 = path_startswith(p1, dir + 1);
|
||||
if (p1)
|
||||
/* Existing entry with higher priority
|
||||
* or same priority, no need to do anything. */
|
||||
return 0;
|
||||
|
||||
p2 = path_startswith(path, dir);
|
||||
if (p2) {
|
||||
/* Our new entry has higher priority */
|
||||
t = path_join(root, path, NULL);
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
return free_and_replace((*strv)[i], t);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (c > 0)
|
||||
/* Following files have lower priority, let's go insert our
|
||||
* new entry. */
|
||||
break;
|
||||
|
||||
/* … we are not there yet, let's continue */
|
||||
}
|
||||
|
||||
t = path_join(root, path, NULL);
|
||||
if (!t)
|
||||
return log_oom();
|
||||
|
||||
r = strv_insert(strv, i, t);
|
||||
if (r < 0)
|
||||
free(t);
|
||||
return r;
|
||||
}
|
||||
|
||||
int conf_files_list_strv(char ***strv, const char *suffix, const char *root, unsigned flags, const char* const* dirs) {
|
||||
_cleanup_strv_free_ char **copy = NULL;
|
||||
|
||||
|
||||
@@ -28,3 +28,4 @@ enum {
|
||||
int conf_files_list(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dir, ...);
|
||||
int conf_files_list_strv(char ***ret, const char *suffix, const char *root, unsigned flags, const char* const* dirs);
|
||||
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dirs);
|
||||
int conf_files_insert(char ***strv, const char *root, const char *dirs, const char *path);
|
||||
|
||||
+6
-3
@@ -446,7 +446,7 @@ int strv_push_pair(char ***l, char *a, char *b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int strv_push_prepend(char ***l, char *value) {
|
||||
int strv_insert(char ***l, unsigned position, char *value) {
|
||||
char **c;
|
||||
unsigned n, m, i;
|
||||
|
||||
@@ -454,6 +454,7 @@ int strv_push_prepend(char ***l, char *value) {
|
||||
return 0;
|
||||
|
||||
n = strv_length(*l);
|
||||
position = MIN(position, n);
|
||||
|
||||
/* increase and check for overflow */
|
||||
m = n + 2;
|
||||
@@ -464,10 +465,12 @@ int strv_push_prepend(char ***l, char *value) {
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
for (i = 0; i < position; i++)
|
||||
c[i] = (*l)[i];
|
||||
c[position] = value;
|
||||
for (i = position; i < n; i++)
|
||||
c[i+1] = (*l)[i];
|
||||
|
||||
c[0] = value;
|
||||
c[n+1] = NULL;
|
||||
|
||||
free(*l);
|
||||
|
||||
+6
-1
@@ -54,7 +54,12 @@ int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
|
||||
int strv_extend_front(char ***l, const char *value);
|
||||
int strv_push(char ***l, char *value);
|
||||
int strv_push_pair(char ***l, char *a, char *b);
|
||||
int strv_push_prepend(char ***l, char *value);
|
||||
int strv_insert(char ***l, unsigned position, char *value);
|
||||
|
||||
static inline int strv_push_prepend(char ***l, char *value) {
|
||||
return strv_insert(l, 0, value);
|
||||
}
|
||||
|
||||
int strv_consume(char ***l, char *value);
|
||||
int strv_consume_pair(char ***l, char *a, char *b);
|
||||
int strv_consume_prepend(char ***l, char *value);
|
||||
|
||||
@@ -553,18 +553,18 @@ int take_etc_passwd_lock(const char *root) {
|
||||
* awfully racy, and thus we just won't do them. */
|
||||
|
||||
if (root)
|
||||
path = prefix_roota(root, "/etc/.pwd.lock");
|
||||
path = prefix_roota(root, ETC_PASSWD_LOCK_PATH);
|
||||
else
|
||||
path = "/etc/.pwd.lock";
|
||||
path = ETC_PASSWD_LOCK_PATH;
|
||||
|
||||
fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
return log_debug_errno(errno, "Cannot open %s: %m", path);
|
||||
|
||||
r = fcntl(fd, F_SETLKW, &flock);
|
||||
if (r < 0) {
|
||||
safe_close(fd);
|
||||
return -errno;
|
||||
return log_debug_errno(errno, "Locking %s failed: %m", path);
|
||||
}
|
||||
|
||||
return fd;
|
||||
@@ -645,6 +645,8 @@ bool valid_gecos(const char *d) {
|
||||
}
|
||||
|
||||
bool valid_home(const char *p) {
|
||||
/* Note that this function is also called by valid_shell(), any
|
||||
* changes must account for that. */
|
||||
|
||||
if (isempty(p))
|
||||
return false;
|
||||
|
||||
@@ -63,6 +63,8 @@ int take_etc_passwd_lock(const char *root);
|
||||
#define UID_NOBODY ((uid_t) 65534U)
|
||||
#define GID_NOBODY ((gid_t) 65534U)
|
||||
|
||||
#define ETC_PASSWD_LOCK_PATH "/etc/.pwd.lock"
|
||||
|
||||
static inline bool uid_is_dynamic(uid_t uid) {
|
||||
return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
|
||||
}
|
||||
@@ -96,6 +98,15 @@ bool valid_user_group_name_or_id(const char *u);
|
||||
bool valid_gecos(const char *d);
|
||||
bool valid_home(const char *p);
|
||||
|
||||
static inline bool valid_shell(const char *p) {
|
||||
/* We have the same requirements, so just piggy-back on the home check.
|
||||
*
|
||||
* Let's ignore /etc/shells because this is only applicable to real and
|
||||
* not system users. It is also incompatible with the idea of empty /etc.
|
||||
*/
|
||||
return valid_home(p);
|
||||
}
|
||||
|
||||
int maybe_setgroups(size_t size, const gid_t *list);
|
||||
|
||||
bool synthesize_nobody(void);
|
||||
|
||||
Reference in New Issue
Block a user