summaryrefslogtreecommitdiff
path: root/libmisc
diff options
context:
space:
mode:
authorBalint Reczey <balint@balintreczey.hu>2022-11-10 16:24:06 +0100
committerBalint Reczey <balint@balintreczey.hu>2022-11-10 16:24:06 +0100
commit3987cc788047570ecf10707dfc8958780d85c73c (patch)
tree109724175f07436696f51b14b5abbd3f4d704d6d /libmisc
parent8ead740677d19e48690d4f144ab090b83d47059f (diff)
downloadshadow-3987cc788047570ecf10707dfc8958780d85c73c.tar.gz
New upstream version 4.13+dfsg1upstream/4.13+dfsg1upstream
Diffstat (limited to 'libmisc')
-rw-r--r--libmisc/chkname.c38
-rw-r--r--libmisc/copydir.c35
-rw-r--r--libmisc/find_new_gid.c7
-rw-r--r--libmisc/find_new_uid.c7
-rw-r--r--libmisc/utmp.c1
-rw-r--r--libmisc/xmalloc.c7
6 files changed, 57 insertions, 38 deletions
diff --git a/libmisc/chkname.c b/libmisc/chkname.c
index cb002a14..e31ee8c9 100644
--- a/libmisc/chkname.c
+++ b/libmisc/chkname.c
@@ -32,26 +32,44 @@ static bool is_valid_name (const char *name)
}
/*
- * User/group names must match [a-z_][a-z0-9_-]*[$]
- */
+ * User/group names must match gnu e-regex:
+ * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]?
+ *
+ * as a non-POSIX, extension, allow "$" as the last char for
+ * sake of Samba 3.x "add machine script"
+ *
+ * Also do not allow fully numeric names or just "." or "..".
+ */
+ int numeric;
- if (('\0' == *name) ||
- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
+ if ('\0' == *name ||
+ ('.' == *name && (('.' == name[1] && '\0' == name[2]) ||
+ '\0' == name[1])) ||
+ !((*name >= 'a' && *name <= 'z') ||
+ (*name >= 'A' && *name <= 'Z') ||
+ (*name >= '0' && *name <= '9') ||
+ *name == '_' ||
+ *name == '.')) {
return false;
}
+ numeric = isdigit(*name);
+
while ('\0' != *++name) {
- if (!(( ('a' <= *name) && ('z' >= *name) ) ||
- ( ('0' <= *name) && ('9' >= *name) ) ||
- ('_' == *name) ||
- ('-' == *name) ||
- ( ('$' == *name) && ('\0' == *(name + 1)) )
+ if (!((*name >= 'a' && *name <= 'z') ||
+ (*name >= 'A' && *name <= 'Z') ||
+ (*name >= '0' && *name <= '9') ||
+ *name == '_' ||
+ *name == '.' ||
+ *name == '-' ||
+ (*name == '$' && name[1] == '\0')
)) {
return false;
}
+ numeric &= isdigit(*name);
}
- return true;
+ return !numeric;
}
bool is_valid_user_name (const char *name)
diff --git a/libmisc/copydir.c b/libmisc/copydir.c
index 5605f6fe..b692aa95 100644
--- a/libmisc/copydir.c
+++ b/libmisc/copydir.c
@@ -126,12 +126,12 @@ static int perm_copy_path(const struct path_info *src,
{
int src_fd, dst_fd, ret;
- src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+ src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
- dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+ dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
@@ -152,12 +152,12 @@ static int attr_copy_path(const struct path_info *src,
{
int src_fd, dst_fd, ret;
- src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+ src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
- dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+ dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
@@ -354,12 +354,8 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
old_uid, new_uid,
old_gid, new_gid);
}
- if (NULL != src_name) {
- free (src_name);
- }
- if (NULL != dst_name) {
- free (dst_name);
- }
+ free (src_name);
+ free (dst_name);
}
}
(void) closedir (dir);
@@ -522,15 +518,14 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
return -1;
}
#endif /* WITH_SELINUX */
- if ( (mkdirat (dst->dirfd, dst->name, statp->st_mode) != 0)
+ if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
+ || (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_path (src, dst, &ctx) != 0)
&& (errno != 0))
-#else /* !WITH_ACL */
- || (chmod (dst, statp->st_mode) != 0)
-#endif /* !WITH_ACL */
+#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
@@ -719,12 +714,11 @@ static int copy_special (const struct path_info *src, const struct path_info *ds
if ( (mknodat (dst->dirfd, dst->name, statp->st_mode & ~07777U, statp->st_rdev) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
+ || (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_path (src, dst, &ctx) != 0)
&& (errno != 0))
-#else /* !WITH_ACL */
- || (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
-#endif /* !WITH_ACL */
+#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
@@ -810,16 +804,15 @@ static int copy_file (const struct path_info *src, const struct path_info *dst,
return -1;
}
#endif /* WITH_SELINUX */
- ofd = openat (dst->dirfd, dst->name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, statp->st_mode & 07777);
+ ofd = openat (dst->dirfd, dst->name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, 0600);
if ( (ofd < 0)
|| (fchown_if_needed (ofd, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
+ || (fchmod (ofd, statp->st_mode & 07777) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0)
&& (errno != 0))
-#else /* !WITH_ACL */
- || (fchmod (ofd, statp->st_mode & 07777) != 0)
-#endif /* !WITH_ACL */
+#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
diff --git a/libmisc/find_new_gid.c b/libmisc/find_new_gid.c
index 666b6107..65ab5d01 100644
--- a/libmisc/find_new_gid.c
+++ b/libmisc/find_new_gid.c
@@ -60,6 +60,13 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
(unsigned long) *max_id);
return EINVAL;
}
+ /*
+ * Zero is reserved for root and the allocation algorithm does not
+ * work right with it.
+ */
+ if (*min_id == 0) {
+ *min_id = (gid_t) 1;
+ }
} else {
/* Non-system groups */
diff --git a/libmisc/find_new_uid.c b/libmisc/find_new_uid.c
index 322d15ab..5f7e74b5 100644
--- a/libmisc/find_new_uid.c
+++ b/libmisc/find_new_uid.c
@@ -60,6 +60,13 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
(unsigned long) *max_id);
return EINVAL;
}
+ /*
+ * Zero is reserved for root and the allocation algorithm does not
+ * work right with it.
+ */
+ if (*min_id == 0) {
+ *min_id = (uid_t) 1;
+ }
} else {
/* Non-system users */
diff --git a/libmisc/utmp.c b/libmisc/utmp.c
index d2b65ac7..45b479f1 100644
--- a/libmisc/utmp.c
+++ b/libmisc/utmp.c
@@ -19,6 +19,7 @@
#endif
#include <assert.h>
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
diff --git a/libmisc/xmalloc.c b/libmisc/xmalloc.c
index 25b136a4..056d472f 100644
--- a/libmisc/xmalloc.c
+++ b/libmisc/xmalloc.c
@@ -44,10 +44,3 @@
{
return strcpy (xmalloc (strlen (str) + 1), str);
}
-
-void xfree(void *ap)
-{
- if (ap) {
- free(ap);
- }
-}