Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как программно добавить пользователя к текущим разрешениям папки?

12K
14 апреля 2009 года
Chinchipos
12 / / 02.12.2005
Суть программы в следующем:
Есть две папки. Нужно разрешения первой папки перенести на вторую + добавить в разрешения второй папки пользователя "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;
12K
16 апреля 2009 года
Chinchipos
12 / / 02.12.2005
Немного разобрался с кодом:
1) в строке 37 заменил 0xFFFFFFFF на GENERIC_ALL
2)Прога работала оказывается - права она правильно раздает на папку. А вот в виндовозе если открыть свойства папки, перейти на закладку "безопасность" и выбрать пользователя "localadm", то мы увидим пустые квадратики для крыжиков в области "Разрешения для localadm". А если нажать кнопку "Дополнительно", то на закладке "разрешения" мы увидим, что пользователь "localadm" присутствует и права на него "разрулены".....

Ну как сделать, чтоб крыжики отображались - не знаю......
14
16 апреля 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: Chinchipos

в строке 34 функция вернет значение 0, тож не понятно почему.....


когда ж вы все научитесь "ресурс" GetLastError() использовать..

Цитата: Chinchipos
...то мы увидим пустые квадратики для крыжиков в области "Разрешения для localadm". А если нажать кнопку "Дополнительно", то на закладке "разрешения" мы увидим, что пользователь "localadm" присутствует и права на него "разрулены".....
Ну как сделать, чтоб крыжики отображались - не знаю......


А Special Permissions непустой квадратик? Если пустой, скрины обоих диалогов приложите (желательно с видимыми всеми полями).

12K
17 апреля 2009 года
Chinchipos
12 / / 02.12.2005
1) GetLastEror возвращает ошибку 122 (ERROR_INSUFFICIENT_BUFFER: The data area passed to a system call is too small). В строках 24, 25, 34 заменил 0x400 на 0x1000 (просто посмотреть, мож что изменится) - результат тот же. В строках 25 и 34 одна и таже функция применяется к различным папкам. При первом проходе процедуры ошибок не возникает, а при втором ошибку выдает только строка 34. Я вручную добавляю к разрешениям первой папки пользователя "localadm" и история повторяется.... Воткнул GetLastError() после каждой строки и вот после строки 25 GetLastError выдает ошибку 997 (ERROR_IO_PENDING), хотя функция GetFileSecurity возвращает 1.
2) В квадратике Special Permissions галочка стоит (не активная).
12K
17 апреля 2009 года
Chinchipos
12 / / 02.12.2005
С пунктом 1 предыдущего сообщения разобрался. Ошибку правильно выдает... Посмотрел параметр dwResult, он кажет 4116. установил вместо 0x400 (оно же 1024) значение 4116 - все работат.
Но вот по отображению галочек вопрос остается в силе.
14
17 апреля 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: Chinchipos
С пунктом 1 предыдущего сообщения разобрался. Ошибку правильно выдает... Посмотрел параметр dwResult, он кажет 4116. установил вместо 0x400 (оно же 1024) значение 4116 - все работат.


Да не бойся ему дать буфер-то побольше! Дай КБ 100-200. Ну или сначала определяй сколько он хочет, потом выделяй.

Цитата: Chinchipos

Но вот по отображению галочек вопрос остается в силе.



Глянь на колонку "Применять к" в "Дополнительных" и все поймешь

12K
20 апреля 2009 года
Chinchipos
12 / / 02.12.2005
В общем разобрался я. Ошибок прога больше не выдает, работает правильно. Вопросов у меня больше нет. Листинг процедуры (с++) привожу ниже, мож кому интересно будет.

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;
12K
20 апреля 2009 года
Chinchipos
12 / / 02.12.2005
P.S. Спасибо!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог