* 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:
parent
9b26525ec3
commit
2d647173bb
|
@ -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.
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue