C ++ - 如何设置文件权限(跨平台) [英] C++ - How to set file permissions (cross platform)

查看:131
本文介绍了C ++ - 如何设置文件权限(跨平台)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用C ++ ofstream 写出一个文件。我想将权限设置为只能由用户访问:700.在unix中;我想我可以发出一个系统(chmod 700 file.txt); ,但我需要这个代码在Windows上工作。我可以使用一些Windows api;但是什么是最好的c ++跨平台的方法来做这个?

解决方案

讽刺的是,我刚刚遇到了同样的需求今天。



在我的例子中,答案是在Windows上需要多少级别的权限粒度,而不是Linux。在我的情况下,我只关心在Linux上的用户,组和其他权限。在Windows上,从DOS的基本的读/写所有权限剩余对我来说是足够好的,即我不需要在Windows上处理ACL。



一般来说, Windows有两个特权模型:基本的DOS模型和较新的访问控制模型。在DOS模式下有一种类型的特权:写特权。所有文件都可以读取,所以没有办法关闭读取权限(因为它不存在)。也没有执行权限的概念。如果一个文件可以读取(答案是肯定的),它是二进制的,那么它可以被执行;



基本的DOS模式足以满足大多数Windows环境,即系统由物理位置中的单个用户使用的环境,认为相对安全。访问控制的模型更复杂几个数量级。



访问控制模型使用访问控制列表(ACL)授予权限。权限只能由具有必要权限的进程授予。此模型不仅允许控制具有读取,写入和执行权限的用户,组和其他,而且还允许通过网络和Windows域之间的文件控制。 (您也可以在具有PAM的Unix系统上获得这种级别的疯狂。)



注意:访问控制模型只能在NTFS分区上使用,使用FAT分区您是SOL。



使用ACL是一个很大的痛苦。这不是一个微不足道的工作,它将要求您不仅学习ACL,而且还了解安全描述符,访问令牌和许多其他高级Windows安全概念。



<对我来说,幸运的是,对于我目前的需要,我不需要访问控制模型提供的真正的安全性。



Windows支持他们所谓的ISO C ++一致性版本,它可以让我基本上假装在Windows上设置权限。的chmod(2)。这个API称为_chmod,它类似于chmod(2),但更受限制,不是类型或名称兼容(当然)。 Windows也有一个已弃用的chmod,所以你不能简单地添加chmod到Windows和使用直线chmod(2)在Linux上。



我写了以下: p>

  #include< sys / stat.h> 
#include< sys / types.h>

#ifdef _WIN32
#include< io.h>

typedef int mode_t;

/// @Note如果未定义STRICT_UGO_PERMISSIONS,则设置为读取任何用户,组或其他的
///将设置为用户读取和设置写
///将设置为用户写入。否则,读取和写入组和
///其他将被忽略。
///
/// @注意对于没有Windows等效的POSIX模式,这里定义的模式
///使用左移16位的POSIX值。

static const mode_t S_ISUID = 0x08000000; ///<什么也不做
static const mode_t S_ISGID = 0x04000000; ///<什么也不做
static const mode_t S_ISVTX = 0x02000000; ///<什么也不做
static const mode_t S_IRUSR = mode_t(_S_IREAD); ///<由用户读取
static const mode_t S_IWUSR = mode_t(_S_IWRITE); ///<由用户写
static const mode_t S_IXUSR = 0x00400000; ///<什么也不做
#ifndef STRICT_UGO_PERMISSIONS
static const mode_t S_IRGRP = mode_t(_S_IREAD); ///<读取* USER *
static const mode_t S_IWGRP = mode_t(_S_IWRITE); ///<写* USER *
static const mode_t S_IXGRP = 0x00080000; ///<什么也不做
static const mode_t S_IROTH = mode_t(_S_IREAD); ///<读取* USER *
static const mode_t S_IWOTH = mode_t(_S_IWRITE); ///<写* by * USER *
static const mode_t S_IXOTH = 0x00010000; ///<什么也不做
#else
static const mode_t S_IRGRP = 0x00200000; ///<什么也不做
static const mode_t S_IWGRP = 0x00100000; ///<什么也不做
static const mode_t S_IXGRP = 0x00080000; ///<什么也不做
static const mode_t S_IROTH = 0x00040000; ///<什么也不做
static const mode_t S_IWOTH = 0x00020000; ///<什么也不做
static const mode_t S_IXOTH = 0x00010000; ///<什么也不做
#endif
static const mode_t MS_MODE_MASK = 0x0000ffff; ///<低字

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(results!= 0)
{
result = errno;
}

return(result);
}
#endif

重要的是记住我的解决方案只提供DOS类型安全。这也被称为无安全性,但它是大多数应用程序给您在Windows上的安全量。



此外,在我的解决方案下,如果你不定义STRICT_UGO_PERMISSIONS,当您授予群组或其他(或删除它)的权限,您确实正在更改所有者。如果你不想这样做,但是你仍然不需要完整的Windows ACL权限,只需定义STRICT_UGO_PERMISSIONS。


I am using C++ ofstream to write out a file. I want to set the permissions to be only accessible by the user: 700. In unix; I suppose I can just issue a system("chmod 700 file.txt"); but I need this code to work on Windows as well. I can use some Windows api; but what is the best c++ cross platform way to do this?

解决方案

Ironically, I have just run into this very same need earlier today.

In my case, the answer came down to what level of permission granularity I need on Windows, versus Linux. In my case, I only care about User, Group, and Other permission on Linux. On Windows, the basic Read/Write All permission leftover from DOS is good enough for me, i.e. I don't need to deal with ACL on Windows.

Generally speaking, Windows has two privilege models: the basic DOS model and the newer access control model. Under the DOS model there is one type of privilege: write privilege. All files can be read, so there is no way to turn off read permission (because it doesn't exist). There is also no concept of execute permission. If a file can be read (answer is yes) and it is binary, then it can be executed; otherwise it can't.

The basic DOS model is sufficient for most Windows environments, i.e. environments where the system is used by a single user in a physical location that can be considered relatively secure. The access control is model more complex by several orders of magnitude.

The access control model uses access control lists (ACL) to grant privileges. Privileges can only be granted by a process with the necessary privileges. This model not only allows the control of User, Group, and Other with Read, Write, and Execute permission, but it also allows control of files over the network and between Windows domains. (You can also get this level of insanity on Unix systems with PAM.)

Note: The Access Control model is only available on NTFS partitions, if you are using FAT partitions you are SOL.

Using ACL is a big pain in the ass. It is not a trivial undertaking and it will require you to learn not just ACL but also all about Security Descriptors, Access Tokens, and a whole lot of other advanced Windows security concepts.

Fortunately for me, for my current needs, I don't need the true security that the access control model provides. I can get by with basically pretending to set permissions on Windows, as long as I really set permissions on Linux.

Windows supports what they call an "ISO C++ conformant" version of chmod(2). This API is called _chmod, and it is similar to chmod(2), but more limited and not type or name compatible (of course). Windows also has a deprecated chmod, so you can't simply add chmod to Windows and use the straight chmod(2) on Linux.

I wrote the following:

#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

It's important to remember that my solution only provides DOS type security. This is also known as no security, but it is the amount of security that most apps give you on Windows.

Also, under my solution, if you don't define STRICT_UGO_PERMISSIONS, when you give a permission to group or other (or remove it for that matter), you are really changing the owner. If you didn't want to do that, but you still didn't need full Windows ACL permissions, just define STRICT_UGO_PERMISSIONS.

这篇关于C ++ - 如何设置文件权限(跨平台)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆