По иронии судьбы, сегодня я столкнулся с той же самой необходимостью.
В моем случае ответ сводился к тому, какой уровень детализации разрешений мне нужен в Windows по сравнению с Linux. В моем случае, я забочусь только о правах пользователя, группы и других в Linux. В Windows для меня достаточно базового разрешения на чтение / запись всех из DOS, т. Е. Мне не нужно иметь дело с ACL в Windows.
Вообще говоря, в Windows есть две модели привилегий: базовая модель DOS и более новая модель контроля доступа. В модели DOS есть один тип привилегий: право на запись. Все файлы могут быть прочитаны, поэтому нет возможности отключить разрешение на чтение (потому что оно не существует). Также нет концепции разрешения на выполнение. Если файл может быть прочитан (ответ - да), и он является двоичным, то он может быть выполнен; в противном случае это невозможно.
Базовая модель DOS достаточна для большинства сред Windows, т. Е. Сред, в которых система используется одним пользователем в физическом месте, которое можно считать относительно безопасным. Модель контроля доступа более сложна на несколько порядков.
Модель контроля доступа использует списки контроля доступа (ACL) для предоставления привилегий. Привилегии могут быть предоставлены только процессом с необходимыми привилегиями. Эта модель не только позволяет управлять пользователями, группами и другими с разрешениями «Чтение», «Запись» и «Выполнять», но также позволяет управлять файлами по сети и между доменами Windows. (Вы также можете получить этот уровень безумия в системах Unix с PAM.)
Примечание. Модель контроля доступа доступна только для разделов NTFS, если вы используете разделы FAT, то вы SOL.
Использование ACL - большая боль в заднице. Это не тривиальное мероприятие, и вам потребуется изучить не только ACL, но и все о дескрипторах безопасности, токенах доступа и множестве других передовых концепций безопасности Windows.
К счастью для меня, для моих текущих потребностей мне не нужна настоящая безопасность, которую обеспечивает модель контроля доступа. Я могу обойтись, в основном, притворяясь, что устанавливаю разрешения в Windows, если я действительно устанавливаю разрешения в Linux.
Windows поддерживает то, что они называют «совместимой с ISO C ++» версией chmod (2). Этот API называется _chmod, и он похож на chmod (2), но более ограничен и не совместим с типом или именем (конечно). В Windows также есть устаревший chmod, поэтому вы не можете просто добавить chmod в Windows и использовать прямой chmod (2) в Linux.
Я написал следующее:
#include <sys/stat.h>
#include <sys/types.h>
#ifdef _WIN32
# include <io.h>
typedef int mode_t;
/// @Note If STRICT_UGO_PERMISSIONS is not defined, then setting Read for any
/// of User, Group, or Other will set Read for User and setting Write
/// will set Write for User. Otherwise, Read and Write for Group and
/// Other are ignored.
///
/// @Note For the POSIX modes that do not have a Windows equivalent, the modes
/// defined here use the POSIX values left shifted 16 bits.
static const mode_t S_ISUID = 0x08000000; ///< does nothing
static const mode_t S_ISGID = 0x04000000; ///< does nothing
static const mode_t S_ISVTX = 0x02000000; ///< does nothing
static const mode_t S_IRUSR = mode_t(_S_IREAD); ///< read by user
static const mode_t S_IWUSR = mode_t(_S_IWRITE); ///< write by user
static const mode_t S_IXUSR = 0x00400000; ///< does nothing
# ifndef STRICT_UGO_PERMISSIONS
static const mode_t S_IRGRP = mode_t(_S_IREAD); ///< read by *USER*
static const mode_t S_IWGRP = mode_t(_S_IWRITE); ///< write by *USER*
static const mode_t S_IXGRP = 0x00080000; ///< does nothing
static const mode_t S_IROTH = mode_t(_S_IREAD); ///< read by *USER*
static const mode_t S_IWOTH = mode_t(_S_IWRITE); ///< write by *USER*
static const mode_t S_IXOTH = 0x00010000; ///< does nothing
# else
static const mode_t S_IRGRP = 0x00200000; ///< does nothing
static const mode_t S_IWGRP = 0x00100000; ///< does nothing
static const mode_t S_IXGRP = 0x00080000; ///< does nothing
static const mode_t S_IROTH = 0x00040000; ///< does nothing
static const mode_t S_IWOTH = 0x00020000; ///< does nothing
static const mode_t S_IXOTH = 0x00010000; ///< does nothing
# endif
static const mode_t MS_MODE_MASK = 0x0000ffff; ///< low word
static inline int my_chmod(const char * path, mode_t mode)
{
int result = _chmod(path, (mode & MS_MODE_MASK));
if (result != 0)
{
result = errno;
}
return (result);
}
#else
static inline int my_chmod(const char * path, mode_t mode)
{
int result = chmod(path, mode);
if (result != 0)
{
result = errno;
}
return (result);
}
#endif
Важно помнить, что мое решение обеспечивает только безопасность типа DOS. Это также называется отсутствием безопасности, но это уровень безопасности, который дает большинство приложений в Windows.
Кроме того, в соответствии с моим решением, если вы не определите STRICT_UGO_PERMISSIONS, когда вы даете разрешение группе или другому лицу (или удаляете его в этом отношении), вы действительно меняете владельца. Если вы не хотели этого делать, но вам по-прежнему не нужны полные разрешения Windows ACL, просто определите STRICT_UGO_PERMISSIONS.