Closed Bug 24461 Opened 20 years ago Closed 20 years ago

Add new function PR_OpenFile that implements the file mode


(NSPR :: NSPR, enhancement, P3)



(Not tracked)



(Reporter: wtc, Assigned: wtc)



The current NSPR function for creating a file, PR_Open,
ignores the 'mode' argument (file mode) on non-Unix
platforms.  In NSPR 4.0, we will add a new function
PR_OpenFile, with the same prototype as PR_Open, that
implements the file mode on non-Unix platforms to the
extent possible.  In particular, file mode will be
implemented using a security descriptor with an
appropriate discretionary access-control list on
Windows NT.

There are some issues with the implementation of file
mode on Windows NT.
1. NT security is only supported in NTFS.
2. On Unix, the actual file mode of the new file is
  the 'mode' argument to PR_Open modified by the caller's
  file mode creation mask (umask) -- bits set in the
  file mode creation mask are cleared in the actual file
  mode.  Windows NT does not have the notion of umask,
  so umask is effectively 0.
3. On Unix, one does not need any access permission to
  read the file mode of a file.  However, on Windows
  NT, one needs the READ_CONTROL access to read the owner,
  primary group, and discretionary access-control list
  of an object.  To emulate the Unix behavior, we will
  need to grant READ_CONTROL access to all users (the
  Everyone group).  It's not clear whether we need to
  do this.
The implementation of PR_OpenFile is checked into

Added file: ntsec.c
Modified files: prio.h, _beos.h, _macos.h, _os2.h,
_unixos.h, _win95.h, _winnt.h, primpl.h, pr/src/Makefile,
prfile.c, pr/src/md/windows/Makefile, ntio.c, ntthread.c,
w95io.c, w95thred.c, ptio.c

Some notes on the implementation:
1. In the pthreads version of NSPR, PR_OpenFile is
  the same as PR_Open.
2. In classic NSPR, each platform needs to define
  _MD_OPEN_FILE.  For Unix, _MD_OPEN_FILE is the
  same as _MD_OPEN.  For WINNT and WIN95 (which can
  also be used on an NT machine), _MD_OPEN_FILE,
  which is different from _MD_OPEN, implements the
  file mode.  On other platforms, I temporarily made
  _MD_OPEN_FILE the same as _MD_OPEN, but each of
  these should be examined to see if file mode can
  be implemented.
3. In the WINNT/WIN95 version of _MD_OPEN_FILE, I do
  not grant the READ_CONTROL access to all users.
  This means a user (other than the owner) who doesn't
  have read access to the file cannot read the owner,
  primary group, and discretionary access-control
  list of the file.
Some notes on my implementation of _MD_OPEN_FILE
for Windows NT (see ntsec.c).

I use NT's security descriptors with appropriate
discretionary access-control lists to implement
file mode.  The security identifiers (SIDs) for
owner, primary group, and the Everyone (all users)
group are looked up during NSPR initialization and
saved in global variables, so that _MD_OPEN_FILE
doesn't have to look them up every time.  When a
new file is created, _MD_OPEN_FILE constructs a
discretionary access-control list with three
access-control entries, one each for owner, primary
group, and Everyone.  The read, write, execute bits
in the specified file mode get mapped to NT's
I discovered that our BeOS code (_MD_open in
bfile.c) calls open() to create a file, passing
the 'mode' argument through, just like Unix.
So we are fine on BeOS.
*** Bug 3986 has been marked as a duplicate of this bug. ***
Other NSPR functions that take a 'mode' argument are
PR_MkDir, PR_OpenSemaphore, and PR_OpenSharedMemory.

We'll need to add a new function PR_CreateDirectory
and let PR_MkDir keep the old behavior of ignoring
'mode' on Windows.

As for PR_OpenSemaphore and PR_OpenSharedMemory, it
should be okay to change their behavior because there
are no users of these two functions that I know of.
I made the following changes to NSPRPUB_RELEASE_4_0_BRANCH:
- I added a new function PR_MakeDir, with the same prototype
  as PR_MkDir, that implements the mode argument.
- I changed the Windows implementation of PR_OpenSemaphore and
  PR_OpenSharedMemory to implement the mode argument.  Note
  that this is a change of behavior and will be documented in
  Bugzilla bug #23641 as backward compatibility issues for
  NSPR 4.0.
I found an extremely useful tool called Check_SD.exe,
which is a sample application in MSDN Library. Check_SD.exe
dumps the NT security information of a file or directory.

I used this tool to look at the security descriptors
corresponding to the standard file and directory access
permissions on Windows NT (as set by the Security
Properties window).  I found that the standard Windows
NT file and directory access permissions do not have
a direct mapping to the Unix file and directory access
permissions.  In the end, I decided to have PR_OpenFile
and PR_MakeDir implement the Unix/Posix file and directory
access permissions.  This means that the files and
directories created by PR_OpenFile or PR_MakeDir may
be shown to have "Special Access" permissions in their
Security Properties window.

One example of the difference between NT and Unix
file security models is the right to delete a file.
In Unix, this is solely controlled by the write
and execute/search permissions on the containing
directory and has nothing to do with the read or
write permission on the file itself.  On NT, this
is usually controlled by the DELETE access right
on the file.  I later found that there is a
FILE_DELETE_CHILD right for directories, apparently
to implement the Unix/Posix model of file deletion

I made the following changes to our NSPR-to-NT access
right mapping table for files and directories:
  works, it's just that Check_SD.exe shows that the
  actual security descriptors on files all have the
  FILE_GENERIC_XXX rights instead of GENERIC_XXX rights.
- I added a separate mapping table for directories because
  the NSPR write permission should map to
  the Unix/Posix model of file deletion right.

/cvsroot/mozilla/nsprpub/pr/src/md/windows/ntio.c, revision
/cvsroot/mozilla/nsprpub/pr/src/md/windows/w95io.c, revision
The values of the individual flags in the "mode" argument should be defined by 
In prio.h, I defined the following access permission macros:
#define PR_IRWXU 00700  /* read, write, execute/search by owner */
#define PR_IRUSR 00400  /* read permission, owner */
#define PR_IWUSR 00200  /* write permission, owner */
#define PR_IXUSR 00100  /* execute/search permission, owner */
#define PR_IRWXG 00070  /* read, write, execute/search by group */
#define PR_IRGRP 00040  /* read permission, group */
#define PR_IWGRP 00020  /* write permission, group */
#define PR_IXGRP 00010  /* execute/search permission, group */
#define PR_IRWXO 00007  /* read, write, execute/search by others */
#define PR_IROTH 00004  /* read permission, others */
#define PR_IWOTH 00002  /* write permission, others */
#define PR_IXOTH 00001  /* execute/search permission, others */

I merely replaced the S_ prefix of the corresponding
Unix macros by PR_.

pripcsem.h and prshm.h need to include prio.h to get the
definition of these macros.

This is checked in on the NSPRPUB_RELEASE_4_0_BRANCH.
/cvsroot/mozilla/nsprpub/pr/include/prio.h, revision
/cvsroot/mozilla/nsprpub/pr/include/pripcsem.h, revision
/cvsroot/mozilla/nsprpub/pr/include/prshm.h, revision
Marked the bug fixed.
Closed: 20 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.