mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: fuse: uidmap option and AzureAD support
This commit is contained in:
parent
74bb51ae07
commit
9ae9b8ff2c
@ -82,6 +82,8 @@ static struct fuse_opt fsp_fuse_core_opts[] =
|
||||
FUSE_OPT_KEY("fstypename=", 'F'),
|
||||
FUSE_OPT_KEY("volname=", 'v'),
|
||||
|
||||
FUSE_OPT_KEY("uidmap=", 'm'),
|
||||
|
||||
FSP_FUSE_CORE_OPT("SectorSize=%hu", VolumeParams.SectorSize, 4096),
|
||||
FSP_FUSE_CORE_OPT("SectorsPerAllocationUnit=%hu", VolumeParams.SectorsPerAllocationUnit, 1),
|
||||
FSP_FUSE_CORE_OPT("MaxComponentLength=%hu", VolumeParams.MaxComponentLength, 0),
|
||||
@ -293,43 +295,241 @@ static int fsp_fuse_sddl_to_security(const char *Sddl, PUINT8 Security, PULONG P
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fsp_fuse_username_to_uid(const char *username, int *puid)
|
||||
static int fsp_fuse_tokenuser_to_sid(HANDLE Token, PSID Sid, PULONG PSidSize)
|
||||
{
|
||||
union
|
||||
{
|
||||
TOKEN_USER V;
|
||||
UINT8 B[128];
|
||||
} InfoBuf;
|
||||
PTOKEN_USER InfoPtr = &InfoBuf.V;
|
||||
DWORD Size;
|
||||
int res = -1;
|
||||
|
||||
if (!GetTokenInformation(Token, TokenUser, InfoPtr, sizeof InfoBuf, &Size))
|
||||
{
|
||||
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||
goto exit;
|
||||
|
||||
InfoPtr = MemAlloc(Size);
|
||||
if (0 == InfoPtr)
|
||||
goto exit;
|
||||
|
||||
if (!GetTokenInformation(Token, TokenUser, InfoPtr, Size, &Size))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Size = GetLengthSid(InfoPtr->User.Sid);
|
||||
if (*PSidSize >= Size)
|
||||
{
|
||||
memcpy(Sid, InfoPtr->User.Sid, Size);
|
||||
*PSidSize = Size;
|
||||
|
||||
res = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (InfoPtr != &InfoBuf.V)
|
||||
MemFree(InfoPtr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fsp_fuse_tokenuser_is_azuread(HANDLE Token)
|
||||
{
|
||||
union
|
||||
{
|
||||
SID V;
|
||||
UINT8 B[SECURITY_MAX_SID_SIZE];
|
||||
} SidBuf;
|
||||
ULONG Size;
|
||||
PSID Sid = &SidBuf.V;
|
||||
BYTE Count, Authority;
|
||||
UINT32 SubAuthority0;
|
||||
|
||||
Size = sizeof SidBuf;
|
||||
if (-1 == fsp_fuse_tokenuser_to_sid(Token, &SidBuf.V, &Size))
|
||||
return 0;
|
||||
|
||||
Count = *GetSidSubAuthorityCount(Sid);
|
||||
Authority = GetSidIdentifierAuthority(Sid)->Value[5];
|
||||
SubAuthority0 = 2 <= Count ? *GetSidSubAuthority(Sid, 0) : 0;
|
||||
|
||||
return 12 == Authority && 1 == SubAuthority0;
|
||||
}
|
||||
|
||||
static int fsp_fuse_username_to_sid(const char *UserName, PSID Sid, PULONG PSidSize)
|
||||
{
|
||||
union
|
||||
{
|
||||
SID V;
|
||||
UINT8 B[SECURITY_MAX_SID_SIZE];
|
||||
} SidBuf;
|
||||
PSID SidPtr = &SidBuf.V;
|
||||
char Name[256], Domn[256];
|
||||
DWORD SidSize, NameSize, DomnSize;
|
||||
DWORD Size, NameSize, DomnSize;
|
||||
SID_NAME_USE Use;
|
||||
UINT32 Uid;
|
||||
NTSTATUS Result;
|
||||
int res = -1;
|
||||
|
||||
*puid = 0;
|
||||
|
||||
NameSize = lstrlenA(username) + 1;
|
||||
if ('S' == UserName[0] && '-' == UserName[1] && '1' == UserName[2] && '-' == UserName[3])
|
||||
{
|
||||
if (!ConvertStringSidToSidA(UserName, &SidPtr))
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
NameSize = lstrlenA(UserName) + 1;
|
||||
if (sizeof Name / sizeof Name[0] < NameSize)
|
||||
return -1;
|
||||
memcpy(Name, username, NameSize);
|
||||
goto exit;
|
||||
memcpy(Name, UserName, NameSize);
|
||||
for (PSTR P = Name, EndP = P + NameSize; EndP > P; P++)
|
||||
if ('+' == *P)
|
||||
*P = '\\';
|
||||
|
||||
SidSize = sizeof SidBuf;
|
||||
Size = sizeof SidBuf;
|
||||
DomnSize = sizeof Domn / sizeof Domn[0];
|
||||
if (!LookupAccountNameA(0, Name, &SidBuf, &SidSize, Domn, &DomnSize, &Use))
|
||||
if (!LookupAccountNameA(0, Name, SidPtr, &Size, Domn, &DomnSize, &Use))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Size = GetLengthSid(SidPtr);
|
||||
if (*PSidSize >= Size)
|
||||
{
|
||||
memcpy(Sid, SidPtr, Size);
|
||||
*PSidSize = Size;
|
||||
|
||||
res = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (SidPtr != &SidBuf.V)
|
||||
LocalFree(SidPtr);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fsp_fuse_username_to_uid(const char *UserName, int *PUid)
|
||||
{
|
||||
union
|
||||
{
|
||||
SID V;
|
||||
UINT8 B[SECURITY_MAX_SID_SIZE];
|
||||
} SidBuf;
|
||||
ULONG SidSize;
|
||||
UINT32 Uid;
|
||||
NTSTATUS Result;
|
||||
|
||||
*PUid = 0;
|
||||
|
||||
SidSize = sizeof SidBuf;
|
||||
if (-1 == fsp_fuse_username_to_sid(UserName, &SidBuf.V, &SidSize))
|
||||
return -1;
|
||||
|
||||
Result = FspPosixMapSidToUid(&SidBuf, &Uid);
|
||||
Result = FspPosixMapSidToUid(&SidBuf.V, &Uid);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return -1;
|
||||
|
||||
*puid = Uid;
|
||||
*PUid = Uid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsp_fuse_set_uidmap(const char *Spec)
|
||||
{
|
||||
char Buf[1024], *P = Buf, *UidP, *UserP, C;
|
||||
int Len;
|
||||
UINT32 Uid[8];
|
||||
PSID Sid[8];
|
||||
union
|
||||
{
|
||||
SID V;
|
||||
UINT8 B[SECURITY_MAX_SID_SIZE];
|
||||
} SidBuf[8];
|
||||
ULONG SidSize;
|
||||
ULONG Count;
|
||||
NTSTATUS Result;
|
||||
int res = -1;
|
||||
|
||||
Len = lstrlenA(Spec);
|
||||
if (sizeof Buf <= Len)
|
||||
return -1;
|
||||
memcpy(Buf, Spec, Len + 1);
|
||||
|
||||
Count = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (sizeof Uid / sizeof Uid[0] <= Count)
|
||||
{
|
||||
/* out of space */
|
||||
goto exit;
|
||||
}
|
||||
|
||||
UidP = P;
|
||||
for (; '\0' != (C = *P) && ';' != C && ':' != C; P++)
|
||||
;
|
||||
*P = '\0';
|
||||
|
||||
if (UidP == P)
|
||||
break;
|
||||
|
||||
Uid[Count] = strtouint(UidP, 0, 10, 0);
|
||||
if (0 == Uid[Count])
|
||||
{
|
||||
/* invalid uid */
|
||||
goto exit;
|
||||
}
|
||||
|
||||
UserP = 0;
|
||||
if (':' == C)
|
||||
{
|
||||
UserP = ++P;
|
||||
for (; '\0' != (C = *P) && ';' != C; P++)
|
||||
;
|
||||
*P = '\0';
|
||||
}
|
||||
|
||||
if (0 != UserP && '\0' != *UserP)
|
||||
{
|
||||
SidSize = sizeof SidBuf[Count];
|
||||
if (-1 == fsp_fuse_username_to_sid(UserP, &SidBuf[Count].V, &SidSize))
|
||||
{
|
||||
/* invalid SID */
|
||||
goto exit;
|
||||
}
|
||||
Sid[Count] = &SidBuf[Count].V;
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE Token;
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token))
|
||||
{
|
||||
SidSize = sizeof SidBuf[Count];
|
||||
if (-1 == fsp_fuse_tokenuser_to_sid(Token, &SidBuf[Count].V, &SidSize))
|
||||
{
|
||||
/* invalid SID */
|
||||
CloseHandle(Token);
|
||||
goto exit;
|
||||
}
|
||||
CloseHandle(Token);
|
||||
Sid[Count] = &SidBuf[Count].V;
|
||||
}
|
||||
}
|
||||
|
||||
Count++;
|
||||
|
||||
if ('\0' == C)
|
||||
break;
|
||||
|
||||
P++;
|
||||
}
|
||||
|
||||
Result = FspPosixSetUidMap(Uid, Sid, Count);
|
||||
res = NT_SUCCESS(Result) ? 0 : -1;
|
||||
|
||||
exit:
|
||||
return res;
|
||||
}
|
||||
|
||||
static int fsp_fuse_utf8towcs_trunc(
|
||||
const char *Str, int StrLen,
|
||||
PWSTR Wcs, int WcsLen)
|
||||
@ -424,6 +624,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
|
||||
" -o KeepFileCache do not discard cache when files are closed\n"
|
||||
" -o LegacyUnlinkRename do not support new POSIX unlink/rename\n"
|
||||
" -o ThreadCount number of file system dispatcher threads\n"
|
||||
" -o uidmap=UID:SID[;...] explicit UID <-> SID map (max 8 entries)\n"
|
||||
);
|
||||
opt_data->help = 1;
|
||||
return 1;
|
||||
@ -531,6 +732,14 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
|
||||
if (0 == opt_data->VolumeLabelLength)
|
||||
return -1;
|
||||
return 0;
|
||||
case 'm':
|
||||
arg += sizeof "uidmap=" - 1;
|
||||
if (-1 == fsp_fuse_set_uidmap(arg))
|
||||
{
|
||||
opt_data->set_uidmap = -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,6 +788,11 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
||||
ErrorMessage = L": invalid user or group name.";
|
||||
goto fail;
|
||||
}
|
||||
else if (-1 == opt_data.set_uidmap)
|
||||
{
|
||||
ErrorMessage = L": invalid uidmap.";
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (opt_data.help)
|
||||
@ -601,6 +815,10 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
||||
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token))
|
||||
{
|
||||
/* if an AzureAD user and no uidmap specified, set a default uidmap that matches Cygwin */
|
||||
if (!opt_data.set_uidmap && fsp_fuse_tokenuser_is_azuread(Token))
|
||||
fsp_fuse_set_uidmap("4096:");
|
||||
|
||||
fsp_fuse_get_token_uidgid(Token, TokenUser,
|
||||
opt_data.set_uid && -1 == opt_data.uid ? &opt_data.uid : 0,
|
||||
opt_data.set_gid && -1 == opt_data.gid ? &opt_data.gid : 0);
|
||||
|
@ -147,6 +147,7 @@ struct fsp_fuse_core_opt_data
|
||||
set_create_dir_umask, create_dir_umask,
|
||||
set_uid, uid, username_to_uid_result,
|
||||
set_gid, gid,
|
||||
set_uidmap,
|
||||
set_attr_timeout, attr_timeout,
|
||||
rellinks,
|
||||
dothidden;
|
||||
|
Loading…
x
Reference in New Issue
Block a user