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.

1574 lines
42 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. * sharebas.cxx
  7. * This file contains the definitions of base share dialog class,
  8. * and some common classes used by the share dialogs,
  9. * including SHARE_DIALOG_BASE, SHARE_LEVEL_PERMISSIONS_DIALOG,
  10. * PERMISSION_GROUP, SHARE_NAME_WITH_PATH_ENUM_ITER,
  11. * SERVER_WITH_PASSWORD_PROMPT and SHARE_NET_NAME.
  12. *
  13. * History:
  14. * Yi-HsinS 8/15/91 Created
  15. * Yi-HsinS 11/15/91 Changed all USHORT to UINT
  16. * Yi-HsinS 12/5/91 Test more thoroughly for invalid
  17. * path name
  18. * Yi-HsinS 12/6/91 Uses NET_NAME
  19. * Yi-HsinS 12/31/91 Unicode work
  20. * Yi-HsinS 1/8/92 Moved SHARE_PROPERTIES_BASE to
  21. * sharewnp.cxx
  22. * Yi-HsinS 3/12/92 Added ACCESS_PERM to PERMISSIONS_GROUP
  23. * Terryk 4/12/92 Change USER limit from UINT to ULONG
  24. * Yi-HsinS 4/21/92 Remove unnecessay code, and remove
  25. * _uiSpecialUserLimit
  26. * Yi-HsinS 5/15/92 Make password dialog show up only if
  27. * focus on share-level servers
  28. * Yi-HsinS 8/6/92 Reorganize to match Winball dialogs.
  29. * ChuckC 8/12/92 Added support for ACLs on Shares.
  30. * Yi-HsinS 11/16/92 Removed SLT_ADMININFO
  31. * YiHsinS 4/2/93 Disable viewing/changing permission on special
  32. * shares ( [A-Z]$, IPC$, ADMIN$ )
  33. */
  34. #define INCL_WINDOWS_GDI
  35. #define INCL_WINDOWS
  36. #define INCL_DOSERRORS
  37. #define INCL_NETERRORS
  38. #define INCL_NETSHARE
  39. #define INCL_NETSERVER
  40. #define INCL_NETWKSTA
  41. #define INCL_NETLIB
  42. #include <lmui.hxx>
  43. extern "C"
  44. {
  45. #include <sharedlg.h>
  46. #include <helpnums.h>
  47. }
  48. #define INCL_BLT_DIALOG
  49. #define INCL_BLT_CONTROL
  50. #define INCL_BLT_MSGPOPUP
  51. #define INCL_BLT_SPIN_GROUP
  52. #define INCL_BLT_GROUP
  53. #include <blt.hxx>
  54. #include <string.hxx>
  55. #include <uitrace.hxx>
  56. #include <dbgstr.hxx>
  57. #include <lmoesh.hxx>
  58. #include <lmoeusr.hxx>
  59. #include <lmosrv.hxx>
  60. #include <lmoshare.hxx>
  61. #include <lmowks.hxx>
  62. #include <strchlit.hxx> // for string and character constants
  63. #include "sharebas.hxx"
  64. #include <shareacl.hxx> // for the function prototypes
  65. #define USERS_DEFAULT 10
  66. #define USERS_MIN 1
  67. #define PERM_DEFAULT_LEN 7 // length of "RWCXDAP"
  68. /*******************************************************************
  69. NAME: SHARE_DIALOG_BASE::SHARE_DIALOG_BASE
  70. SYNOPSIS: Constructor for SHARE_DIALOG_BASE class
  71. ENTRY: pszDlgResource - resource name for DIALOG_WINDOW
  72. hwndParent - handle of parent window
  73. ulMaxUserLimit - the maximum user limit to be set
  74. in the user limit spin button
  75. ulHelpContextBase - the base help context
  76. EXIT:
  77. RETURNS:
  78. NOTES:
  79. HISTORY:
  80. Yi-HsinS 8/15/91 Created
  81. Yi-HsinS 1/17/91 Added _uiSpecialUserLimit
  82. Yi-HsinS 4/25/91 Remove _uiSpecialUserLimit
  83. Yi-HsinS 10/9/92 Added _ulHelpContextBase
  84. ********************************************************************/
  85. SHARE_DIALOG_BASE::SHARE_DIALOG_BASE( const TCHAR *pszDlgResource,
  86. HWND hwndParent,
  87. ULONG ulHelpContextBase,
  88. ULONG ulMaxUserLimit )
  89. : DIALOG_WINDOW ( pszDlgResource, hwndParent ),
  90. _slePath( this, SLE_PATH ),
  91. _sleComment( this, SLE_COMMENT, SHARE_COMMENT_LENGTH ),
  92. _mgrpUserLimit( this, RB_UNLIMITED, 2, RB_UNLIMITED), // 2 buttons
  93. _spsleUsers( this, SLE_USERS, USERS_DEFAULT,
  94. USERS_MIN, ulMaxUserLimit - USERS_MIN + 1, TRUE,
  95. FRAME_USERS ),
  96. _spgrpUsers( this, SB_USERS_GROUP, SB_USERS_UP, SB_USERS_DOWN),
  97. _buttonOK( this, IDOK ),
  98. _buttonCancel( this, IDCANCEL ),
  99. _buttonPermissions( this, BUTTON_PERMISSIONS ),
  100. _pStoredSecDesc( NULL ), // default : NULL
  101. _fSecDescModified( FALSE ), // initially unchanged
  102. _nlsStoredPassword(), // default : empty string
  103. _uiStoredPermissions( ACCESS_READ | ACCESS_EXEC ), // default permission
  104. _fStoredAdminOnly( FALSE ),
  105. _ulHelpContextBase( ulHelpContextBase )
  106. {
  107. if ( QueryError() != NERR_Success )
  108. return;
  109. APIERR err;
  110. if ( ((err = _mgrpUserLimit.QueryError()) != NERR_Success )
  111. || ((err = _spgrpUsers.AddAssociation( &_spsleUsers )) != NERR_Success )
  112. || ((err = _mgrpUserLimit.AddAssociation( RB_USERS, &_spgrpUsers ))
  113. != NERR_Success )
  114. || ((err = _nlsStoredPassword.QueryError()) != NERR_Success )
  115. )
  116. {
  117. ReportError( err );
  118. return;
  119. }
  120. }
  121. /*******************************************************************
  122. NAME: SHARE_DIALOG_BASE::~SHARE_DIALOG_BASE
  123. SYNOPSIS: Destructor for SHARE_DIALOG_BASE class
  124. ENTRY:
  125. EXIT:
  126. RETURNS:
  127. NOTES:
  128. HISTORY:
  129. Yi-HsinS 8/15/91 Created
  130. ********************************************************************/
  131. SHARE_DIALOG_BASE::~SHARE_DIALOG_BASE()
  132. {
  133. delete _pStoredSecDesc;
  134. SecureZeroMemory((LPVOID) _nlsStoredPassword.QueryPch(), _nlsStoredPassword.QueryTextSize());
  135. _pStoredSecDesc = NULL;
  136. }
  137. /*******************************************************************
  138. NAME: SHARE_DIALOG_BASE::ClearStoredInfo
  139. SYNOPSIS: Clear the permission or security description stored
  140. internally.
  141. ENTRY:
  142. EXIT:
  143. RETURNS:
  144. NOTES:
  145. HISTORY:
  146. Yi-HsinS 8/6/92 Created
  147. ********************************************************************/
  148. APIERR SHARE_DIALOG_BASE::ClearStoredInfo( VOID )
  149. {
  150. delete _pStoredSecDesc;
  151. _pStoredSecDesc = NULL;
  152. _nlsStoredPassword = EMPTY_STRING;
  153. _uiStoredPermissions = ACCESS_READ | ACCESS_EXEC;
  154. return _nlsStoredPassword.QueryError();
  155. }
  156. /*******************************************************************
  157. NAME: SHARE_DIALOG_BASE::UpdateInfo
  158. SYNOPSIS: Set the information about the share in the dialog
  159. ENTRY: psvr - pointer to the server object that the share is on
  160. pszShare - the share to display
  161. EXIT:
  162. RETURNS:
  163. NOTES:
  164. HISTORY:
  165. Yi-HsinS 8/15/91 Created
  166. ********************************************************************/
  167. APIERR SHARE_DIALOG_BASE::UpdateInfo( SERVER_WITH_PASSWORD_PROMPT *psvr,
  168. const TCHAR *pszShare )
  169. {
  170. AUTO_CURSOR autocur;
  171. UIASSERT( psvr != NULL );
  172. UIASSERT( pszShare != NULL );
  173. APIERR err;
  174. SHARE_2 sh2( pszShare, psvr->QueryName(), FALSE );
  175. if ( ((err = sh2.QueryError() ) == NERR_Success )
  176. && ((err = sh2.GetInfo()) == NERR_Success )
  177. )
  178. {
  179. if ( _slePath.QueryTextLength() == 0
  180. && NULL != sh2.QueryPath() ) // JonN 01/27/00: PREFIX bug 444916
  181. SetPath( sh2.QueryPath() );
  182. SetComment( sh2.QueryComment() );
  183. SetUserLimit( sh2.QueryMaxUses() );
  184. err = UpdatePermissionsInfo( psvr, &sh2, pszShare );
  185. }
  186. return err;
  187. }
  188. /*******************************************************************
  189. NAME: SHARE_DIALOG_BASE::UpdatePermissionsInfo
  190. SYNOPSIS: Set the permissions information about the share
  191. ENTRY: psvr - pointer to the server object that the share is on
  192. psh2 - pointer to an existing SHARE_2 object
  193. pszShare - the share to display
  194. EXIT:
  195. RETURNS:
  196. NOTES:
  197. HISTORY:
  198. JonN 11/22/93 Created
  199. ********************************************************************/
  200. APIERR SHARE_DIALOG_BASE::UpdatePermissionsInfo(
  201. SERVER_WITH_PASSWORD_PROMPT *psvr,
  202. SHARE_2 * psh2,
  203. const TCHAR *pszShare )
  204. {
  205. AUTO_CURSOR autocur;
  206. UIASSERT( psvr != NULL );
  207. UIASSERT( psh2 != NULL );
  208. UIASSERT( pszShare != NULL );
  209. APIERR err = NERR_Success;
  210. if ( psvr->IsNT() )
  211. {
  212. _fSecDescModified = FALSE ;
  213. if ( psh2->IsAdminOnly() ) // There are no security descriptors in
  214. // special shares.
  215. {
  216. delete _pStoredSecDesc;
  217. _pStoredSecDesc = NULL;
  218. _fStoredAdminOnly = TRUE;
  219. }
  220. else
  221. {
  222. _fStoredAdminOnly = FALSE;
  223. err = QuerySharePermissions( psvr->QueryName(),
  224. pszShare,
  225. &_pStoredSecDesc );
  226. }
  227. }
  228. else if ( psvr->IsShareLevel() ) // LM 2.x share-level server
  229. {
  230. _nlsStoredPassword = psh2->QueryPassword();
  231. _uiStoredPermissions = psh2->QueryPermissions();
  232. err = _nlsStoredPassword.QueryError();
  233. }
  234. //
  235. // Do not need to get permissions on LM2.x user-level server
  236. // because it has no permissions for shares.
  237. //
  238. return err;
  239. }
  240. /*******************************************************************
  241. NAME: SHARE_DIALOG_BASE::OnChangeShareProperty
  242. SYNOPSIS: Helper method to change the properties of the share
  243. ENTRY: psvr - pointer the server object that the share is on
  244. pszShare - the share that we want to change properties on
  245. EXIT:
  246. RETURNS:
  247. NOTES:
  248. HISTORY:
  249. Yi-HsinS 8/15/91 Created
  250. ********************************************************************/
  251. APIERR SHARE_DIALOG_BASE::OnChangeShareProperty(
  252. SERVER_WITH_PASSWORD_PROMPT *psvr,
  253. const TCHAR *pszShare )
  254. {
  255. APIERR err;
  256. UIASSERT( psvr != NULL );
  257. UIASSERT( pszShare != NULL );
  258. //
  259. // Get all information about the share
  260. //
  261. SHARE_2 sh2( pszShare, psvr->QueryName(), FALSE);
  262. NLS_STR nlsComment;
  263. do { // Not a loop
  264. if ( ((err = sh2.QueryError() ) != NERR_Success )
  265. || ((err = sh2.GetInfo()) != NERR_Success )
  266. || ((err = nlsComment.QueryError()) != NERR_Success )
  267. )
  268. {
  269. break;
  270. }
  271. //
  272. // Set validation flag to TRUE to enable checking for invalid
  273. // information set to the share object.
  274. //
  275. sh2.SetValidation( TRUE );
  276. //
  277. // Query, validate and set the comment on the share
  278. //
  279. if ( ((err = QueryComment( &nlsComment )) != NERR_Success )
  280. || ((err = sh2.SetComment( nlsComment )) != NERR_Success )
  281. )
  282. {
  283. err = ( err == ERROR_INVALID_PARAMETER ) ?
  284. (APIERR) IERR_SHARE_INVALID_COMMENT : err;
  285. SetFocusOnComment();
  286. break;
  287. }
  288. //
  289. // Set the max uses on the share
  290. //
  291. if ((err = sh2.SetMaxUses( (UINT) QueryUserLimit())) != NERR_Success )
  292. {
  293. SetFocusOnUserLimit();
  294. break;
  295. }
  296. //
  297. // Set the permissions on the share if it's on LM share level servers
  298. //
  299. if ( !psvr->IsNT() && psvr->IsShareLevel() )
  300. {
  301. //
  302. // Upper case the password => same as netcmd
  303. // since Share-level servers are down level servers only
  304. //
  305. _nlsStoredPassword._strupr();
  306. //
  307. // Give a warning if the user wants to change the password
  308. //
  309. if ( ::stricmpf( _nlsStoredPassword, sh2.QueryPassword() ) != 0 )
  310. {
  311. NLS_STR nlsComputer;
  312. if ( ((err = nlsComputer.QueryError()) != NERR_Success )
  313. || ((err = psvr->QueryDisplayName( &nlsComputer ))
  314. != NERR_Success )
  315. )
  316. {
  317. break;
  318. }
  319. if ( ::MsgPopup( this,
  320. (MSGID) IDS_SHARE_PROP_CHANGE_PASSWD_WARN_TEXT,
  321. MPSEV_WARNING, MP_OKCANCEL,
  322. nlsComputer.QueryPch(),
  323. sh2.QueryName(), MP_CANCEL ) == IDCANCEL )
  324. {
  325. //
  326. // User click CANCEL =>
  327. // Reset password to the original value!
  328. //
  329. _nlsStoredPassword = sh2.QueryPassword();
  330. err = IERR_USER_CLICKED_CANCEL;
  331. break;
  332. }
  333. //
  334. // Set the password on the share
  335. //
  336. if (( err = sh2.SetPassword( _nlsStoredPassword ))
  337. != NERR_Success )
  338. break;
  339. }
  340. //
  341. // We are successful up to this point, so set the permissions
  342. //
  343. if ( (err = sh2.SetPermissions( _uiStoredPermissions ))
  344. != NERR_Success )
  345. break;
  346. }
  347. //
  348. // Write the information out
  349. //
  350. if ( (err = sh2.WriteInfo()) != NERR_Success )
  351. break;
  352. //
  353. // If the share is on an NT server and it is not
  354. // a special share, set the permission to it.
  355. //
  356. if ( psvr->IsNT() && !sh2.IsAdminOnly() )
  357. {
  358. err = ApplySharePermissions( sh2.QueryServer(),
  359. sh2.QueryName(),
  360. QueryStoredSecDesc() );
  361. if (err)
  362. break ;
  363. }
  364. // Falls through if error occurs
  365. }
  366. while (FALSE);
  367. return err;
  368. }
  369. /*******************************************************************
  370. NAME: SHARE_DIALOG_BASE::OnCommand
  371. SYNOPSIS: Handle the case where the user clicked the permission button
  372. ENTRY: event - the CONTROL_EVENT that occurred
  373. EXIT:
  374. RETURNS:
  375. NOTES:
  376. HISTORY:
  377. Yi-HsinS 8/6/92 Created
  378. ********************************************************************/
  379. BOOL SHARE_DIALOG_BASE::OnCommand( const CONTROL_EVENT &event )
  380. {
  381. APIERR err = NERR_Success;
  382. if ( event.QueryCid() == BUTTON_PERMISSIONS )
  383. {
  384. OnPermissions();
  385. return TRUE;
  386. }
  387. return DIALOG_WINDOW::OnCommand( event );
  388. }
  389. /*******************************************************************
  390. NAME: SHARE_DIALOG_BASE::OnPermissions
  391. SYNOPSIS: Helper method to popup the permission dialog
  392. when the permission button is clicked
  393. ENTRY:
  394. EXIT:
  395. RETURNS:
  396. NOTES:
  397. HISTORY:
  398. Yi-HsinS 8/6/92 Created
  399. ********************************************************************/
  400. VOID SHARE_DIALOG_BASE::OnPermissions( VOID )
  401. {
  402. AUTO_CURSOR autocur;
  403. //
  404. // Get the server that the share is on
  405. //
  406. SERVER_WITH_PASSWORD_PROMPT *psvr = NULL;
  407. APIERR err = QueryServer2( &psvr );
  408. if ( err == NERR_Success )
  409. {
  410. if ( psvr->IsNT() ) // On NT servers
  411. {
  412. //
  413. // If we are viewing a admin only share,
  414. // we cannot change permission on it.
  415. //
  416. if ( _fStoredAdminOnly )
  417. {
  418. err = IERR_SPECIAL_SHARE_CANNOT_SET_PERMISSIONS;
  419. }
  420. else
  421. {
  422. NLS_STR nlsShare;
  423. if ( ((err = nlsShare.QueryError()) == NERR_Success )
  424. && ((err = QueryShare( &nlsShare )) == NERR_Success )
  425. )
  426. {
  427. err = EditShareAcl( QueryHwnd(),
  428. psvr->QueryName(),
  429. nlsShare.QueryPch(),
  430. &_fSecDescModified,
  431. &_pStoredSecDesc,
  432. QueryHelpContextBase() ) ;
  433. }
  434. }
  435. }
  436. else if ( psvr->IsShareLevel() ) // On LM share-level server
  437. {
  438. SHARE_LEVEL_PERMISSIONS_DIALOG *pdlg =
  439. new SHARE_LEVEL_PERMISSIONS_DIALOG( QueryHwnd(),
  440. &_nlsStoredPassword,
  441. &_uiStoredPermissions,
  442. QueryHelpContextBase() );
  443. if ( ( pdlg == NULL )
  444. || (( pdlg->QueryError()) != NERR_Success )
  445. || (( pdlg->Process()) != NERR_Success )
  446. )
  447. {
  448. err = err? err: ERROR_NOT_ENOUGH_MEMORY;
  449. }
  450. delete pdlg;
  451. }
  452. else // On LM user-level server
  453. {
  454. err = IERR_CANNOT_SET_PERM_ON_LMUSER_SERVER;
  455. }
  456. }
  457. if ( err != NERR_Success )
  458. {
  459. if ( (err == IERR_CANNOT_SET_PERM_ON_LMUSER_SERVER )
  460. || (err == IERR_SPECIAL_SHARE_CANNOT_SET_PERMISSIONS )
  461. )
  462. {
  463. ::MsgPopup( this, err, MPSEV_WARNING );
  464. }
  465. else
  466. {
  467. ::MsgPopup( this, err );
  468. }
  469. }
  470. }
  471. /*******************************************************************
  472. NAME: SHARE_DIALOG_BASE::SetMaxUserLimit
  473. SYNOPSIS: Set the maximum number of users in the spin button
  474. ENTRY: ulMaxUserLimit - the maximum user limit to be set
  475. in the spin button
  476. EXIT:
  477. RETURNS:
  478. NOTES: We need this because the maximum number of users on
  479. LM servers and on NT servers are different.
  480. HISTORY:
  481. Yi-HsinS 1/17/92 Created
  482. ********************************************************************/
  483. APIERR SHARE_DIALOG_BASE::SetMaxUserLimit( ULONG ulMaxUserLimit )
  484. {
  485. APIERR err = NERR_Success;
  486. if (ulMaxUserLimit < _spsleUsers.QueryValue())
  487. {
  488. // the maximum is less than the default, so adjust the default
  489. err = _spsleUsers.SetSaveValue(ulMaxUserLimit);
  490. }
  491. _spsleUsers.SetRange( ulMaxUserLimit - USERS_MIN + 1);
  492. return err;
  493. }
  494. /*******************************************************************
  495. NAME: SHARE_DIALOG_BASE::QueryUserLimit
  496. SYNOPSIS: Get the user limit from the magic group
  497. ENTRY:
  498. EXIT:
  499. RETURNS: The user limit stored in the user limit magic group
  500. NOTES:
  501. HISTORY:
  502. Yi-HsinS 8/15/91 Created
  503. ********************************************************************/
  504. ULONG SHARE_DIALOG_BASE::QueryUserLimit( VOID ) const
  505. {
  506. ULONG ulUserLimit;
  507. switch ( _mgrpUserLimit.QuerySelection() )
  508. {
  509. case RB_UNLIMITED:
  510. ulUserLimit = (ULONG) SHI_USES_UNLIMITED;
  511. break;
  512. case RB_USERS:
  513. // We don't need to check whether the value is valid or not
  514. // because SPIN_BUTTON checks it.
  515. ulUserLimit = _spsleUsers.QueryValue();
  516. UIASSERT( ( ulUserLimit <= _spsleUsers.QueryMax() )
  517. && ( ulUserLimit >= USERS_MIN )
  518. );
  519. break;
  520. default:
  521. UIASSERT(!SZ("User Limit: This shouldn't have happened!\n\r"));
  522. ulUserLimit = (ULONG) SHI_USES_UNLIMITED;
  523. break;
  524. }
  525. return ulUserLimit;
  526. }
  527. /*******************************************************************
  528. NAME: SHARE_DIALOG_BASE::SetUserLimit
  529. SYNOPSIS: Sets the user limit on the magic group
  530. ENTRY: ulUserLimit - maximum number of users allowed
  531. EXIT:
  532. RETURNS: NERR_Success
  533. NOTES: If the limit is invalid, sets it to "Maximum allowed".
  534. HISTORY:
  535. Yi-HsinS 8/15/91 Created
  536. ********************************************************************/
  537. APIERR SHARE_DIALOG_BASE::SetUserLimit( ULONG ulUserLimit )
  538. {
  539. APIERR err = NERR_Success;
  540. if ( ulUserLimit == (ULONG) SHI_USES_UNLIMITED )
  541. {
  542. // Set selection to the Unlimited button
  543. _mgrpUserLimit.SetSelection( RB_UNLIMITED );
  544. ULONG ulMaxUserLimit = _spsleUsers.QueryMax();
  545. ULONG ulNewUserLimit = (ulMaxUserLimit < USERS_DEFAULT) ? ulMaxUserLimit : USERS_DEFAULT;
  546. _spsleUsers.SetSaveValue( ulNewUserLimit );
  547. }
  548. else if ( ( ulUserLimit >= USERS_MIN)
  549. && ( ulUserLimit <= _spsleUsers.QueryMax())
  550. )
  551. {
  552. // Set the Users button
  553. _mgrpUserLimit.SetSelection( RB_USERS );
  554. _spsleUsers.SetValue( ulUserLimit );
  555. _spsleUsers.Update();
  556. }
  557. else
  558. {
  559. // The user limit wasn't in range. Go back and set the share to
  560. // "maximum allowed".
  561. return SetUserLimit((ULONG)SHI_USES_UNLIMITED);
  562. }
  563. return err;
  564. }
  565. /*******************************************************************
  566. NAME: SHARE_DIALOG_BASE::ApplySharePermissions
  567. SYNOPSIS: Sets the NT permissions of a share (security descriptor)
  568. ENTRY: pszServer - the server that the share is on
  569. pszShare - the share that we want to set permissions on
  570. posSecDesc - the security descriptor to be set to the share
  571. EXIT:
  572. RETURNS:
  573. NOTES:
  574. HISTORY:
  575. ChuckC 8/10/92 Created
  576. ********************************************************************/
  577. APIERR SHARE_DIALOG_BASE::ApplySharePermissions( const TCHAR *pszServer,
  578. const TCHAR *pszShare,
  579. const OS_SECURITY_DESCRIPTOR *
  580. posSecDesc)
  581. {
  582. UIASSERT(pszShare) ;
  583. // if nothing changed, no need to set.
  584. if (!_fSecDescModified)
  585. return NERR_Success ;
  586. return ( ::SetSharePerm(pszServer,
  587. pszShare,
  588. posSecDesc) ) ;
  589. }
  590. /*******************************************************************
  591. NAME: SHARE_DIALOG_BASE::QuerySharePermissions
  592. SYNOPSIS: Gets the NT permissions of a share (security descriptor)
  593. ENTRY: pszServer - the server that the share is on
  594. pszShare - the share that we want to set permissions on
  595. EXIT: posSecDesc - pointer to the security descriptor
  596. of the share
  597. RETURNS:
  598. NOTES:
  599. HISTORY:
  600. ChuckC 8/10/92 Created
  601. ********************************************************************/
  602. APIERR SHARE_DIALOG_BASE::QuerySharePermissions( const TCHAR *pszServer,
  603. const TCHAR *pszShare,
  604. OS_SECURITY_DESCRIPTOR **pposSecDesc)
  605. {
  606. UIASSERT(pszShare) ;
  607. UIASSERT(pposSecDesc) ;
  608. return ( ::GetSharePerm(pszServer,
  609. pszShare,
  610. pposSecDesc) ) ;
  611. }
  612. /*******************************************************************
  613. NAME: SHARE_LEVEL_PERMISSIONS_DIALOG
  614. SYNOPSIS: The permission dialog for LM share-level servers
  615. ENTRY: hwndParent - parent window
  616. pnlsPassword - the initial password to be displayed and
  617. place to return the password typed by the
  618. user
  619. puiPermissions - the initial permission to be displayed and
  620. place to return the permission entered by
  621. the user
  622. ulHelpContextBase - the base help context
  623. EXIT:
  624. RETURNS:
  625. NOTES:
  626. HISTORY:
  627. Yi-HsinS 8/15/91 Created
  628. ********************************************************************/
  629. SHARE_LEVEL_PERMISSIONS_DIALOG::SHARE_LEVEL_PERMISSIONS_DIALOG( HWND hwndParent,
  630. NLS_STR *pnlsPassword,
  631. UINT *puiPermissions,
  632. ULONG ulHelpContextBase )
  633. : DIALOG_WINDOW ( IDD_SHAREPERMDLG, hwndParent ),
  634. _pnlsPassword ( pnlsPassword ),
  635. _puiPermissions( puiPermissions ),
  636. _permgrp ( this, RB_READONLY, SLE_OTHER ),
  637. _slePassword ( this, SLE_PASSWORD, SHPWLEN ),
  638. _ulHelpContextBase( ulHelpContextBase )
  639. {
  640. UIASSERT( pnlsPassword != NULL );
  641. UIASSERT( puiPermissions != NULL );
  642. if ( QueryError() != NERR_Success )
  643. return;
  644. APIERR err;
  645. if ( ((err = _permgrp.QueryError()) != NERR_Success )
  646. || ((err = _permgrp.SetPermission( *_puiPermissions )) != NERR_Success)
  647. )
  648. {
  649. ReportError( err );
  650. return;
  651. }
  652. _slePassword.SetText( *_pnlsPassword );
  653. _permgrp.ClaimFocus();
  654. }
  655. /*******************************************************************
  656. NAME: SHARE_LEVEL_PERMISSION_DIALOG::OnOK
  657. SYNOPSIS: Validate and return the password/permission that
  658. the user entered.
  659. ENTRY:
  660. EXIT:
  661. RETURNS:
  662. NOTES:
  663. HISTORY:
  664. Yi-HsinS 8/25/91 Created
  665. ********************************************************************/
  666. BOOL SHARE_LEVEL_PERMISSIONS_DIALOG::OnOK( VOID )
  667. {
  668. APIERR err = NERR_Success;
  669. UINT uiPerm;
  670. if ( ( err = _permgrp.QueryPermission( &uiPerm ) ) != NERR_Success)
  671. {
  672. err = IERR_SHARE_INVALID_PERMISSIONS;
  673. _permgrp.SetFocusOnOther();
  674. }
  675. else
  676. {
  677. *_puiPermissions = uiPerm;
  678. err = _slePassword.QueryText( _pnlsPassword );
  679. }
  680. if ( err == NERR_Success )
  681. {
  682. Dismiss( TRUE );
  683. }
  684. else
  685. {
  686. ::MsgPopup( this, err );
  687. }
  688. return TRUE;
  689. }
  690. /*******************************************************************
  691. NAME: SHARE_LEVEL_PERMISSIONS_DIALOG::QueryHelpContext
  692. SYNOPSIS: Query the help context of the dialog
  693. ENTRY:
  694. EXIT:
  695. RETURNS: Return the help context of the dialog
  696. NOTES:
  697. HISTORY:
  698. Yi-HsinS 8/25/91 Created
  699. ********************************************************************/
  700. ULONG SHARE_LEVEL_PERMISSIONS_DIALOG::QueryHelpContext( VOID )
  701. {
  702. return _ulHelpContextBase + HC_LMSHARELEVELPERMS;
  703. }
  704. /*******************************************************************
  705. NAME: PERMISSION_GROUP::PERMISSION_GROUP
  706. SYNOPSIS: Constructor for PERMISSION_GROUP
  707. ENTRY: powin - pointer to the parent window
  708. cidBase - CID of first button of the permission group
  709. cidOtherEditField - CID of the Other Edit field
  710. cidInitialSelection - CID of the initial selection
  711. pGroupOwner - pointer to owner group
  712. EXIT:
  713. RETURNS:
  714. NOTES:
  715. HISTORY:
  716. Yi-HsinS 8/15/91 Created
  717. ********************************************************************/
  718. //
  719. // Table for converting permissions from string to UINT and vice versa.
  720. //
  721. static struct {
  722. WCHAR chPerm;
  723. UINT uiPerm;
  724. } permTable[] = {
  725. { READ_CHAR, ACCESS_READ},
  726. { WRITE_CHAR, ACCESS_WRITE},
  727. { CREATE_CHAR, ACCESS_CREATE},
  728. { EXEC_CHAR, ACCESS_EXEC},
  729. { DEL_CHAR, ACCESS_DELETE},
  730. { ACCESS_CHAR, ACCESS_ATRIB},
  731. { PERM_CHAR, ACCESS_PERM}
  732. };
  733. PERMISSION_GROUP::PERMISSION_GROUP( OWNER_WINDOW *powin,
  734. CID cidBase,
  735. CID cidOtherEditField,
  736. CID cidInitialSelection,
  737. CONTROL_GROUP *pGroupOwner)
  738. : _mgrpPermission( powin, cidBase, 3, cidInitialSelection, pGroupOwner),
  739. // 3 is the number of buttons in the magic group
  740. _sleOther(powin, cidOtherEditField, PERM_DEFAULT_LEN )
  741. {
  742. if ( QueryError() != NERR_Success )
  743. return;
  744. APIERR err;
  745. if ( ((err = _mgrpPermission.QueryError()) != NERR_Success )
  746. || ((err = _mgrpPermission.AddAssociation( RB_OTHER, &_sleOther ))
  747. != NERR_Success )
  748. )
  749. {
  750. ReportError( err );
  751. return;
  752. }
  753. }
  754. /*******************************************************************
  755. NAME: PERMISSION_GROUP::GetAndCheckOtherField
  756. SYNOPSIS: Validate the contents in "Other" Edit field
  757. ENTRY:
  758. EXIT: puiPermission - the permission
  759. RETURNS: returns ERROR_INVALID_PARAMETER if the string in
  760. other edit field is not valid
  761. NOTES:
  762. HISTORY:
  763. Yi-HsinS 8/15/91 Created
  764. ********************************************************************/
  765. APIERR PERMISSION_GROUP::GetAndCheckOtherField( UINT *puiPermission ) const
  766. {
  767. APIERR err = NERR_Success;
  768. NLS_STR nlsOther( PERM_DEFAULT_LEN );
  769. if ( (( err = nlsOther.QueryError()) != NERR_Success )
  770. || (( err = _sleOther.QueryText( &nlsOther )) != NERR_Success )
  771. )
  772. {
  773. return err;
  774. }
  775. nlsOther._strupr();
  776. *puiPermission = 0;
  777. ISTR istrOther( nlsOther );
  778. BOOL fFound = FALSE; // A flag indicating whether a valid char is found
  779. // in the permission string.
  780. while ( nlsOther.QueryChar( istrOther) != STRING_TERMINATOR )
  781. {
  782. for ( UINT i = 0; i < PERM_DEFAULT_LEN; i++ )
  783. {
  784. if ( nlsOther.QueryChar( istrOther ) == permTable[i].chPerm )
  785. {
  786. fFound = TRUE;
  787. if ( !(*puiPermission & permTable[i].uiPerm ))
  788. {
  789. *puiPermission |= permTable[i].uiPerm;
  790. break; // break the for loop but continue the while loop
  791. }
  792. else
  793. return ERROR_INVALID_PARAMETER;
  794. }
  795. else if ( nlsOther.QueryChar( istrOther) == SPACE )
  796. fFound = TRUE;
  797. }
  798. //
  799. // If the current character does not belong to "RWCXDAP" or is not
  800. // a space, then error
  801. //
  802. if ( fFound )
  803. fFound = FALSE;
  804. else
  805. return ERROR_INVALID_PARAMETER;
  806. ++istrOther;
  807. }
  808. //
  809. // If the assigned permission is still zero, then the user
  810. // did not type anything in _sleOther.
  811. //
  812. if ( *puiPermission == 0 )
  813. return ERROR_INVALID_PARAMETER;
  814. else
  815. return NERR_Success;
  816. }
  817. /*******************************************************************
  818. NAME: PERMISSION_GROUP::SetPermission
  819. SYNOPSIS: Check the permission to see if it's READ_ONLY or MODIFY.
  820. If yes, set the corresponding radio button. Else convert
  821. the permission to a string of "RWCXDAP" and displayed
  822. it on the Other Edit field
  823. ENTRY: uiPermission - the permission
  824. EXIT:
  825. RETURNS:
  826. NOTES:
  827. HISTORY:
  828. Yi-HsinS 8/15/91 Created
  829. ********************************************************************/
  830. APIERR PERMISSION_GROUP::SetPermission( UINT uiPermission )
  831. {
  832. if ( (uiPermission & ACCESS_ALL ) == (ACCESS_READ | ACCESS_EXEC) )
  833. {
  834. _sleOther.SetText( EMPTY_STRING );
  835. _mgrpPermission.SetSelection( RB_READONLY );
  836. }
  837. else if ( (uiPermission & ACCESS_ALL ) == (ACCESS_ALL & ~ACCESS_PERM))
  838. {
  839. _sleOther.SetText( EMPTY_STRING );
  840. _mgrpPermission.SetSelection( RB_MODIFY );
  841. }
  842. else
  843. {
  844. NLS_STR nlsPermission( PERM_DEFAULT_LEN );
  845. APIERR err = NERR_Success;
  846. if ( ( err = nlsPermission.QueryError()) != NERR_Success )
  847. return err;
  848. for ( UINT i = 0; i < PERM_DEFAULT_LEN; i++ )
  849. {
  850. if ( uiPermission & permTable[i].uiPerm )
  851. {
  852. if ( (err = nlsPermission.AppendChar( permTable[i].chPerm ))
  853. != NERR_Success )
  854. return err;
  855. }
  856. }
  857. _mgrpPermission.SetSelection( RB_OTHER );
  858. _sleOther.SetText( nlsPermission );
  859. }
  860. return NERR_Success;
  861. }
  862. /*******************************************************************
  863. NAME: PERMISSION_GROUP::QueryPermission
  864. SYNOPSIS: Get the permission from the permission group
  865. ENTRY:
  866. EXIT: puiPermission - will contain the permission
  867. RETURNS:
  868. NOTES:
  869. HISTORY:
  870. Yi-HsinS 8/15/91 Created
  871. ********************************************************************/
  872. APIERR PERMISSION_GROUP::QueryPermission( UINT *puiPermission ) const
  873. {
  874. APIERR err = NERR_Success;
  875. switch ( _mgrpPermission.QuerySelection() )
  876. {
  877. case RB_READONLY:
  878. *puiPermission = ACCESS_READ | ACCESS_EXEC;
  879. break;
  880. case RB_MODIFY:
  881. *puiPermission = ACCESS_ALL & ~ACCESS_PERM;
  882. break;
  883. case RB_OTHER:
  884. err = GetAndCheckOtherField( puiPermission );
  885. break;
  886. }
  887. return err;
  888. }
  889. /*******************************************************************
  890. NAME: SHARE_NAME_WITH_PATH_ENUM_ITER::SHARE_NAME_WITH_PATH_ENUM_ITER
  891. SYNOPSIS: Constructor
  892. ENTRY: sh2Enum - The thing to iterate on
  893. nlsActPath - The path we are interested in finding
  894. EXIT:
  895. RETURNS:
  896. NOTES:
  897. HISTORY:
  898. Yi-HsinS 8/15/91 Created
  899. ********************************************************************/
  900. SHARE_NAME_WITH_PATH_ENUM_ITER::SHARE_NAME_WITH_PATH_ENUM_ITER(
  901. SHARE2_ENUM &sh2Enum,
  902. const NLS_STR &nlsActPath)
  903. : _sh2EnumIter( sh2Enum ),
  904. _nlsActPath( nlsActPath )
  905. {
  906. if ( QueryError() != NERR_Success )
  907. return;
  908. APIERR err;
  909. if ( ( err = _nlsActPath.QueryError() ) != NERR_Success )
  910. {
  911. ReportError( err );
  912. return;
  913. }
  914. }
  915. /*******************************************************************
  916. NAME: SHARE_NAME_WITH_PATH_ENUM_ITER::operator()
  917. SYNOPSIS: iterator
  918. ENTRY:
  919. EXIT:
  920. RETURNS: returns the share name if its path matches the _nlsActPath
  921. NOTES:
  922. HISTORY:
  923. Yi-HsinS 8/15/91 Created
  924. ********************************************************************/
  925. const TCHAR *SHARE_NAME_WITH_PATH_ENUM_ITER::operator()( VOID )
  926. {
  927. const SHARE2_ENUM_OBJ *pshi2;
  928. while ( (pshi2 = _sh2EnumIter()) != NULL )
  929. {
  930. if ( ::stricmpf( pshi2->QueryPath(), _nlsActPath) == 0)
  931. return( pshi2->QueryName());
  932. }
  933. return NULL;
  934. }
  935. /*******************************************************************
  936. NAME: SERVER_WITH_PASSWORD_PROMPT::SERVER_WITH_PASSWORD_PROMPT
  937. SYNOPSIS: Constructor
  938. ENTRY:
  939. EXIT: pszServer - Server name
  940. hwndParent - Handle of the parent window
  941. ulHelpContextBase - The base help context
  942. RETURNS:
  943. NOTES:
  944. HISTORY:
  945. Yi-HsinS 8/15/91 Created
  946. ********************************************************************/
  947. SERVER_WITH_PASSWORD_PROMPT::SERVER_WITH_PASSWORD_PROMPT(const TCHAR *pszServer,
  948. HWND hwndParent,
  949. ULONG ulHelpContextBase )
  950. : SERVER_2( pszServer ),
  951. _hwndParent( hwndParent ),
  952. _pprompt( NULL ),
  953. _ulHelpContextBase( ulHelpContextBase )
  954. {
  955. if ( QueryError() != NERR_Success )
  956. return;
  957. }
  958. /*******************************************************************
  959. NAME: SERVER_WITH_PASSWORD_PROMPT::~SERVER_WITH_PASSWORD_PROMPT
  960. SYNOPSIS: Destructor
  961. ENTRY:
  962. EXIT:
  963. RETURNS:
  964. NOTES:
  965. HISTORY:
  966. Yi-HsinS 8/15/91 Created
  967. ********************************************************************/
  968. SERVER_WITH_PASSWORD_PROMPT::~SERVER_WITH_PASSWORD_PROMPT()
  969. {
  970. delete _pprompt;
  971. _pprompt = NULL;
  972. }
  973. /*******************************************************************
  974. NAME: SERVER_WITH_PASSWORD_PROMPT::I_GetInfo
  975. SYNOPSIS: Get the SERVER_2 Info and if the user does not have admin
  976. privilege and the server is a LM share-level server,
  977. it will pop up a dialog asking for password,
  978. make a connection to the server's ADMIN$ with the
  979. password and attempts to get SERVER_2 info again.
  980. ENTRY:
  981. EXIT:
  982. RETURNS:
  983. NOTES:
  984. HISTORY:
  985. Yi-HsinS 8/15/91 Created
  986. ********************************************************************/
  987. APIERR SERVER_WITH_PASSWORD_PROMPT::I_GetInfo( VOID )
  988. {
  989. APIERR errOriginal = SERVER_2::I_GetInfo();
  990. if ( errOriginal == NERR_Success )
  991. return errOriginal;
  992. APIERR err;
  993. switch ( errOriginal )
  994. {
  995. case ERROR_ACCESS_DENIED:
  996. case ERROR_INVALID_PASSWORD:
  997. {
  998. //
  999. // Check if the machine is user level or share level
  1000. // Return the original error if it's user level
  1001. //
  1002. LOCATION loc( QueryName() );
  1003. BOOL fNT;
  1004. if ( ((err = loc.QueryError()) == NERR_Success )
  1005. && ((err = loc.CheckIfNT( &fNT )) == NERR_Success )
  1006. )
  1007. {
  1008. if ( fNT ) // Always user level
  1009. {
  1010. err = errOriginal;
  1011. break;
  1012. }
  1013. else
  1014. {
  1015. USER0_ENUM usr0( QueryName() );
  1016. if ((err = usr0.QueryError()) != NERR_Success )
  1017. break;
  1018. //
  1019. // ERROR_NOT_SUPPORTED is returned by share level servers
  1020. //
  1021. if ((err = usr0.GetInfo()) != ERROR_NOT_SUPPORTED )
  1022. {
  1023. // user level
  1024. err = errOriginal;
  1025. break;
  1026. }
  1027. }
  1028. }
  1029. else
  1030. {
  1031. break;
  1032. }
  1033. //
  1034. // Prompt password and connect to the ADMIN$ share of
  1035. // share-level servers.
  1036. //
  1037. NLS_STR nlsServer( QueryName() );
  1038. if ( ((err = nlsServer.QueryError()) != NERR_Success )
  1039. || ((err = QueryDisplayName( &nlsServer )) != NERR_Success)
  1040. )
  1041. {
  1042. break;
  1043. }
  1044. NLS_STR nlsAdmin( nlsServer );
  1045. ALIAS_STR nlsAdminShare( ADMIN_SHARE );
  1046. if ( ((err = nlsAdmin.QueryError()) == NERR_Success )
  1047. && ((err = nlsAdmin.AppendChar( PATH_SEPARATOR)) == NERR_Success)
  1048. && ((err = nlsAdmin.Append( nlsAdminShare )) == NERR_Success )
  1049. )
  1050. {
  1051. _pprompt = new PROMPT_AND_CONNECT( _hwndParent,
  1052. nlsAdmin,
  1053. _ulHelpContextBase
  1054. + HC_SHAREPASSWORDPROMPT,
  1055. SHPWLEN);
  1056. if ( ( _pprompt != NULL )
  1057. && ( (err = _pprompt->QueryError()) == NERR_Success )
  1058. && ( (err = _pprompt->Connect()) == NERR_Success )
  1059. )
  1060. {
  1061. if ( _pprompt->IsConnected() )
  1062. {
  1063. err = SERVER_2::I_GetInfo();
  1064. }
  1065. else // user clicks CANCEL in the password dialog
  1066. {
  1067. err = IERR_USER_CLICKED_CANCEL;
  1068. }
  1069. }
  1070. }
  1071. break;
  1072. }
  1073. case NERR_BadTransactConfig:
  1074. err = (APIERR) IERR_SHARE_REMOTE_ADMIN_NOT_SUPPORTED;
  1075. break;
  1076. default:
  1077. err = errOriginal;
  1078. break;
  1079. }
  1080. return err;
  1081. }
  1082. /*******************************************************************
  1083. NAME: SERVER_WITH_PASSWORD_PROMPT::QueryName
  1084. SYNOPSIS: Query the name of the server
  1085. ENTRY:
  1086. EXIT:
  1087. RETURNS:
  1088. NOTES: Redefine SERVER_2::QueryName because we want to return
  1089. EMPTY_STRING instead of NULL when the server is local.
  1090. HISTORY:
  1091. Yi-HsinS 8/15/91 Created
  1092. ********************************************************************/
  1093. const TCHAR *SERVER_WITH_PASSWORD_PROMPT::QueryName( VOID ) const
  1094. {
  1095. if ( SERVER_2::QueryName() == NULL )
  1096. return EMPTY_STRING;
  1097. else
  1098. return SERVER_2::QueryName();
  1099. }
  1100. /*******************************************************************
  1101. NAME: SERVER_WITH_PASSWORD_PROMPT::IsNT
  1102. SYNOPSIS: Check if the server is an NT server or not.
  1103. ENTRY:
  1104. EXIT:
  1105. RETURNS: TRUE if the server is a NT server, FALSE otherwise.
  1106. NOTES:
  1107. HISTORY:
  1108. Yi-HsinS 8/6/92 Created
  1109. ********************************************************************/
  1110. #define NT_NOS_MAJOR_VER 3
  1111. BOOL SERVER_WITH_PASSWORD_PROMPT::IsNT( VOID ) const
  1112. {
  1113. return ( QueryMajorVer() >= NT_NOS_MAJOR_VER );
  1114. }
  1115. /*******************************************************************
  1116. NAME: SHARE_NET_NAME::SHARE_NET_NAME
  1117. SYNOPSIS: Constructor
  1118. ENTRY:
  1119. EXIT:
  1120. RETURNS:
  1121. NOTES: Report why the local server cannot share directories,
  1122. whether it's because NT server service is not started
  1123. or if the local computer is a WIN16 computer
  1124. HISTORY:
  1125. Yi-HsinS 8/15/91 Created
  1126. ********************************************************************/
  1127. SHARE_NET_NAME::SHARE_NET_NAME( const TCHAR *pszSharePath,
  1128. NETNAME_TYPE netNameType )
  1129. : NET_NAME( pszSharePath, netNameType )
  1130. {
  1131. if ( QueryError() != NERR_Success )
  1132. return;
  1133. APIERR err;
  1134. BOOL fLocal = IsLocal( &err );
  1135. if ( err != NERR_Success )
  1136. {
  1137. ReportError( err );
  1138. return;
  1139. }
  1140. if ( !fLocal )
  1141. return;
  1142. //
  1143. // Check whether the local computer can share directories
  1144. //
  1145. if ( IsSharable( &err ) && ( err == NERR_Success ))
  1146. {
  1147. return;
  1148. }
  1149. else if ( err == NERR_Success ) // Not sharable!
  1150. {
  1151. //
  1152. // Determine the reason why the local computer cannot share directories
  1153. //
  1154. LOCATION loc; // Local Computer
  1155. BOOL fNT;
  1156. if ( ((err = loc.QueryError()) == NERR_Success )
  1157. && ((err = loc.CheckIfNT( &fNT )) == NERR_Success )
  1158. )
  1159. {
  1160. // NOTE: What should we do here if we admin NT from
  1161. // WinBall machine?
  1162. if ( !fNT )
  1163. err = NERR_RemoteOnly;
  1164. else
  1165. err = NERR_ServerNotStarted;
  1166. }
  1167. }
  1168. if ( err != NERR_Success )
  1169. {
  1170. ReportError( err );
  1171. return;
  1172. }
  1173. }