私はファイルを書き出すためにC++ ofstream
を使用しています。私はアクセス権をユーザーがアクセスできるように設定したい:700. Unixでは、私はちょうどsystem("chmod 700 file.txt");
を発行することができますが、私はこのコードもWindows上で動作する必要があります。私はいくつかのWindows APIを使うことができます。これを行うには最高のC++クロスプラットフォームの方法は何ですか?C++ - ファイル許可を設定する方法(クロスプラットフォーム)
答えて
皮肉なことに、私はちょうどこのまさに同じ必要性に今すぐ遭遇しました。
私のケースでは、答えは、Linuxと比較して、Windowsで必要な権限レベルのレベルまで下がっています。私の場合、私はLinuxのユーザー、グループ、およびその他のアクセス許可のみに注意します。 Windowsでは、DOSからの基本的な読み取り/書き込みすべての権限は十分です。つまり、Windows上でACLを処理する必要はありません。
一般に、Windowsには基本的なDOSモデルと新しいアクセス制御モデルの2つの特権モデルがあります。 DOSモデルでは、1つのタイプの特権、書き込み特権があります。すべてのファイルを読み取ることができるため、読み取り権限を無効にする方法はありません(存在しないため)。実行権限の概念もありません。ファイルを読み取ることができれば(答えはイエス)、バイナリであれば実行できます。それ以外の場合はできません。
ほとんどのWindows環境、つまり比較的安全であると考えることができる物理的な場所で単一のユーザーがシステムを使用する環境では、基本的なDOSモデルで十分です。アクセス制御モデルは、数桁程度複雑です。
アクセス制御モデルでは、アクセス制御リスト(ACL)を使用して特権を付与します。特権は、必要な特権を持つプロセスによってのみ付与されます。このモデルは、読み取り、書き込み、および実行の権限を持つユーザー、グループ、その他のコントロールを許可するだけでなく、ネットワーク上およびWindowsドメイン間のファイルの制御も可能です。
注意:アクセスコントロールモデルは、あなたがSOLであるFATパーティションを使用している場合にのみNTFSパーティションで利用できます。
ACLを使用することはお尻の大きな痛みです。これは簡単な作業ではなく、ACLだけでなく、セキュリティ記述子、アクセストークン、その他の高度なWindowsセキュリティの概念についても学ぶ必要があります。
幸い私の現在のニーズのために、アクセスコントロールモデルが提供する真のセキュリティは必要ありません。私は、基本的にLinux上でパーミッションを設定している限り、Windows上でパーミッションを設定しようとしています。
Windowsでは、「ISO C++準拠」バージョンのchmod(2)をサポートしています。このAPIは_chmodと呼ばれ、chmod(2)と似ていますが、より限定されており、型や名前には互換性がありません(もちろん)。 Windowsでは廃止予定のchmodもありますので、単にWindowsにchmodを追加するだけではなく、Linux上で直接chmod(2)を使用することはできません。
私は次のように書いた:
#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を定義してください。
これを実行するためのクロスプラットフォームの方法はありません。 WindowsはUnix形式のファイルアクセス許可をサポートしていません。必要な作業を行うには、そのファイルのアクセス制御リストを作成する必要があります。これにより、ユーザーとグループのアクセス許可を明示的に定義できます。
セキュリティ設定がすでに設定されているディレクトリにファイルを作成し、そのユーザー以外のすべてのユーザーを除外することもできます。
その答えは、人々が実際に考えるべきものです。アプリのアクセス権を本当に必要としているのですか?多くの場合、多くの場合、管理者やユーザーは適切なアクセス権を制御することができるため、多くの場合、それは事実ではないし、物事を壊すことさえあります。特に。 Windowsでは、デフォルトでは他のユーザーがユーザーのホームディレクトリにアクセスすることはできないため、ファイルを手動で「非公開」にする必要はほとんどありません。 Linuxアプリケーションのchmod + umask処理の多くは、ACLや適切な継承などがないために残っています。可能な限り避けてください。 –
クロスプラットフォームの方法ではできません。 Linuxでは、system(2)
を使用して新しいシェルを作成する代わりに、関数chmod(2)
を使用する必要があります。 Windowsでは、様々なauthorization functionsを使用して、適切な権限を持つACL(アクセス制御リスト)を作成する必要があります。
system()
コールは変な獣です。私は多くの月前のMacでNOPシステム()の実装に噛まれています。実装定義(プラットフォーム/コンパイラ)が何をすべきかを定義していないことを意味する実装定義です。残念ながら、これはあなたの関数の範囲外のことを行う唯一の標準的な方法です(あなたの場合は権限を変更する)。
更新:提案ハック:
- お使いのシステムに適切な権限を持つ非空のファイルを作成します。
ブーストファイルシステムの
copy_file
を使用して、このファイルを目的の出力にコピーします。void copy_file(const path& frompath, const path& topath)
:frompathが参照するファイルの内容と属性は、topathが参照するファイルにコピーされます。このルーチンは、宛先ファイルが存在しないことを前提としています。宛先ファイルが存在する場合、例外がスローされます。したがって、これはUNIXのシステム指定のcpコマンドと等価ではありません。また、frompath変数が適切な正規ファイルを参照することも期待されます。次の例を考えてみましょう:frompathは/ tmp/file1というシンボリックリンクを参照し、/ tmp/file2というファイルを参照します。 topathは、例えば、/ tmp/file3です。この場合、copy_fileは失敗します。これは、このAPIのスポーツがcpコマンドと比較して、さらに別の違いです。ここで、出力を実際の内容で上書きします。
しかし、これは私が真夜中の後に長い考えるだけハックです。塩のピンチでそれを取って、これを試してください:)
私は、Windowsコマンドラインからchmod 700の簡単な方法をいくつか見つけました。私は別の質問を投稿して、使用する同等のwin32セキュリティ記述子構造を思いつくための助けを頼んでいます(もし私が数時間後にそれを理解できなければ)。
のWindows 2000 & XP(常に求められているようだmessy-):
echo Y|cacls *onlyme.txt* /g %username%:F
のWindows 2003+:
icacls *onlyme.txt* /inheritance:r /grant %username%:r
EDIT:
あなたが能力を持っていた場合ATLを使用すると、この記事で説明しています(私はVisual Studioを利用できません):
実際には、サンプルコードは、それはあなたのために働く何か持っている必要がありますよく、非ATLのサンプルコードが含ま言う(私を!)
覚えておくべき重要なことは、R/W得ることです/ xはwin32のみの所有者であるため、ファイルからすべてのセキュリティ記述子を抹消し、完全に制御できるように自分で追加する必要があります。
クロスプラットフォームの例では、C++ 17およびそのstd::filesystem
のファイルに対して0700を設定しています。
#include <exception>
//#include <filesystem>
#include <experimental/filesystem> // Use this for most compilers as of yet.
//namespace fs = std::filesystem;
namespace fs = std::experimental::filesystem; // Use this for most compilers as of yet.
int main()
{
fs::path myFile = "path/to/file.ext";
try {
fs::permissions(myFile, fs::perms::owner_all); // Uses fs::perm_options::replace.
}
catch (std::exception& e) {
// Handle exception or use another overload of fs::permissions()
// with std::error_code.
}
}
はstd::filesystem::permissions
、std::filesystem::perms
とstd::filesystem::perm_options
を参照してください。
- 1. Kubernetes:VolumeMountユーザーグループとファイルのアクセス許可を設定する方法
- 2. ファイルをamazon s3にアップロードする際に許可を設定する方法
- 3. Windowsサービスのアクセス許可を設定する方法
- 4. フォルダのアクセス許可を設定する方法
- 5. C++を使用してクロスプラットフォーム実行可能ファイルをコンパイルする方法
- 6. androidのプログラムでsdcardのファイルにアクセス許可を設定する方法
- 7. MSMQクラスターキューのアクセス許可を設定する方法?
- 8. MLCP -option_permissionsで複数のアクセス許可を設定する方法
- 9. OneNote APIのアクセス許可を設定する方法
- 10. Node.jsモジュールのファイルアクセス許可を設定する方法は?
- 11. Azure AD認証v2.0のアクセス許可を設定する方法
- 12. Linux UbuntuでCassandraのアクセス許可を設定する方法
- 13. サイトのデフォルトページのみを許可するrobot.txtの設定方法
- 14. SQL Azureでデータベースのアクセス許可を設定する方法は?
- 15. mdmsoft/yii2-adminのaccesscontrolのアクセス許可を設定する方法
- 16. 許可を設定するには?
- 17. C#.NETでNTFSアクセス許可を設定する
- 18. フォルダ/ファイルを作成してアクセス許可を設定する
- 19. htmlを許可するPHPIDS設定
- 20. リストフィールドのアクセス許可を設定する
- 21. ZipArchiveのアクセス許可を設定する
- 22. アプリケーションイベントログのアクセス許可を設定する
- 23. ファイル許可をMODE_WORLD_READABLEに設定するには
- 24. ディレクトリ/サブディレクトリ/ファイルのアクセス許可を設定する
- 25. android内のファイルのフルアクセス許可を設定する
- 26. ASP.NET MVC設定ファイル!デバッグを許可する
- 27. jekyllを設定し、許可マークダウン構文を指定する方法
- 28. アクセスコントロールを設定する方法特定のファイルの原点を許可するweb.config
- 29. SSRSサイト設定の許可
- 30. SilverStripeハードコード許可設定EDIT_SITECONFIG
恐ろしい!安全でない! 'system(" chmod ")'のようなクレイジーなハックを使わずに、ファイルを作成してからアクセス権を修正してください。代わりに、制限のあるアクセス許可で作成し、レースフリーのAPIを使用するようにしてください。 'umask'(スレッドセーフではない)または' open + fchmod + fdopen + std :: fstream'を使用してください。 –
機密データをファイルに書き込む前にchmodが使用されている限り、chmodの使用には何も問題ありません。あなたはfchmod()がchmodと非常に似ている、あなたの "答え"に気付いていますよね? – samoz