This is the mail archive of the
cygwin-developers@sourceware.cygnus.com
mailing list for the Cygwin project.
ntsec-patch16 (and some other)
- To: Chris Faylor <cgf at cygnus dot com>
- Subject: ntsec-patch16 (and some other)
- From: Corinna Vinschen <corinna at vinschen dot de>
- Date: Sat, 08 Jan 2000 20:03:41 +0100
- CC: cygdev <cygwin-developers at sourceware dot cygnus dot com>
Hello Chris, hello all.
First of all, I have four patches related to the rearrangment of
the sources. Chris, would you please take a special look into
these changes?
- configure: I had to add the directory `mingw/profile'
else it was ignored.
- cygwin/smallprintf.c: I had to add `#define __INSIDE_CYGWIN__'
else the linker said sth. about `undef'd ref to _ctype_'.
- cygwin/regexp/regexp.c: Ditto.
- mingw/profile/configure: This configure script couldn't find
install-sh, because the search paths for $ac_dir didn't reach
back enough in the dir hirarchy. Here I have added the path
`$srcdir/../../..'.
Moreover, I couldn't find any problem with ntsec. What kind of
problem did you find, Chris? Do you have more detailed info?
The next is to correct an error made in an earlier patch:
- My last patch to access() was messy. I forgot to set errno to
EACCES in case of missing permissions and to set EINVAL in case
of incorrect specified flags.
At least, I have made many changes to the ntsec code:
- Defined some constants for better readability:
MAX_SID_LEN instead of using the constant 40.
DONT_INHERIT for no inheritance of permissions.
INHERIT_ONLY for permissions that are only inheritid to child
objects but are not applied to the object itself.
INHERIT_ALL for permissions that are applied to the object and
child objects.
Extended usage of defines instead of constants.
- Eliminated any code that sets special permissions to local
administrators group.
- Usage of /etc/passwd and /etc/group to get info about the users
group membership (including supplementary groups).
This is used when constructing POSIX permission bits.
- Not only ACCESS_ALLOWED_ACEs but also ACCESS_DENIED_ACEs are
resolved when constructing POSIX permission bits.
- When constructing ACLs, only ACCESS_ALLOWED_ACEs are used
so far they are able to reflect the POSIX permissions.
If the rights of the user are less than the rights of
group and the user is member of the group, the superfluous
rights are explicitly denied using an ACCESS_DENIED_ACE.
This is needed because the group allow bits are valid for
the user as well.
The same is done for the combinations user/world and
group/world.
This has one disadvantage because M$ has not well thought-out
their DACL model. Their documentation contains in short the
following:
1. ACCESS_ALLOW_ACEs will be accumulated related to group
memberships.
2. Order of ACEs is important, because system reads them in
sequence, 'til either any needed right is denied or all
needed rights are granted.
3. All ACCESS_DENIED_ACEs _should_ precede any ACCESS_ALLOWED_ACE.
Notice, that the last rule is a preference, not the law.
The system will correctly deal with the ACEs regardless of
the sequence order. Unfortunately, the security tab of the
NT4 explorer is completely unable to deal with ACCESS_DENIED_ACEs
while the explorer of W2K forces the sort order before you can take
a look on them. If you then press cancel, the old sort order
remains unchanged (thank God).
Why is this sort method not thought-out? It's because it is
unable to reflect each possible situation of a POSIX permission.
The special case is, when the group has less permissions than
the user _and_ less permissions than others. Let's make an
example:
rw-r-xrw-
UserAllow: 110
GroupAllow: 101
OthersAllow: 110
Because of the accumulation of allow rights, user may execute, too,
because the group may execute.
Next try:
UserDeny: 001
GroupAllow: 101
OthersAllow: 110
Now the user may read and write but not execute. Unfortunately, the
group may write because others may write.
Next try, according to M$ rules:
UserDeny: 001
GroupDeny: 010
GroupAllow: 001
OthersAllow: 110
Now the group may not write, but unfortunately the user may not write
anymore, too. How should this problem be solved? According to the M$
rules a UserAllow has to follow the GroupDeny but it's easy to see,
that this never could solve the problem, because the GroupDeny is
harder.
So, the only chance to solve this is:
UserDeny: 001
UserAllow: 010
GroupDeny: 010
GroupAllow: 001
OthersAllow: 110
As I mentioned earlier this works for both, NT4 and W2K, but the GUI
and M$ tools are not able to deal with it.
Only in this (unusual) case, ntsec sets the ACEs in the above manner.
Of course, if this should be more a burden than a help, it could be
solved in another way (slightly incorrect for POSIX rules but in
conformance to M$).
- For more dealing with ACLs I have (nearly completely) implemented
the acl API that is used by newer versions of Solaris. The new
data structure for a single ACL entry (ACE in Win32 terminology)
is defined as:
typedef struct acl {
int a_type; /* entry type */
uid_t a_id; /* UID | GID */
mode_t a_perm; /* permissions */
} aclent_t;
The new API calls are
acl(2), facl(2),
aclcheck(3),
aclsort(3),
acltomode(3), aclfrommode(3),
acltopbits(3), aclfrompbits(3),
acltotext(3), aclfromtext(3)
- Like in Solaris, Cygwin has two new commands for working with
ACLs on the command line: getfacl(1) and setfacl(1). They are
implemented in the winsup/utils directory.
- Online man pages for the aforementioned commands and API calls can
be found on eg. docs.sun.com.
- Not fully implemented is the CLASS_OBJ or MASK acl entry. I haven't
found a way to implement it in the NT security model.
- The a_perm member of the aclent_t type contains only the bits for
read, write and execute as in the file mode. If eg. read permission
is granted, all read bits (S_IRUSR, S_IRGRP, S_IROTH) are set.
A point of discussion is the following:
! Should the a_perm element contain POSIX compliant permissions as
! today or should it filled according to NT permission bits to
! reflect the possibilities of the guest os as good as possible???
Best Regards,
Corinna
ChangeLog:
==========
Sat Jan 8 20:00:00 2000 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Added new acl API calls.
* grp.cc (getgroups): Changed to work for any username.
* smallprintf.c: Added define for __INSIDE_CYGWIN__
* regexp/regexp.c: Ditto.
* security.cc (get_id_from_sid): Changed to work with acl API.
(is_grp_member): New function.
(get_nt_attribute): Rewritten.
(add_access_allowed_ace): New function.
(add_access_denied_ace): Ditto.
(alloc_sd): Rewritten.
(setacl): New function.
(getace): Ditto.
(searchace): Ditto.
(getacl): Ditto.
(acl): Ditto.
(facl): Ditto.
(aclcheck): Ditto.
(acecmp): Ditto.
(aclsort): Ditto.
(acltomode): Ditto.
(aclfrommode): Ditto.
(acltopbits): Ditto.
(aclfrompbits): Ditto.
(permtostr): Ditto.
(acltotext): Ditto.
(permfromstr): Ditto.
(aclfromtext): Ditto.
* syscalls.cc (access): Sets errno again when needed.
* include/cygwin/acl.h: New file.
* include/sys/acl.h: Ditto.
* utils/Makefile.in: Added getfacl.exe and setfacl.exe to
list of PROGS.
* utils/getfacl.c: New file.
* utils/setfacl.c: New file.
CV-patch.gz