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

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

问题描述

我正在使用C ++ ofstream 来写出文件。我想将权限设置为仅可由用户访问:700。我想我可以只发布 system( 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安全概念的知识。



<对我而言,幸运的是,对于我当前的需求,我不需要访问控制模型提供的真正的安全性。只要我真的在Linux上设置权限,我就可以假装在Windows上设置权限。



Windows支持他们所谓的符合ISO C ++版本chmod(2)。该API称为_chmod,它与chmod(2)类似,但受到限制,并且不兼容类型或名称(当然)。 Windows也已经弃用了chmod,因此您不能简单地将chmod添加到Windows并在Linux上使用直接的chmod(2)。



我写了以下内容:

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

#ifdef _WIN32
#include< io.h>

typedef int mode_t;

/// @注如果未定义STRICT_UGO_PERMISSIONS,则为用户,组或其他任何
///设置读取将为用户设置读取,并设置写入
///将为用户设置Write。否则,将忽略Group的读写操作和
///其他。
///
/// @注对于没有Windows等效项的POSIX模式,此处定义的模式
///使用POSIX值左移16位。

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); ///<用户
读取的静态常量mode_t S_IWUSR = mode_t(_S_IWRITE); ///<用户写入
static const mode_t S_IXUSR = 0x00400000; ///<什么都不做
#ifndef STRICT_UGO_PERMISSIONS
静态const mode_t S_IRGRP = mode_t(_S_IREAD); ///<由* USER *读取
静态常量mode_t S_IWGRP = mode_t(_S_IWRITE); ///<由* USER *写
静态const mode_t S_IXGRP = 0x00080000; ///<什么也不做
static const mode_t S_IROTH = mode_t(_S_IREAD); ///<由* USER *读取
静态常量mode_t S_IWOTH = mode_t(_S_IWRITE); ///<由* USER *写
静态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; ///<低位字

静态内联int my_chmod(const char * path,mode_t mode)
{
int result = _chmod(path,(mode& MS_MODE_MASK));

if(结果!= 0)
{
结果= errno;
}

回报(结果);
}
#else
静态内联int my_chmod(const char * path,mode_t mode)
{
int result = chmod(path,mode);

if(结果!= 0)
{
结果= errno;
}

回报(结果);
}
#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 model is 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天全站免登陆