NTSTATUS LsaSrvDuplicateSid( PSID *ppSidOut, PSID pSidIn ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSID pSid = NULL; ULONG ulSidSize = 0; ulSidSize = RtlLengthSid(pSidIn); ntStatus = LsaSrvAllocateMemory((void**)&pSid, ulSidSize); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = RtlCopySid(ulSidSize, pSid, pSidIn); BAIL_ON_NTSTATUS_ERROR(ntStatus); *ppSidOut = pSid; cleanup: return ntStatus; error: if (pSid) { LsaSrvFreeMemory(pSid); } *ppSidOut = NULL; goto cleanup; }
NTSTATUS LsaSrvSidAppendRid( PSID *ppOutSid, PSID pInSid, DWORD dwRid ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwSidLen = 0; PSID pSid = NULL; dwSidLen = RtlLengthRequiredSid(pInSid->SubAuthorityCount + 1); ntStatus = LsaSrvAllocateMemory((void**)&pSid, dwSidLen); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = RtlCopySid(dwSidLen, pSid, pInSid); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = RtlAppendRidSid(dwSidLen, pSid, dwRid); BAIL_ON_NTSTATUS_ERROR(ntStatus); *ppOutSid = pSid; cleanup: return ntStatus; error: if (pSid) { LsaSrvFreeMemory(pSid); } *ppOutSid = NULL; goto cleanup; }
static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, struct nss_domain_entry *e, const char *alias, char **name) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct likewise_cell *cell = NULL; nt_status = _idmap_adex_init(NULL); BAIL_ON_NTSTATUS_ERROR(nt_status); if ((cell = cell_list_head()) == NULL) { nt_status = NT_STATUS_INVALID_SERVER_STATE; BAIL_ON_NTSTATUS_ERROR(nt_status); } nt_status = cell->provider->map_from_alias(mem_ctx, e->domain, alias, name); /* go ahead and allow the cache mgr to mark this in negative cache */ if (!NT_STATUS_IS_OK(nt_status)) nt_status = NT_STATUS_NONE_MAPPED; done: return nt_status; }
NTSTATUS LsaSrvInitAuthInfo( IN handle_t hBinding, OUT PPOLICY_CONTEXT pPolCtx ) { NTSTATUS ntStatus = STATUS_SUCCESS; unsigned32 rpcStatus = 0; rpc_transport_info_handle_t hTransportInfo = NULL; DWORD dwProtSeq = rpc_c_invalid_protseq_id; rpc_binding_inq_access_token_caller( hBinding, &pPolCtx->pUserToken, &rpcStatus); ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NTSTATUS_ERROR(ntStatus); rpc_binding_inq_transport_info(hBinding, &hTransportInfo, &rpcStatus); ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NTSTATUS_ERROR(ntStatus); if (hTransportInfo) { rpc_binding_inq_prot_seq(hBinding, (unsigned32*)&dwProtSeq, &rpcStatus); ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NTSTATUS_ERROR(ntStatus); switch (dwProtSeq) { case rpc_c_protseq_id_ncacn_np: ntStatus = LsaSrvInitNpAuthInfo(hTransportInfo, pPolCtx); BAIL_ON_NTSTATUS_ERROR(ntStatus); break; } } cleanup: return ntStatus; error: LsaSrvFreeAuthInfo(pPolCtx); goto cleanup; }
NTSTATUS SamrSrvCreateUser2( IN handle_t hBinding, IN DOMAIN_HANDLE hDomain, IN UNICODE_STRING *pAccountName, IN DWORD dwAccountFlags, IN DWORD dwAccessMask, OUT ACCOUNT_HANDLE *phUser, OUT PDWORD pdwAccessGranted, OUT PDWORD pdwRid ) { NTSTATUS ntStatus = STATUS_SUCCESS; PDOMAIN_CONTEXT pDomCtx = NULL; pDomCtx = (PDOMAIN_CONTEXT)hDomain; if (pDomCtx == NULL || pDomCtx->Type != SamrContextDomain) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } if (!(pDomCtx->dwAccessGranted & DOMAIN_ACCESS_CREATE_USER)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } ntStatus = SamrSrvCreateAccount(hBinding, hDomain, pAccountName, DS_OBJECT_CLASS_USER, dwAccountFlags, dwAccessMask, phUser, pdwAccessGranted, pdwRid); BAIL_ON_NTSTATUS_ERROR(ntStatus); cleanup: return ntStatus; error: *phUser = NULL; *pdwAccessGranted = 0; *pdwRid = 0; goto cleanup; }
static NTSTATUS SamrFillAliasInfo1( PDIRECTORY_ENTRY pEntry, DWORD dwNumMembers, AliasInfo *pInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; AliasInfoAll *pInfoAll = NULL; WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME; WCHAR wszAttrDescription[] = DS_ATTR_DESCRIPTION; PWSTR pwszName = NULL; PWSTR pwszDescription = NULL; pInfoAll = &(pInfo->all); /* name */ dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrSamAccountName, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszName); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvInitUnicodeString(&pInfoAll->name, pwszName); BAIL_ON_NTSTATUS_ERROR(ntStatus); /* num_members */ pInfoAll->num_members = dwNumMembers; /* description */ dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrDescription, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszDescription); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvInitUnicodeString(&pInfoAll->description, pwszDescription); BAIL_ON_NTSTATUS_ERROR(ntStatus); cleanup: return ntStatus; error: memset(pInfo, 0, sizeof(*pInfo)); goto cleanup; }
NTSTATUS LsaSrvClose( /* [in] */ handle_t hBinding, /* [out, context_handle] */ void **phInOut ) { NTSTATUS ntStatus = STATUS_SUCCESS; PLSA_GENERIC_CONTEXT pContext = NULL; BAIL_ON_INVALID_PTR(phInOut); BAIL_ON_INVALID_PTR(*phInOut); pContext = (PLSA_GENERIC_CONTEXT)(*phInOut); switch (pContext->Type) { case LsaContextPolicy: ntStatus = LsaSrvPolicyContextClose((PPOLICY_CONTEXT)pContext); break; default: /* Something is seriously wrong if we get a context we haven't created */ ntStatus = STATUS_INTERNAL_ERROR; } BAIL_ON_NTSTATUS_ERROR(ntStatus); *phInOut = NULL; cleanup: return ntStatus; error: goto cleanup; }
NTSTATUS DsrSrvInitAuthInfo( IN handle_t hBinding, OUT PACCESS_TOKEN *ppAccessToken ) { NTSTATUS ntStatus = STATUS_SUCCESS; unsigned32 rpcStatus = 0; rpc_binding_inq_access_token_caller( hBinding, ppAccessToken, &rpcStatus); ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NTSTATUS_ERROR(ntStatus); cleanup: return ntStatus; error: goto cleanup; }
static NTSTATUS SamrFillAliasInfo2( PDIRECTORY_ENTRY pEntry, AliasInfo *pInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; WCHAR wszAttrSamrAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME; PWSTR pwszName = NULL; /* name */ dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrSamrAccountName, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszName); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvInitUnicodeString(&pInfo->name, pwszName); BAIL_ON_NTSTATUS_ERROR(ntStatus); cleanup: return ntStatus; error: memset(pInfo, 0, sizeof(*pInfo)); goto cleanup; }
NTSTATUS LsaSrvDuplicateUnicodeStringEx( UNICODE_STRING *pOut, UNICODE_STRING *pIn ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwLen = 0; DWORD dwSize = 0; dwLen = pIn->Length; dwSize = pIn->MaximumLength; ntStatus = LsaSrvAllocateMemory((void**)&(pOut->Buffer), dwSize); BAIL_ON_NTSTATUS_ERROR(ntStatus); memcpy(pOut->Buffer, pIn->Buffer, dwLen); pOut->MaximumLength = dwSize; pOut->Length = dwLen; cleanup: return ntStatus; error: if (pOut->Buffer) { LsaSrvFreeMemory(pOut->Buffer); } pOut->MaximumLength = 0; pOut->Length = 0; goto cleanup; }
static NTSTATUS SamrFillAliasInfo3( PDIRECTORY_ENTRY pEntry, AliasInfo *pInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; WCHAR wszAttrDescription[] = DS_ATTR_DESCRIPTION; PWSTR pwszDescription = NULL; /* name */ dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrDescription, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszDescription); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvInitUnicodeString(&pInfo->description, pwszDescription); BAIL_ON_NTSTATUS_ERROR(ntStatus); cleanup: return ntStatus; error: memset(pInfo, 0, sizeof(*pInfo)); goto cleanup; }
NTSTATUS LsaSrvDuplicateWC16String( PWSTR *ppwszOut, PWSTR pwszIn ) { NTSTATUS ntStatus = STATUS_SUCCESS; PWSTR pwszStr = NULL; DWORD dwLen = 0; dwLen = wc16slen(pwszIn); ntStatus = LsaSrvAllocateMemory((void**)&pwszStr, (dwLen + 1) * sizeof(*pwszStr)); BAIL_ON_NTSTATUS_ERROR(ntStatus); wc16sncpy(pwszStr, pwszIn, dwLen); *ppwszOut = pwszStr; cleanup: return ntStatus; error: if (pwszStr) { LsaSrvFreeMemory(pwszStr); } *ppwszOut = NULL; goto cleanup; }
NTSTATUS LsaSrvGetFromUnicodeStringEx( PWSTR *ppwszOut, UNICODE_STRING *pIn ) { NTSTATUS ntStatus = STATUS_SUCCESS; PWSTR pwszStr = NULL; ntStatus = LsaSrvAllocateMemory((void**)&pwszStr, (pIn->MaximumLength) * sizeof(WCHAR)); BAIL_ON_NTSTATUS_ERROR(ntStatus); wc16sncpy(pwszStr, pIn->Buffer, (pIn->Length / sizeof(WCHAR))); *ppwszOut = pwszStr; cleanup: return ntStatus; error: if (pwszStr) { LsaSrvFreeMemory(pwszStr); } *ppwszOut = NULL; goto cleanup; }
NTSTATUS SamrSrvGetUserPwInfo( IN handle_t hBinding, IN ACCOUNT_HANDLE hUser, OUT PwInfo *pInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; PACCOUNT_CONTEXT pAcctCtx = NULL; PDOMAIN_CONTEXT pDomCtx = NULL; BAIL_ON_INVALID_PTR(hBinding); BAIL_ON_INVALID_PTR(hUser); BAIL_ON_INVALID_PTR(pInfo); pAcctCtx = (PACCOUNT_CONTEXT)hUser; pDomCtx = pAcctCtx->pDomCtx; if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } /* Check access rights required */ if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } /* * This is in fact returning domain- not user-specific * settings */ pInfo->min_password_length = pDomCtx->dwMinPasswordLen; pInfo->password_properties = pDomCtx->dwPasswordProperties; cleanup: return ntStatus; error: pInfo->min_password_length = 0; pInfo->password_properties = 0; goto cleanup; }
NTSTATUS LsaSrvInitUnicodeStringEx( PUNICODE_STRING pOut, PCWSTR pwszIn ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; size_t sLen = 0; size_t sSize = 0; BAIL_ON_INVALID_POINTER(pOut); if (pwszIn) { dwError = LwWc16sLen(pwszIn, &sLen); BAIL_ON_LSA_ERROR(dwError); sSize = (sLen + 1) * sizeof(WCHAR); ntStatus = LsaSrvAllocateMemory(OUT_PPVOID(&pOut->Buffer), sSize); BAIL_ON_NTSTATUS_ERROR(ntStatus); memcpy(pOut->Buffer, pwszIn, sLen * sizeof(WCHAR)); } else { pOut->Buffer = NULL; } pOut->MaximumLength = sSize; pOut->Length = sLen * sizeof(WCHAR); cleanup: if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pOut->Buffer) { LsaSrvFreeMemory(pOut->Buffer); pOut->Buffer = NULL; } pOut->MaximumLength = 0; pOut->Length = 0; goto cleanup; }
NTSTATUS LsaSrvAllocateSidFromWC16String( PSID *ppSid, PCWSTR pwszSidStr ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSID pSid = NULL; ULONG ulSidSize = 0; PSID pSidCopy = NULL; ntStatus = RtlAllocateSidFromWC16String(&pSid, pwszSidStr); BAIL_ON_NTSTATUS_ERROR(ntStatus); ulSidSize = RtlLengthSid(pSid); ntStatus = LsaSrvAllocateMemory((void**)&pSidCopy, ulSidSize); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = RtlCopySid(ulSidSize, pSidCopy, pSid); BAIL_ON_NTSTATUS_ERROR(ntStatus); *ppSid = pSidCopy; cleanup: if (pSid) { RTL_FREE(&pSid); } return ntStatus; error: if (pSidCopy) { LsaSrvFreeMemory(pSidCopy); } *ppSid = NULL; goto cleanup; }
NTSTATUS cell_connect_dn(struct likewise_cell **c, const char *dn) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct likewise_cell *new_cell = NULL; char *dns_domain = NULL; if (*c || !dn) { nt_status = NT_STATUS_INVALID_PARAMETER; BAIL_ON_NTSTATUS_ERROR(nt_status); } if ((new_cell = cell_new()) == NULL) { nt_status = NT_STATUS_NO_MEMORY; BAIL_ON_NTSTATUS_ERROR(nt_status); } /* Set the DNS domain, dn, etc ... and add it to the list */ dns_domain = cell_dn_to_dns(dn); cell_set_dns_domain(new_cell, dns_domain); SAFE_FREE(dns_domain); cell_set_dn(new_cell, dn); nt_status = cell_connect(new_cell); BAIL_ON_NTSTATUS_ERROR(nt_status); *c = new_cell; done: if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("LWI: Failled to connect to cell \"%s\" (%s)\n", dn ? dn : "NULL", nt_errstr(nt_status))); talloc_destroy(new_cell); } return nt_status; }
NTSTATUS SamrSrvConnect( /* [in] */ handle_t hBinding, /* [in] */ PCWSTR pwszSystemName, /* [in] */ DWORD dwAccessMask, /* [out] */ CONNECT_HANDLE *hConn ) { const DWORD dwConnectVersion = 2; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; PCONNECT_CONTEXT pConnCtx = NULL; ntStatus = SamrSrvConnectInternal(hBinding, pwszSystemName, dwAccessMask, dwConnectVersion, 0, NULL, NULL, NULL, &pConnCtx); BAIL_ON_NTSTATUS_ERROR(ntStatus); *hConn = (CONNECT_HANDLE)pConnCtx; cleanup: if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pConnCtx) { SamrSrvConnectContextFree(pConnCtx); } *hConn = NULL; goto cleanup; }
NTSTATUS SamrSrvConnect4( /* [in] */ handle_t hBinding, /* [in] */ PCWSTR pwszSystemName, /* [in] */ DWORD dwUnknown1, /* [in] */ DWORD dwAccessMask, /* [out] */ CONNECT_HANDLE *hConn ) { const DWORD dwConnectVersion = 4; NTSTATUS ntStatus = STATUS_SUCCESS; PCONNECT_CONTEXT pConnCtx = NULL; ntStatus = SamrSrvConnectInternal(hBinding, pwszSystemName, dwAccessMask, dwConnectVersion, 0, NULL, NULL, NULL, &pConnCtx); BAIL_ON_NTSTATUS_ERROR(ntStatus); *hConn = (CONNECT_HANDLE)pConnCtx; cleanup: return ntStatus; error: if (pConnCtx) { SamrSrvConnectContextFree(pConnCtx); } *hConn = NULL; goto cleanup; }
NTSTATUS SamrSrvOpenAlias( IN handle_t hBinding, IN DOMAIN_HANDLE hDomain, IN DWORD dwAccessMask, IN DWORD dwRid, OUT ACCOUNT_HANDLE *phAlias ) { NTSTATUS ntStatus = STATUS_SUCCESS; ACCOUNT_HANDLE hAlias = NULL; PACCOUNT_CONTEXT pAcctCtx = NULL; ntStatus = SamrSrvOpenAccount(hBinding, hDomain, dwAccessMask, dwRid, DS_OBJECT_CLASS_LOCAL_GROUP, &hAlias); BAIL_ON_NTSTATUS_ERROR(ntStatus); pAcctCtx = (PACCOUNT_CONTEXT)hAlias; pAcctCtx->dwAccountType = SID_TYPE_ALIAS; *phAlias = (ACCOUNT_HANDLE)pAcctCtx; cleanup: pAcctCtx = NULL; hAlias = NULL; return ntStatus; error: *phAlias = NULL; goto cleanup; }
NTSTATUS SamrSrvEnumDomainAccounts( IN handle_t hBinding, IN DOMAIN_HANDLE hDomain, IN OUT PDWORD pdwResume, IN DWORD dwObjectClass, IN DWORD dwFlagsFilter, IN DWORD dwMaxSize, OUT RID_NAME_ARRAY **ppNames, OUT UINT32 *pdwNumEntries ) { wchar_t wszFilterFmt[] = L"%ws=%u AND %ws='%ws'"; NTSTATUS ntStatus = STATUS_SUCCESS; NTSTATUS ntEnumStatus = STATUS_SUCCESS; DWORD dwError = 0; PDOMAIN_CONTEXT pDomCtx = NULL; PCONNECT_CONTEXT pConnCtx = NULL; PWSTR pwszBase = NULL; WCHAR wszAttrObjectClass[] = DS_ATTR_OBJECT_CLASS; WCHAR wszAttrDomainName[] = DS_ATTR_DOMAIN; WCHAR wszAttrAccountFlags[] = DS_ATTR_ACCOUNT_FLAGS; WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME; WCHAR wszAttrObjectSid[] = DS_ATTR_OBJECT_SID; DWORD dwScope = 0; PWSTR pwszFilter = NULL; size_t sDomainNameLen = 0; PWSTR pwszDomainName = NULL; DWORD dwFilterLen = 0; PDIRECTORY_ENTRY pEntries = NULL; PDIRECTORY_ENTRY pEntry = NULL; DWORD dwNumEntries = 0; DWORD dwTotalSize = 0; DWORD dwSize = 0; DWORD i = 0; DWORD dwCount = 0; DWORD dwNumEntriesReturned = 0; DWORD dwResume = 0; DWORD dwAccountFlags = 0; size_t sNameLen = 0; PWSTR pwszName = NULL; PWSTR pwszSid = NULL; PSID pSid = NULL; DWORD dwRid = 0; RID_NAME_ARRAY *pNames = NULL; RID_NAME *pName = NULL; DWORD dwNewResumeIdx = 0; PWSTR wszAttributes[] = { wszAttrSamAccountName, wszAttrObjectSid, wszAttrAccountFlags, NULL }; BAIL_ON_INVALID_PTR(hDomain); BAIL_ON_INVALID_PTR(pdwResume); BAIL_ON_INVALID_PTR(ppNames); BAIL_ON_INVALID_PTR(pdwNumEntries); pDomCtx = (PDOMAIN_CONTEXT)hDomain; dwResume = *pdwResume; if (pDomCtx == NULL || pDomCtx->Type != SamrContextDomain) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } if (!(pDomCtx->dwAccessGranted & DOMAIN_ACCESS_ENUM_ACCOUNTS)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } pConnCtx = pDomCtx->pConnCtx; pwszBase = pDomCtx->pwszDn; pwszDomainName = pDomCtx->pwszDomainName; dwError = LwWc16sLen(pwszDomainName, &sDomainNameLen); BAIL_ON_LSA_ERROR(dwError); dwFilterLen = ((sizeof(wszAttrObjectClass)/sizeof(WCHAR)) - 1) + 10 + ((sizeof(wszAttrDomainName)/sizeof(WCHAR)) - 1) + (sDomainNameLen + 1) + (sizeof(wszFilterFmt)/sizeof(wszFilterFmt[0])); dwError = LwAllocateMemory(dwFilterLen * sizeof(pwszFilter[0]), OUT_PPVOID(&pwszFilter)); BAIL_ON_LSA_ERROR(dwError); if (sw16printfw(pwszFilter, dwFilterLen, wszFilterFmt, wszAttrObjectClass, dwObjectClass, wszAttrDomainName, pwszDomainName) < 0) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NTSTATUS_ERROR(ntStatus); } dwError = DirectorySearch(pConnCtx->hDirectory, pwszBase, dwScope, pwszFilter, wszAttributes, FALSE, &pEntries, &dwNumEntries); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvAllocateMemory(OUT_PPVOID(&pNames), sizeof(*pNames)); BAIL_ON_NTSTATUS_ERROR(ntStatus); if (dwResume >= dwNumEntries) { ntEnumStatus = STATUS_NO_MORE_ENTRIES; BAIL_ON_NTSTATUS_ERROR(ntStatus); } dwTotalSize += sizeof(pNames->dwCount); for (i = 0; i + dwResume < dwNumEntries; i++) { pEntry = &(pEntries[i + dwResume]); dwError = DirectoryGetEntryAttrValueByName( pEntry, wszAttrSamAccountName, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszName); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryGetEntryAttrValueByName( pEntry, wszAttrAccountFlags, DIRECTORY_ATTR_TYPE_INTEGER, &dwAccountFlags); BAIL_ON_LSA_ERROR(dwError); dwSize = 0; if (dwFlagsFilter && !(dwAccountFlags & dwFlagsFilter)) { continue; } dwError = LwWc16sLen(pwszName, &sNameLen); BAIL_ON_LSA_ERROR(dwError); dwSize += sizeof(UINT32); dwSize += sNameLen * sizeof(pwszName[0]); dwSize += 2 * sizeof(UINT16); dwTotalSize += dwSize; dwCount++; if (dwTotalSize > dwMaxSize) { dwTotalSize -= dwSize; dwCount--; ntEnumStatus = STATUS_MORE_ENTRIES; break; } } /* * At least one entry is returned regardless of declared * max response size */ dwNumEntriesReturned = (dwSize > 0 && dwCount == 0) ? 1 : dwCount; pNames->dwCount = dwNumEntriesReturned; ntStatus = SamrSrvAllocateMemory( OUT_PPVOID(&pNames->pEntries), sizeof(pNames->pEntries[0]) * pNames->dwCount); BAIL_ON_NTSTATUS_ERROR(ntStatus); for (i = 0, dwCount = 0; dwCount < dwNumEntriesReturned && i + dwResume < dwNumEntries; i++) { pEntry = &(pEntries[i + dwResume]); dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrObjectSid, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszSid); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrSamAccountName, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszName); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryGetEntryAttrValueByName(pEntry, wszAttrAccountFlags, DIRECTORY_ATTR_TYPE_INTEGER, &dwAccountFlags); BAIL_ON_LSA_ERROR(dwError); dwNewResumeIdx = i + dwResume + 1; if (dwFlagsFilter && !(dwAccountFlags & dwFlagsFilter)) { continue; } pName = &(pNames->pEntries[dwCount++]); ntStatus = RtlAllocateSidFromWC16String(&pSid, pwszSid); BAIL_ON_NTSTATUS_ERROR(ntStatus); dwRid = pSid->SubAuthority[pSid->SubAuthorityCount - 1]; pName->dwRid = (UINT32)dwRid; ntStatus = SamrSrvInitUnicodeString(&pName->Name, pwszName); BAIL_ON_NTSTATUS_ERROR(ntStatus); RTL_FREE(&pSid); } *pdwResume = dwNewResumeIdx; *pdwNumEntries = dwNumEntriesReturned; *ppNames = pNames; cleanup: LW_SAFE_FREE_MEMORY(pwszFilter); RTL_FREE(&pSid); if (pEntries) { DirectoryFreeEntries(pEntries, dwNumEntries); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } if (ntStatus == STATUS_SUCCESS && ntEnumStatus != STATUS_SUCCESS) { ntStatus = ntEnumStatus; } return ntStatus; error: if (pNames) { for (i = 0; i < pNames->dwCount; i++) { SamrSrvFreeUnicodeString(&(pNames->pEntries[i].Name)); } SamrSrvFreeMemory(pNames->pEntries); SamrSrvFreeMemory(pNames); } *pdwResume = 0; *pdwNumEntries = 0; *ppNames = NULL; goto cleanup; }
NTSTATUS SamrSrvQueryAliasInfo( /* [in] */ handle_t hBinding, /* [in] */ ACCOUNT_HANDLE hAlias, /* [in] */ UINT16 level, /* [out] */ AliasInfo **info ) { PCSTR filterFormat = "%s=%Q"; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; PACCOUNT_CONTEXT pAcctCtx = NULL; PDOMAIN_CONTEXT pDomCtx = NULL; PCONNECT_CONTEXT pConnCtx = NULL; PWSTR pwszBase = NULL; WCHAR wszAttrDn[] = DS_ATTR_DISTINGUISHED_NAME; WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME; WCHAR wszAttrDescription[] = DS_ATTR_DESCRIPTION; CHAR szAttrDn[] = DS_ATTR_DISTINGUISHED_NAME; DWORD dwScope = 0; PSTR pszDn = NULL; PWSTR pwszFilter = NULL; PDIRECTORY_ENTRY pEntry = NULL; DWORD dwEntriesNum = 0; PDIRECTORY_ENTRY pMemberEntry = NULL; DWORD dwNumMembers = 0; AliasInfo *pAliasInfo = NULL; PWSTR wszAttributesLevel1[] = { wszAttrSamAccountName, wszAttrDescription, NULL }; PWSTR wszAttributesLevel2[] = { wszAttrSamAccountName, NULL }; PWSTR wszAttributesLevel3[] = { wszAttrDescription, NULL }; PWSTR *pwszAttributes[] = { wszAttributesLevel1, wszAttributesLevel2, wszAttributesLevel3 }; PWSTR wszMemberAttributes[] = { wszAttrDn, NULL }; pAcctCtx = (PACCOUNT_CONTEXT)hAlias; if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } if (!(pAcctCtx->dwAccessGranted & ALIAS_ACCESS_LOOKUP_INFO)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } pDomCtx = pAcctCtx->pDomCtx; pConnCtx = pDomCtx->pConnCtx; pwszBase = pDomCtx->pwszDn; dwError = LwWc16sToMbs(pAcctCtx->pwszDn, &pszDn); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryAllocateWC16StringFilterPrintf( &pwszFilter, filterFormat, szAttrDn, pszDn); BAIL_ON_LSA_ERROR(dwError); dwError = DirectorySearch(pConnCtx->hDirectory, pwszBase, dwScope, pwszFilter, pwszAttributes[level - 1], FALSE, &pEntry, &dwEntriesNum); BAIL_ON_LSA_ERROR(dwError); if (dwEntriesNum == 0) { ntStatus = STATUS_INVALID_HANDLE; } else if (dwEntriesNum > 1) { ntStatus = STATUS_INTERNAL_ERROR; } BAIL_ON_NTSTATUS_ERROR(ntStatus); if (level == ALIAS_INFO_ALL) { dwError = DirectoryGetGroupMembers(pConnCtx->hDirectory, pAcctCtx->pwszDn, wszMemberAttributes, &pMemberEntry, &dwNumMembers); BAIL_ON_LSA_ERROR(dwError); } ntStatus = SamrSrvAllocateMemory((void**)&pAliasInfo, sizeof(*pAliasInfo)); BAIL_ON_NTSTATUS_ERROR(ntStatus); switch (level) { case ALIAS_INFO_ALL: ntStatus = SamrFillAliasInfo1(pEntry, dwNumMembers, pAliasInfo); break; case ALIAS_INFO_NAME: ntStatus = SamrFillAliasInfo2(pEntry, pAliasInfo); break; case ALIAS_INFO_DESCRIPTION: ntStatus = SamrFillAliasInfo3(pEntry, pAliasInfo); break; default: ntStatus = STATUS_INVALID_INFO_CLASS; } BAIL_ON_NTSTATUS_ERROR(ntStatus); *info = pAliasInfo; cleanup: LW_SAFE_FREE_MEMORY(pszDn); LW_SAFE_FREE_MEMORY(pwszFilter); if (pEntry) { DirectoryFreeEntries(pEntry, dwEntriesNum); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pAliasInfo) { SamrSrvFreeMemory(pAliasInfo); } *info = NULL; goto cleanup; }
NTSTATUS LsaSrvLookupNames( /* [in] */ handle_t IDL_handle, /* [in] */ POLICY_HANDLE hPolicy, /* [in] */ UINT32 num_names, /* [in] */ UNICODE_STRING *names, /* [out] */ RefDomainList **domains, /* [in, out] */ TranslatedSidArray *sids, /* [in] */ UINT16 level, /* [in, out] */ UINT32 *count ) { NTSTATUS ntStatus = STATUS_SUCCESS; NTSTATUS ntLookupStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PPOLICY_CONTEXT pPolCtx = NULL; PUNICODE_STRING pNames = NULL; PWSTR pwszName = NULL; DWORD i = 0; RefDomainList *pDomains = NULL; TranslatedSidArray2 *pSidArray = NULL; DWORD dwCount = 0; pPolCtx = (PPOLICY_CONTEXT)hPolicy; if (pPolCtx == NULL || pPolCtx->Type != LsaContextPolicy) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } if (!(pPolCtx->dwAccessGranted & LSA_ACCESS_LOOKUP_NAMES_SIDS)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } ntStatus = LsaSrvAllocateMemory((void**)&pNames, sizeof(*pNames) * num_names); BAIL_ON_NTSTATUS_ERROR(ntStatus); for (i = 0; i < num_names; i++) { dwError = LwAllocateWc16StringFromUnicodeString( &pwszName, &(names[i])); BAIL_ON_LSA_ERROR(dwError); ntStatus = LsaSrvInitUnicodeStringEx(&(pNames[i]), pwszName); BAIL_ON_NTSTATUS_ERROR(ntStatus); if (pwszName) { LW_SAFE_FREE_MEMORY(pwszName); } } ntStatus = LsaSrvAllocateMemory((void**)&pSidArray, sizeof(*pSidArray) * num_names); BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = LsaSrvLookupNames2(IDL_handle, hPolicy, num_names, pNames, &pDomains, pSidArray, level, &dwCount, 0, 0); if (ntStatus != STATUS_SUCCESS && ntStatus != STATUS_SOME_NOT_MAPPED && ntStatus != STATUS_NONE_MAPPED) { BAIL_ON_NTSTATUS_ERROR(ntStatus); } ntLookupStatus = ntStatus; sids->count = pSidArray->count; ntStatus = LsaSrvAllocateMemory((void**)&(sids->sids), sizeof(sids->sids[0]) * sids->count); BAIL_ON_NTSTATUS_ERROR(ntStatus); for (i = 0; i < sids->count; i++) { TranslatedSid2 *pTransSid2 = &(pSidArray->sids[i]); TranslatedSid *pTransSid = &(sids->sids[i]); pTransSid->type = pTransSid2->type; pTransSid->rid = pTransSid2->rid; pTransSid->index = pTransSid2->index; } *domains = pDomains; *count = dwCount; cleanup: if (pSidArray) { if (pSidArray->sids) { LsaSrvFreeMemory(pSidArray->sids); } LsaSrvFreeMemory(pSidArray); } if (pwszName) { LW_SAFE_FREE_MEMORY(pwszName); } if (pNames) { LsaSrvFreeMemory(pNames); } if (ntStatus == STATUS_SUCCESS && ntLookupStatus != STATUS_SUCCESS) { ntStatus = ntLookupStatus; } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pDomains) { LsaSrvFreeMemory(pDomains); } if (sids->sids) { LsaSrvFreeMemory(sids->sids); } *domains = NULL; sids->sids = NULL; sids->count = 0; *count = 0; goto cleanup; }
NTSTATUS LsaSrvQuerySecurity( /* [in] */ handle_t IDL_handle, /* [in] */ PVOID hObject, /* [in] */ SECURITY_INFORMATION SecurityInformation, /* [out] */ PLSA_SECURITY_DESCRIPTOR_BUFFER *ppSecurityDescBuffer ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD err = ERROR_SUCCESS; PLSA_GENERIC_CONTEXT pContext = NULL; PSECURITY_DESCRIPTOR_RELATIVE pSecurityDescRelative = NULL; DWORD securityDescRelativeSize = 0; PLSA_SECURITY_DESCRIPTOR_BUFFER pSecurityDescBuffer = NULL; pContext = (PLSA_GENERIC_CONTEXT)(hObject); switch (pContext->Type) { case LsaContextPolicy: ntStatus = LsaSrvQueryPolicySecurity( (PPOLICY_CONTEXT)pContext, SecurityInformation, &pSecurityDescRelative, &securityDescRelativeSize); break; case LsaContextAccount: ntStatus = LsaSrvQueryAccountSecurity( (PLSAR_ACCOUNT_CONTEXT)pContext, SecurityInformation, &pSecurityDescRelative, &securityDescRelativeSize); break; default: /* Something is seriously wrong if we get a context we haven't created */ ntStatus = STATUS_INTERNAL_ERROR; } BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = LsaSrvAllocateMemory( OUT_PPVOID(&pSecurityDescBuffer), sizeof(*pSecurityDescBuffer)); BAIL_ON_NT_STATUS(ntStatus); pSecurityDescBuffer->pBuffer = (PBYTE)pSecurityDescRelative; pSecurityDescBuffer->BufferLen = securityDescRelativeSize; *ppSecurityDescBuffer = pSecurityDescBuffer; error: if (err || ntStatus) { if (pSecurityDescBuffer) { if (pSecurityDescBuffer->pBuffer) { LsaSrvFreeMemory(pSecurityDescBuffer->pBuffer); } LsaSrvFreeMemory(pSecurityDescBuffer); } if (ppSecurityDescBuffer) { *ppSecurityDescBuffer = NULL; } } if (ntStatus == STATUS_SUCCESS && err != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(err); } return ntStatus; }
NTSTATUS SamrSrvQuerySecurity( IN handle_t hBinding, IN void *hObject, IN DWORD dwSecurityInfo, OUT PSAMR_SECURITY_DESCRIPTOR_BUFFER *ppSecDescBuf ) { PCSTR filterFormat = "%s=%Q"; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PSAMR_GENERIC_CONTEXT pCtx = (PSAMR_GENERIC_CONTEXT)hObject; PDOMAIN_CONTEXT pDomCtx = NULL; PACCOUNT_CONTEXT pAcctCtx = NULL; PWSTR pwszDn = NULL; HANDLE hDirectory = NULL; PWSTR pwszBaseDn = NULL; DWORD dwScope = 0; WCHAR wszAttrSecDesc[] = DS_ATTR_SECURITY_DESCRIPTOR; CHAR szAttrDn[] = DS_ATTR_DISTINGUISHED_NAME; PSTR pszDn = NULL; PWSTR pwszFilter = NULL; PDIRECTORY_ENTRY pEntries = NULL; DWORD dwNumEntries = 0; PDIRECTORY_ENTRY pObjectEntry = NULL; POCTET_STRING pSecDescBlob = NULL; PSAMR_SECURITY_DESCRIPTOR_BUFFER pSecDescBuf = NULL; PWSTR wszAttributes[] = { wszAttrSecDesc, NULL }; /* * Only querying security descriptor on an account is allowed */ if (pCtx->Type == SamrContextAccount) { pAcctCtx = (PACCOUNT_CONTEXT)hObject; pDomCtx = pAcctCtx->pDomCtx; pwszDn = pAcctCtx->pwszDn; hDirectory = pDomCtx->pConnCtx->hDirectory; } else if (pCtx->Type == SamrContextConnect || pCtx->Type == SamrContextDomain) { ntStatus = STATUS_ACCESS_DENIED; } else { ntStatus = STATUS_INVALID_HANDLE; } BAIL_ON_NTSTATUS_ERROR(ntStatus); /* * 1) READ_CONTROL right is required to read a security descriptor * 2) Querying SACL part of the SD is not permitted over rpc */ if (!(pAcctCtx->dwAccessGranted & READ_CONTROL) || dwSecurityInfo & SACL_SECURITY_INFORMATION) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } dwError = LwWc16sToMbs(pwszDn, &pszDn); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryAllocateWC16StringFilterPrintf( &pwszFilter, filterFormat, szAttrDn, pszDn); BAIL_ON_LSA_ERROR(dwError); dwError = DirectorySearch(hDirectory, pwszBaseDn, dwScope, pwszFilter, wszAttributes, FALSE, &pEntries, &dwNumEntries); BAIL_ON_LSA_ERROR(dwError); if (dwNumEntries == 0) { ntStatus = STATUS_INVALID_HANDLE; } else if (dwNumEntries > 1) { ntStatus = STATUS_INTERNAL_ERROR; } BAIL_ON_NTSTATUS_ERROR(ntStatus); pObjectEntry = &(pEntries[0]); dwError = DirectoryGetEntryAttrValueByName( pObjectEntry, wszAttrSecDesc, DIRECTORY_ATTR_TYPE_NT_SECURITY_DESCRIPTOR, &pSecDescBlob); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvAllocateSecDescBuffer( &pSecDescBuf, (SECURITY_INFORMATION)dwSecurityInfo, pSecDescBlob); BAIL_ON_NTSTATUS_ERROR(ntStatus); *ppSecDescBuf = pSecDescBuf; cleanup: if (pEntries) { DirectoryFreeEntries(pEntries, dwNumEntries); } LW_SAFE_FREE_MEMORY(pszDn); LW_SAFE_FREE_MEMORY(pwszFilter); if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pSecDescBuf) { if (pSecDescBuf->pBuffer) { SamrSrvFreeMemory(pSecDescBuf->pBuffer); } SamrSrvFreeMemory(pSecDescBuf); } *ppSecDescBuf = NULL; goto cleanup; }
NTSTATUS cell_connect(struct likewise_cell *c) { ADS_STRUCT *ads = NULL; ADS_STATUS ads_status; fstring dc_name; struct sockaddr_storage dcip; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; /* have to at least have the AD domain name */ if (!c->dns_domain) { nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; BAIL_ON_NTSTATUS_ERROR(nt_status); } /* clear out any old information */ if (c->conn) { ads_destroy(&c->conn); c->conn = NULL; } /* now setup the new connection */ ads = ads_init(c->dns_domain, NULL, NULL); BAIL_ON_PTR_ERROR(ads, nt_status); ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); ads->auth.realm = SMB_STRDUP(lp_realm()); /* Make the connection. We should already have an initial TGT using the machine creds */ if (cell_flags(c) & LWCELL_FLAG_GC_CELL) { ads_status = ads_connect_gc(ads); } else { /* Set up server affinity for normal cells and the client site name cache */ if (!get_dc_name("", c->dns_domain, dc_name, &dcip)) { nt_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; BAIL_ON_NTSTATUS_ERROR(nt_status); } ads_status = ads_connect(ads); } c->conn = ads; nt_status = ads_ntstatus(ads_status); done: if (!NT_STATUS_IS_OK(nt_status)) { ads_destroy(&ads); c->conn = NULL; } return nt_status; }
NTSTATUS SamrSrvQueryUserInfo( /* [in] */ handle_t hBinding, /* [in] */ ACCOUNT_HANDLE hUser, /* [in] */ UINT16 level, /* [out] */ UserInfo **info ) { PCSTR filterFormat = "%s=%Q"; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; PACCOUNT_CONTEXT pAcctCtx = NULL; PDOMAIN_CONTEXT pDomCtx = NULL; PCONNECT_CONTEXT pConnCtx = NULL; PWSTR pwszBase = NULL; WCHAR wszAttrObjectSid[] = DS_ATTR_OBJECT_SID; WCHAR wszAttrSamAccountName[] = DS_ATTR_SAM_ACCOUNT_NAME; WCHAR wszAttrFullName[] = DS_ATTR_FULL_NAME; WCHAR wszAttrPrimaryGroup[] = DS_ATTR_PRIMARY_GROUP; WCHAR wszAttrDescription[] = DS_ATTR_DESCRIPTION; WCHAR wszAttrComment[] = DS_ATTR_COMMENT; WCHAR wszAttrCountryCode[] = DS_ATTR_COUNTRY_CODE; WCHAR wszAttrCodePage[] = DS_ATTR_CODE_PAGE; WCHAR wszAttrHomeDirectory[] = DS_ATTR_HOME_DIR; WCHAR wszAttrHomeDrive[] = DS_ATTR_HOME_DRIVE; WCHAR wszAttrLogonScript[] = DS_ATTR_LOGON_SCRIPT; WCHAR wszAttrProfilePath[] = DS_ATTR_PROFILE_PATH; WCHAR wszAttrWorkstations[]= DS_ATTR_WORKSTATIONS; WCHAR wszAttrParameters[] = DS_ATTR_PARAMETERS; WCHAR wszAttrLastLogon[] = DS_ATTR_LAST_LOGON; WCHAR wszAttrLastLogoff[] = DS_ATTR_LAST_LOGOFF; WCHAR wszAttrPasswordLastSet[] = DS_ATTR_PASSWORD_LAST_SET; WCHAR wszAttrAllowPasswordChange[] = DS_ATTR_ALLOW_PASSWORD_CHANGE; WCHAR wszAttrForcePasswordChange[] = DS_ATTR_FORCE_PASSWORD_CHANGE; WCHAR wszAttrLogonHours[] = DS_ATTR_LOGON_HOURS; WCHAR wszAttrBadPasswordCount[] = DS_ATTR_BAD_PASSWORD_COUNT; WCHAR wszAttrLogonCount[] = DS_ATTR_LOGON_COUNT; WCHAR wszAttrAccountFlags[] = DS_ATTR_ACCOUNT_FLAGS; WCHAR wszAttrAccountExpiry[] = DS_ATTR_ACCOUNT_EXPIRY; WCHAR wszAttrLmHash[] = DS_ATTR_LM_HASH; WCHAR wszAttrNtHash[] = DS_ATTR_NT_HASH; CHAR szAttrDn[] = DS_ATTR_DISTINGUISHED_NAME; DWORD dwScope = 0; PSTR pszDn = NULL; PWSTR pwszFilter = NULL; PDIRECTORY_ENTRY pEntry = NULL; DWORD dwEntriesNum = 0; UserInfo *pUserInfo = NULL; PWSTR wszAttributesLevel1[] = { wszAttrSamAccountName, wszAttrFullName, wszAttrPrimaryGroup, wszAttrDescription, wszAttrComment, NULL }; PWSTR wszAttributesLevel2[] = { wszAttrComment, wszAttrCountryCode, wszAttrCodePage, NULL }; PWSTR wszAttributesLevel3[] = { wszAttrSamAccountName, wszAttrFullName, wszAttrObjectSid, wszAttrPrimaryGroup, wszAttrHomeDirectory, wszAttrHomeDrive, wszAttrLogonScript, wszAttrProfilePath, wszAttrWorkstations, wszAttrLastLogon, wszAttrLastLogoff, wszAttrPasswordLastSet, wszAttrAllowPasswordChange, wszAttrForcePasswordChange, wszAttrLogonHours, wszAttrBadPasswordCount, wszAttrLogonCount, wszAttrAccountFlags, NULL }; PWSTR wszAttributesLevel4[] = { wszAttrLogonHours, NULL }; PWSTR wszAttributesLevel5[] = { wszAttrSamAccountName, wszAttrFullName, wszAttrObjectSid, wszAttrPrimaryGroup, wszAttrHomeDirectory, wszAttrHomeDrive, wszAttrLogonScript, wszAttrProfilePath, wszAttrDescription, wszAttrWorkstations, wszAttrLastLogon, wszAttrLastLogoff, wszAttrLogonHours, wszAttrBadPasswordCount, wszAttrLogonCount, wszAttrPasswordLastSet, wszAttrAccountExpiry, wszAttrAccountFlags, NULL }; PWSTR wszAttributesLevel6[] = { wszAttrSamAccountName, wszAttrFullName, NULL }; PWSTR wszAttributesLevel7[] = { wszAttrSamAccountName, NULL }; PWSTR wszAttributesLevel8[] = { wszAttrFullName, NULL }; PWSTR wszAttributesLevel9[] = { wszAttrPrimaryGroup, NULL }; PWSTR wszAttributesLevel10[] = { wszAttrHomeDirectory, wszAttrHomeDrive, NULL }; PWSTR wszAttributesLevel11[] = { wszAttrLogonScript, NULL }; PWSTR wszAttributesLevel12[] = { wszAttrProfilePath, NULL }; PWSTR wszAttributesLevel13[] = { wszAttrDescription, NULL }; PWSTR wszAttributesLevel14[] = { wszAttrWorkstations, NULL }; PWSTR wszAttributesLevel16[] = { wszAttrAccountFlags, NULL }; PWSTR wszAttributesLevel17[] = { wszAttrAccountExpiry, NULL }; PWSTR wszAttributesLevel20[] = { wszAttrParameters, NULL }; PWSTR wszAttributesLevel21[] = { wszAttrLastLogon, wszAttrLastLogoff, wszAttrPasswordLastSet, wszAttrAccountExpiry, wszAttrAllowPasswordChange, wszAttrForcePasswordChange, wszAttrSamAccountName, wszAttrFullName, wszAttrHomeDirectory, wszAttrHomeDrive, wszAttrLogonScript, wszAttrProfilePath, wszAttrDescription, wszAttrWorkstations, wszAttrComment, wszAttrParameters, wszAttrObjectSid, wszAttrPrimaryGroup, wszAttrAccountFlags, wszAttrLogonHours, wszAttrBadPasswordCount, wszAttrLogonCount, wszAttrCountryCode, wszAttrCodePage, wszAttrLmHash, wszAttrNtHash, NULL }; PWSTR *pwszAttributes[] = { wszAttributesLevel1, wszAttributesLevel2, wszAttributesLevel3, wszAttributesLevel4, wszAttributesLevel5, wszAttributesLevel6, wszAttributesLevel7, wszAttributesLevel8, wszAttributesLevel9, wszAttributesLevel10, wszAttributesLevel11, wszAttributesLevel12, wszAttributesLevel13, wszAttributesLevel14, NULL, wszAttributesLevel16, wszAttributesLevel17, NULL, NULL, wszAttributesLevel20, wszAttributesLevel21 }; pAcctCtx = (PACCOUNT_CONTEXT)hUser; if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } switch (level) { case 15: case 18: case 19: ntStatus = STATUS_INVALID_INFO_CLASS; break; default: ntStatus = STATUS_SUCCESS; } BAIL_ON_NTSTATUS_ERROR(ntStatus); pDomCtx = pAcctCtx->pDomCtx; pConnCtx = pDomCtx->pConnCtx; pwszBase = pDomCtx->pwszDn; dwError = LwWc16sToMbs(pAcctCtx->pwszDn, &pszDn); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryAllocateWC16StringFilterPrintf( &pwszFilter, filterFormat, szAttrDn, pszDn); BAIL_ON_LSA_ERROR(dwError); dwError = DirectorySearch(pConnCtx->hDirectory, pwszBase, dwScope, pwszFilter, pwszAttributes[level - 1], FALSE, &pEntry, &dwEntriesNum); BAIL_ON_LSA_ERROR(dwError); if (dwEntriesNum == 0) { ntStatus = STATUS_INVALID_HANDLE; } else if (dwEntriesNum > 1) { ntStatus = STATUS_INTERNAL_ERROR; } BAIL_ON_NTSTATUS_ERROR(ntStatus); ntStatus = SamrSrvAllocateMemory((void**)&pUserInfo, sizeof(*pUserInfo)); BAIL_ON_NTSTATUS_ERROR(ntStatus); switch (level) { case 1: case 6: case 7: case 8: case 13: if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_NAME_ETC) || !(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } break; case 2: if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_LOCALE) || !(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } break; case 4: case 5: case 10: case 11: case 12: case 14: case 17: if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_LOGONINFO) || !(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } break; case 3: case 9: case 16: case 20: case 21: if (!(pAcctCtx->dwAccessGranted & USER_ACCESS_GET_ATTRIBUTES)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } break; } switch (level) { case 1: ntStatus = SamrFillUserInfo1(pEntry, pUserInfo); break; case 2: ntStatus = SamrFillUserInfo2(pEntry, pUserInfo); break; case 3: ntStatus = SamrFillUserInfo3(pAcctCtx, pEntry, pUserInfo); break; case 4: ntStatus = SamrFillUserInfo4(pEntry, pUserInfo); break; case 5: ntStatus = SamrFillUserInfo5(pEntry, pUserInfo); break; case 6: ntStatus = SamrFillUserInfo6(pEntry, pUserInfo); break; case 7: ntStatus = SamrFillUserInfo7(pEntry, pUserInfo); break; case 8: ntStatus = SamrFillUserInfo8(pEntry, pUserInfo); break; case 9: ntStatus = SamrFillUserInfo9(pEntry, pUserInfo); break; case 10: ntStatus = SamrFillUserInfo10(pEntry, pUserInfo); break; case 11: ntStatus = SamrFillUserInfo11(pEntry, pUserInfo); break; case 12: ntStatus = SamrFillUserInfo12(pEntry, pUserInfo); break; case 13: ntStatus = SamrFillUserInfo13(pEntry, pUserInfo); break; case 14: ntStatus = SamrFillUserInfo14(pEntry, pUserInfo); break; case 16: ntStatus = SamrFillUserInfo16(pEntry, pUserInfo); break; case 17: ntStatus = SamrFillUserInfo17(pEntry, pUserInfo); break; case 20: ntStatus = SamrFillUserInfo20(pEntry, pUserInfo); break; case 21: ntStatus = SamrFillUserInfo21(pAcctCtx, pEntry, pUserInfo); break; default: ntStatus = STATUS_INVALID_INFO_CLASS; } BAIL_ON_NTSTATUS_ERROR(ntStatus); *info = pUserInfo; cleanup: LW_SAFE_FREE_MEMORY(pszDn); LW_SAFE_FREE_MEMORY(pwszFilter); if (pEntry) { DirectoryFreeEntries(pEntry, dwEntriesNum); } return ntStatus; error: if (pUserInfo) { SamrSrvFreeMemory(pUserInfo); } *info = NULL; goto cleanup; }
NTSTATUS SamrSrvGetMembersInAlias( IN handle_t hBinding, IN ACCOUNT_HANDLE hAlias, OUT SID_ARRAY *pSids ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; PACCOUNT_CONTEXT pAcctCtx = NULL; PCONNECT_CONTEXT pConnCtx = NULL; HANDLE hDirectory = NULL; PWSTR pwszAliasDn = NULL; WCHAR wszAttrObjectSid[] = DS_ATTR_OBJECT_SID; PDIRECTORY_ENTRY pMemberEntries; DWORD dwMembersNum = 0; DWORD i = 0; PWSTR pwszMemberSid = NULL; PSID pMemberSid = NULL; SID_ARRAY Sids = {0}; PWSTR wszAttributes[] = { wszAttrObjectSid, NULL }; pAcctCtx = (PACCOUNT_CONTEXT)hAlias; if (pAcctCtx == NULL || pAcctCtx->Type != SamrContextAccount) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } if (!(pAcctCtx->dwAccessGranted & ALIAS_ACCESS_GET_MEMBERS)) { ntStatus = STATUS_ACCESS_DENIED; BAIL_ON_NTSTATUS_ERROR(ntStatus); } pConnCtx = (PCONNECT_CONTEXT)pAcctCtx->pDomCtx->pConnCtx; hDirectory = pConnCtx->hDirectory; pwszAliasDn = pAcctCtx->pwszDn; dwError = DirectoryGetGroupMembers(hDirectory, pwszAliasDn, wszAttributes, &pMemberEntries, &dwMembersNum); BAIL_ON_LSA_ERROR(dwError); Sids.dwNumSids = dwMembersNum; ntStatus = SamrSrvAllocateMemory((PVOID*)&Sids.pSids, sizeof(*Sids.pSids) * Sids.dwNumSids); BAIL_ON_NTSTATUS_ERROR(ntStatus); for (i = 0; i < dwMembersNum; i++) { PDIRECTORY_ENTRY pEntry = &(pMemberEntries[i]); dwError = DirectoryGetEntryAttrValueByName( pEntry, wszAttrObjectSid, DIRECTORY_ATTR_TYPE_UNICODE_STRING, &pwszMemberSid); BAIL_ON_LSA_ERROR(dwError); ntStatus = SamrSrvAllocateSidFromWC16String( &pMemberSid, pwszMemberSid); BAIL_ON_NTSTATUS_ERROR(ntStatus); Sids.pSids[i].pSid = pMemberSid; } pSids->dwNumSids = Sids.dwNumSids; pSids->pSids = Sids.pSids; cleanup: if (pMemberEntries) { DirectoryFreeEntries(pMemberEntries, dwMembersNum); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: for (i = 0; i < dwMembersNum; i++) { SamrSrvFreeMemory(Sids.pSids[i].pSid); } SamrSrvFreeMemory(Sids.pSids); memset(pSids, 0, sizeof(*pSids)); goto cleanup; }
static NTSTATUS _idmap_adex_init(struct idmap_domain *dom) { ADS_STRUCT *ads = NULL; ADS_STATUS status; static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct dom_sid domain_sid; fstring dcname; struct sockaddr_storage ip; struct likewise_cell *lwcell; if (NT_STATUS_IS_OK(init_status)) return NT_STATUS_OK; /* Silently fail if we are not a member server in security = ads */ if ((lp_server_role() != ROLE_DOMAIN_MEMBER) || (lp_security() != SEC_ADS)) { init_status = NT_STATUS_INVALID_SERVER_STATE; BAIL_ON_NTSTATUS_ERROR(init_status); } /* fetch our domain SID first */ if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; BAIL_ON_NTSTATUS_ERROR(init_status); } /* reuse the same ticket cache as winbindd */ setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); /* Establish a connection to a DC */ if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) { init_status = NT_STATUS_NO_MEMORY; BAIL_ON_NTSTATUS_ERROR(init_status); } ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); ads->auth.realm = SMB_STRDUP(lp_realm()); /* get the DC name here to setup the server affinity cache and local krb5.conf */ get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip); status = ads_connect(ads); if (!ADS_ERR_OK(status)) { DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n", ads_errstr(status))); } init_status = ads_ntstatus(status); BAIL_ON_NTSTATUS_ERROR(init_status); /* Find out cell membership */ init_status = cell_locate_membership(ads); if (!NT_STATUS_IS_OK(init_status)) { DEBUG(0,("LWI: Fail to locate cell membership (%s).", nt_errstr(init_status))); goto done; } /* Fill in the cell information */ lwcell = cell_list_head(); init_status = cell_lookup_settings(lwcell); BAIL_ON_NTSTATUS_ERROR(init_status); /* Miscellaneous setup. E.g. set up the list of GC servers and domain list for our forest (does not actually connect). */ init_status = gc_init_list(); BAIL_ON_NTSTATUS_ERROR(init_status); init_status = domain_init_list(); BAIL_ON_NTSTATUS_ERROR(init_status); done: if (!NT_STATUS_IS_OK(init_status)) { DEBUG(1,("Likewise initialization failed (%s)\n", nt_errstr(init_status))); } /* cleanup */ if (!NT_STATUS_IS_OK(init_status)) { cell_list_destroy(); /* init_status stores the failure reason but we need to return success or else idmap_init() will drop us from the backend list */ return NT_STATUS_OK; } init_status = NT_STATUS_OK; return init_status; }
NTSTATUS SamrSrvLookupDomain( /* [in] */ handle_t hBinding, /* [in] */ CONNECT_HANDLE hConn, /* [in] */ UNICODE_STRING *domain_name, /* [out] */ SID **ppSid ) { CHAR szDnToken[] = "DC"; wchar_t wszFilter[] = L"%ws=%u AND %ws=\'%ws\'"; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = 0; PCONNECT_CONTEXT pConnCtx = NULL; PWSTR pwszBase = NULL; WCHAR wszAttrObjectClass[] = DS_ATTR_OBJECT_CLASS; WCHAR wszAttrDomain[] = DS_ATTR_DOMAIN; WCHAR wszAttrObjectSID[] = DS_ATTR_OBJECT_SID; DWORD dwObjectClass = DS_OBJECT_CLASS_DOMAIN; WCHAR wszBuiltinDomainName[] = SAMR_BUILTIN_DOMAIN_NAME; PWSTR pwszDomainName = NULL; DWORD dwBaseLen = 0; DWORD dwScope = 0; PWSTR pwszFilter = NULL; DWORD dwFilterLen = 0; PWSTR wszAttributes[2]; PDIRECTORY_ENTRY pEntries = NULL; DWORD dwCount = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrVal = NULL; PSID pDomainSid = NULL; BAIL_ON_INVALID_PARAMETER(ppSid); BAIL_ON_INVALID_PARAMETER(domain_name); memset(wszAttributes, 0, sizeof(wszAttributes)); pConnCtx = (PCONNECT_CONTEXT)hConn; if (pConnCtx == NULL || pConnCtx->Type != SamrContextConnect) { ntStatus = STATUS_INVALID_HANDLE; BAIL_ON_NTSTATUS_ERROR(ntStatus); } ntStatus = SamrSrvGetFromUnicodeString(&pwszDomainName, domain_name); BAIL_ON_NO_MEMORY(pwszDomainName); if (!wc16scasecmp(pwszDomainName, wszBuiltinDomainName)) { dwObjectClass = DS_OBJECT_CLASS_BUILTIN_DOMAIN; } dwBaseLen = domain_name->MaximumLength + ((sizeof(szDnToken) + 2) * sizeof(WCHAR)); dwFilterLen = (sizeof(wszAttrObjectClass) - 1) + 10 + (sizeof(wszAttrDomain) - 1) + domain_name->Length + sizeof(wszFilter); ntStatus = SamrSrvAllocateMemory(OUT_PPVOID(&pwszFilter), dwFilterLen); BAIL_ON_NTSTATUS_ERROR(ntStatus); if (sw16printfw(pwszFilter, dwFilterLen/sizeof(WCHAR), wszFilter, wszAttrObjectClass, dwObjectClass, wszAttrDomain, pwszDomainName) < 0) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(ntStatus); } wszAttributes[0] = wszAttrObjectSID; wszAttributes[1] = NULL; dwError = DirectorySearch(pConnCtx->hDirectory, pwszBase, dwScope, pwszFilter, wszAttributes, FALSE, &pEntries, &dwCount); BAIL_ON_LSA_ERROR(dwError); if (dwCount == 1) { dwError = DirectoryGetEntryAttributeSingle(pEntries, &pAttr); BAIL_ON_LSA_ERROR(dwError); dwError = DirectoryGetAttributeValue(pAttr, &pAttrVal); BAIL_ON_LSA_ERROR(dwError); if (pAttrVal->Type == DIRECTORY_ATTR_TYPE_UNICODE_STRING) { ntStatus = SamrSrvAllocateSidFromWC16String( &pDomainSid, pAttrVal->data.pwszStringValue); BAIL_ON_NTSTATUS_ERROR(ntStatus); } else { ntStatus = STATUS_INTERNAL_ERROR; BAIL_ON_NTSTATUS_ERROR(ntStatus); } } else if (dwCount == 0) { ntStatus = STATUS_NO_SUCH_DOMAIN; BAIL_ON_NTSTATUS_ERROR(ntStatus); } else { ntStatus = STATUS_INTERNAL_ERROR; BAIL_ON_NTSTATUS_ERROR(ntStatus); } *ppSid = pDomainSid; cleanup: if (pwszBase) { SamrSrvFreeMemory(pwszBase); } if (pwszDomainName) { SamrSrvFreeMemory(pwszDomainName); } if (pwszFilter) { SamrSrvFreeMemory(pwszFilter); } if (pEntries) { DirectoryFreeEntries(pEntries, dwCount); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pDomainSid) { SamrSrvFreeMemory(&pDomainSid); } *ppSid = NULL; goto cleanup; }