Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1174 lines
37 KiB

  1. /*****************************************************************************
  2. S H A R E S
  3. Name: shares.c
  4. Date: 21-Jan-1994
  5. Creator: Unknown
  6. Description:
  7. This file contains functions for manipulating NetDDE shares.
  8. *****************************************************************************/
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <nddeapi.h>
  12. #include <nddesec.h>
  13. #include <sedapi.h>
  14. #include <strsafe.h>
  15. #include "common.h"
  16. #include "clipbook.h"
  17. #include "clipbrd.h"
  18. #include "auditchk.h"
  19. #include "clipdsp.h"
  20. #include "dialogs.h"
  21. #include "helpids.h"
  22. #include "shares.h"
  23. #include "clpbkdlg.h"
  24. #include "cvutil.h"
  25. #include "debugout.h"
  26. #include "security.h"
  27. #include "initmenu.h"
  28. #define MAX_PERMNAMELEN 64
  29. // Typedefs used to dynamically load and call the permission editors.
  30. typedef DWORD (WINAPI *LPFNSACLEDIT)(HWND,
  31. HANDLE,
  32. LPWSTR,
  33. PSED_OBJECT_TYPE_DESCRIPTOR,
  34. PSED_APPLICATION_ACCESSES,
  35. LPWSTR,
  36. PSED_FUNC_APPLY_SEC_CALLBACK,
  37. ULONG_PTR,
  38. PSECURITY_DESCRIPTOR,
  39. BOOLEAN,
  40. LPDWORD,
  41. DWORD);
  42. typedef DWORD (WINAPI *LPFNDACLEDIT)(HWND,
  43. HANDLE,
  44. LPWSTR,
  45. PSED_OBJECT_TYPE_DESCRIPTOR,
  46. PSED_APPLICATION_ACCESSES,
  47. LPWSTR,
  48. PSED_FUNC_APPLY_SEC_CALLBACK,
  49. ULONG_PTR,
  50. PSECURITY_DESCRIPTOR,
  51. BOOLEAN,
  52. BOOLEAN,
  53. LPDWORD,
  54. DWORD);
  55. // Typedef for dynamically loading the Edit Owner dialog.
  56. typedef DWORD (WINAPI *LPFNOWNER)(HWND,
  57. HANDLE,
  58. LPWSTR,
  59. LPWSTR,
  60. LPWSTR,
  61. UINT,
  62. PSED_FUNC_APPLY_SEC_CALLBACK,
  63. ULONG_PTR,
  64. PSECURITY_DESCRIPTOR,
  65. BOOLEAN,
  66. BOOLEAN,
  67. LPDWORD,
  68. PSED_HELP_INFO,
  69. DWORD);
  70. static TCHAR szDirName[256] = {'\0',};
  71. static WCHAR ShareObjectName[80];
  72. static SED_APPLICATION_ACCESS KeyPerms[] =
  73. {
  74. SED_DESC_TYPE_RESOURCE, 0, 0, NULL,
  75. SED_DESC_TYPE_RESOURCE, NDDE_GUI_READ, 0, NULL,
  76. SED_DESC_TYPE_RESOURCE, NDDE_GUI_READ_LINK, 0, NULL,
  77. SED_DESC_TYPE_RESOURCE, NDDE_GUI_CHANGE, 0, NULL,
  78. SED_DESC_TYPE_RESOURCE, GENERIC_ALL, 0, NULL,
  79. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_READ, 0, NULL,
  80. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_WRITE, 0, NULL,
  81. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_INITIATE_STATIC, 0, NULL,
  82. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_INITIATE_LINK, 0, NULL,
  83. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_REQUEST, 0, NULL,
  84. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_ADVISE, 0, NULL,
  85. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_POKE, 0, NULL,
  86. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_EXECUTE, 0, NULL,
  87. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_ADD_ITEMS, 0, NULL,
  88. SED_DESC_TYPE_RESOURCE_SPECIAL, NDDE_SHARE_LIST_ITEMS, 0, NULL,
  89. SED_DESC_TYPE_RESOURCE_SPECIAL, DELETE, 0, NULL,
  90. SED_DESC_TYPE_RESOURCE_SPECIAL, READ_CONTROL, 0, NULL,
  91. SED_DESC_TYPE_RESOURCE_SPECIAL, WRITE_DAC, 0, NULL,
  92. SED_DESC_TYPE_RESOURCE_SPECIAL, WRITE_OWNER, 0, NULL,
  93. };
  94. static SED_APPLICATION_ACCESS KeyAudits[] =
  95. {
  96. SED_DESC_TYPE_AUDIT, NDDE_GUI_READ, 0, NULL,
  97. SED_DESC_TYPE_AUDIT, NDDE_GUI_CHANGE, 0, NULL,
  98. SED_DESC_TYPE_AUDIT, WRITE_DAC, 0, NULL,
  99. SED_DESC_TYPE_AUDIT, WRITE_OWNER, 0, NULL
  100. };
  101. // Callback function gets called by the permission editor
  102. DWORD CALLBACK SedCallback(HWND,
  103. HANDLE,
  104. ULONG_PTR,
  105. PSECURITY_DESCRIPTOR,
  106. PSECURITY_DESCRIPTOR,
  107. BOOLEAN,
  108. BOOLEAN,
  109. LPDWORD);
  110. #if DEBUG
  111. /*
  112. * DumpDdeInfo
  113. */
  114. void DumpDdeInfo(
  115. PNDDESHAREINFO pDdeI,
  116. LPTSTR lpszServer)
  117. {
  118. LPTSTR lpszT;
  119. unsigned i;
  120. PINFO(TEXT("Dde block:\r\n\r\n"));
  121. PINFO(TEXT("Server: <%s> Share: <%s>\r\n"),
  122. lpszServer ? lpszServer : "NULL",
  123. pDdeI->lpszShareName);
  124. lpszT = pDdeI->lpszAppTopicList;
  125. for (i = 0;i < 3;i++)
  126. {
  127. PINFO(TEXT("App|Topic %d: <%s>\r\n"),i, lpszT);
  128. lpszT += lstrlen(lpszT) + 1;
  129. }
  130. PINFO(TEXT("Rev: %ld Shared: %ld Service: %ld Start: %ld\r\n"),
  131. pDdeI->lRevision,
  132. pDdeI->fSharedFlag,
  133. pDdeI->fService,
  134. pDdeI->fStartAppFlag);
  135. PINFO(TEXT("Type: %ld Show: %ld Mod1: %lx Mod2: %lx\r\n"),
  136. pDdeI->lShareType,
  137. pDdeI->nCmdShow,
  138. pDdeI->qModifyId[0],
  139. pDdeI->qModifyId[1]);
  140. PINFO(TEXT("Items: %ld ItemList:"),
  141. pDdeI->cNumItems);
  142. lpszT = pDdeI->lpszItemList;
  143. if (lpszT)
  144. {
  145. for (i = 0;i < (unsigned)pDdeI->cNumItems;i++)
  146. {
  147. if ((i - 1)% 4 == 0)
  148. {
  149. PINFO(TEXT("\r\n"));
  150. }
  151. PINFO(TEXT("%s\t"),lpszT);
  152. lpszT += lstrlen(lpszT) + 1;
  153. }
  154. PINFO(TEXT("\r\n"));
  155. }
  156. else
  157. {
  158. PINFO(TEXT("NULL\r\n"));
  159. }
  160. }
  161. #endif // DEBUG
  162. /*
  163. * SedCallback
  164. *
  165. * Purpose: Callback function called by ACLEDIT.DLL. See SEDAPI.H for
  166. * details on its parameters and return value.
  167. *
  168. * Notes: The CallbackContext of this callback should be a string in
  169. * this format: Computername\0Sharename\0SECURITY_INFORMATION struct.
  170. */
  171. DWORD CALLBACK SedCallback(
  172. HWND hwndParent,
  173. HANDLE hInstance,
  174. ULONG_PTR penvstr,
  175. PSECURITY_DESCRIPTOR SecDesc,
  176. PSECURITY_DESCRIPTOR SecDescNewObjects,
  177. BOOLEAN ApplyToSubContainers,
  178. BOOLEAN ApplyToSubObjects,
  179. LPDWORD StatusReturn)
  180. {
  181. PSECURITY_DESCRIPTOR psdSet;
  182. SEDCALLBACKCONTEXT *pcbcontext;
  183. DWORD ret = NDDE_NO_ERROR + 37;
  184. DWORD dwMyRet = ERROR_INVALID_PARAMETER;
  185. DWORD dwLen;
  186. DWORD dwErr;
  187. pcbcontext = (SEDCALLBACKCONTEXT *)penvstr;
  188. PINFO(TEXT("SedCallback: machine %ls share %ls SI %ld\r\n"),
  189. pcbcontext->awchCName, pcbcontext->awchSName, pcbcontext->si);
  190. // Need to give this capability to remote shares somehow!!!
  191. if (!IsValidSecurityDescriptor(SecDesc))
  192. {
  193. PERROR(TEXT("Bad security descriptor created, can't set security."));
  194. *StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
  195. dwMyRet = ERROR_INVALID_SECURITY_DESCR;
  196. }
  197. else
  198. {
  199. PINFO(TEXT("Setting security to "));
  200. PrintSD(SecDesc);
  201. SetLastError(0);
  202. dwLen = GetSecurityDescriptorLength (SecDesc);
  203. if (dwErr = GetLastError())
  204. {
  205. PERROR(TEXT("GetSecurityDescriptorLength -> %u\r\n"), dwErr);
  206. dwMyRet = ERROR_INVALID_SECURITY_DESCR;
  207. }
  208. else
  209. {
  210. // Try to make sure that the SD is self-relative, 'cause the
  211. // NetDDE functions vomit when given absolute SDs.
  212. if (psdSet = LocalAlloc (LPTR, dwLen))
  213. {
  214. if (FALSE == MakeSelfRelativeSD (SecDesc, psdSet, &dwLen))
  215. {
  216. LocalFree(psdSet);
  217. if (psdSet = LocalAlloc (LPTR, dwLen))
  218. {
  219. if (FALSE == MakeSelfRelativeSD (SecDesc, psdSet, &dwLen))
  220. {
  221. LocalFree(psdSet);
  222. psdSet = NULL;
  223. dwMyRet = ERROR_INVALID_SECURITY_DESCR;
  224. }
  225. }
  226. else
  227. {
  228. dwMyRet = ERROR_NOT_ENOUGH_MEMORY;
  229. }
  230. }
  231. if (psdSet)
  232. {
  233. DWORD dwTrust[3];
  234. NDdeGetTrustedShareW (pcbcontext->awchCName,
  235. pcbcontext->awchSName,
  236. dwTrust,
  237. dwTrust + 1,
  238. dwTrust + 2);
  239. ret = NDdeSetShareSecurityW (pcbcontext->awchCName,
  240. pcbcontext->awchSName,
  241. pcbcontext->si,
  242. psdSet);
  243. PINFO(TEXT("Set share info. %d\r\n"),ret);
  244. if (ret != NDDE_NO_ERROR)
  245. {
  246. NDdeMessageBox (hInst,
  247. hwndParent,
  248. ret,
  249. IDS_APPNAME,
  250. MB_OK|MB_ICONSTOP);
  251. *StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
  252. dwMyRet = ERROR_ACCESS_DENIED;
  253. }
  254. else
  255. {
  256. NDdeSetTrustedShareW (pcbcontext->awchCName,
  257. pcbcontext->awchSName,
  258. 0);
  259. NDdeSetTrustedShareW (pcbcontext->awchCName,
  260. pcbcontext->awchSName,
  261. dwTrust[0]);
  262. *StatusReturn = SED_STATUS_MODIFIED;
  263. dwMyRet = ERROR_SUCCESS;
  264. }
  265. LocalFree(psdSet);
  266. }
  267. }
  268. }
  269. }
  270. return(dwMyRet);
  271. }
  272. /*
  273. * EditPermissions
  274. *
  275. * Purpose: Call the Acl Editor for the selected page.
  276. *
  277. * Parameters:
  278. * fSacl - TRUE to call the SACL editor (auditing); FALSE to call
  279. * the DACL editor (permissions).
  280. *
  281. * Returns: current selected item in list box or LB_ERR.
  282. */
  283. LRESULT EditPermissions (
  284. BOOL fSacl)
  285. {
  286. LPLISTENTRY lpLE;
  287. TCHAR rgtchCName[MAX_COMPUTERNAME_LENGTH + 3];
  288. TCHAR rgtchShareName[MAX_NDDESHARENAME + 1];
  289. DWORD dwBAvail;
  290. WORD wItems;
  291. unsigned iListIndex;
  292. TCHAR szBuff[MAX_PAGENAME_LENGTH + 32];
  293. iListIndex = (int)SendMessage(pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
  294. if (iListIndex != LB_ERR)
  295. {
  296. if (SendMessage (pActiveMDI->hWndListbox,
  297. LB_GETTEXT, iListIndex, (LPARAM)(LPCSTR)&lpLE)
  298. == LB_ERR)
  299. {
  300. PERROR(TEXT("PermsEdit No text: %d\n\r"), iListIndex );
  301. }
  302. else
  303. {
  304. // NDdeShareGetInfo wants a wItems containing 0. Fine.
  305. wItems = 0;
  306. // Get computer name containing share
  307. rgtchCName[0] = rgtchCName[1] = TEXT('\\');
  308. if (pActiveMDI->flags & F_LOCAL)
  309. {
  310. dwBAvail = MAX_COMPUTERNAME_LENGTH + 1;
  311. GetComputerName (rgtchCName + 2, &dwBAvail);
  312. }
  313. else
  314. {
  315. StringCchCopy(rgtchCName + 2, MAX_COMPUTERNAME_LENGTH + 1, pActiveMDI->szBaseName);
  316. }
  317. PINFO(TEXT("Getting page %s from server %s\r\n"),
  318. lpLE->name, rgtchCName);
  319. // Set up sharename string ("$<pagename>")
  320. StringCchCopy(rgtchShareName, MAX_NDDESHARENAME + 1, lpLE->name);
  321. rgtchShareName[0] = SHR_CHAR;
  322. // Edit the permissions
  323. PINFO(TEXT("Editing permissions for share %s\r\n"), rgtchShareName);
  324. EditPermissions2 (hwndApp, rgtchShareName, fSacl);
  325. ///////////////////////////////////////////////
  326. // do the execute to change the security on the file.
  327. StringCchCopy(szBuff, sizeof(szBuff), IsShared(lpLE) ? SZCMD_SHARE : SZCMD_UNSHARE);
  328. StringCchCat(szBuff, sizeof(szBuff), lpLE->name);
  329. PINFO(TEXT("sending cmd [%s]\n\r"), szBuff);
  330. MySyncXact ( (LPBYTE)szBuff,
  331. lstrlen(szBuff) +1, GETMDIINFO(hwndLocal)->hExeConv, 0L, CF_TEXT,
  332. XTYP_EXECUTE, SHORT_SYNC_TIMEOUT, NULL);
  333. }
  334. }
  335. return iListIndex;
  336. }
  337. /*
  338. * EditPermissions2
  339. *
  340. * Purpose: Put up the standard "permission editor" dialog.
  341. *
  342. * Parameters:
  343. * hWnd - Parent window for the dialog.
  344. * pShareName - Name of the DDE share.
  345. * lpDdeI - Pointer to an NDDESHAREINFO describing the share.
  346. * fSacl - TRUE if you're editing the SACL, FALSE to edit the DACL
  347. *
  348. * Returns:
  349. * TRUE on success, FALSE on failure.
  350. */
  351. BOOL WINAPI EditPermissions2 (
  352. HWND hWnd,
  353. LPTSTR pShareName,
  354. BOOL fSacl)
  355. {
  356. SED_OBJECT_TYPE_DESCRIPTOR ObjectTypeDescriptor;
  357. SED_APPLICATION_ACCESSES ApplicationAccesses;
  358. PSECURITY_DESCRIPTOR pSD = NULL;
  359. GENERIC_MAPPING GmDdeShare;
  360. SED_HELP_INFO HelpInfo;
  361. SEDCALLBACKCONTEXT cbcontext;
  362. DWORD Status;
  363. DWORD dwRtn;
  364. unsigned i, iFirst;
  365. BOOL fRet = FALSE;
  366. DWORD dwSize;
  367. BOOL fCouldntRead;
  368. HMODULE hMod;
  369. LPWSTR szPermNames = NULL;
  370. WCHAR szSpecial[256];
  371. PINFO(TEXT("EditPermissions2: %s"), fSacl ? "SACL\r\n" : "DACL\r\n");
  372. if (fSacl && !AuditPrivilege (AUDIT_PRIVILEGE_ON))
  373. return fRet;
  374. SetCursor(LoadCursor(NULL, IDC_WAIT));
  375. // Set up the callback context for the SedCallback function.
  376. cbcontext.awchCName[0] = cbcontext.awchCName[1] = L'\\';
  377. if (pActiveMDI->flags & (F_LOCAL | F_CLPBRD))
  378. {
  379. dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  380. GetComputerNameW(cbcontext.awchCName + 2, &dwSize);
  381. }
  382. else
  383. {
  384. #ifdef REMOTE_ADMIN_OK
  385. MultiByteToWideChar (CP_ACP,
  386. 0,
  387. pActiveMDI->szBaseName, -1,
  388. cbcontext.awchCName + 2,
  389. MAX_COMPUTERNAME_LENGTH + 1);
  390. #else
  391. PERROR(TEXT("EditPermissions2() on remote window!!!\r\n"));
  392. MessageBoxID (hInst,
  393. hwndApp,
  394. IDS_INTERNALERR,
  395. IDS_APPNAME,
  396. MB_OK | MB_ICONHAND);
  397. #endif
  398. }
  399. #ifdef UNICODE
  400. lstrcpyW(cbcontext.awchSName, pShareName);
  401. #else
  402. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pShareName, -1,
  403. cbcontext.awchSName, MAX_NDDESHARENAME);
  404. #endif
  405. cbcontext.si = (fSacl? SACL_SECURITY_INFORMATION: DACL_SECURITY_INFORMATION);
  406. pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, 30);
  407. if (!pSD)
  408. {
  409. PERROR(TEXT("LocalAlloc fail\r\n"));
  410. }
  411. else
  412. {
  413. // Get the security descriptor off of the share
  414. dwRtn = NDdeGetShareSecurityW (cbcontext.awchCName,
  415. cbcontext.awchSName,
  416. cbcontext.si |
  417. OWNER_SECURITY_INFORMATION,
  418. pSD,
  419. 30,
  420. &dwSize);
  421. switch (dwRtn)
  422. {
  423. case NDDE_NO_ERROR:
  424. fCouldntRead = FALSE;
  425. PrintSD(pSD);
  426. break;
  427. case NDDE_BUF_TOO_SMALL:
  428. {
  429. PINFO(TEXT("GetShareSec sez SD is %ld bytes long, ret %ld\r\n"),
  430. dwSize, dwRtn);
  431. LocalFree(pSD);
  432. pSD = NULL;
  433. if (dwSize < 65535 && (pSD = LocalAlloc(LPTR, dwSize)))
  434. {
  435. dwRtn = NDdeGetShareSecurityW (cbcontext.awchCName,
  436. cbcontext.awchSName,
  437. cbcontext.si |
  438. OWNER_SECURITY_INFORMATION,
  439. pSD,
  440. dwSize,
  441. &dwSize);
  442. if (NDDE_NO_ERROR == dwRtn)
  443. {
  444. fCouldntRead = FALSE;
  445. PINFO(TEXT("Got security!\r\n"));
  446. PrintSD(pSD);
  447. }
  448. else
  449. {
  450. PERROR(TEXT("NDdeGetSecurity fail %ld!\r\n"), dwRtn);
  451. fCouldntRead = TRUE;
  452. LocalFree(pSD);
  453. pSD = NULL;
  454. break;
  455. }
  456. }
  457. else
  458. {
  459. PERROR(TEXT("LocalReAlloc fail (%ld bytes)\r\n"), dwSize);
  460. }
  461. }
  462. break;
  463. case NDDE_ACCESS_DENIED:
  464. default:
  465. fCouldntRead = TRUE;
  466. LocalFree(pSD);
  467. pSD = NULL;
  468. break;
  469. }
  470. }
  471. if (!pSD && !fCouldntRead)
  472. {
  473. MessageBoxID(hInst, hWnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
  474. goto done;
  475. }
  476. LoadStringW(hInst, IDS_SHROBJNAME, ShareObjectName,
  477. ARRAYSIZE(ShareObjectName));
  478. // Set up help contexts for all of the dialogs, so the Help
  479. // buttons will work.
  480. HelpInfo.pszHelpFileName = L"clipbrd.hlp";
  481. HelpInfo.aulHelpContext[HC_SPECIAL_ACCESS_DLG] = 0;
  482. HelpInfo.aulHelpContext[HC_NEW_ITEM_SPECIAL_ACCESS_DLG] = 0;
  483. HelpInfo.aulHelpContext[HC_ADD_USER_DLG] = IDH_ADD_USER_DLG;
  484. HelpInfo.aulHelpContext[HC_ADD_USER_MEMBERS_LG_DLG] = IDH_ADD_MEM_LG_DLG;
  485. HelpInfo.aulHelpContext[HC_ADD_USER_MEMBERS_GG_DLG] = IDH_ADD_MEM_GG_DLG;
  486. HelpInfo.aulHelpContext[HC_ADD_USER_SEARCH_DLG] = IDH_FIND_ACCT_DLG;
  487. HelpInfo.aulHelpContext[HC_MAIN_DLG] = fSacl ?
  488. IDH_AUDITDLG :
  489. IDH_PERMSDLG;
  490. // Set up a GENERIC_MAPPING struct-- we don't use generic
  491. // rights, but the struct has to be there.
  492. GmDdeShare.GenericRead = NDDE_GUI_READ;
  493. GmDdeShare.GenericWrite = NDDE_GUI_CHANGE;
  494. GmDdeShare.GenericExecute = NDDE_GUI_READ_LINK;
  495. GmDdeShare.GenericAll = NDDE_GUI_FULL_CONTROL;
  496. ObjectTypeDescriptor.Revision = SED_REVISION1;
  497. ObjectTypeDescriptor.IsContainer = FALSE;
  498. ObjectTypeDescriptor.AllowNewObjectPerms = FALSE;
  499. ObjectTypeDescriptor.MapSpecificPermsToGeneric = FALSE;
  500. ObjectTypeDescriptor.GenericMapping = &GmDdeShare;
  501. ObjectTypeDescriptor.GenericMappingNewObjects = &GmDdeShare;
  502. ObjectTypeDescriptor.ObjectTypeName = ShareObjectName;
  503. ObjectTypeDescriptor.HelpInfo = &HelpInfo;
  504. ObjectTypeDescriptor.ApplyToSubContainerTitle = NULL;
  505. ObjectTypeDescriptor.ApplyToSubContainerConfirmation = NULL;
  506. LoadStringW (hInst, IDS_SPECIAL, szSpecial, 256 );
  507. ObjectTypeDescriptor.SpecialObjectAccessTitle = szSpecial;
  508. ObjectTypeDescriptor.SpecialNewObjectAccessTitle = NULL;
  509. if (fSacl)
  510. {
  511. PINFO(TEXT("Editing SACL..\r\n"));
  512. ApplicationAccesses.Count = sizeof(KeyAudits)/sizeof(KeyAudits[0]);
  513. ApplicationAccesses.AccessGroup = KeyAudits;
  514. }
  515. else
  516. {
  517. ApplicationAccesses.Count = sizeof(KeyPerms)/sizeof(KeyPerms[0]);
  518. ApplicationAccesses.AccessGroup = KeyPerms;
  519. // This corresponds to "Read and Link"
  520. ApplicationAccesses.DefaultPermName = KeyPerms[2].PermissionTitle;
  521. }
  522. // Load the permission names-- note ternary operator to give us
  523. // the AUDIT names if we're editing the SACL
  524. iFirst = fSacl ? IDS_AUDITNAMEFIRST : IDS_PERMNAMEFIRST;
  525. szPermNames = GlobalAlloc (LPTR,
  526. ApplicationAccesses.Count
  527. * MAX_PERMNAMELEN
  528. * sizeof(WCHAR));
  529. if (!szPermNames)
  530. goto done;
  531. for (i=0; i<ApplicationAccesses.Count; i++)
  532. {
  533. ApplicationAccesses.AccessGroup[i].PermissionTitle
  534. = szPermNames + i * MAX_PERMNAMELEN;
  535. LoadStringW (hInst,
  536. iFirst + i,
  537. ApplicationAccesses.AccessGroup[i].PermissionTitle,
  538. MAX_PERMNAMELEN - 1);
  539. }
  540. if (fSacl)
  541. {
  542. LPFNSACLEDIT lpfn;
  543. PINFO(TEXT("Finding SACL editor..\r\n"));
  544. if (hMod = LoadLibrary("ACLEDIT.DLL"))
  545. {
  546. if (lpfn = (LPFNSACLEDIT)GetProcAddress(hMod, "SedSystemAclEditor"))
  547. {
  548. SetCursor(LoadCursor(NULL, IDC_ARROW));
  549. PINFO(TEXT("Calling SACL editor..\r\n"));
  550. dwRtn = (*lpfn) (hWnd, // owner wnd
  551. hInst, // hinstance
  552. NULL, // Server (NULL means local)
  553. &ObjectTypeDescriptor, // Object type
  554. &ApplicationAccesses, // Access types.
  555. cbcontext.awchSName + 1, // Object name
  556. SedCallback, // Apply security callback
  557. (ULONG_PTR)&cbcontext, // Callback context
  558. pSD, // Points to current ACL
  559. (BOOLEAN)fCouldntRead, // true if user can't read ACL list.
  560. &Status, // Status return code
  561. (DWORD)0);
  562. }
  563. else
  564. {
  565. MessageBoxID(hInst, hWnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
  566. }
  567. FreeLibrary(hMod);
  568. }
  569. else
  570. {
  571. MessageBoxID(hInst, hWnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
  572. }
  573. }
  574. else
  575. {
  576. LPFNDACLEDIT lpfn;
  577. PINFO(TEXT("Getting DACL edit \r\n"));
  578. if (hMod = LoadLibrary("ACLEDIT.DLL"))
  579. {
  580. if (lpfn = (LPFNDACLEDIT)GetProcAddress(hMod,
  581. "SedDiscretionaryAclEditor"))
  582. {
  583. SetCursor(LoadCursor(NULL, IDC_ARROW));
  584. dwRtn = (*lpfn) (hWnd, // owner wnd
  585. hInst, // hinstance
  586. NULL, // Server (NULL means local)
  587. &ObjectTypeDescriptor, // Object type
  588. &ApplicationAccesses, // Access types.
  589. cbcontext.awchSName + 1, // Object name
  590. SedCallback, // Apply security callback
  591. (ULONG_PTR)&cbcontext, // Callback context
  592. pSD, // Points to current ACL
  593. (BOOLEAN)fCouldntRead, // true if user can't read ACL list.
  594. FALSE, // true if user can't write ACL list
  595. &Status, // Status return code
  596. 0L);
  597. }
  598. FreeLibrary(hMod);
  599. }
  600. }
  601. fRet = TRUE;
  602. SendMessage (hWnd, WM_COMMAND, IDM_REFRESH, 0);
  603. done:
  604. if (pSD) LocalFree((HLOCAL)pSD);
  605. if (szPermNames) GlobalFree (szPermNames);
  606. SetCursor(LoadCursor(NULL, IDC_ARROW));
  607. AuditPrivilege(AUDIT_PRIVILEGE_OFF);
  608. return fRet;
  609. }
  610. /*
  611. * EditOwner
  612. *
  613. * Purpose: Edit ownership on the selected page.
  614. */
  615. LRESULT EditOwner(void)
  616. {
  617. LPLISTENTRY lpLE;
  618. DWORD dwBAvail;
  619. unsigned iListIndex;
  620. DWORD Status;
  621. DWORD ret;
  622. WCHAR ShareObjName[100];
  623. BOOL fCouldntRead;
  624. BOOL fCouldntWrite;
  625. DWORD dwSize;
  626. HMODULE hMod;
  627. SED_HELP_INFO HelPINFO;
  628. SEDCALLBACKCONTEXT cbcontext;
  629. PSECURITY_DESCRIPTOR pSD = NULL;;
  630. iListIndex = (int)SendMessage(pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
  631. if (iListIndex == LB_ERR)
  632. {
  633. PERROR(TEXT("Attempt to modify ownership with no item sel'ed\r\n"));
  634. goto done;
  635. }
  636. if (SendMessage ( pActiveMDI->hWndListbox, LB_GETTEXT, iListIndex, (LPARAM)(LPCSTR)&lpLE)
  637. == LB_ERR)
  638. {
  639. PERROR(TEXT("PermsEdit No text: %d\n\r"), iListIndex );
  640. goto done;
  641. }
  642. // Set up the callback context
  643. if (pActiveMDI->flags & F_LOCAL)
  644. {
  645. cbcontext.awchCName[0] = cbcontext.awchCName[1] = L'\\';
  646. dwBAvail = MAX_COMPUTERNAME_LENGTH + 1;
  647. GetComputerNameW(cbcontext.awchCName + 2, &dwBAvail);
  648. }
  649. else
  650. {
  651. #ifdef UNICODE
  652. lstrcpy (cbcontext.awchCName, pActiveMDI->szBaseName);
  653. #else
  654. MultiByteToWideChar (CP_ACP, 0, pActiveMDI->szBaseName, -1,
  655. cbcontext.awchCName, MAX_COMPUTERNAME_LENGTH + 1);
  656. #endif
  657. }
  658. // Get page name
  659. SendMessage(pActiveMDI->hWndListbox, LB_GETTEXT, iListIndex, (LPARAM)&lpLE);
  660. PINFO(TEXT("Getting page %s from server %ws\r\n"),
  661. lpLE->name, cbcontext.awchCName);
  662. #ifdef UNICODE
  663. lstrcpyW (cbcontext.awchSName, lpLE->name);
  664. #else
  665. MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, lpLE->name,
  666. -1, cbcontext.awchSName, 100);
  667. #endif
  668. #ifndef USETWOSHARESPERPAGE
  669. cbcontext.awchSName[0] = L'$';
  670. #endif
  671. cbcontext.si = OWNER_SECURITY_INFORMATION;
  672. // Get object name
  673. LoadStringW(hInst, IDS_CB_PAGE, ShareObjName, 99);
  674. // Get owner
  675. dwSize = 0L;
  676. PINFO(TEXT("Getting secinfo for %ls ! %ls\r\n"),
  677. cbcontext.awchCName,
  678. cbcontext.awchSName);
  679. NDdeGetShareSecurityW (cbcontext.awchCName,
  680. cbcontext.awchSName,
  681. OWNER_SECURITY_INFORMATION,
  682. pSD,
  683. 0L,
  684. &dwSize);
  685. if (!(pSD = LocalAlloc(LPTR, min(dwSize, 65535L))))
  686. {
  687. PERROR(TEXT("Couldn't get current owner (%ld bytes)!\r\n"), dwSize);
  688. }
  689. PINFO(TEXT("Getting owner on %ls ! %ls..\r\n"),
  690. cbcontext.awchCName, cbcontext.awchSName);
  691. ret = NDdeGetShareSecurityW(
  692. cbcontext.awchCName,
  693. cbcontext.awchSName,
  694. OWNER_SECURITY_INFORMATION,
  695. pSD,
  696. dwSize,
  697. &dwSize);
  698. if (NDDE_NO_ERROR == ret)
  699. {
  700. DWORD adwTrust[3];
  701. fCouldntRead = FALSE;
  702. NDdeGetTrustedShareW(
  703. cbcontext.awchCName,
  704. cbcontext.awchSName,
  705. adwTrust, adwTrust + 1, adwTrust + 2);
  706. ret = NDdeSetShareSecurityW(
  707. cbcontext.awchCName,
  708. cbcontext.awchSName,
  709. OWNER_SECURITY_INFORMATION,
  710. pSD);
  711. if (NDDE_NO_ERROR == ret)
  712. {
  713. NDdeSetTrustedShareW (cbcontext.awchCName,
  714. cbcontext.awchSName,
  715. adwTrust[0]);
  716. fCouldntWrite = FALSE;
  717. }
  718. }
  719. else
  720. {
  721. PERROR(TEXT("Couldn't get owner (err %d)!\r\n"), ret);
  722. fCouldntRead = TRUE;
  723. // We just set fCouldntWrite to FALSE if we couldn't read,
  724. // because the only way to find out if we could would be
  725. // to overwrite the current ownership info (and we DON'T
  726. // KNOW WHAT IT IS!!)
  727. fCouldntWrite = FALSE;
  728. }
  729. HelPINFO.pszHelpFileName = L"CLIPBRD.HLP";
  730. HelPINFO.aulHelpContext[ HC_MAIN_DLG ] = IDH_OWNER;
  731. if (hMod = LoadLibrary("ACLEDIT.DLL"))
  732. {
  733. LPFNOWNER lpfn;
  734. if (lpfn = (LPFNOWNER)GetProcAddress(hMod, "SedTakeOwnership"))
  735. {
  736. ret = (*lpfn)(
  737. hwndApp,
  738. hInst,
  739. cbcontext.awchCName,
  740. ShareObjName,
  741. cbcontext.awchSName + 1,
  742. 1,
  743. SedCallback,
  744. (ULONG_PTR)&cbcontext,
  745. fCouldntRead ? NULL : pSD,
  746. (BOOLEAN)fCouldntRead,
  747. (BOOLEAN)fCouldntWrite,
  748. &Status,
  749. &HelPINFO,
  750. 0L);
  751. }
  752. else
  753. {
  754. PERROR(TEXT("Couldn't get proc!\r\n"));
  755. }
  756. FreeLibrary(hMod);
  757. }
  758. else
  759. {
  760. PERROR(TEXT("Couldn't loadlib!\r\n"));
  761. }
  762. PINFO(TEXT("Ownership edited. Ret code %d, status %d\r\n"), ret, Status);
  763. LocalFree((HLOCAL)pSD);
  764. done:
  765. return 0L;
  766. }
  767. /*
  768. * Properties
  769. *
  770. * Purpose: Change the properties of a share by displaying the Properties
  771. * dialog and applying the changes the user makes to the share.
  772. *
  773. * Parameters:
  774. * hwnd - Parent window for the properties dialog
  775. * lpLE - The entry we're messing with.
  776. *
  777. * Returns:
  778. * 0L always. We don't return an error code because we handle informing
  779. * the user of errors inside the routine.
  780. */
  781. LRESULT Properties(
  782. HWND hwnd,
  783. PLISTENTRY lpLE)
  784. {
  785. PNDDESHAREINFO lpDdeI;
  786. LRESULT ret;
  787. WORD wAddlItems;
  788. DWORD dwRet;
  789. TCHAR szBuff[MAX_PAGENAME_LENGTH + 32];
  790. BOOL fAlreadyShared;
  791. DWORD adwTrust[3];
  792. PINFO(TEXT("Props "));
  793. lpDdeI = GlobalAllocPtr(GHND, 2048 * sizeof(TCHAR));
  794. if (!lpDdeI)
  795. {
  796. PERROR(TEXT("GlobalAllocPtr failed\n\r"));
  797. return 0L;
  798. }
  799. // Use "shared" version of name, because that's the way the DDE
  800. // share is named.
  801. fAlreadyShared = IsShared(lpLE);
  802. SetShared (lpLE, TRUE);
  803. PINFO(TEXT("for share [%s]"), lpLE->name);
  804. wAddlItems = 0;
  805. ret = NDdeShareGetInfo (NULL,
  806. lpLE->name,
  807. 2,
  808. (LPBYTE)lpDdeI,
  809. 2048 * sizeof(TCHAR),
  810. &dwRet,
  811. &wAddlItems );
  812. if (!fAlreadyShared)
  813. {
  814. SetShared(lpLE, FALSE);
  815. }
  816. PINFO(TEXT(" GetInfo ret %ld\r\n"), ret);
  817. if (NDDE_ACCESS_DENIED == ret)
  818. {
  819. MessageBoxID(hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME, MB_OK | MB_ICONHAND);
  820. }
  821. else if (ret != NDDE_NO_ERROR)
  822. {
  823. PERROR(TEXT("Error from NDdeShareGetInfo %d\n\r"), ret );
  824. NDdeMessageBox ( hInst,
  825. hwndApp,
  826. (UINT)ret,
  827. IDS_SHAREDLGTITLE,
  828. MB_ICONHAND | MB_OK);
  829. }
  830. else if (ret == NDDE_NO_ERROR)
  831. {
  832. PINFO(TEXT("Dialog "));
  833. // Put up the properties dialog
  834. dwCurrentHelpId = 0; // F1 will be context sensitive
  835. ret = DialogBoxParam (hInst,
  836. fAlreadyShared?
  837. MAKEINTRESOURCE(IDD_PROPERTYDLG):
  838. MAKEINTRESOURCE(IDD_SHAREDLG),
  839. hwnd,
  840. ShareDlgProc,
  841. (LPARAM)lpDdeI );
  842. dwCurrentHelpId = 0;
  843. // If the user hit OK, try to apply the changes asked for.
  844. if (ret)
  845. {
  846. PINFO(TEXT("OK "));
  847. // Change static app/topic to $<pagename> form
  848. if (!fAlreadyShared)
  849. {
  850. register LPTSTR lpOog;
  851. lpOog = lpDdeI->lpszAppTopicList;
  852. // Jump over the first two NULL chars you find-- these
  853. // are the old- and new-style app/topic pairs, we don't
  854. // mess with them. Then jump over the next BAR_CHAR you find.
  855. // The first character after that is the first char of the
  856. // static topic-- change that to a SHR_CHAR.
  857. while (*lpOog++) ;
  858. while (*lpOog++) ;
  859. // FEATURE: TEXT('|') should == BAR_CHAR. If not, this needs to
  860. // be adjusted.
  861. while (*lpOog++ != TEXT('|')) ;
  862. *lpOog = SHR_CHAR;
  863. }
  864. lpDdeI->fSharedFlag = 1L;
  865. // Get current trusted status
  866. if (NDDE_NO_ERROR != NDdeGetTrustedShare (NULL,
  867. lpDdeI->lpszShareName,
  868. adwTrust,
  869. adwTrust + 1,
  870. adwTrust + 2))
  871. {
  872. adwTrust[0] = 0;
  873. }
  874. DumpDdeInfo(lpDdeI, NULL);
  875. ret = NDdeShareSetInfo (NULL,
  876. lpDdeI->lpszShareName,
  877. 2,
  878. (LPBYTE)lpDdeI,
  879. 2048 * sizeof(TCHAR),
  880. 0);
  881. if (NDDE_ACCESS_DENIED == ret)
  882. {
  883. MessageBoxID(hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME,
  884. MB_OK | MB_ICONHAND);
  885. }
  886. else if (NDDE_NO_ERROR != ret)
  887. {
  888. PERROR(TEXT("Error from NDdeShareSetInfo %d\n\r"), ret );
  889. NDdeMessageBox (hInst, hwndApp, (UINT)ret,
  890. IDS_SHAREDLGTITLE, MB_ICONHAND | MB_OK );
  891. }
  892. else
  893. {
  894. NDdeSetTrustedShare(NULL, lpDdeI->lpszShareName, adwTrust[0]);
  895. ///////////////////////////////////////////////
  896. // do the execute to change the server state
  897. StringCchCopy(szBuff, sizeof(szBuff), SZCMD_SHARE);
  898. StringCchCat( szBuff, sizeof(szBuff), lpLE->name);
  899. PINFO(TEXT("sending cmd [%s]\n\r"), szBuff);
  900. if (MySyncXact ((LPBYTE)szBuff,
  901. lstrlen(szBuff) +1,
  902. GETMDIINFO(hwndLocal)->hExeConv,
  903. 0L,
  904. CF_TEXT,
  905. XTYP_EXECUTE,
  906. SHORT_SYNC_TIMEOUT,
  907. NULL))
  908. {
  909. InitializeMenu(GetMenu(hwndApp));
  910. }
  911. else
  912. {
  913. XactMessageBox (hInst, hwnd, IDS_APPNAME, MB_OK | MB_ICONSTOP);
  914. }
  915. }
  916. }
  917. else if (!fAlreadyShared) // User hit cancel on the dialog, restore the original shared state
  918. {
  919. SetShared(lpLE, FALSE);
  920. }
  921. }
  922. GlobalFreePtr(lpDdeI);
  923. return 0L;
  924. }