aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin/sec
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/sec')
-rw-r--r--winsup/cygwin/sec/acl.cc20
-rw-r--r--winsup/cygwin/sec/posixacl.cc179
2 files changed, 181 insertions, 18 deletions
diff --git a/winsup/cygwin/sec/acl.cc b/winsup/cygwin/sec/acl.cc
index fa4ea4c..129fe9a 100644
--- a/winsup/cygwin/sec/acl.cc
+++ b/winsup/cygwin/sec/acl.cc
@@ -219,10 +219,10 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid,
aclbufp[3].a_type = DEF_USER_OBJ;
aclbufp[3].a_id = ACL_UNDEFINED_ID;
aclbufp[3].a_perm = (attr >> 6) & S_IRWXO;
- aclbufp[4].a_type = GROUP_OBJ;
+ aclbufp[4].a_type = DEF_GROUP_OBJ;
aclbufp[4].a_id = ACL_UNDEFINED_ID;
aclbufp[4].a_perm = (attr >> 3) & S_IRWXO;
- aclbufp[5].a_type = OTHER_OBJ;
+ aclbufp[5].a_type = DEF_OTHER_OBJ;
aclbufp[5].a_id = ACL_UNDEFINED_ID;
aclbufp[5].a_perm = attr & S_IRWXO;
nentries += MIN_ACL_ENTRIES;
@@ -256,7 +256,21 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid,
}
}
if (!aclsid[idx])
- aclsid[idx] = sidfromuid (aclbufp[idx].a_id, &cldap);
+ {
+ struct passwd *pw = internal_getpwuid (aclbufp[idx].a_id, &cldap);
+ if (pw)
+ {
+ /* Don't allow to pass special accounts as USER, only as
+ USER_OBJ, GROUP_OBJ, or GROUP */
+#define BUILTIN "U-BUILTIN\\"
+#define NT_AUTH "U-NT AUTHORITY\\"
+#define NT_SVC "U-NT SERVICE\\"
+ if (strncmp (pw->pw_gecos, BUILTIN, strlen (BUILTIN)) != 0
+ && strncmp (pw->pw_gecos, NT_AUTH, strlen (NT_AUTH)) != 0
+ && strncmp (pw->pw_gecos, NT_SVC, strlen (NT_SVC)) != 0)
+ aclsid[idx] = (PSID) ((pg_pwd *) pw)->sid;
+ }
+ }
break;
case GROUP_OBJ:
aclsid[idx] = group;
diff --git a/winsup/cygwin/sec/posixacl.cc b/winsup/cygwin/sec/posixacl.cc
index 6b01ded..6f3ef15 100644
--- a/winsup/cygwin/sec/posixacl.cc
+++ b/winsup/cygwin/sec/posixacl.cc
@@ -322,7 +322,7 @@ acl_delete_perm (acl_permset_t permset_d, acl_perm_t perm)
}
__except (EINVAL) {}
__endtry
- return -1;
+ return -1;
}
extern "C" int
@@ -674,14 +674,11 @@ fhandler_socket_unix::acl_get (acl_type_t type)
extern "C" acl_t
acl_get_fd (int fd)
{
- cygheap_fdget cfd (fd);
- if (cfd < 0)
- return NULL;
- return cfd->acl_get (ACL_TYPE_ACCESS);
+ return acl_get_fd_np (fd, ACL_TYPE_ACCESS);
}
-extern "C" acl_t
-acl_get_file (const char *path_p, acl_type_t type)
+static acl_t
+__acl_get_file (const char *path_p, acl_type_t type, unsigned follow_mode)
{
if (type != ACL_TYPE_ACCESS && type != ACL_TYPE_DEFAULT)
{
@@ -689,7 +686,7 @@ acl_get_file (const char *path_p, acl_type_t type)
return NULL;
}
fhandler_base *fh;
- if (!(fh = build_fh_name (path_p, PC_SYM_FOLLOW, stat_suffixes)))
+ if (!(fh = build_fh_name (path_p, follow_mode, stat_suffixes)))
return NULL;
if (fh->error ())
{
@@ -701,6 +698,12 @@ acl_get_file (const char *path_p, acl_type_t type)
return acl;
}
+extern "C" acl_t
+acl_get_file (const char *path_p, acl_type_t type)
+{
+ return __acl_get_file (path_p, type, PC_SYM_FOLLOW);
+}
+
int
fhandler_base::acl_set (acl_t acl, acl_type_t type)
{
@@ -844,14 +847,12 @@ fhandler_socket_unix::acl_set (acl_t acl, acl_type_t type)
extern "C" int
acl_set_fd (int fd, acl_t acl)
{
- cygheap_fdget cfd (fd);
- if (cfd < 0)
- return -1;
- return cfd->acl_set (acl, ACL_TYPE_ACCESS);
+ return acl_set_fd_np (fd, acl, ACL_TYPE_ACCESS);
}
-extern "C" int
-acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
+static int
+__acl_set_file (const char *path_p, acl_type_t type, acl_t acl,
+ unsigned follow_mode)
{
if (type != ACL_TYPE_ACCESS && type != ACL_TYPE_DEFAULT)
{
@@ -859,7 +860,7 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
return -1;
}
fhandler_base *fh;
- if (!(fh = build_fh_name (path_p, PC_SYM_FOLLOW, stat_suffixes)))
+ if (!(fh = build_fh_name (path_p, follow_mode, stat_suffixes)))
return -1;
if (fh->error ())
{
@@ -872,6 +873,12 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl)
}
extern "C" int
+acl_set_file (const char *path_p, acl_type_t type, acl_t acl)
+{
+ return __acl_set_file (path_p, type, acl, PC_SYM_FOLLOW);
+}
+
+extern "C" int
acl_delete_def_file (const char *path_p)
{
acl_t acl = (acl_t) alloca (sizeof (struct __acl_t));
@@ -1151,3 +1158,145 @@ acl_to_any_text (acl_t acl, const char *prefix, char separator, int options)
__endtry
return NULL;
}
+
+/* FreeBSD extensions */
+
+extern "C" acl_t
+acl_get_fd_np (int fd, acl_type_t type)
+{
+ cygheap_fdget cfd (fd);
+ if (cfd < 0)
+ return NULL;
+ return cfd->acl_get (type);
+}
+
+extern "C" int
+acl_is_trivial_np (const acl_t acl, int *trivialp)
+{
+ __try
+ {
+ if (!(__aclcheck (acl->entry, acl->count, NULL, true)))
+ *trivialp = acl->count - acl->deleted <= MIN_ACL_ENTRIES ? 1 : 0;
+ return 0;
+ }
+ __except (EINVAL) {}
+ __endtry
+ return -1;
+}
+
+extern "C" acl_t
+acl_get_link_np (const char *path_p, acl_type_t type)
+{
+ return __acl_get_file (path_p, type, PC_SYM_NOFOLLOW);
+}
+
+extern "C" int
+acl_set_fd_np (int fd, acl_t acl, acl_type_t type)
+{
+ if (type != ACL_TYPE_ACCESS && type != ACL_TYPE_DEFAULT)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+ cygheap_fdget cfd (fd);
+ if (cfd < 0)
+ return -1;
+ return cfd->acl_set (acl, type);
+}
+
+extern "C" int
+acl_set_link_np (const char *path_p, acl_type_t type, acl_t acl)
+{
+ return __acl_set_file (path_p, type, acl, PC_SYM_NOFOLLOW);
+}
+
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2001 Chris D. Faulhaber
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+extern "C" acl_t
+acl_strip_np (const acl_t acl, int recalculate_mask)
+{
+ acl_t acl_new, acl_old;
+ acl_entry_t entry, entry_new;
+ acl_tag_t tag;
+ int entry_id, have_mask_entry;
+
+ acl_old = acl_dup (acl);
+ if (acl_old == NULL)
+ return NULL;
+
+ have_mask_entry = 0;
+ acl_new = acl_init (MAX_ACL_ENTRIES);
+ if (acl_new == NULL)
+ {
+ acl_free (acl_old);
+ return NULL;
+ }
+ tag = ACL_UNDEFINED_TAG;
+
+ /* only save the default user/group/other entries */
+ entry_id = ACL_FIRST_ENTRY;
+ while (acl_get_entry (acl_old, entry_id, &entry) == 1)
+ {
+ entry_id = ACL_NEXT_ENTRY;
+
+ if (acl_get_tag_type (entry, &tag) == -1)
+ goto fail;
+
+ switch (tag)
+ {
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_OTHER:
+ if (acl_create_entry (&acl_new, &entry_new) == -1)
+ goto fail;
+ if (acl_copy_entry (entry_new, entry) == -1)
+ goto fail;
+ break;
+ case ACL_MASK:
+ have_mask_entry = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (have_mask_entry && recalculate_mask)
+ {
+ if (acl_calc_mask (&acl_new) == -1)
+ goto fail;
+ }
+
+ return (acl_new);
+
+fail:
+ acl_free (acl_new);
+ acl_free (acl_old);
+
+ return NULL;
+}