DWORD LWICheckSecurity( handle_t hBindingHandle, ACCESS_MASK dwAccessMask ) { DWORD dwError = ERROR_SUCCESS; volatile unsigned32 rpcError; PACCESS_TOKEN pUserToken = NULL; TRY { rpc_binding_inq_access_token_caller( hBindingHandle, &pUserToken, (unsigned32*)&rpcError); } CATCH_ALL ENDTRY; BAIL_ON_DCE_ERROR(dwError, rpcError); dwError = EVTCheckAllowed( pUserToken, dwAccessMask); BAIL_ON_EVT_ERROR(dwError); error: if (pUserToken) { RtlReleaseAccessToken(&pUserToken); } return dwError; }
static NTSTATUS LwIoFuseCreateAccessTokenForOther( PACCESS_TOKEN* ppOtherToken ) { NTSTATUS status = STATUS_SUCCESS; PACCESS_TOKEN pOtherToken = NULL; TOKEN_USER user = {{0}}; TOKEN_OWNER owner = {0}; TOKEN_GROUPS groups = {0}; TOKEN_PRIVILEGES privileges = {0}; TOKEN_PRIMARY_GROUP primaryGroup = {0}; TOKEN_DEFAULT_DACL dacl = {0}; status = RtlAllocateSidFromCString( &user.User.Sid, "S-1-1-0"); BAIL_ON_NT_STATUS(status); status = RtlCreateAccessToken( &pOtherToken, &user, &groups, &privileges, &owner, &primaryGroup, &dacl, NULL); BAIL_ON_NT_STATUS(status); *ppOtherToken = pOtherToken; cleanup: RTL_FREE(&user.User.Sid); return status; error: *ppOtherToken = NULL; if (pOtherToken) { RtlReleaseAccessToken(&pOtherToken); } goto cleanup; }
static NTSTATUS LwIoFuseCreateAccessTokenForGroup( PSID pGroupSid, PACCESS_TOKEN* ppGroupToken ) { NTSTATUS status = STATUS_SUCCESS; PACCESS_TOKEN pGroupToken = NULL; TOKEN_USER user = {{0}}; TOKEN_OWNER owner = {0}; TOKEN_GROUPS groups = {0}; TOKEN_PRIVILEGES privileges = {0}; TOKEN_PRIMARY_GROUP primaryGroup = {0}; TOKEN_DEFAULT_DACL dacl = {0}; user.User.Sid = pGroupSid; status = RtlCreateAccessToken( &pGroupToken, &user, &groups, &privileges, &owner, &primaryGroup, &dacl, NULL); BAIL_ON_NT_STATUS(status); *ppGroupToken = pGroupToken; cleanup: return status; error: *ppGroupToken = NULL; if (pGroupToken) { RtlReleaseAccessToken(&pGroupToken); } goto cleanup; }
void LwmEvtSrvDestructSession( LWMsgSecurityToken* pToken, void* pSessionData ) { PLWMSG_LW_EVENTLOG_CONNECTION pConn = (PLWMSG_LW_EVENTLOG_CONNECTION)pSessionData; if (pConn) { if (pConn->pUserToken) { RtlReleaseAccessToken(&pConn->pUserToken); } LW_SAFE_FREE_MEMORY(pConn); } }
void RegSrvCloseServer( HANDLE hServer ) { PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)hServer; if (pServerState->hEventLog != (HANDLE)NULL) { //RegSrvCloseEventLog(pServerState->hEventLog); } if (pServerState->pToken) { RtlReleaseAccessToken(&pServerState->pToken); } LwRtlMemoryFree(pServerState); }
VOID LsaSrvFreeAuthInfo( IN PPOLICY_CONTEXT pPolCtx ) { if (pPolCtx == NULL) return; if (pPolCtx->pUserToken) { RtlReleaseAccessToken(&pPolCtx->pUserToken); pPolCtx->pUserToken = NULL; } if (pPolCtx->pSessionKey) { LW_SECURE_FREE_MEMORY(pPolCtx->pSessionKey, pPolCtx->dwSessionKeyLen); pPolCtx->pSessionKey = NULL; pPolCtx->dwSessionKeyLen = 0; } }
VOID SamrSrvFreeAuthInfo( IN PCONNECT_CONTEXT pConnCtx ) { if (pConnCtx == NULL) return; if (pConnCtx->pUserToken) { RtlReleaseAccessToken(&pConnCtx->pUserToken); pConnCtx->pUserToken = NULL; } if (pConnCtx->pSessionKey) { LW_SECURE_FREE_MEMORY(pConnCtx->pSessionKey, pConnCtx->dwSessionKeyLen); pConnCtx->pSessionKey = NULL; pConnCtx->dwSessionKeyLen = 0; } }
NTSTATUS PvfsFreeCCB( PPVFS_CCB pCCB ) { LWIO_ASSERT(pCCB->RefCount == 0); if (pCCB->pScb) { PvfsRemoveCCBFromSCB(pCCB->pScb, pCCB); PvfsReleaseSCB(&pCCB->pScb); } if (pCCB->pDirContext) { PvfsFreeDirectoryContext(pCCB->pDirContext); } if (pCCB->pUserToken) { RtlReleaseAccessToken(&pCCB->pUserToken); pCCB->pUserToken = NULL; } PvfsListDestroy(&pCCB->pZctContextList); LwRtlWC16StringFree(&pCCB->pwszShareName); PVFS_FREE(&pCCB->LockTable.ExclusiveLocks.pLocks); PVFS_FREE(&pCCB->LockTable.SharedLocks.pLocks); pthread_mutex_destroy(&pCCB->ControlBlock); PVFS_FREE(&pCCB); InterlockedDecrement(&gPvfsDriverState.Counters.Ccb); return STATUS_SUCCESS; }
DWORD LsaSrvPrivsLookupPrivilegeValue( IN OPTIONAL HANDLE hServer, IN OPTIONAL PACCESS_TOKEN AccessToken, IN PCWSTR pwszPrivilegeName, OUT PLUID pPrivilegeValue ) { DWORD err = ERROR_SUCCESS; NTSTATUS ntStatus = STATUS_SUCCESS; PLSASRV_PRIVILEGE_GLOBALS pGlobals = &gLsaPrivilegeGlobals; PACCESS_TOKEN accessToken = AccessToken; BOOLEAN releaseAccessToken = FALSE; ACCESS_MASK accessRights = LSA_ACCESS_VIEW_POLICY_INFO; ACCESS_MASK grantedAccess = 0; GENERIC_MAPPING genericMapping = {0}; PSTR pszPrivilegeName = NULL; PLSA_PRIVILEGE pPrivilegeEntry = NULL; if (!accessToken) { err = LsaSrvPrivsGetAccessTokenFromServerHandle( hServer, &accessToken); BAIL_ON_LSA_ERROR(err); releaseAccessToken = TRUE; } if (!RtlAccessCheck(pGlobals->pPrivilegesSecDesc, accessToken, accessRights, 0, &genericMapping, &grantedAccess, &ntStatus)) { BAIL_ON_NT_STATUS(ntStatus); } err = LwWc16sToMbs(pwszPrivilegeName, &pszPrivilegeName); BAIL_ON_LSA_ERROR(err); err = LsaSrvGetPrivilegeEntryByName( pszPrivilegeName, &pPrivilegeEntry); BAIL_ON_LSA_ERROR(err); *pPrivilegeValue = pPrivilegeEntry->Luid; error: if (err || ntStatus) { if (pPrivilegeValue) { pPrivilegeValue->HighPart = 0; pPrivilegeValue->LowPart = 0; } } LW_SAFE_FREE_MEMORY(pszPrivilegeName); if (releaseAccessToken) { RtlReleaseAccessToken(&accessToken); } if (err == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { err = LwNtStatusToWin32Error(ntStatus); } return err; }
DWORD LsaSrvPrivsLookupPrivilegeDescription( IN OPTIONAL HANDLE hServer, IN OPTIONAL PACCESS_TOKEN AccessToken, IN PCWSTR PrivilegeName, IN SHORT ClientLanguageId, IN SHORT ClientSystemLanguageId, OUT PWSTR *pPrivilegeDescription, OUT PUSHORT pLanguageId ) { DWORD err = ERROR_SUCCESS; NTSTATUS ntStatus = STATUS_SUCCESS; PLSASRV_PRIVILEGE_GLOBALS pGlobals = &gLsaPrivilegeGlobals; PACCESS_TOKEN accessToken = AccessToken; BOOLEAN releaseAccessToken = FALSE; ACCESS_MASK accessRights = LSA_ACCESS_VIEW_POLICY_INFO; ACCESS_MASK grantedAccess = 0; GENERIC_MAPPING genericMapping = {0}; PSTR pszPrivilegeName = NULL; PLSA_PRIVILEGE pPrivilegeEntry = NULL; PWSTR privilegeDescription = NULL; USHORT descriptionLanguageId = 0; if (!accessToken) { err = LsaSrvPrivsGetAccessTokenFromServerHandle( hServer, &accessToken); BAIL_ON_LSA_ERROR(err); releaseAccessToken = TRUE; } if (!RtlAccessCheck(pGlobals->pPrivilegesSecDesc, accessToken, accessRights, 0, &genericMapping, &grantedAccess, &ntStatus)) { BAIL_ON_NT_STATUS(ntStatus); } if (ClientLanguageId || ClientSystemLanguageId) { // // Right now we don't support multilingual privilege descriptions // so just return 0x0409 (which means "en-US") whenever a caller // requests some particular language id // descriptionLanguageId = 0x0409; } err = LwWc16sToMbs(PrivilegeName, &pszPrivilegeName); BAIL_ON_LSA_ERROR(err); err = LsaSrvGetPrivilegeEntryByName( pszPrivilegeName, &pPrivilegeEntry); BAIL_ON_LSA_ERROR(err); err = LwAllocateWc16String( &privilegeDescription, pPrivilegeEntry->pwszDescription); BAIL_ON_LSA_ERROR(err); *pPrivilegeDescription = privilegeDescription; *pLanguageId = descriptionLanguageId; error: if (err || ntStatus) { if (pPrivilegeDescription) { *pPrivilegeDescription = NULL; } if (pLanguageId) { *pLanguageId = 0; } } LW_SAFE_FREE_MEMORY(pszPrivilegeName); if (releaseAccessToken) { RtlReleaseAccessToken(&accessToken); } if (err == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { err = LwNtStatusToWin32Error(ntStatus); } return err; }
static NTSTATUS LwIoFuseTranslateAbsoluteSecurityDescriptor( PSECURITY_DESCRIPTOR_ABSOLUTE pSecurityDescriptor, PSID pOwnerSid, PSID pGroupSid, struct stat* pStatbuf ) { NTSTATUS status = STATUS_SUCCESS; PACCESS_TOKEN pOwnerToken = NULL; PACCESS_TOKEN pGroupToken = NULL; PACCESS_TOKEN pOtherToken = NULL; PLW_MAP_SECURITY_CONTEXT pContext = NULL; ULONG ulUserId = 0; ULONG ulGroupId = 0; BOOLEAN bIsUser = TRUE; status = LwMapSecurityCreateContext(&pContext); BAIL_ON_NT_STATUS(status); status = LwMapSecurityGetIdFromSid( pContext, &bIsUser, &ulUserId, pOwnerSid); if (status != STATUS_SUCCESS || bIsUser != TRUE) { status = STATUS_SUCCESS; ulUserId = 0; } status = LwMapSecurityGetIdFromSid( pContext, &bIsUser, &ulGroupId, pGroupSid); if (status != STATUS_SUCCESS || bIsUser != FALSE) { status = STATUS_SUCCESS; ulGroupId = 0; } pStatbuf->st_uid = (uid_t) ulUserId; pStatbuf->st_gid = (gid_t) ulGroupId; /* Create access tokens for user/group/other */ status = LwIoFuseCreateAccessTokenForOwner( pOwnerSid, &pOwnerToken); BAIL_ON_NT_STATUS(status); status = LwIoFuseCreateAccessTokenForGroup( pGroupSid, &pGroupToken); BAIL_ON_NT_STATUS(status); status = LwIoFuseCreateAccessTokenForOther( &pOtherToken); BAIL_ON_NT_STATUS(status); /* Generate unix permissions */ status = LwIoFuseTranslateSecurityDescriptorPermissions( pSecurityDescriptor, pOwnerToken, pGroupToken, pOtherToken, pStatbuf); BAIL_ON_NT_STATUS(status); error: if (pOwnerToken) { RtlReleaseAccessToken(&pOwnerToken); } if (pGroupToken) { RtlReleaseAccessToken(&pGroupToken); } if (pOtherToken) { RtlReleaseAccessToken(&pOtherToken); } return status; }
static DWORD test_access_token( PCSTR pszUpn) { PTOKEN_USER pUser = NULL; PTOKEN_GROUPS pGroups = NULL; PACCESS_TOKEN pAccessToken = NULL; PSTR pszUserSid = NULL; PSTR pszGroupSid = NULL; PLW_MAP_SECURITY_CONTEXT pMapSecurityContext = NULL; DWORD ulBufLen = 0; DWORD dwError = 0; DWORD dwIndex = 0; dwError = LwMapSecurityCreateContext(&pMapSecurityContext); BAIL_ON_VMDIR_ERROR(dwError); printf("Creating access token for UPN: %s\n", pszUpn); dwError = LwMapSecurityCreateAccessTokenFromCStringUsername( pMapSecurityContext, &pAccessToken, pszUpn); BAIL_ON_VMDIR_ERROR(dwError); // get user sid dwError = RtlQueryAccessTokenInformation( pAccessToken, TokenUser, NULL, 0, &ulBufLen); dwError = LwNtStatusToWin32Error(dwError); BAIL_ON_VMDIR_ERROR(dwError != ERROR_INSUFFICIENT_BUFFER); pUser = RtlMemoryAllocate(ulBufLen, TRUE); if (!pUser) { dwError = ERROR_NOT_ENOUGH_MEMORY; BAIL_ON_VMDIR_ERROR(dwError); } dwError = RtlQueryAccessTokenInformation( pAccessToken, TokenUser, pUser, ulBufLen, &ulBufLen); dwError = LwNtStatusToWin32Error(dwError); BAIL_ON_VMDIR_ERROR(dwError); dwError = RtlAllocateCStringFromSid( &pszUserSid, pUser->User.Sid); BAIL_ON_VMDIR_ERROR(dwError); printf("User SID: %s\n", pszUserSid); dwError = RtlQueryAccessTokenInformation( pAccessToken, TokenGroups, NULL, 0, &ulBufLen); dwError = LwNtStatusToWin32Error(dwError); BAIL_ON_VMDIR_ERROR(dwError != ERROR_INSUFFICIENT_BUFFER); pGroups = RtlMemoryAllocate(ulBufLen, TRUE); if (!pGroups) { dwError = ERROR_NOT_ENOUGH_MEMORY; BAIL_ON_VMDIR_ERROR(dwError); } dwError = RtlQueryAccessTokenInformation( pAccessToken, TokenGroups, pGroups, ulBufLen, &ulBufLen); dwError = LwNtStatusToWin32Error(dwError); BAIL_ON_VMDIR_ERROR(dwError); for (dwIndex = 0; dwIndex < pGroups->GroupCount; dwIndex++) { dwError = RtlAllocateCStringFromSid( &pszGroupSid, pGroups->Groups[dwIndex].Sid); BAIL_ON_VMDIR_ERROR(dwError); printf("Group SID: %s\n", pszGroupSid); } cleanup: if (pMapSecurityContext) { LwMapSecurityFreeContext(&pMapSecurityContext); } if (pAccessToken) { RtlReleaseAccessToken(&pAccessToken); } if (pszUserSid) { RtlMemoryFree(pszUserSid); } if (pGroups) { RtlMemoryFree(pGroups); } if (pUser) { RtlMemoryFree(pUser); } return dwError; error: goto cleanup; }
NTSTATUS RtlCreateAccessToken( OUT PACCESS_TOKEN* AccessToken, IN PTOKEN_USER User, IN PTOKEN_GROUPS Groups, IN PTOKEN_PRIVILEGES Privileges, IN PTOKEN_OWNER Owner, IN PTOKEN_PRIMARY_GROUP PrimaryGroup, IN PTOKEN_DEFAULT_DACL DefaultDacl, IN OPTIONAL PTOKEN_UNIX Unix ) { NTSTATUS status = STATUS_SUCCESS; int unixError = 0; ULONG requiredSize = 0; PACCESS_TOKEN token = NULL; ULONG i = 0; ULONG size = 0; PVOID location = NULL; if (!User || !User->User.Sid || !Groups || !Owner || !PrimaryGroup || !DefaultDacl) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP(); } if (!RtlValidSid(User->User.Sid) || (Owner->Owner && !RtlValidSid(Owner->Owner)) || (PrimaryGroup->PrimaryGroup && !RtlValidSid(PrimaryGroup->PrimaryGroup))) { status = STATUS_INVALID_SID; GOTO_CLEANUP(); } // No user attributes currently exist. if (User->User.Attributes != 0) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP(); } for (i = 0; i < Groups->GroupCount; i++) { // TODO-Perhaps validate Group attributes if (!Groups->Groups[i].Sid) { status = STATUS_INVALID_PARAMETER; GOTO_CLEANUP(); } if (!RtlValidSid(Groups->Groups[i].Sid)) { status = STATUS_INVALID_SID; GOTO_CLEANUP(); } } if (DefaultDacl->DefaultDacl && !RtlValidAcl(DefaultDacl->DefaultDacl, NULL)) { status = STATUS_INVALID_ACL; GOTO_CLEANUP(); } // Compute size required requiredSize = sizeof(*token); size = RtlLengthSid(User->User.Sid); status = RtlSafeAddULONG(&requiredSize, requiredSize, size); GOTO_CLEANUP_ON_STATUS(status); if (Owner->Owner) { size = RtlLengthSid(Owner->Owner); status = RtlSafeAddULONG(&requiredSize, requiredSize, size); GOTO_CLEANUP_ON_STATUS(status); } if (PrimaryGroup->PrimaryGroup) { size = RtlLengthSid(PrimaryGroup->PrimaryGroup); status = RtlSafeAddULONG(&requiredSize, requiredSize, size); GOTO_CLEANUP_ON_STATUS(status); } if (DefaultDacl->DefaultDacl) { status = RtlSafeAddULONG(&requiredSize, requiredSize, DefaultDacl->DefaultDacl->AclSize); GOTO_CLEANUP_ON_STATUS(status); } status = RtlSafeMultiplyULONG(&size, sizeof(Groups->Groups[0]), Groups->GroupCount); GOTO_CLEANUP_ON_STATUS(status); status = RtlSafeAddULONG(&requiredSize, requiredSize, size); GOTO_CLEANUP_ON_STATUS(status); for (i = 0; i < Groups->GroupCount; i++) { size = RtlLengthSid(Groups->Groups[i].Sid); status = RtlSafeAddULONG(&requiredSize, requiredSize, size); GOTO_CLEANUP_ON_STATUS(status); } status = RtlSafeMultiplyULONG(&size, sizeof(Privileges->Privileges[0]), Privileges->PrivilegeCount); GOTO_CLEANUP_ON_STATUS(status); status = RtlSafeAddULONG(&requiredSize, requiredSize, size); GOTO_CLEANUP_ON_STATUS(status); status = RTL_ALLOCATE(&token, ACCESS_TOKEN, requiredSize); GOTO_CLEANUP_ON_STATUS(status); location = LW_PTR_ADD(token, sizeof(*token)); // Initialize token->ReferenceCount = 1; token->Flags = 0; unixError = pthread_rwlock_init(&token->RwLock, NULL); if (unixError) { LW_RTL_LOG_ERROR("Failed to init rwlock in access token " "(error = %d).", unixError); status = LwErrnoToNtStatus(unixError); GOTO_CLEANUP(); } token->pRwLock = &token->RwLock; token->User.Attributes = User->User.Attributes; token->User.Sid = (PSID) location; location = RtlpAppendData(location, User->User.Sid, RtlLengthSid(User->User.Sid)); token->GroupCount = Groups->GroupCount; token->Groups = (PSID_AND_ATTRIBUTES) location; location = LwRtlOffsetToPointer(location, sizeof(Groups->Groups[0]) * Groups->GroupCount); for (i = 0; i < Groups->GroupCount; i++) { token->Groups[i].Attributes = Groups->Groups[i].Attributes; token->Groups[i].Sid = (PSID) location; location = RtlpAppendData(location, Groups->Groups[i].Sid, RtlLengthSid(Groups->Groups[i].Sid)); } token->PrivilegeCount = Privileges->PrivilegeCount; token->Privileges = (PLUID_AND_ATTRIBUTES) location; location = LwRtlOffsetToPointer( location, sizeof(Privileges->Privileges[0]) * Privileges->PrivilegeCount); memcpy(token->Privileges, Privileges->Privileges, sizeof(token->Privileges[0]) * token->PrivilegeCount); if (Owner->Owner) { token->Owner = (PSID) location; location = RtlpAppendData(location, Owner->Owner, RtlLengthSid(Owner->Owner)); } if (PrimaryGroup->PrimaryGroup) { token->PrimaryGroup = (PSID) location; location = RtlpAppendData(location, PrimaryGroup->PrimaryGroup, RtlLengthSid(PrimaryGroup->PrimaryGroup)); } if (DefaultDacl->DefaultDacl) { token->DefaultDacl = (PACL) location; location = RtlpAppendData(location, DefaultDacl->DefaultDacl, DefaultDacl->DefaultDacl->AclSize); } if (Unix) { SetFlag(token->Flags, ACCESS_TOKEN_FLAG_UNIX_PRESENT); token->Uid = Unix->Uid; token->Gid = Unix->Gid; token->Umask = Unix->Umask; } if (location != LW_PTR_ADD(token, requiredSize)) { status = STATUS_ASSERTION_FAILURE; GOTO_CLEANUP(); } status = STATUS_SUCCESS; cleanup: if (!NT_SUCCESS(status)) { RtlReleaseAccessToken(&token); } *AccessToken = token; return status; }