/* Editor Settings: expandtabs and use 4 spaces for indentation * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: * * -*- mode: c, c-basic-offset: 4 -*- */ /* * Copyright Likewise Software 2004-2008 * All rights reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the license, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. You should have received a copy * of the GNU Lesser General Public License along with this program. If * not, see . * * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT * license@likewisesoftware.com */ /* * Copyright (C) Likewise Software. All rights reserved. * * Module Name: * * nss-group.c * * Abstract: * * Name Server Switch (Likewise LSASS) * * Handle NSS Group Information * * Authors: Krishna Ganugapati (krishnag@likewisesoftware.com) * Sriram Nambakam (snambakam@likewisesoftware.com) * */ #include "lsanss.h" #include "externs.h" #include static const DWORD MAX_NUM_GROUPS = 500; static LSA_ENUMGROUPS_STATE gEnumGroupsState = {0}; NSS_STATUS _nss_lsass_setgrent( void ) { return LsaNssCommonGroupSetgrent(&hLsaConnection, &gEnumGroupsState); } NSS_STATUS _nss_lsass_getgrent_r( struct group* pResultGroup, char * pszBuf, size_t bufLen, int* pErrorNumber ) { return LsaNssCommonGroupGetgrent(&hLsaConnection, &gEnumGroupsState, pResultGroup, pszBuf, bufLen, pErrorNumber); } NSS_STATUS _nss_lsass_endgrent( void ) { return LsaNssCommonGroupEndgrent(&hLsaConnection, &gEnumGroupsState); } NSS_STATUS _nss_lsass_getgrgid_r( gid_t gid, struct group* pResultGroup, char* pszBuf, size_t bufLen, int* pErrorNumber ) { return LsaNssCommonGroupGetgrgid(&hLsaConnection, gid, pResultGroup, pszBuf, bufLen, pErrorNumber); } NSS_STATUS _nss_lsass_getgrnam_r( const char * pszGroupName, struct group * pResultGroup, char * pszBuf, size_t bufLen, int* pErrorNumber ) { return LsaNssCommonGroupGetgrnam(&hLsaConnection, pszGroupName, pResultGroup, pszBuf, bufLen, pErrorNumber); } NSS_STATUS _nss_lsass_initgroups_dyn( PCSTR pszUserName, gid_t groupGid, long int* pResultsSize, long int* pResultsCapacity, gid_t** ppGidResults, long int maxGroups, int* pErrorNumber ) { int ret = NSS_STATUS_SUCCESS; DWORD dwNumGroupsFound = 0; gid_t* pGidTotalResult = NULL; gid_t* pGidNewResult = NULL; gid_t* pExistingResult = NULL; DWORD dwNumTotalGroup = 0; DWORD iGroup = 0, iExistingGroup = 0, iNewGroup = 0; if ((*pResultsCapacity > maxGroups && maxGroups != -1) || *pResultsSize > *pResultsCapacity) { ret = NSS_STATUS_UNAVAIL; *pErrorNumber = EINVAL; BAIL_ON_NSS_ERROR(ret); } if (hLsaConnection == (HANDLE)NULL) { ret = MAP_LSA_ERROR(pErrorNumber, LsaOpenServer(&hLsaConnection)); BAIL_ON_NSS_ERROR(ret); } ret = MAP_LSA_ERROR(pErrorNumber, LsaGetGidsForUserByName( hLsaConnection, pszUserName, &dwNumGroupsFound, &pGidNewResult)); BAIL_ON_NSS_ERROR(ret); dwNumTotalGroup += dwNumGroupsFound; dwNumTotalGroup += 1; //count in the group that is passed in //count in the groups that are already in ppGidResults dwNumTotalGroup += *pResultsSize; if (dwNumTotalGroup > *pResultsCapacity) { if (dwNumTotalGroup > maxGroups && maxGroups != -1) dwNumTotalGroup = maxGroups; ret = MAP_LSA_ERROR(pErrorNumber, LwAllocateMemory( sizeof(gid_t) * dwNumTotalGroup * 2, (PVOID*)&pGidTotalResult)); BAIL_ON_NSS_ERROR(ret); pExistingResult = *ppGidResults; for (iExistingGroup = 0, iGroup = 0; iExistingGroup < *pResultsSize; iExistingGroup++, iGroup++) { pGidTotalResult[iGroup] = pExistingResult[iExistingGroup]; } for (iNewGroup = 0; iNewGroup < dwNumGroupsFound && iGroup < dwNumTotalGroup; iNewGroup++, iGroup++) { pGidTotalResult[iGroup] = pGidNewResult[iNewGroup]; } *pResultsCapacity = dwNumTotalGroup * 2; *pResultsSize = dwNumTotalGroup; *ppGidResults = pGidTotalResult; pGidTotalResult = NULL; LW_SAFE_FREE_MEMORY(pExistingResult); } else { pExistingResult = *ppGidResults; iGroup = *pResultsSize; pExistingResult[iGroup++] = groupGid; for (iNewGroup = 0; iNewGroup < dwNumGroupsFound && iGroup < dwNumTotalGroup; iNewGroup++, iGroup++) { pExistingResult[iGroup] = pGidNewResult[iNewGroup]; } } *pResultsSize = iGroup; cleanup: LW_SAFE_FREE_MEMORY(pGidNewResult); return ret; error: if (ret != NSS_STATUS_TRYAGAIN && hLsaConnection != (HANDLE)NULL) { LsaCloseServer(hLsaConnection); hLsaConnection = (HANDLE)NULL; } LW_SAFE_FREE_MEMORY(pGidTotalResult); LW_SAFE_FREE_MEMORY(pGidNewResult); goto cleanup; }