Сущность технологии COM




Управление маркерами - часть 3


Метод RevertToSelf заставляет текущий процесс вернуться к использованию маркера доступа, принадлежащего процессу. Если текущий вызов метода заканчивает работу во время режима заимствования прав, то COM неявно вернет поток к использованию маркера процесса. И наконец, метод IServerSecurity::IsImpersonating показывает, что использует текущий поток: полномочия клиента или маркер процесса объекта. Подобно методу QueryBlanket, два метода IServerSecurity также имеют удобные оболочки, которые вызывают CoGetCallContext изнутри и затем вызывают соответствующий метод:

HRESULT CoImpersonateClient(void); HRESULT CoRevertToSelf(void);

В общем случае, если будет использоваться более одного метода IServerSecurity, то эффективнее было бы вызвать CoGetCallContext один раз, а для вызова каждого метода использовать результирующий интерфейс IServerSecurity.

Следующий код демонстрирует использование контекстного объекта вызова для выполнения части кода метода с полномочиями клиента:

STDMETHODIMP MyClass::ReadWrite(DWORD dwNew, DWORD *pdw0ld) { // execute using server's token to let anyone read the value // выполняем с использованием маркера сервера, чтобы // все могли прочитать данное значение ULONG cb; HANDLE hfile = CreateFile("C:\\file1.bin", GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hfile == INVALID_HANDLE_VALUE) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); ReadFile(hfile, pdwOld, sizeof(DWORD), &cb, 0); CloseHandle(hfile);

// get call context object // получаем контекстный объект вызова IServerSecurlty *pss = 0; HRESULT hr = CoGetCallContext(IID_IServerSecurity, (void**)&pss); if (FAILED(hr)) return hr; // set thread token to use caller's credentials // устанавливаем маркер потока для использования // полномочий вызывающей программы hr = pss->ImpersonateClient(); assert(SUCCEEDED(hr)); // execute using client's token to let only users that can // write to the file change the value // выполняем с использованием маркера клиента, чтобы // изменять это значение могли только те пользователи, // которые имеют право записывать в файл hfile = CreateFile("C:\\file2.bin", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hfile == INVALID_HANDLE_VALUE) hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); else { WriteFile(hfile, &dwNew, sizeof(DWORD), &cb, 0); CloseHandle(hfile); } // restore thread to use process-level token // восстанавливаем режим использования потоком маркера процесса pss->RevertToSelf(); // release call context // освобождаем контекст вызова pss->Release(); return hr; }




Содержание  Назад  Вперед