bool SetFileOwner(const string& Object, const string& Owner) { NTPath strNtObject(Object); bool Result = SetOwnerInternal(strNtObject, Owner); if(!Result && ElevationRequired(ELEVATION_MODIFY_REQUEST)) { Result = Global->Elevation->fSetOwner(strNtObject, Owner); } return Result; }
bool SetREPARSE_DATA_BUFFER(const wchar_t *Object,PREPARSE_DATA_BUFFER rdb) { bool Result=false; if (IsReparseTagValid(rdb->ReparseTag)) { Privilege CreateSymlinkPrivilege(SE_CREATE_SYMBOLIC_LINK_NAME); File fObject; bool ForceElevation=false; DWORD Attributes = apiGetFileAttributes(Object); if(Attributes&FILE_ATTRIBUTE_READONLY) { apiSetFileAttributes(Object, Attributes&~FILE_ATTRIBUTE_READONLY); } for(size_t i=0;i<2;i++) { if (fObject.Open(Object,GENERIC_WRITE,0,nullptr,OPEN_EXISTING,FILE_FLAG_OPEN_REPARSE_POINT,nullptr,ForceElevation)) { DWORD dwBytesReturned; if (fObject.IoControl(FSCTL_SET_REPARSE_POINT,rdb,rdb->ReparseDataLength+REPARSE_DATA_BUFFER_HEADER_SIZE,nullptr,0,&dwBytesReturned)) { Result=true; } fObject.Close(); // Open() success, but IoControl() fails. We can't handle this automatically :( if(!i && !Result && ElevationRequired(ELEVATION_MODIFY_REQUEST)) { ForceElevation=true; continue; } break; } } if(Attributes&FILE_ATTRIBUTE_READONLY) { apiSetFileAttributes(Object, Attributes); } } return Result; }
static bool SetREPARSE_DATA_BUFFER(const string& Object, REPARSE_DATA_BUFFER* rdb) { if (!IsReparseTagValid(rdb->ReparseTag)) return false; SCOPED_ACTION(os::security::privilege){ SE_CREATE_SYMBOLIC_LINK_NAME }; const auto Attributes = os::fs::get_file_attributes(Object); if(Attributes&FILE_ATTRIBUTE_READONLY) { os::fs::set_file_attributes(Object, Attributes&~FILE_ATTRIBUTE_READONLY); } SCOPE_EXIT { if (Attributes&FILE_ATTRIBUTE_READONLY) os::fs::set_file_attributes(Object, Attributes); }; const auto& SetBuffer = [&](bool ForceElevation) { const os::fs::file fObject(Object, GetDesiredAccessForReparsePointChange(), 0, nullptr, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, nullptr, ForceElevation); DWORD dwBytesReturned; return fObject && fObject.IoControl(FSCTL_SET_REPARSE_POINT, rdb, rdb->ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE, nullptr, 0, &dwBytesReturned); }; if (SetBuffer(false)) return true; if (ElevationRequired(ELEVATION_MODIFY_REQUEST)) { // Open() succeeded, but IoControl() failed. We can't handle this automatically :( return SetBuffer(true); } return false; }