static DWORD MapBuiltinNameToSid( PSID *ppSid, PCWSTR pwszName ) { DWORD dwError = 0; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } Sid; ULONG SidSize = sizeof(Sid.buffer); PWSTR pwszEveryone = NULL; dwError = LwNtStatusToWin32Error( RtlWC16StringAllocateFromCString( &pwszEveryone, "Everyone")); BAIL_ON_SRVSVC_ERROR(dwError); if (LwRtlWC16StringIsEqual(pwszName, pwszEveryone, FALSE)) { dwError = LwNtStatusToWin32Error( RtlCreateWellKnownSid( WinWorldSid, NULL, &Sid.sid, &SidSize)); } BAIL_ON_SRVSVC_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlDuplicateSid(ppSid, &Sid.sid)); cleanup: LW_RTL_FREE(&pwszEveryone); return dwError; error: goto cleanup; }
DWORD IDMCloneSid( PSID pSid, PSID *ppNewSid ) { DWORD dwError = 0; NTSTATUS status = 0; PSID pNewSid = NULL; status = RtlDuplicateSid(&pNewSid, pSid); dwError = LwNtStatusToWin32Error(status); BAIL_ON_ERROR(dwError); *ppNewSid = pNewSid; error: if (dwError) { IDM_SAFE_FREE_MEMORY(pNewSid); } return dwError; }
NTSTATUS SrvShareSetDefaultSecurity( PSRV_SHARE_INFO pShareInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL; ULONG ulRelSecDescLen = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL; DWORD dwAceCount = 0; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; PACL pDacl = NULL; DWORD dwSizeDacl = 0; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } administratorsSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } powerUsersSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } everyoneSid; ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer); ULONG ulPowerUsersSidSize = sizeof(powerUsersSid.buffer); ULONG ulEveryoneSidSize = sizeof(everyoneSid.buffer); ACCESS_MASK worldAccessMask = 0; /* Clear out any existing SecDesc's. This is not a normal use case, but be paranoid */ if (pShareInfo->ulSecDescLen) { SrvShareFreeSecurity(pShareInfo); } /* Build the new Absolute Security Descriptor */ ntStatus = RTL_ALLOCATE( &pAbsSecDesc, VOID, SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateSecurityDescriptorAbsolute( pAbsSecDesc, SECURITY_DESCRIPTOR_REVISION); BAIL_ON_NT_STATUS(ntStatus); /* Create some SIDs */ ntStatus = RtlCreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, (PSID)administratorsSid.buffer, &ulAdministratorsSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinBuiltinPowerUsersSid, NULL, (PSID)powerUsersSid.buffer, &ulPowerUsersSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinWorldSid, NULL, (PSID)everyoneSid.buffer, &ulEveryoneSidSize); BAIL_ON_NT_STATUS(ntStatus); /* Owner: Administrators */ ntStatus = RtlDuplicateSid(&pOwnerSid, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetOwnerSecurityDescriptor( pAbsSecDesc, pOwnerSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Group: Power Users */ ntStatus = RtlDuplicateSid(&pGroupSid, &powerUsersSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetGroupSecurityDescriptor( pAbsSecDesc, pGroupSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* DACL: Administrators - (Full Control) Everyone - (Read) for disk shares, (Read/Write) to IPC shares */ dwAceCount = 2; dwSizeDacl = ACL_HEADER_SIZE + dwAceCount * sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(&administratorsSid.sid) + RtlLengthSid(&everyoneSid.sid) - dwAceCount * sizeof(ULONG); ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, 0, FILE_ALL_ACCESS, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); worldAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE; if (pShareInfo->service == SHARE_SERVICE_NAMED_PIPE) { worldAccessMask |= FILE_GENERIC_WRITE; } ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, 0, worldAccessMask, &everyoneSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetDaclSecurityDescriptor( pAbsSecDesc, TRUE, pDacl, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Create the SelfRelative SD and assign them to the Share */ ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, NULL, &ulRelSecDescLen); if (ntStatus == STATUS_BUFFER_TOO_SMALL) { ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, pRelSecDesc, &ulRelSecDescLen); } BAIL_ON_NT_STATUS(ntStatus); pShareInfo->pSecDesc = pRelSecDesc; pShareInfo->ulSecDescLen = ulRelSecDescLen; pShareInfo->pAbsSecDesc = pAbsSecDesc; ntStatus = STATUS_SUCCESS; cleanup: return ntStatus; error: RTL_FREE(&pAbsSecDesc); RTL_FREE(&pOwnerSid); RTL_FREE(&pGroupSid); RTL_FREE(&pDacl); if (pRelSecDesc) { SrvFreeMemory(pRelSecDesc); } goto cleanup; }
static DWORD LwpsLegacyCreateSecurityDescriptor( IN BOOLEAN bIsWorldReadable, IN OUT PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecurityDescriptor ) { NTSTATUS status = STATUS_SUCCESS; int EE = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL; PACL pDacl = NULL; PSID pRootSid = NULL; PSID pAdminsSid = NULL; PSID pEveryoneSid = NULL; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; DWORD dwError = 0; status = RtlAllocateWellKnownSid(WinLocalSystemSid, NULL, &pRootSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlAllocateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &pAdminsSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); if (bIsWorldReadable) { status = RtlAllocateWellKnownSid(WinWorldSid, NULL, &pEveryoneSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); } status = LW_RTL_ALLOCATE( &pSecDesc, VOID, SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlCreateSecurityDescriptorAbsolute( pSecDesc, SECURITY_DESCRIPTOR_REVISION); GOTO_CLEANUP_ON_STATUS_EE(status, EE); // Owner: Root status = RtlDuplicateSid(&pOwnerSid, pRootSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlSetOwnerSecurityDescriptor( pSecDesc, pOwnerSid, FALSE); GOTO_CLEANUP_ON_STATUS_EE(status, EE); pOwnerSid = NULL; // Group: Administrators status = RtlDuplicateSid(&pGroupSid, pAdminsSid); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlSetGroupSecurityDescriptor( pSecDesc, pGroupSid, FALSE); GOTO_CLEANUP_ON_STATUS_EE(status, EE); pGroupSid = NULL; // Do not set Sacl currently // DACL status = LwpsLegacyBuildRestrictedDaclForKey( pRootSid, pEveryoneSid, &pDacl); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = RtlSetDaclSecurityDescriptor( pSecDesc, TRUE, pDacl, FALSE); GOTO_CLEANUP_ON_STATUS_EE(status, EE); pDacl = NULL; if (!RtlValidSecurityDescriptor(pSecDesc)) { status = STATUS_INVALID_SECURITY_DESCR; GOTO_CLEANUP_ON_STATUS_EE(status, EE); } cleanup: if (status) { if (pSecDesc) { LwpsLegacyFreeSecurityDescriptor(&pSecDesc); } } LW_RTL_FREE(&pDacl); LW_RTL_FREE(&pRootSid); LW_RTL_FREE(&pAdminsSid); LW_RTL_FREE(&pEveryoneSid); LW_RTL_FREE(&pOwnerSid); LW_RTL_FREE(&pGroupSid); *ppSecurityDescriptor = pSecDesc; dwError = LwNtStatusToWin32Error(status); LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE); return dwError; }
static NTSTATUS LsaDisableMachineAccount( IN PCWSTR pwszDCName, IN LW_PIO_CREDS pCreds, IN PCWSTR pwszMachineAccountName ) { const DWORD dwConnAccess = SAMR_ACCESS_OPEN_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS; const DWORD dwDomainAccess = DOMAIN_ACCESS_ENUM_ACCOUNTS | DOMAIN_ACCESS_OPEN_ACCOUNT | DOMAIN_ACCESS_LOOKUP_INFO_2; const DWORD dwUserAccess = USER_ACCESS_GET_ATTRIBUTES | USER_ACCESS_SET_ATTRIBUTES | USER_ACCESS_SET_PASSWORD; NTSTATUS ntStatus = STATUS_SUCCESS; SAMR_BINDING hSamrBinding = NULL; CONNECT_HANDLE hConnect = NULL; PSID pBuiltinSid = NULL; DWORD dwResume = 0; DWORD dwSize = 256; PWSTR *ppwszDomainNames = NULL; DWORD i = 0; DWORD dwNumEntries = 0; PSID pSid = NULL; PSID pDomainSid = NULL; DOMAIN_HANDLE hDomain = NULL; PDWORD pdwRids = NULL; PDWORD pdwTypes = NULL; ACCOUNT_HANDLE hUser = NULL; DWORD dwLevel = 0; UserInfo *pInfo = NULL; DWORD dwFlagsDisable = 0; UserInfo Info; memset(&Info, 0, sizeof(Info)); ntStatus = SamrInitBindingDefault(&hSamrBinding, pwszDCName, pCreds); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SamrConnect2(hSamrBinding, pwszDCName, dwConnAccess, &hConnect); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAllocateWellKnownSid( WinBuiltinDomainSid, NULL, &pBuiltinSid); BAIL_ON_NT_STATUS(ntStatus); do { ntStatus = SamrEnumDomains(hSamrBinding, hConnect, &dwResume, dwSize, &ppwszDomainNames, &dwNumEntries); BAIL_ON_NT_STATUS(ntStatus); if (ntStatus != STATUS_SUCCESS && ntStatus != STATUS_MORE_ENTRIES) { BAIL_ON_NT_STATUS(ntStatus); } for (i = 0; pDomainSid == NULL && i < dwNumEntries; i++) { ntStatus = SamrLookupDomain(hSamrBinding, hConnect, ppwszDomainNames[i], &pSid); BAIL_ON_NT_STATUS(ntStatus); if (!RtlEqualSid(pSid, pBuiltinSid)) { ntStatus = RtlDuplicateSid(&pDomainSid, pSid); BAIL_ON_NT_STATUS(ntStatus); } SamrFreeMemory(pSid); pSid = NULL; } if (ppwszDomainNames) { SamrFreeMemory(ppwszDomainNames); ppwszDomainNames = NULL; } } while (ntStatus == STATUS_MORE_ENTRIES); ntStatus = SamrOpenDomain(hSamrBinding, hConnect, dwDomainAccess, pDomainSid, &hDomain); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SamrLookupNames(hSamrBinding, hDomain, 1, (PWSTR*)&pwszMachineAccountName, &pdwRids, &pdwTypes, NULL); if (ntStatus == STATUS_NONE_MAPPED) { BAIL_ON_LSA_ERROR(NERR_SetupAlreadyJoined); } ntStatus = SamrOpenUser(hSamrBinding, hDomain, dwUserAccess, pdwRids[0], &hUser); BAIL_ON_NT_STATUS(ntStatus); dwLevel = 16; ntStatus = SamrQueryUserInfo(hSamrBinding, hUser, dwLevel, &pInfo); BAIL_ON_NT_STATUS(ntStatus); dwFlagsDisable = pInfo->info16.account_flags | ACB_DISABLED; Info.info16.account_flags = dwFlagsDisable; ntStatus = SamrSetUserInfo2(hSamrBinding, hUser, dwLevel, &Info); BAIL_ON_NT_STATUS(ntStatus); cleanup: if (hSamrBinding && hUser) { SamrClose(hSamrBinding, hUser); } if (hSamrBinding && hDomain) { SamrClose(hSamrBinding, hDomain); } if (hSamrBinding && hConnect) { SamrClose(hSamrBinding, hConnect); } if (hSamrBinding) { SamrFreeBinding(&hSamrBinding); } if (pInfo) { SamrFreeMemory(pInfo); } if (pdwRids) { SamrFreeMemory(pdwRids); } if (pdwTypes) { SamrFreeMemory(pdwTypes); } if (ppwszDomainNames) { SamrFreeMemory(ppwszDomainNames); } RTL_FREE(&pBuiltinSid); RTL_FREE(&pDomainSid); return ntStatus; error: goto cleanup; }
static NTSTATUS SrvBuildDefaultShareSID( PSECURITY_DESCRIPTOR_RELATIVE* ppSecDesc ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL; ULONG ulRelSecDescLen = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL; DWORD dwAceCount = 0; PSID pOwnerSid = NULL; PSID pGroupSid = NULL; PACL pDacl = NULL; DWORD dwSizeDacl = 0; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } localSystemSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } administratorsSid; union { SID sid; BYTE buffer[SID_MAX_SIZE]; } builtinUsersSid; ULONG ulLocalSystemSidSize = sizeof(localSystemSid.buffer); ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer); ULONG ulBuiltinUsersSidSize = sizeof(builtinUsersSid.buffer); ACCESS_MASK builtinUsersAccessMask = 0; ULONG ulAceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; /* Build the new Absolute Security Descriptor */ ntStatus = RTL_ALLOCATE( &pAbsSecDesc, VOID, SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateSecurityDescriptorAbsolute( pAbsSecDesc, SECURITY_DESCRIPTOR_REVISION); BAIL_ON_NT_STATUS(ntStatus); /* Create some SIDs */ ntStatus = RtlCreateWellKnownSid( WinLocalSystemSid, NULL, (PSID)localSystemSid.buffer, &ulLocalSystemSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, (PSID)administratorsSid.buffer, &ulAdministratorsSidSize); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateWellKnownSid( WinBuiltinUsersSid, NULL, (PSID)builtinUsersSid.buffer, &ulBuiltinUsersSidSize); BAIL_ON_NT_STATUS(ntStatus); /* Owner: Local System */ ntStatus = RtlDuplicateSid(&pOwnerSid, &localSystemSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetOwnerSecurityDescriptor( pAbsSecDesc, pOwnerSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Group: Administrators */ ntStatus = RtlDuplicateSid(&pGroupSid, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetGroupSecurityDescriptor( pAbsSecDesc, pGroupSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* DACL: Administrators - (Full Control) LocalSystem - (Full Control) Builtin Users - (Read && Execute && List Directory Contents) */ dwAceCount = 3; dwSizeDacl = ACL_HEADER_SIZE + dwAceCount * sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(&localSystemSid.sid) + RtlLengthSid(&administratorsSid.sid) + RtlLengthSid(&builtinUsersSid.sid) - dwAceCount * sizeof(ULONG); ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, ulAceFlags, FILE_ALL_ACCESS, &localSystemSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, ulAceFlags, FILE_ALL_ACCESS, &administratorsSid.sid); BAIL_ON_NT_STATUS(ntStatus); builtinUsersAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE; ntStatus = RtlAddAccessAllowedAceEx( pDacl, ACL_REVISION, ulAceFlags, builtinUsersAccessMask, &builtinUsersSid.sid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetDaclSecurityDescriptor( pAbsSecDesc, TRUE, pDacl, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* Create the SelfRelative SD */ ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, NULL, &ulRelSecDescLen); if (ntStatus == STATUS_BUFFER_TOO_SMALL) { ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc); BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlAbsoluteToSelfRelativeSD( pAbsSecDesc, pRelSecDesc, &ulRelSecDescLen); } BAIL_ON_NT_STATUS(ntStatus); *ppSecDesc = pRelSecDesc; cleanup: RTL_FREE(&pAbsSecDesc); RTL_FREE(&pOwnerSid); RTL_FREE(&pGroupSid); RTL_FREE(&pDacl); return ntStatus; error: *ppSecDesc = NULL; if (pRelSecDesc) { SrvFreeMemory(pRelSecDesc); } goto cleanup; }
static NTSTATUS LsaSrvLookupForeignDomainSids( PPOLICY_CONTEXT pPolCtx, PACCOUNT_SIDS pAccountSids, DWORD dwLevel, RefDomainList *pDomains, TranslatedNameArray2 *pNamesArray ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PDOMAIN_ENTRY pDomEntry = NULL; handle_t hLsaBinding = NULL; POLICY_HANDLE hDcPolicy = NULL; PSID pDomSid = NULL; DWORD iDomSid = 0; DWORD iResolvSid = 0; DWORD iSid = 0; DWORD dwDomIndex = 0; ACCOUNT_SIDS ForeignSids = {0}; SID_ARRAY Sids = {0}; RefDomainList *pForeignDomains = NULL; TranslatedName *pForeignNames = NULL; DWORD dwForeignNamesCount = 0; DWORD iDomain = 0; DWORD i = 0; PSID pSid = NULL; DWORD dwSidIndex = 0; /* * Allocate enough space for potential sequence of sid lookups */ dwError = LwAllocateMemory( sizeof(ForeignSids.ppSids[0]) * pAccountSids->dwCount, OUT_PPVOID(&ForeignSids.ppSids)); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateMemory( sizeof(ForeignSids.pdwIndices[0]) * pAccountSids->dwCount, OUT_PPVOID(&ForeignSids.pdwIndices)); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateMemory( sizeof(Sids.pSids[0]) * pAccountSids->dwCount, OUT_PPVOID(&Sids.pSids)); BAIL_ON_LSA_ERROR(dwError); while (iDomSid < pAccountSids->dwCount) { ntStatus = RtlDuplicateSid(&pDomSid, pAccountSids->ppSids[iDomSid]); BAIL_ON_NTSTATUS_ERROR(ntStatus); pDomSid->SubAuthorityCount--; pDomSid->SubAuthority[pDomSid->SubAuthorityCount] = 0; iResolvSid = 0; for (iSid = iDomSid; iSid < pAccountSids->dwCount; iSid++) { pSid = pAccountSids->ppSids[iSid]; dwSidIndex = pAccountSids->pdwIndices[iSid]; if (RtlIsPrefixSid(pDomSid, pSid)) { ntStatus = RtlDuplicateSid( &(ForeignSids.ppSids[iResolvSid]), pSid); BAIL_ON_NTSTATUS_ERROR(ntStatus); ForeignSids.pdwIndices[iResolvSid] = dwSidIndex; ForeignSids.dwCount = ++iResolvSid; /* * Free the sid so it's not looked up again */ RTL_FREE(&pAccountSids->ppSids[iSid]); pAccountSids->ppSids[iSid] = NULL; pSid = NULL; } } for (i = 0; i < ForeignSids.dwCount; i++) { Sids.pSids[i].pSid = ForeignSids.ppSids[i]; } Sids.dwNumSids = ForeignSids.dwCount; ntStatus = LsaSrvConnectDomainBySid(pPolCtx, pDomSid, &pDomEntry); BAIL_ON_NTSTATUS_ERROR(ntStatus); hLsaBinding = pDomEntry->hLsaBinding; hDcPolicy = pDomEntry->hPolicy; ntStatus = LsaLookupSids(hLsaBinding, hDcPolicy, &Sids, &pForeignDomains, &pForeignNames, dwLevel, &dwForeignNamesCount); if (ntStatus == STATUS_SUCCESS || ntStatus == STATUS_SOME_NOT_MAPPED) { for (iDomain = 0; iDomain < pForeignDomains->count; iDomain++) { LsaDomainInfo *pSrcDomInfo = NULL; LsaDomainInfo *pDstDomInfo = NULL; dwDomIndex = pDomains->count; pSrcDomInfo = &(pForeignDomains->domains[iDomain]); pDstDomInfo = &(pDomains->domains[dwDomIndex]); ntStatus = LsaSrvDuplicateUnicodeStringEx(&pDstDomInfo->name, &pSrcDomInfo->name); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = LsaSrvDuplicateSid(&pDstDomInfo->sid, pSrcDomInfo->sid); BAIL_ON_NTSTATUS_ERROR(ntStatus); for (iSid = 0; iSid < dwForeignNamesCount; iSid++) { DWORD iTransName = ForeignSids.pdwIndices[iSid]; TranslatedName *pSrcName = &(pForeignNames[iSid]); TranslatedName2 *pDstName = &(pNamesArray->names[iTransName]); if (iDomain != pSrcName->sid_index) { continue; } ntStatus = LsaSrvDuplicateUnicodeString(&pDstName->name, &pSrcName->name); BAIL_ON_NTSTATUS_ERROR(ntStatus); pDstName->type = pSrcName->type; pDstName->sid_index = dwDomIndex; pDstName->unknown1 = 0; } pDomains->count = (++dwDomIndex); } pNamesArray->count += dwForeignNamesCount; } else if (ntStatus == STATUS_NONE_MAPPED) { for (i = 0; i < ForeignSids.dwCount; i++) { DWORD iTransName = ForeignSids.pdwIndices[i]; TranslatedName2 *pDstName = &(pNamesArray->names[iTransName]); pDstName->type = SID_TYPE_UNKNOWN; pDstName->sid_index = 0; pDstName->unknown1 = 0; } pNamesArray->count += ForeignSids.dwCount; } else { BAIL_ON_NTSTATUS_ERROR(ntStatus); } /* * Free the sids array before the next round of lookup. * The entire allocated space (i.e. as big as pAccountSids) * is cleaned up. */ for (i = 0; i < pAccountSids->dwCount; i++) { RTL_FREE(&(ForeignSids.ppSids[i])); ForeignSids.ppSids[i] = NULL; Sids.pSids[i].pSid = NULL; ForeignSids.pdwIndices[i] = -1; } Sids.dwNumSids = 0; if (pDomEntry) { LsaSrvDomainEntryFree(&pDomEntry); } if (pForeignDomains) { LsaRpcFreeMemory(pForeignDomains); pForeignDomains = NULL; } if (pForeignNames) { LsaRpcFreeMemory(pForeignNames); pForeignNames = NULL; } RTL_FREE(&pDomSid); /* * Find another domain name (first name that hasn't * been nulled out) */ iDomSid = 0; while (iDomSid < pAccountSids->dwCount && pAccountSids->ppSids[iDomSid] == NULL) { iDomSid++; } } /* * Lookup status is checked later by the caller * so avoid bailing accidentally because other lookups * may be successful */ if (ntStatus == STATUS_SOME_NOT_MAPPED || ntStatus == STATUS_NONE_MAPPED) { ntStatus = STATUS_SUCCESS; } cleanup: for (i = 0; i < pAccountSids->dwCount; i++) { RTL_FREE(&(ForeignSids.ppSids[i])); } LW_SAFE_FREE_MEMORY(ForeignSids.ppSids); LW_SAFE_FREE_MEMORY(ForeignSids.pdwIndices); LW_SAFE_FREE_MEMORY(Sids.pSids); if (pDomEntry) { LsaSrvDomainEntryFree(&pDomEntry); } if (pForeignDomains) { LsaRpcFreeMemory(pForeignDomains); } if (pForeignNames) { LsaRpcFreeMemory(pForeignNames); } RTL_FREE(&pDomSid); if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: goto cleanup; }