home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / utils / sossntr3 / src / ntfsauth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  22.7 KB  |  988 lines

  1. /* NTFS authentication */
  2.  
  3. #include <windows.h>
  4. #include <stdio.h>
  5. #include <io.h>
  6. #include <string.h>
  7. #include <malloc.h>
  8.  
  9. #include "ntfsauth.h"
  10.  
  11. #define PERR(a) printf(a);
  12.  
  13. #define GROUP   "Group"
  14. #define OWNER   "Owner"
  15. #define WORLD   "World"
  16. #define USER    "User"
  17.  
  18. struct NTFSMAP
  19. {
  20.     u_long      unixId;
  21.     char*       Name;
  22.     char*       Type;
  23.     ACCESS_MASK Mask;
  24.     PSID        psid;
  25.     LPSTR       Domain;
  26.     struct NTFSMAP*    next;
  27. };
  28.  
  29. typedef struct NTFSMAP NtfsMap;
  30.  
  31. struct NTFSHOST
  32. {
  33.     LPSTR       Host;
  34.     NtfsMap*    User;
  35.     NtfsMap*    Group;
  36.     NtfsMap*    World;
  37.     struct NTFSHOST*   next;
  38. };
  39. typedef struct NTFSHOST NtfsHost;
  40.  
  41. struct NTFSDRIVE
  42. {
  43.     LPSTR   Type;
  44.     LPSTR   Drive;
  45.     NtfsHost*   Host;
  46.     struct NTFSDRIVE*  next;
  47. };
  48. typedef struct NTFSDRIVE     NtfsDrive;
  49.  
  50.  
  51. static NtfsHost* NtfsInitHost( LPSTR Host);
  52. static NtfsMap* NtfsInitMap( LPSTR Host, LPSTR Type);
  53. static FILE* OpenMapFile( LPSTR FileName);
  54. static BOOL GetNextMapEntry( FILE* fp, u_long* punixId, LPSTR NTName);
  55. static void CloseMapFile( FILE* fp);
  56. static NtfsMap* NtfsGetAttrib( LPSTR FileName, LPSTR Type);
  57. static NtfsMap* NtfsGetOwner( LPSTR FileName);
  58. static NtfsMap* NtfsGetWorld( LPSTR FileName);
  59. static NtfsMap* NtfsGetGroup( LPSTR FileName);
  60. static NtfsDrive* NtfsGetDrive( LPSTR FileName);
  61. static BOOL NtfsSetOwner(  PSECURITY_DESCRIPTOR psd, NtfsDrive* pDrive, 
  62.             u_long unixId);
  63. static BOOL NtfsSetRights(  PACL pAcl, NtfsDrive* pDrive, 
  64.             u_long unixId, u_long na_mode, LPSTR type);
  65. static BOOL NtfsSetGroup(  PACL pAcl, NtfsDrive* pDrive, 
  66.             u_long oldUnixId, u_long newUnixId);
  67. static BOOL NtfsChangeDacl( PACL pAcl, ACCESS_MASK Mask, 
  68.                 PSID pOldSid, PSID pNewSid);
  69.  
  70. static NtfsDrive*   FirstDrive= NULL;
  71. static NtfsHost*    FirstHost = NULL;
  72.            
  73. BOOL NtfsSetUnixAttrib( char* FileName, struct nfsfattr* attr)
  74. {
  75. #define                                 SZ_ABS_SD_BUF  500
  76. #define                                 SZ_DACL_BUF    500
  77. #define                                 SZ_SACL_BUF    500
  78. #define                                 SZ_SID_OWN_BUF 500
  79. #define                                 SZ_SID_PG_BUF  500
  80.     UCHAR                ucBufAbs          [SZ_ABS_SD_BUF];
  81.     UCHAR                ucBufDacl         [SZ_DACL_BUF];
  82.     UCHAR                ucBufDacl2        [SZ_DACL_BUF];
  83.     UCHAR                ucBufSacl         [SZ_SACL_BUF];
  84.     UCHAR                ucBufCtrl         [sizeof(PSECURITY_DESCRIPTOR_CONTROL)];
  85.     UCHAR                ucBufSidOwn       [SZ_SID_OWN_BUF];
  86.     UCHAR                ucBufSidPG        [SZ_SID_PG_BUF];
  87.     DWORD                dwSDLength       = 0;
  88.     DWORD                dwDACLLength     = SZ_DACL_BUF;
  89.     DWORD                dwSACLLength     = SZ_SACL_BUF;
  90.     DWORD                dwSidOwnLength   = SZ_SID_OWN_BUF;
  91.     DWORD                dwSidPGLength    = SZ_SID_PG_BUF;
  92.     DWORD                dwSDLengthNeeded;
  93.     PSECURITY_DESCRIPTOR psdSrelFileSD    = NULL;
  94.     PSECURITY_DESCRIPTOR psdAbsFileSD     = (PSECURITY_DESCRIPTOR)&ucBufAbs;
  95.     PSECURITY_DESCRIPTOR_CONTROL psdcCtrl = (PSECURITY_DESCRIPTOR_CONTROL)&ucBufCtrl;
  96.     PACL                 paclDacl         = (PACL)&ucBufDacl;
  97.     PACL                 paclDacl2        = (PACL)&ucBufDacl2;
  98.     PACL                 paclSacl         = (PACL)&ucBufSacl;
  99.     PSID                 psidSidOwn       = (PSID)&ucBufSidOwn;
  100.     PSID                 psidSidPG        = (PSID)&ucBufSidPG;
  101.     BOOL                 bDaclPresent;
  102.     BOOL                 bDaclDefaulted;
  103.     BOOL                 bSaclPresent;
  104.     BOOL                 bSaclDefaulted;
  105.     BOOL                 bOwnerDefaulted;
  106.     BOOL                 bGroupDefaulted;
  107.     BOOL                 bSDSelfRelative;
  108.     DWORD                dwRevision;
  109.     ACCESS_ALLOWED_ACE*  pAce;
  110.     DWORD       AceIndex;
  111.  
  112.     struct nfsfattr oldattr;
  113.     struct nfsfattr* poldattr = &oldattr;
  114.     NtfsDrive*  pDrive;
  115.     u_long      na_mode;
  116.     u_long      ModeMask;
  117.     u_long      OldId;
  118.     u_long      NewId;
  119.     SECURITY_INFORMATION    si;
  120.  
  121.     //oldattr = 0;
  122.  
  123. #define PERR(a) printf("NTFSAUTH.C NtfsSetUnixAttr () failedat %s\n",a)
  124.  
  125.     printf( "    NtfsSetAttr( %s, Uid %ld, Gid %ld, Mode %lx)\n", 
  126.            FileName, attr->na_uid, attr->na_gid, attr->na_mode);
  127.  
  128.     pDrive = NtfsGetDrive( FileName);
  129.  
  130.     if( ( pDrive == NULL) || (stricmp( pDrive->Type, "NTFS") ) )
  131.     { PERR("pDrive == NULL || ...");
  132.       return(FALSE);
  133.     }
  134.  
  135.     si = (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
  136.                                | GROUP_SECURITY_INFORMATION
  137.                                | DACL_SECURITY_INFORMATION
  138.                               /* | SACL_SECURITY_INFORMATION */ );
  139.  
  140.     dwSDLength = dwSDLengthNeeded = 0;
  141.     GetFileSecurity( FileName, si, psdSrelFileSD, dwSDLength,
  142.             (LPDWORD)&dwSDLengthNeeded);
  143.     if( !dwSDLengthNeeded)
  144.     { PERR("GetFileSecurity1");
  145.       return(FALSE);
  146.     }
  147.  
  148.     dwSDLength = dwSDLengthNeeded;
  149.     if (NULL == ( psdSrelFileSD  = (PSECURITY_DESCRIPTOR) 
  150.                     _alloca(dwSDLengthNeeded) ) )
  151.     { PERR("NULL == psdrel..");
  152.       return(FALSE);
  153.     }
  154.  
  155.     if (!GetFileSecurity(FileName, si, psdSrelFileSD, dwSDLength,
  156.             (LPDWORD)&dwSDLengthNeeded))
  157.     { PERR("GetFileSecurity2");
  158.       return(FALSE);
  159.     }
  160.  
  161.  
  162.     if (!InitializeSecurityDescriptor(psdAbsFileSD,
  163.                    SECURITY_DESCRIPTOR_REVISION))
  164.     { PERR("InitializeSecurityDescriptor");
  165.       return FALSE;
  166.     }
  167.     if (!GetSecurityDescriptorControl(psdSrelFileSD,
  168.             psdcCtrl,
  169.             &dwRevision))
  170.     { PERR("GetSecurityDescriptorControl");
  171.       return FALSE;
  172.     }
  173.  
  174.     bSDSelfRelative = (SE_SELF_RELATIVE & *psdcCtrl);
  175.  
  176.     if (bDaclPresent = (SE_DACL_PRESENT   & *psdcCtrl))
  177.     {                // SE_DACL_DEFAULTED ignored if SE_DACL_PRESENT not set
  178.       bDaclDefaulted = (SE_DACL_DEFAULTED & *psdcCtrl);
  179.     }
  180.     else
  181.     { // No DACL at all
  182.     }
  183.  
  184.     if (!GetSecurityDescriptorDacl(psdSrelFileSD,
  185.             &bDaclPresent,      // fDaclPresent flag
  186.             &paclDacl,
  187.             &bDaclDefaulted))   // is/is not a default DACL
  188.     { PERR("GetSecurityDescriptorDacl");
  189.       return FALSE;
  190.     }
  191.     if (!SetSecurityDescriptorDacl(psdAbsFileSD,
  192.             bDaclPresent,       // fDaclPresent flag
  193.             paclDacl,
  194.             bDaclDefaulted))    // is/is not a default DACL
  195.     { PERR("SetSecurityDescriptorDacl");
  196.       return FALSE;
  197.     }
  198.  
  199.  
  200.     if (bSaclPresent = (SE_SACL_PRESENT   & *psdcCtrl))
  201.     {                // SE_SACL_DEFAULTED ignored if SE_SACL_PRESENT not set
  202.       bSaclDefaulted = (SE_SACL_DEFAULTED & *psdcCtrl);
  203.     }
  204.     else
  205.     { // No SACL at all
  206.     }
  207.  
  208.     if (!GetSecurityDescriptorSacl(psdSrelFileSD,
  209.             &bSaclPresent,      // fSaclPresent flag
  210.             &paclSacl,
  211.             &bSaclDefaulted))   // is/is not a default SACL
  212.     { PERR("GetSecurityDescriptorSacl");
  213.       return FALSE;
  214.     }
  215.     if (!SetSecurityDescriptorSacl(psdAbsFileSD,
  216.             bSaclPresent,       // fSaclPresent flag
  217.             paclSacl,
  218.             bSaclDefaulted))    // is/is not a default SACL
  219.     { PERR("SetSecurityDescriptorSacl");
  220.       return FALSE;
  221.     }
  222.  
  223.     bOwnerDefaulted = (SE_OWNER_DEFAULTED & *psdcCtrl);
  224.  
  225.     if (!GetSecurityDescriptorOwner(psdSrelFileSD,
  226.             &psidSidOwn,
  227.             &bOwnerDefaulted))   // is/is not a default Owner
  228.     { PERR("GetSecurityDescriptorOwner");
  229.       return FALSE;
  230.     }
  231.     if (!SetSecurityDescriptorOwner(psdAbsFileSD,
  232.             psidSidOwn,
  233.             bOwnerDefaulted))    // is/is not a default Owner
  234.     { PERR("SetSecurityDescriptorOwner");
  235.       return FALSE;
  236.     }
  237.  
  238.     bGroupDefaulted = (SE_GROUP_DEFAULTED & *psdcCtrl);
  239.  
  240.     if (!GetSecurityDescriptorGroup(psdSrelFileSD,
  241.             &psidSidOwn,
  242.             &bGroupDefaulted))   // is/is not a default Group
  243.     { PERR("GetSecurityDescriptorGroup");
  244.       return FALSE;
  245.     }
  246.     if (!SetSecurityDescriptorGroup(psdAbsFileSD,
  247.             psidSidOwn,
  248.             bGroupDefaulted))    // is/is not a default Group
  249.     { PERR("SetSecurityDescriptorGroup");
  250.       return FALSE;
  251.     }
  252.  
  253.     if( !InitializeAcl( paclDacl2, SZ_DACL_BUF, paclDacl->AclRevision))
  254.     { PERR("InitializeAcl");
  255.       return FALSE;
  256.     }
  257.  
  258.     AceIndex = 0;
  259.  
  260.     for( AceIndex = 0; AceIndex < paclDacl->AceCount; AceIndex++)
  261.     {
  262.         if( FALSE == GetAce( paclDacl, AceIndex, (LPVOID)&pAce) )
  263.             continue;
  264.         if( pAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
  265.         {
  266.             if( FALSE == AddAccessAllowedAce( paclDacl2, 
  267.                         paclDacl->AclRevision, 
  268.                         pAce->Mask, &(pAce->SidStart)))
  269.             { PERR("AddAccessAllowedAce");
  270.                 return FALSE;
  271.             }
  272.         }
  273.         else if( pAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
  274.         {
  275.             if( FALSE == AddAccessDeniedAce( paclDacl2, 
  276.                         paclDacl2->AclRevision, 
  277.                         pAce->Mask, &(pAce->SidStart)))
  278.             { PERR("AddAccessDeniedAce");
  279.                 return FALSE;
  280.             }
  281.         }
  282.     }
  283.  
  284.     oldattr.na_uid = 0xffffffff;
  285.     oldattr.na_gid = 0xffffffff;
  286.     oldattr.na_mode = 0xffffffff;
  287.  
  288.     NtfsGetUnixAttrib( FileName, &oldattr);
  289.     if( attr->na_mode == -1)
  290.         attr->na_mode == oldattr.na_mode;
  291.     if( attr->na_uid == -1)
  292.         attr->na_uid = oldattr.na_uid;
  293.     if( attr->na_gid == -1)
  294.         attr->na_gid = oldattr.na_gid;
  295.  
  296.     ModeMask = UPERM_OWNER;
  297.     na_mode = (attr->na_mode & ModeMask);
  298.     OldId = oldattr.na_uid;
  299.     NewId = attr->na_uid;
  300.     
  301.     if( OldId != NewId )
  302.     {
  303.         NtfsSetOwner( psdAbsFileSD, pDrive, NewId);
  304.         if( FALSE == NtfsSetRights( paclDacl2, pDrive, NewId, na_mode, OWNER))
  305.         { PERR("NtfsSetowner(owner)");
  306.             return FALSE;
  307.         }
  308.     }    
  309.     if (na_mode != (oldattr.na_mode & ModeMask) )
  310.     {
  311.         if( FALSE == NtfsSetRights( paclDacl2, pDrive, NewId, na_mode, OWNER))
  312.         { PERR("NtfsSetRights(ownerrights)");
  313.             return FALSE;
  314.         }
  315.     }
  316.  
  317.     ModeMask = UPERM_GROUP;
  318.     na_mode = (attr->na_mode & ModeMask);
  319.     OldId = oldattr.na_gid;
  320.     NewId = attr->na_gid;
  321.  
  322.     if( OldId != NewId )
  323.     {
  324.         if( FALSE == NtfsSetGroup( paclDacl2, pDrive, OldId, NewId))
  325.         { PERR("NtfsSetGroup(group)");
  326.             return FALSE;
  327.         }
  328.     }
  329.  
  330.     if (na_mode != (oldattr.na_mode & ModeMask) )
  331.     {
  332.         if( FALSE == NtfsSetRights( paclDacl2, pDrive, NewId, na_mode, GROUP))
  333.         { PERR("NtfsSetRights(GroupRights)");
  334.             return FALSE;
  335.         }
  336.     }
  337.  
  338.     ModeMask = UPERM_WORLD;
  339.     na_mode = (attr->na_mode & ModeMask);
  340.     if( NULL == pDrive->Host->World)
  341.         return TRUE;
  342.  
  343.     OldId = pDrive->Host->World->unixId;
  344.     NewId = OldId;
  345.  
  346.     if ( na_mode != (oldattr.na_mode & ModeMask) )
  347.     {
  348.         if( FALSE == NtfsSetRights( paclDacl2, pDrive, NewId, na_mode, WORLD))
  349.         { PERR("NtfsSetRights(WorldRights)");
  350.             return FALSE;
  351.         }
  352.     }
  353.  
  354.     if (!SetSecurityDescriptorDacl(psdAbsFileSD,
  355.             bDaclPresent,       // fDaclPresent flag
  356.             paclDacl2,
  357.             bDaclDefaulted))    // is/is not a default DACL
  358.     { PERR("SetSecurityDescriptorDacl");
  359.       return FALSE;
  360.     }
  361.        
  362.     if( !SetFileSecurity( FileName, si, psdAbsFileSD))
  363.     { PERR("SetFileSecurity");
  364.       printf("%ld = GetLastError()\n", GetLastError());
  365.       return FALSE;
  366.     }
  367.     return TRUE;
  368. }
  369.  
  370. static BOOL NtfsSetGroup( PACL pAcl, NtfsDrive* pDrive, 
  371.         u_long oldUnixId, u_long newUnixId )
  372. {
  373.  
  374.     NtfsMap*    pOldMap;
  375.     NtfsMap*    pNewMap;
  376.     PSID        pOldSid;
  377.  
  378.     if( NULL == ( pOldMap = pNewMap = pDrive->Host->Group) )
  379.         return FALSE;
  380.  
  381.     while( pOldMap != NULL && pOldMap->unixId != oldUnixId)
  382.         pOldMap = pOldMap->next;
  383.  
  384.     if( pOldMap == NULL)
  385.         pOldSid = NULL;
  386.     else
  387.         pOldSid = pOldMap->psid;
  388.                        
  389.  
  390.     while( pNewMap != NULL && pNewMap->unixId != newUnixId)
  391.         pNewMap = pNewMap->next;
  392.  
  393.     if( pNewMap == NULL)
  394.         return FALSE;
  395.  
  396.     return NtfsChangeDacl( pAcl, 0xffffffff, pOldSid, pNewMap->psid);
  397. }
  398.  
  399. static BOOL NtfsChangeDacl( PACL pAcl, ACCESS_MASK Mask, 
  400.                 PSID pOldSid, PSID pNewSid)
  401. {
  402.     DWORD       AceIndex;
  403.     ACCESS_ALLOWED_ACE* pAce = NULL;
  404.  
  405.     if( pOldSid == NULL && pNewSid == NULL)
  406.         return FALSE;
  407.  
  408.     AceIndex = 0;
  409.  
  410.  
  411.     if( pOldSid)
  412.     {
  413.         if( !IsValidSid( pOldSid) )
  414.             return FALSE;
  415.  
  416.         for( AceIndex = pAcl->AceCount ; AceIndex--; )
  417.         {
  418.             if( FALSE == GetAce( pAcl, AceIndex, (LPVOID)&pAce) )
  419.                 continue;
  420.             if( (pAce->Header.AceType != ACCESS_ALLOWED_ACE_TYPE))
  421.                continue;
  422.  
  423.             if( EqualSid( (PSID)&(pAce->SidStart), pOldSid) )
  424.             {
  425.                 if( FALSE == DeleteAce( pAcl, AceIndex))
  426.                     return FALSE;
  427.                 if( Mask == 0xffffffff)
  428.                     Mask = pAce->Mask;
  429.             }
  430.         }
  431.     }
  432.     if( Mask && pNewSid)
  433.     {
  434.         if( FALSE == AddAccessAllowedAce( 
  435.                 pAcl, pAcl->AclRevision, Mask, pNewSid))
  436.             return FALSE;
  437.     }
  438.  
  439.     return TRUE;
  440. }
  441.  
  442. static BOOL NtfsSetRights(  PACL pAcl, NtfsDrive* pDrive, 
  443.             u_long unixId, u_long na_mode, LPSTR type)
  444. {
  445.     NtfsMap*    pMap;
  446.     BOOL        result = FALSE;
  447.     u_long      Mask;
  448.  
  449.     if( !stricmp( type, WORLD))
  450.         pMap = pDrive->Host->World;
  451.     else
  452.     {
  453.         if( !stricmp( type, OWNER))
  454.             pMap = pDrive->Host->User;
  455.  
  456.         if( !stricmp( type, GROUP))
  457.             pMap = pDrive->Host->Group;
  458.  
  459.         while( (pMap != NULL) && (pMap->unixId != unixId))
  460.             pMap = pMap->next;
  461.     }
  462.     if( pMap == NULL || pMap->psid == NULL)
  463.         return FALSE;
  464.  
  465.     Mask = 0;
  466.     if( na_mode & UPERM_READ)
  467.         Mask |= GENERIC_READ;
  468.     if( na_mode & UPERM_WRITE)
  469.         Mask |= GENERIC_WRITE;
  470.     if( na_mode & UPERM_EXEC)
  471.         Mask |= GENERIC_EXECUTE;
  472.     if( Mask == ( GENERIC_EXECUTE| GENERIC_READ | GENERIC_WRITE) )
  473.         Mask = GENERIC_ALL;
  474.  
  475.     pMap = pMap;
  476.  
  477.     return NtfsChangeDacl( pAcl, Mask, pMap->psid, pMap->psid);
  478. }
  479.  
  480. static BOOL NtfsSetOwner(  PSECURITY_DESCRIPTOR psd, NtfsDrive* pDrive, 
  481.             u_long unixId)
  482. {
  483.  
  484.     NtfsMap*    pMap;
  485.  
  486.     pMap = pDrive->Host->User;
  487.     while( pMap != NULL)
  488.     {
  489.         if( pMap->unixId == unixId)
  490.             break;
  491.         pMap = pMap->next;
  492.     }
  493.     if( pMap == NULL)
  494.         return FALSE;
  495.  
  496.  
  497.     return SetSecurityDescriptorOwner( psd, pMap->psid, FALSE);
  498. }
  499.  
  500.  
  501. BOOL NtfsGetUnixAttrib( char* FileName, struct nfsfattr* attr)
  502. {
  503.     NtfsMap* pMap;
  504.     NtfsDrive* pDrive;
  505.     struct _finddata_t  findbuf;
  506.     long fhand;
  507.  
  508. //printf( "    NtfsGetAttr( %s, Uid %ld, Gid %ld, Mode %lx)\n", 
  509. //            FileName, attr->na_uid, attr->na_gid, attr->na_mode);
  510.  
  511.     attr->na_mode = 0;
  512.  
  513.     pDrive = NtfsGetDrive( FileName);
  514.  
  515.     if( ( pDrive == NULL) || (stricmp( pDrive->Type, "NTFS") ) )
  516.         return FALSE;     // not NTFS, leave alone
  517.  
  518.  
  519.     fhand = _findfirst( FileName, &findbuf);
  520.     if ( fhand < 0 )
  521.     { PERR("_findfirst");
  522.         return FALSE;
  523.     }
  524.  
  525.     _findclose( fhand);
  526.  
  527.     if( findbuf.attrib & _A_SUBDIR)
  528.         attr->na_mode = UPERM_DIR;
  529.  
  530.     attr->na_mode &= ((~UPERM_OWNER) & (~UPERM_GROUP) & (~UPERM_WORLD));
  531.     pMap = NtfsGetOwner( FileName);
  532.     if( pMap != NULL)
  533.     {
  534.         attr->na_uid = pMap->unixId;
  535.  
  536.         if( pMap->Mask & GENERIC_ALL)
  537.             attr->na_mode |= UPERM_OWNER;
  538.         if( pMap->Mask & (FILE_READ_ATTRIBUTES | GENERIC_READ))
  539.             attr->na_mode |= (UPERM_READ & UPERM_OWNER);
  540.  
  541.         if( pMap->Mask & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE))
  542.             attr->na_mode |= (UPERM_WRITE & UPERM_OWNER);
  543.  
  544.         if( pMap->Mask & (FILE_EXECUTE | GENERIC_EXECUTE))
  545.             attr->na_mode |= (UPERM_EXEC & UPERM_OWNER);
  546.     }
  547.     else
  548.     {
  549.         attr->na_uid = 0xfffffffe;
  550.     }
  551.  
  552.     pMap = NtfsGetGroup( FileName);
  553.     if( pMap != NULL)
  554.     {
  555.         attr->na_gid = pMap->unixId;
  556.         if( pMap->Mask & GENERIC_ALL)
  557.             attr->na_mode |= UPERM_GROUP;
  558.         if( pMap->Mask & (FILE_READ_ATTRIBUTES | GENERIC_READ))
  559.             attr->na_mode |= (UPERM_READ & UPERM_GROUP);
  560.  
  561.         if( pMap->Mask & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE))
  562.             attr->na_mode |= (UPERM_WRITE & UPERM_GROUP);
  563.  
  564.         if( pMap->Mask & (FILE_EXECUTE | GENERIC_EXECUTE))
  565.             attr->na_mode |= (UPERM_EXEC & UPERM_GROUP);
  566.     }
  567.     else
  568.     {
  569.         attr->na_gid = 0xfffffffe;
  570.     }
  571.  
  572.     pMap = NtfsGetWorld( FileName);
  573.     if( pMap != NULL)
  574.     {
  575.         if( pMap->Mask & GENERIC_ALL)
  576.             attr->na_mode |= UPERM_WORLD;
  577.  
  578.         if( pMap->Mask & (FILE_READ_ATTRIBUTES | GENERIC_READ))
  579.             attr->na_mode |= (UPERM_READ & UPERM_WORLD);
  580.  
  581.         if( pMap->Mask & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE))
  582.             attr->na_mode |= (UPERM_WRITE & UPERM_WORLD);
  583.  
  584.         if( pMap->Mask & (FILE_EXECUTE | GENERIC_EXECUTE))
  585.             attr->na_mode |= (UPERM_EXEC & UPERM_WORLD);
  586.     }
  587.     else
  588.     {
  589.     }
  590.     return TRUE;
  591. }
  592.  
  593.  
  594. BOOL NtfsCompDriveType( LPSTR FileName, LPSTR DriveType)
  595. {
  596.  
  597.     NtfsDrive* pDrive;
  598.  
  599.     pDrive = NtfsGetDrive( FileName);
  600.     if( pDrive == NULL)
  601.         return FALSE;
  602.  
  603.     if( stricmp( pDrive->Type, DriveType))
  604.         return FALSE;
  605.  
  606.     return TRUE;
  607. }
  608.  
  609. NtfsDrive* NtfsGetDrive( LPSTR FileName)
  610. {
  611.  
  612.     char        DriveLetter[3];
  613.     NtfsDrive* pDrive = FirstDrive;
  614.  
  615.     if( FileName[1] != ':')
  616.         return NULL;
  617.  
  618.     strncpy( DriveLetter, FileName, 2);
  619.  
  620.     DriveLetter[2] = 0;   
  621.    
  622.  
  623.     while( pDrive != NULL)    
  624.     {
  625.         if( !stricmp( pDrive->Drive, DriveLetter) )
  626.             return pDrive;
  627.         pDrive = pDrive->next;
  628.     }
  629.  
  630.     return NULL;
  631. }
  632.  
  633. BOOL NtfsInitDrive( LPSTR FileName)
  634. {
  635.  
  636.     NtfsDrive*  pDrive = FirstDrive;
  637.     NtfsDrive** ppDrive = NULL;
  638.     LPSTR       lpszRemoteName = NULL;
  639.     DWORD       cchRemoteName = 0;
  640.     LPSTR       p;
  641.     char        Drive[4];
  642.  
  643.  
  644.     // Is drive already in list
  645.  
  646.     if( FileName[1] != ':')
  647.         return FALSE;
  648.  
  649.     strncpy( Drive, FileName, 2);
  650.  
  651.     Drive[2] = 0;   
  652.     Drive[3] = 0;
  653.    
  654.  
  655.     while( pDrive != NULL)
  656.     {
  657.         if( !stricmp (pDrive->Drive, Drive) )
  658.             return TRUE;
  659.         pDrive = pDrive->next;
  660.     }
  661.  
  662.     if( ERROR_MORE_DATA != WNetGetConnection( Drive, lpszRemoteName, 
  663.                     &cchRemoteName) )
  664.         return FALSE;
  665.  
  666.     if( NULL == (lpszRemoteName = (LPSTR) malloc( cchRemoteName + 1)))
  667.         return FALSE;
  668.  
  669.     // get hostname
  670.  
  671.     
  672.     if( NO_ERROR != WNetGetConnection( Drive, lpszRemoteName, 
  673.                     &cchRemoteName) )
  674.     {
  675.         if( ERROR_NOT_CONNECTED != GetLastError() )
  676.         {
  677.             free( lpszRemoteName);
  678.             return FALSE;
  679.         }
  680.     }
  681.     else
  682.     {
  683.         p = strchr( lpszRemoteName + 2, '\\') ;
  684.         *p = 0;
  685.     }
  686.  
  687.     // Insert drive into List
  688.     ppDrive = &FirstDrive;
  689.     while( *ppDrive != NULL)
  690.     {
  691.         ppDrive = &((*ppDrive)->next);
  692.     }
  693.  
  694.     pDrive = (NtfsDrive*) malloc( sizeof(NtfsDrive) );
  695.     pDrive->Drive = (LPSTR) malloc( strlen( Drive) +1);
  696.     strcpy( pDrive->Drive, Drive);
  697.     pDrive->next = NULL;
  698.     pDrive->Host = NtfsInitHost( lpszRemoteName);
  699.     free( lpszRemoteName);
  700.  
  701.     {
  702.         char    SystemName[40];
  703.         DWORD   nSystemNameSize = sizeof(SystemName);
  704.  
  705.         Drive[2] = '\\';   
  706.         if (FALSE == GetVolumeInformation(Drive,
  707.                            NULL,
  708.                            0,
  709.                            NULL,
  710.                            NULL,
  711.                            NULL,
  712.                            SystemName,
  713.                            nSystemNameSize))
  714.         {
  715.             pDrive->Type = (LPSTR) malloc(sizeof("NONE"));
  716.             strcpy(pDrive->Type, "NONE");
  717.         }
  718.         else
  719.         {
  720.             pDrive->Type = (LPSTR) malloc(strlen(SystemName) + 1);
  721.             strcpy( pDrive->Type, SystemName);
  722.         }
  723.     }   
  724.     *ppDrive = pDrive;
  725.  
  726.     return TRUE;
  727. }
  728.  
  729. static NtfsHost* NtfsInitHost( LPSTR Host)
  730. {
  731.     NtfsHost*   pHost = FirstHost;
  732.     NtfsHost**  ppHost = NULL;
  733.  
  734.     while( pHost != NULL)
  735.     {
  736.         if( !stricmp (pHost->Host, Host) )
  737.             return pHost;
  738.         pHost = pHost->next;
  739.     }
  740.     // Insert Host into List
  741.     ppHost = &FirstHost;
  742.     while( *ppHost != NULL)
  743.     {
  744.         ppHost = &((*ppHost)->next);
  745.     }
  746.  
  747.     pHost = (NtfsHost*) malloc( sizeof(NtfsHost) );
  748.     pHost->Host = (LPSTR) malloc( strlen( Host) +1);
  749.     strcpy( pHost->Host, Host);
  750.     pHost->next = NULL;
  751.     *ppHost = pHost;
  752.     pHost->User = NtfsInitMap( Host, USER);
  753.     pHost->Group = NtfsInitMap( Host, GROUP);
  754.     pHost->World = NtfsInitMap( Host, WORLD);
  755.     return pHost;
  756. }
  757.  
  758. NtfsMap* NtfsGetOwner( LPSTR FileName)
  759. {
  760.     return NtfsGetAttrib( FileName, OWNER);
  761. }
  762.  
  763. NtfsMap* NtfsGetWorld( LPSTR FileName)
  764. {
  765.     return NtfsGetAttrib( FileName, WORLD);
  766. }
  767.  
  768.  
  769. NtfsMap* NtfsGetGroup( LPSTR FileName)
  770. {
  771.     return NtfsGetAttrib( FileName, GROUP);
  772. }
  773.  
  774. static NtfsMap* NtfsGetAttrib( LPSTR FileName, LPSTR Type)
  775. {
  776.  
  777.     char        DriveLetter[3];
  778.     NtfsMap*    pMap = NULL;
  779.     NtfsDrive*  pDrive = NULL;
  780.     PSID        psid;
  781.     PSECURITY_DESCRIPTOR    psd = NULL;
  782.     DWORD       lsd = 0;
  783.     DWORD       rlsd = 0;
  784.     BOOL        Defaulted;
  785.     BOOL        DaclPresent;            
  786.     PACL        pAcl;
  787.     DWORD       AceIndex;
  788.     ACCESS_ALLOWED_ACE* pAce;
  789.     SECURITY_INFORMATION    si;
  790.  
  791.     
  792.     if( FileName[1] != ':')
  793.         return NULL;
  794.  
  795.     strncpy( DriveLetter, FileName, 2);
  796.     DriveLetter[2] = 0;   
  797.    
  798.     if( NULL == ( pDrive = NtfsGetDrive( DriveLetter) ) )
  799.         return NULL;
  800.  
  801.     if( !stricmp( Type, OWNER) )
  802.     {
  803.         si = OWNER_SECURITY_INFORMATION;
  804.         GetFileSecurity( FileName, si, psd, lsd, &rlsd);
  805.  
  806.         if( 0 == rlsd )
  807.             return NULL;
  808.  
  809.         psd = (PSECURITY_DESCRIPTOR) malloc( rlsd);
  810.         lsd = rlsd;
  811.         while(1)
  812.         {
  813.             if( FALSE == GetFileSecurity( FileName, si, psd, lsd, &rlsd) )
  814.                 break;
  815.             if( FALSE == GetSecurityDescriptorOwner( psd, &psid
  816.                     , &Defaulted))
  817.                 break;
  818.             pMap = pDrive->Host->User;
  819.             while( pMap != NULL)
  820.             {
  821.                 if( (pMap->psid != NULL) && ( EqualSid( psid, pMap->psid) ) )
  822.                     break;
  823.                 pMap = pMap->next;
  824.             }
  825.             break;
  826.         }
  827.         free (psd);
  828.         psd = NULL;
  829.  
  830.         if( pMap == NULL)
  831.             return NULL;
  832.     }
  833.  
  834.     lsd = rlsd = 0;
  835.     si = DACL_SECURITY_INFORMATION;
  836.     GetFileSecurity( FileName, si, psd, lsd, &rlsd);
  837.  
  838.  
  839.     if( 0 == rlsd )
  840.         return NULL;
  841.  
  842.     psd = (PSECURITY_DESCRIPTOR) malloc( rlsd);
  843.     lsd = rlsd;
  844.  
  845.     while(1)
  846.     {
  847.         if( FALSE == GetFileSecurity( FileName, si, psd, lsd, &rlsd) )
  848.             break;
  849.  
  850.         if( FALSE == GetSecurityDescriptorDacl( psd, &DaclPresent, &pAcl
  851.             , &Defaulted))
  852.                 break;
  853.         if( FALSE == DaclPresent)
  854.             break;
  855.  
  856.         AceIndex = 0;
  857.  
  858.         for( AceIndex = 0; AceIndex < pAcl->AceCount; AceIndex++)
  859.         {
  860.             if( FALSE == GetAce( pAcl, AceIndex, (LPVOID)&pAce) )
  861.                 continue;
  862.             if( pAce->Header.AceType != ACCESS_ALLOWED_ACE_TYPE)
  863.                 continue;
  864.  
  865.             psid = (PSID) & (pAce->SidStart);
  866.  
  867.             
  868.             if( !stricmp( Type, OWNER) )
  869.             {
  870.                 if( EqualSid( psid, pMap->psid) )
  871.                 {
  872.                     pMap->Mask = pAce->Mask;
  873.                     break;
  874.                 }
  875.                 continue;
  876.             }
  877.             else
  878.             {
  879.                 if( !stricmp( Type, GROUP) )
  880.                     pMap = pDrive->Host->Group;
  881.                 else if( !stricmp( Type, WORLD) )
  882.                     pMap = pDrive->Host->World;
  883.                 while( pMap != NULL)
  884.                 {
  885.                     if( (pMap->psid != NULL) && ( EqualSid( psid, pMap->psid) ) )
  886.                        break;
  887.                     pMap = pMap->next;
  888.                 }
  889.                 if( pMap != NULL)
  890.                 {
  891.                     pMap->Mask = pAce->Mask;
  892.                     break;
  893.                 }
  894.             }
  895.         }
  896.         break;
  897.     }
  898.  
  899.  
  900.     free( psd);
  901.  
  902.     return pMap;
  903. }
  904.  
  905. static NtfsMap* NtfsInitMap( LPSTR Host, LPSTR Type)
  906. {
  907.  
  908.     FILE*       pFile= NULL;
  909.     NtfsMap*    pLastMap = NULL;
  910.     NtfsMap*    pMap = NULL;
  911.     u_long      unixId;
  912.     char        NTName[80];
  913.     DWORD       lSid;
  914.     DWORD       lDomain;
  915.     SID_NAME_USE   smu;
  916.  
  917.     if( NULL == (pFile = OpenMapFile( Type)))
  918.         return NULL;
  919.  
  920.     while( TRUE == GetNextMapEntry( pFile, &unixId, NTName))
  921.     {
  922.         pMap = (NtfsMap*) malloc( sizeof(NtfsMap));
  923.         pMap->Name = (LPSTR) malloc( strlen( NTName) + 1);
  924.         strcpy( pMap->Name, NTName);
  925.         pMap->psid = NULL;
  926.         pMap->Mask =0xffffffff;
  927.         pMap->Domain = NULL;
  928.         lSid = 0;
  929.         lDomain = 0;
  930.         LookupAccountName( Host, NTName, pMap->psid, &lSid, pMap->Domain,
  931.                 &lDomain, &smu);
  932.  
  933.         if( lSid != 0)      // Found Sid
  934.         {
  935.             pMap->psid = (PSID) malloc( lSid);
  936.             pMap->Domain = (LPSTR) malloc( lDomain); 
  937.  
  938.             LookupAccountName( Host, NTName, pMap->psid, &lSid, 
  939.                     pMap->Domain,&lDomain, &smu);
  940.  
  941. //            if( ( stricmp( Type, USER) && (smu == SidTypeUser))
  942. //                || ( stricmp( Type, GROUP) && (smu == SidTypeGroup)) )
  943.  
  944.  
  945.         }
  946.  
  947.         pMap->unixId = unixId;
  948.         pMap->next = pLastMap;
  949.         pLastMap = pMap;
  950.     }
  951.  
  952.     fclose( pFile);
  953.     return pMap;
  954. }
  955.  
  956.  
  957. static FILE* OpenMapFile( LPSTR FileName)
  958. {
  959.     FILE*   fp;
  960.  
  961.     if ( NULL == ( fp = fopen( FileName, "r") ) )
  962.         return NULL;
  963.  
  964. }
  965.  
  966. static BOOL GetNextMapEntry( FILE* fp, u_long* punixId, LPSTR NTName)
  967. {
  968.     char    buffer[128];
  969.  
  970.  
  971.     while( 1)
  972.     {
  973.         if( NULL == fgets( buffer, sizeof(buffer), fp ) )
  974.             return FALSE;
  975.     
  976.         if( 2 == sscanf( buffer, "%d %s", punixId, NTName))
  977.             return TRUE;
  978.     }
  979.  
  980.     return TRUE;
  981. }
  982.  
  983. static void CloseMapFile( FILE* fp)
  984. {
  985.     fclose( fp);
  986. }
  987.  
  988.