| ||||
| ||||
Я пытаюсь получить DACL машинного кейсета так: ::CryptGetProvParam(x1, PP_KEYSET_SEC_DESCR, x2, x3, DACL_SECURITY_INFORMATION); // вызов успешен Полученный таким образом DACL от КриптоПро (2.0 Build 2049) не проходит проверку функцией ::IsValidSecurityDescriptor(); DACL от MS провайдера такую проверку проходит успешно. OC - WinXP SP1. В чем проблема? Вот код (успешно работает с MS провайдерами): void AddKeysetUser(const string_t& user_name) { // blob === vector<BYTE> // blob_ptr === auto_ptr<vector<BYTE> > // blob_cast<T>(b) === reinterpret_cast<T>(&b[0]) // provider_ - хэндл провайдера // get the keyset’s security descriptor in the self-related form blob_ptr sd_blob( get_blob_param(provider_, PP_KEYSET_SEC_DESCR, DACL_SECURITY_INFORMATION)); PSECURITY_DESCRIPTOR sd(blob_cast<PSECURITY_DESCRIPTOR>(sd_blob)); if(!::IsValidSecurityDescriptor(sd)) throw crypto_api_runtime_error("the keyset security descriptor is invalid"); // get the descriptor’s DACL BOOL acl_present, acl_defaulted; PACL current_acl; if(!::GetSecurityDescriptorDacl(sd, &acl_present, ¤t_acl, &acl_defaulted) || !acl_present) throw crypto_api_runtime_error("::GetSecurityDescriptorDacl() failed"); EXPLICIT_ACCESS ea; ::BuildExplicitAccessWithName( &ea, const_cast<string_t::pointer>(user_name.c_str()), GENERIC_ALL, GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT ); // add the new user to a new DACL merged with current DACL util::hlocal new_acl; if(ERROR_SUCCESS != ::SetEntriesInAcl( 1, &ea, current_acl, reinterpret_cast<PACL*>(&new_acl.get_ref()))) throw crypto_api_runtime_error("::SetEntriesInAcl() failed"); // convert the security descriptor to the absolute form DWORD asd_size(0), s1(0), s2(0), s3(0), s4(0); ::MakeAbsoluteSD(sd, 0, &asd_size, 0, &s1, 0, &s2, 0, &s3, 0, &s4); blob asd_blob(asd_size), b1(s1), b2(s2), b3(s3), b4(s4); PSECURITY_DESCRIPTOR asd(blob_cast<PSECURITY_DESCRIPTOR>(asd_blob)); if(!::MakeAbsoluteSD( sd, asd, &asd_size, blob_cast<PACL>(b1), &s1, blob_cast<PACL>(b2), &s2, blob_cast<PSID>(b3), &s3, blob_cast<PSID>(b4), &s4)) throw crypto_api_runtime_error("::MakeAbsoluteSD() failed"); // renew the descriptor’s DACL if(!::SetSecurityDescriptorDacl(asd, true, reinterpret_cast<PACL>(new_acl.get()), false)) throw crypto_api_runtime_error("::SetSecurityDescriptorDacl() failed"); // set the renewed descriptor to the keyset set_blob_param(provider_, PP_KEYSET_SEC_DESCR, asd_blob, DACL_SECURITY_INFORMATION); } | ||||
Ответы: | ||||
| ||||
Правильно ли я понимаю, что КриптоПро не поддерживает получение DACL кейсета, так как функция CryptGetProvParam(..., PP_KEYSET_SEC_DESCR, ..., DACL_SECURITY_INFORMATION) всегда возвращает нулевую длину записаных в буфер данных? | ||||
| ||||
Да, параметр не поддерживается. Это связано с тем, что в нашем провайдере, в отличие от Microsoft-овского, контейнеры могут располагаться не только в реестре, но и на съёмных носителях. | ||||
| ||||
Можно справедливо заметить, что равно как и таблетки, ни память, ни жесткий диск не умеют работать с SECURITY_DESCRIPTOR. Это ПО реализует эту возможность. Очень жаль, что ваше ПО не реализует этой возможности, и вводит в заблуждение небрежной документацией. | ||||