Как программно добавить пользователя к текущим разрешениям папки?
Есть две папки. Нужно разрешения первой папки перенести на вторую + добавить в разрешения второй папки пользователя "localadm" с правами full.
Разрешения первой папки:
SYSTEM full
Администраторы full
Все read
Все работает, разрешения переносятся, к этим разрешениям пользователь localadm добавляется, но с пустыми правами. А должны быть full - строка 37. Если менять 0xFFFFFFFF на другие значения - эффект тот же самый.
Теперь, если еще раз запустить прогу, в строке 34 функция вернет значение 0, тож не понятно почему.....
Использовал ресурсы:
1) msdn
2) http://74.125.77.132/search?q=cache:Igq2KwPGXnQJ:alexgolovin.narod.ru/FAQ/winci.htm+%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F+GetFileSecurity&cd=5&hl=ru&ct=clnk&gl=ru
---------------------------------------------------------------------------
1. //Объявляем переменные
2. TCHAR *szFileName1="d:\\temp";
3. TCHAR *szFileName2="d:\\QWER";
4. DWORD dwResult;
5. PACL pACLNew,pACL;
6. PSID SystempSID, AdminspSID, AllpSID;
7. DWORD SystemcbSID = 1024;
8. LPSTR SystemAccount = "localadm";
9. DWORD cchDomainName = 128;
10. TCHAR szDomain[128];
11. void *pACE;
12. PSECURITY_DESCRIPTOR pSD,sd;
13. PSID_NAME_USE psnuType;
14. pSD = (PSECURITY_DESCRIPTOR)new BYTE[4096];
15. pACLNew = (PACL)new BYTE[4096];
16. SystempSID = (PSID)new BYTE[SystemcbSID];
17. psnuType = (PSID_NAME_USE)new BYTE[1024];
18. //Инициализируем
19. InitializeSecurityDescriptor(pSD,SECURITY_DESCRIPTOR_REVISION);
20. InitializeAcl(pACLNew,4096,ACL_REVISION2);
21. //Получаем pSID на пользователя "localadm"
22. d = LookupAccountName(NULL,SystemAccount,SystempSID,&SystemcbSID,szDomain,&cchDomainName,psnuType);
23. //Получаем дескриптор безопасности для первой папки
24. sd=(SECURITY_DESCRIPTOR *)new BYTE[0x400];
25. d = GetFileSecurity(szFileName1,DACL_SECURITY_INFORMATION,sd,0x400,&dwResult);
26. d = GetSecurityDescriptorDacl(sd,(int *)&dwResult,&pACL,(int *)&dwResult);
27. //Получаем ACL первой папки и задаем ACL, предназначенный для второй папки
28. for(int i=0; i < pACL->AceCount; i++)
29. {
30. GetAce(pACL,i,&pACE);
31. AddAce(pACLNew,ACL_REVISION,MAXDWORD,pACE,((PACE_HEADER)pACE)->AceSize);
32. }
33. //Получаем дескриптор безопасности для второй папки
34. d = GetFileSecurity(szFileName2,DACL_SECURITY_INFORMATION,sd,0x400,&dwResult);
35. d = GetSecurityDescriptorDacl(sd,(int *)&dwResult,&pACL,(int *)&dwResult);
36. //Добавляем к сформированному ACL нового пользователя (localadm в нашем случае) с полными правами
37. d =AddAccessAllowedAce(pACLNew,ACL_REVISION2,0xFFFFFFFF,SystempSID);
38. //Применяем сформированный ACL ко второй папке
39. d = SetSecurityDescriptorDacl(pSD,TRUE,pACLNew,FALSE);
40. d = SetFileSecurity(szFileName2,DACL_SECURITY_INFORMATION,pSD);
41. delete SystempSID;
42. delete pSD;
43. delete pACLNew;
44. delete psnuType;
1) в строке 37 заменил 0xFFFFFFFF на GENERIC_ALL
2)Прога работала оказывается - права она правильно раздает на папку. А вот в виндовозе если открыть свойства папки, перейти на закладку "безопасность" и выбрать пользователя "localadm", то мы увидим пустые квадратики для крыжиков в области "Разрешения для localadm". А если нажать кнопку "Дополнительно", то на закладке "разрешения" мы увидим, что пользователь "localadm" присутствует и права на него "разрулены".....
Ну как сделать, чтоб крыжики отображались - не знаю......
Цитата: Chinchipos
в строке 34 функция вернет значение 0, тож не понятно почему.....
когда ж вы все научитесь "ресурс" GetLastError() использовать..
Цитата: Chinchipos
...то мы увидим пустые квадратики для крыжиков в области "Разрешения для localadm". А если нажать кнопку "Дополнительно", то на закладке "разрешения" мы увидим, что пользователь "localadm" присутствует и права на него "разрулены".....
Ну как сделать, чтоб крыжики отображались - не знаю......
Ну как сделать, чтоб крыжики отображались - не знаю......
А Special Permissions непустой квадратик? Если пустой, скрины обоих диалогов приложите (желательно с видимыми всеми полями).
2) В квадратике Special Permissions галочка стоит (не активная).
Но вот по отображению галочек вопрос остается в силе.
Цитата: Chinchipos
С пунктом 1 предыдущего сообщения разобрался. Ошибку правильно выдает... Посмотрел параметр dwResult, он кажет 4116. установил вместо 0x400 (оно же 1024) значение 4116 - все работат.
Да не бойся ему дать буфер-то побольше! Дай КБ 100-200. Ну или сначала определяй сколько он хочет, потом выделяй.
Цитата: Chinchipos
Но вот по отображению галочек вопрос остается в силе.
Глянь на колонку "Применять к" в "Дополнительных" и все поймешь
TCHAR *szFileName1="d:\\temp";
TCHAR *szFileName2="d:\\QWER";
DWORD dwResult, szAcl, szSecDesc;
PACL pACLNew,pACLTemp,pACL;
PSID localadmpSID;
DWORD localadmcbSID = 1024;
LPSTR localadmName = "localadm";
DWORD cchDomainName = 128;
TCHAR szDomain[128];
void *pACE;
PSECURITY_DESCRIPTOR pSD,sd;
PSID_NAME_USE psnuType;
localadmpSID = (PSID)new BYTE[localadmcbSID];
psnuType = (PSID_NAME_USE)new BYTE[1024];
int d;
//Получаем дескриптор безопасности для первой папки
sd = (SECURITY_DESCRIPTOR *)new BYTE[1024];
d = GetFileSecurity(szFileName1,DACL_SECURITY_INFORMATION,sd,1024,&dwResult);
d = GetSecurityDescriptorDacl(sd,(int *)&dwResult,&pACL,(int *)&dwResult);
//Инициализируем временный ACL
pACLTemp = (PACL)new BYTE[1024];
d = InitializeAcl(pACLTemp,1024,ACL_REVISION2);
//Копируем разрешения ACL первой папки во временный ACL,
//одновременно подсчитываем размер ACL
szAcl = sizeof(ACL);
for(i=0; i < pACL->AceCount; i++)
{
GetAce(pACL,i,&pACE);
AddAce(pACLTemp,ACL_REVISION,MAXDWORD,pACE,((PACE_HEADER)pACE)->AceSize);
szAcl += ((PACE_HEADER)pACE)->AceSize;
}
//Получаем pSID на пользователя "localadm"
d = LookupAccountName(NULL,localadmName,localadmpSID,&localadmcbSID,szDomain,&cchDomainName,psnuType);
//Добавляем к времменому ACL пользователя "localadm" c полными правами
d =AddAccessAllowedAce(pACLTemp,ACL_REVISION2,GENERIC_ALL,localadmpSID);
GetAce(pACLTemp,(pACLTemp->AceCount-1),&pACE);
((PACE_HEADER)pACE)->AceFlags = '\x03'; //Разрешения для влож. файлов и папок
szAcl += ((PACE_HEADER)pACE)->AceSize; //Корректируем размер нового ACL
//Инициализируем новый ACL (для второй папки)
pACLNew = (PACL)new BYTE[szAcl];
d = InitializeAcl(pACLNew,szAcl,ACL_REVISION2);
//Копируем разрешения из временного ACL в ACL второй папки
for(i=0; i < pACLTemp->AceCount; i++)
{
GetAce(pACLTemp,i,&pACE);
AddAce(pACLNew,ACL_REVISION,MAXDWORD,pACE,((PACE_HEADER)pACE)->AceSize);
}
//Выделяем память под дескриптор безопасности и инициализируем его
szSecDesc = szAcl + sizeof(SECURITY_DESCRIPTOR);
pSD = (PSECURITY_DESCRIPTOR)new BYTE[szSecDesc];
d = InitializeSecurityDescriptor(pSD,SECURITY_DESCRIPTOR_REVISION);
//Применяем сформированный ACL ко второй папке
d = SetSecurityDescriptorDacl(pSD,TRUE,pACLNew,FALSE);
d = SetFileSecurity(szFileName2,DACL_SECURITY_INFORMATION,pSD);
delete localadmpSID;
delete pSD;
delete pACLTemp;
delete pACLNew;
delete psnuType;
P.S. Спасибо!