* fhandler_disk_file.cc (fhandler_disk_file::fchown): Catch an

error when changing the user account on a standalone Samba server.
	Explain why.
	* sec_acl.cc (setacl): Accommodate additional parameter to set_file_sd.
	* sec_helper.cc (SECURITY_SAMBA_UNIX_AUTHORITY): Define.
	(well_known_samba_unix_user_fake_sid): Define.
	* security.cc (set_file_sd): Take additional parameter if ownership
	should be changed.  Restrict requested permissions accordingly.
	(set_file_attribute): Accommodate additional parameter to set_file_sd.
	* security.h (well_known_samba_unix_user_fake_sid): Declare.
	(set_file_sd): Align declaration to above change.
This commit is contained in:
Corinna Vinschen 2009-04-09 09:19:03 +00:00
parent 9b26525ec3
commit 2d647173bb
6 changed files with 56 additions and 8 deletions

View File

@ -1,3 +1,17 @@
2009-04-09 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::fchown): Catch an
error when changing the user account on a standalone Samba server.
Explain why.
* sec_acl.cc (setacl): Accommodate additional parameter to set_file_sd.
* sec_helper.cc (SECURITY_SAMBA_UNIX_AUTHORITY): Define.
(well_known_samba_unix_user_fake_sid): Define.
* security.cc (set_file_sd): Take additional parameter if ownership
should be changed. Restrict requested permissions accordingly.
(set_file_attribute): Accommodate additional parameter to set_file_sd.
* security.h (well_known_samba_unix_user_fake_sid): Declare.
(set_file_sd): Align declaration to above change.
2009-04-07 Corinna Vinschen <corinna@vinschen.de>
* include/stdint.h (int_least32_t): Define as int.

View File

@ -24,6 +24,7 @@ details. */
#include "ntdll.h"
#include "tls_pbuf.h"
#include "nfs.h"
#include "pwdgrp.h"
#include <winioctl.h>
#define _COMPILING_NEWLIB
@ -870,7 +871,8 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
mode_t attrib = 0;
if (pc.isdir ())
attrib |= S_IFDIR;
int res = get_file_attribute (get_handle (), pc, &attrib, NULL, NULL);
__uid32_t old_uid;
int res = get_file_attribute (get_handle (), pc, &attrib, &old_uid, NULL);
if (!res)
{
/* Typical Windows default ACLs can contain permissions for one
@ -883,6 +885,29 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
if (pc.issymlink ())
attrib = S_IFLNK | STD_RBITS | STD_WBITS;
res = set_file_attribute (get_handle (), pc, uid, gid, attrib);
/* If you're running a Samba server which has no winbidd running, the
uid<->SID mapping is disfunctional. Even trying to chown to your
own account fails since the account used on the server is the UNIX
account which gets used for the standard user mapping. This is a
default mechanism which doesn't know your real Windows SID.
There are two possible error codes in different Samba releases for
this situation, one of them is unfortunately the not very significant
STATUS_ACCESS_DENIED. Instead of relying on the error codes, we're
using the below very simple heuristic. If set_file_attribute failed,
and the original user account was either already unknown, or one of
the standard UNIX accounts, we're faking success. */
if (res == -1 && pc.fs_is_samba ())
{
cygsid sid;
if (old_uid == ILLEGAL_UID
|| (sid.getfrompw (internal_getpwuid (old_uid))
&& EqualPrefixSid (sid, well_known_samba_unix_user_fake_sid)))
{
debug_printf ("Faking chown worked on standalone Samba");
res = 0;
}
}
}
if (oret)
close_fs ();

View File

@ -225,7 +225,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, __aclent32_t *aclbufp,
return -1;
}
debug_printf ("Created SD-Size: %d", sd_ret.size ());
return set_file_sd (handle, pc, sd_ret);
return set_file_sd (handle, pc, sd_ret, false);
}
/* Temporary access denied bits */

View File

@ -67,6 +67,10 @@ MKSID (mandatory_high_integrity_sid, "S-1-16-12288",
SECURITY_MANDATORY_LABEL_AUTHORITY, 1, SECURITY_MANDATORY_HIGH_RID);
MKSID (mandatory_system_integrity_sid, "S-1-16-16384",
SECURITY_MANDATORY_LABEL_AUTHORITY, 1, SECURITY_MANDATORY_SYSTEM_RID);
/* UNIX accounts on a Samba server have the SID prefix "S-1-22-1" */
#define SECURITY_SAMBA_UNIX_AUTHORITY {0,0,0,0,0,22}
MKSID (well_known_samba_unix_user_fake_sid, "S-1-22-1-0",
SECURITY_SAMBA_UNIX_AUTHORITY, 2, 1, 0);
bool
cygpsid::operator== (const char *nsidstr) const

View File

@ -83,7 +83,7 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
}
LONG
set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, bool is_chown)
{
NTSTATUS status = STATUS_SUCCESS;
int retry = 0;
@ -93,7 +93,10 @@ set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
{
if (fh)
{
status = NtSetSecurityObject (fh, ALL_SECURITY_INFORMATION, sd);
status = NtSetSecurityObject (fh,
is_chown ? ALL_SECURITY_INFORMATION
: DACL_SECURITY_INFORMATION,
sd);
if (NT_SUCCESS (status))
{
res = 0;
@ -104,8 +107,7 @@ set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
{
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
status = NtOpenFile (&fh, WRITE_OWNER | WRITE_DAC,
status = NtOpenFile (&fh, (is_chown ? WRITE_OWNER : 0) | WRITE_DAC,
pc.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
@ -712,7 +714,8 @@ set_file_attribute (HANDLE handle, path_conv &pc,
if (!get_file_sd (handle, pc, sd)
&& alloc_sd (pc, uid, gid, attribute, sd))
ret = set_file_sd (handle, pc, sd);
ret = set_file_sd (handle, pc, sd,
uid != ILLEGAL_UID || gid != ILLEGAL_GID);
}
else
ret = 0;

View File

@ -327,6 +327,7 @@ extern cygpsid fake_logon_sid;
extern cygpsid mandatory_medium_integrity_sid;
extern cygpsid mandatory_high_integrity_sid;
extern cygpsid mandatory_system_integrity_sid;
extern cygpsid well_known_samba_unix_user_fake_sid;
bool privilege_luid (const PWCHAR pname, LUID *luid);
@ -345,7 +346,8 @@ int __stdcall set_file_attribute (HANDLE, path_conv &,
__uid32_t, __gid32_t, int);
int __stdcall get_reg_attribute (HKEY hkey, mode_t *, __uid32_t *, __gid32_t *);
LONG __stdcall get_file_sd (HANDLE fh, path_conv &, security_descriptor &sd);
LONG __stdcall set_file_sd (HANDLE fh, path_conv &, security_descriptor &sd);
LONG __stdcall set_file_sd (HANDLE fh, path_conv &, security_descriptor &sd,
bool is_chown);
bool __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
bool __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
int __stdcall check_file_access (path_conv &, int);