From: Jeffrey Altman Date: Thu, 12 Aug 2010 05:48:16 +0000 (-0400) Subject: Windows: Only Local System Account may set tokens for alternate ids X-Git-Tag: openafs-devel-1_5_76~4 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=22f6306cc8651f08841c66cd222c27c70ec5a00f Windows: Only Local System Account may set tokens for alternate ids Only permit tokens to be set for alternate ids from the system account. LICENSE MIT Change-Id: Ibeaf16950b0317db99dfebccb9534697a258db78 Reviewed-on: http://gerrit.openafs.org/2541 Reviewed-by: Derrick Brashear Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index 33a71dc..d44c14e 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -138,6 +138,10 @@ extern const int utf8_prefix_size; #define AFSCALL_RXSTATS_DISABLE 0x2 /* Disable RX stats */ #define AFSCALL_RXSTATS_CLEAR 0x4 /* Clear RX stats */ +/* pioctl flags */ + +#define AFSCALL_FLAG_LOCAL_SYSTEM 0x1 + #ifndef __CM_IOCTL_INTERFACES_ONLY__ extern void cm_InitIoctl(void); diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 8261fd7..5f6f657 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -15,6 +15,7 @@ #pragma warning(disable: 4005) #include #pragma warning(pop) +#include #include #include #include @@ -1230,6 +1231,63 @@ smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags) return uidp; } +afs_int32 smb_userIsLocalSystem(smb_user_t *uidp) +{ + SID *pSid = NULL; + DWORD dwSize1 = 0, dwSize2 = 0; + wchar_t *pszRefDomain = NULL; + SID_NAME_USE snu = SidTypeGroup; + clientchar_t * secSidString = NULL; + DWORD gle; + afs_int32 isSystem = 0; + + /* + * The input name is probably not a SID for the user which is how + * the user is now being identified as a result of the SMB + * extended authentication. See if we can obtain the SID for the + * specified name. If we can, use that instead of the name + * provided. + */ + + LookupAccountNameW( NULL /* System Name to begin Search */, + uidp->unp->name, + NULL, &dwSize1, + NULL, &dwSize2, + &snu); + gle = GetLastError(); + if (gle == ERROR_INSUFFICIENT_BUFFER) { + pSid = malloc(dwSize1); + /* + * Although dwSize2 is supposed to include the terminating + * NUL character, on Win7 it does not. + */ + pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t)); + } + + if ( pSid && pszRefDomain ) { + memset(pSid, 0, dwSize1); + + if (LookupAccountNameW( NULL /* System Name to begin Search */, + uidp->unp->name, + pSid, &dwSize1, + pszRefDomain, &dwSize2, + &snu)) + ConvertSidToStringSidW(pSid, &secSidString); + } + + if (secSidString) { + isSystem = !cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, secSidString); + LocalFree(secSidString); + } + + if (pSid) + free(pSid); + if (pszRefDomain) + free(pszRefDomain); + + return isSystem; +} + smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags) { diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index a5a7bf0..71fbc06 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -170,6 +170,8 @@ typedef struct smb { #define NTNEGOTIATE_CAPABILITY_COMPRESSED 0x40000000L #define NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY 0x80000000L +#define NTSID_LOCAL_SYSTEM L"S-1-5-18" + /* a packet structure for receiving SMB messages; locked by smb_globalLock. * Most of the work involved is in handling chained requests and responses. * @@ -600,6 +602,8 @@ extern void smb_ReleaseTID(smb_tid_t *tidp, afs_uint32 locked); extern smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags); +extern afs_int32 smb_userIsLocalSystem(smb_user_t *userp); + extern smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags); extern cm_user_t *smb_FindCMUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags); diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index f085ba2..85216ff 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -205,21 +205,37 @@ smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o afs_int32 leftToCopy; char *op; afs_int32 code; - cm_user_t *userp; + smb_user_t *uidp; + cm_user_t *userp = NULL; + smb_t *smbp; + int isSystem = 0; iop = fidp->ioctlp; count = smb_GetSMBParm(inp, 1); - userp = smb_GetUserFromVCP(vcp, inp); + + /* Get the user and determine if it is the local machine account */ + smbp = (smb_t *) inp; + uidp = smb_FindUID(vcp, smbp->uid, 0); + if (uidp) { + isSystem = smb_userIsLocalSystem(uidp); + userp = smb_GetUserFromUID(uidp); + smb_ReleaseUID(uidp); + } + + if (!userp) { + userp = cm_rootUserp; + cm_HoldUser(userp); + } /* Identify tree */ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); - if(code) { + if (code) { cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } /* turn the connection around, if required */ - code = smb_IoctlPrepareRead(fidp, iop, userp, 0); + code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0); if (code) { cm_ReleaseUser(userp); @@ -1016,7 +1032,7 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp); tp += strlen(tp) + 1; - if (flags & PIOCTL_LOGON) { + if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) { /* SMB user name with which to associate tokens */ smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp); osi_Log2(smb_logp,"cm_IoctlSetToken for user [%S] smbname [%S]", @@ -1040,7 +1056,7 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified"); } - if (flags & PIOCTL_LOGON) { + if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) { userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname, SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON); release_userp = 1; @@ -1077,7 +1093,7 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf ucellp->flags |= CM_UCELLFLAG_RXKAD; lock_ReleaseMutex(&userp->mx); - if (flags & PIOCTL_LOGON) { + if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) { ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON; }