Esempio n. 1
0
static OSStatus
AuthMechanismDestroy(
        IN AuthorizationMechanismRef pMechanismRef
        )
{
    PLW_AUTH_MECHANISM_INSTANCE pMechanismInstance = pMechanismRef;
    OSStatus osStatus = noErr;

    if (pMechanismInstance == NULL)
    {
        LSA_LOG_DEBUG(
            "Likewise auth plugin called with NULL mechanism instance");
        goto error;
    }

    if (pMechanismInstance->pAuthMechanism == NULL)
    {
        LSA_LOG_DEBUG(
            "Likewise auth plugin called with NULL mechanism pointer");
        goto error;
    }

    LSA_LOG_DEBUG(
        "Destroying auth mechanism Likewise:%s",
        pMechanismInstance->pAuthMechanism->name);

    if (pMechanismInstance->pAuthMechanism->Destroy != NULL &&
                pMechanismInstance->pAuthMechanism->Destroy(
                    pMechanismInstance) != noErr)
    {
        LSA_LOG_DEBUG(
            "Destroying auth mechanism Likewise:%s failed",
            pMechanismInstance->pAuthMechanism->name);
        goto error;
    }

cleanup:
    return osStatus;

error:
    /*
     * The documentation says all errors should return
     * errAuthorizationInternal.
     */
    osStatus = errAuthorizationInternal;
    goto cleanup;
}
Esempio n. 2
0
static
DWORD
LsaAdBatchGatherNonSchemaModeGroup(
    IN OUT PLSA_AD_BATCH_ITEM pItem,
    IN DWORD dwKeywordValuesCount,
    IN PSTR* ppszKeywordValues
    )
{
    DWORD dwError = 0;
    DWORD dwValue = 0;

    dwError = ADNonSchemaKeywordGetUInt32(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_GID_TAG,
                    &dwValue);
    if (LW_ERROR_INVALID_LDAP_ATTR_VALUE == dwError)
    {
        SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED);
        dwError = LW_ERROR_SUCCESS;
    }
    BAIL_ON_LSA_ERROR(dwError);

    if (IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED))
    {
        goto cleanup;
    }

    if (!dwValue)
    {
        LSA_LOG_DEBUG("gid must be non-zero for SID '%s'", pItem->pszSid);
        // SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_SKIP);
        dwError = LW_ERROR_DATA_ERROR;
        BAIL_ON_LSA_ERROR(dwError);
    }

    pItem->GroupInfo.gid = (gid_t)dwValue;

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_DISPLAY_NAME_TAG,
                    &pItem->GroupInfo.pszAlias);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_PASSWD_TAG,
                    &pItem->GroupInfo.pszPasswd);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    return dwError;

error:
    goto cleanup;
}
Esempio n. 3
0
DWORD
LsaSrvInitAuthProvider(
    IN PLSA_AUTH_PROVIDER pProvider,
    IN OPTIONAL PLSA_STATIC_PROVIDER pStaticProviders
    )
{
    DWORD dwError = 0;
    PFNINITIALIZEPROVIDER pfnInitProvider = NULL;
    PCSTR pszError = NULL;
    PSTR pszProviderLibpath = NULL;
    int i = 0;

    if (pStaticProviders)
    {
        /* First look for a static provider entry with the given name */
        for (i = 0; pStaticProviders[i].pszId; i++)
        {
            if (!strcmp(pStaticProviders[i].pszId, pProvider->pszId))
            {
                pfnInitProvider = pStaticProviders[i].pInitialize;
                LSA_LOG_DEBUG("Provider %s loaded from static list", pProvider->pszId);
                break;
            }
        }
    }

    if (!pfnInitProvider)
    {
        /* Try to load the provider dynamically */
        if (LW_IS_NULL_OR_EMPTY_STR(pProvider->pszProviderLibpath))
        {
            dwError = LW_ERROR_INVALID_AUTH_PROVIDER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        pszProviderLibpath = pProvider->pszProviderLibpath;

        dlerror();
        pProvider->pLibHandle = dlopen(pszProviderLibpath, RTLD_NOW | RTLD_LOCAL);
        if (!pProvider->pLibHandle)
        {
            LSA_LOG_ERROR("Failed to open auth provider at path '%s'", pszProviderLibpath);

            pszError = dlerror();
            if (!LW_IS_NULL_OR_EMPTY_STR(pszError))
            {
                LSA_LOG_ERROR("%s", pszError);
            }

            dwError = LW_ERROR_INVALID_AUTH_PROVIDER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        dlerror();
        pfnInitProvider = (PFNINITIALIZEPROVIDER) dlsym(
            pProvider->pLibHandle,
            LSA_SYMBOL_NAME_INITIALIZE_PROVIDER);
        if (!pfnInitProvider)
        {
            LSA_LOG_ERROR("Ignoring invalid auth provider at path '%s'", pszProviderLibpath);

            pszError = dlerror();
            if (!LW_IS_NULL_OR_EMPTY_STR(pszError))
            {
                LSA_LOG_ERROR("%s", pszError);
            }

            dwError = LW_ERROR_INVALID_AUTH_PROVIDER;
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    dwError = pfnInitProvider(
                    &pProvider->pszName,
                    &pProvider->pFnTable);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LsaSrvValidateProvider(pProvider);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:

    return dwError;

error:

    goto cleanup;
}
Esempio n. 4
0
DWORD
LsaReadVersionFile(
    PLSA_VERSION pVersion
    )
{  
    DWORD dwError = 0;
    DWORD dwMajor = 0;
    DWORD dwMinor = 0;
    DWORD dwBuild = 0;
    DWORD dwRevision = 0;
    int versionFile = -1;
    // A typical version file is 40 bytes long. The whole file can be read into
    // a static buffer, because if the file is too long, then it is invalid.
    char szFileBuffer[200];
    ssize_t dwCount = 0;
    // Do not free
    PSTR pszPos = szFileBuffer;

#ifdef MINIMAL_LSASS
    versionFile = open(LOCALSTATEDIR "/VERSION", O_RDONLY, 0);
#else
    versionFile = open(PREFIXDIR "/data/ENTERPRISE_VERSION", O_RDONLY, 0);
    if (versionFile < 0 && errno == ENOENT)
    {
        versionFile = open(PREFIXDIR "/data/VERSION", O_RDONLY, 0);
    }
#endif
    if (versionFile < 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwCount = read(versionFile, szFileBuffer, sizeof(szFileBuffer));
    if (dwCount < 0)
    {
        dwError = LwMapErrnoToLwError(errno);
        BAIL_ON_LSA_ERROR(dwError);
    }

    if (dwCount == sizeof(szFileBuffer))
    {
        dwError = LW_ERROR_INVALID_AGENT_VERSION;
        BAIL_ON_LSA_ERROR(dwError);
    }
    szFileBuffer[dwCount] = 0;

    while (*pszPos)
    {
        LwStripWhitespace(pszPos, TRUE, TRUE);
        if (!strncmp(pszPos, "VERSION=", sizeof("VERSION=") - 1))
        {
            pszPos += sizeof("VERSION=") - 1;

            errno = 0;
            dwMajor = strtoul(pszPos, &pszPos, 10);

            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);

            if (pszPos[0] != '.')
            {
                dwError = LW_ERROR_INVALID_AGENT_VERSION;
                BAIL_ON_LSA_ERROR(dwError);
            }
            pszPos++;
            dwMinor = strtoul(pszPos, &pszPos, 10);

            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);
        }
        else if (!strncmp(pszPos, "BUILD=", sizeof("BUILD=") - 1))
        {
            pszPos += sizeof("BUILD=") - 1;

            errno = 0;
            dwBuild = strtoul(pszPos, &pszPos, 10);
            dwError = LwMapErrnoToLwError(errno);
            BAIL_ON_LSA_ERROR(dwError);
        }
        else if (!strncmp(pszPos, "REVISION=", sizeof("REVISION=") - 1))
        {
            pszPos += sizeof("REVISION=") - 1;

            errno = 0;
            dwRevision = strtoul(pszPos, &pszPos, 10);
            dwError = LwMapErrnoToLwError(errno);
            if (dwError != 0)
            {
                LSA_LOG_DEBUG("Unable to parse revision due to error %u", dwError);
                dwRevision = 0;
                dwError = 0;
            }
        }
        pszPos = strchr(pszPos, '\n');
        if (!pszPos)
        {
            break;
        }
        // Skip the \n
        pszPos++;
        if (*pszPos == '\r')
        {
            pszPos++;
        }
    }
    
    pVersion->dwMajor = dwMajor;
    pVersion->dwMinor = dwMinor;
    pVersion->dwBuild = dwBuild;
    pVersion->dwRevision = dwRevision;
    
cleanup:
    if (versionFile != -1)
    {
        close(versionFile);
    }
    return dwError;
    
error:
    memset(pVersion, 0, sizeof(*pVersion));
    goto cleanup;
}
Esempio n. 5
0
DWORD
AD_GroupExpansionDataGetNextGroupToExpand(
    IN PLSA_AD_GROUP_EXPANSION_DATA pExpansionData,
    OUT PLSA_SECURITY_OBJECT* ppGroupToExpand,
    OUT PDWORD pdwGroupToExpandDepth
    )
{
    DWORD dwError = 0;
    PLSA_SECURITY_OBJECT pGroupToExpand = NULL;
    DWORD dwGroupToExpandDepth = 0;
    const LW_HASH_ENTRY* pHashEntry = NULL;

    dwError = pExpansionData->dwLastError;
    BAIL_ON_LSA_ERROR(dwError);

    if (pExpansionData->pGroupsToExpand->sCount < 1)
    {
        // Nothing to return
        goto cleanup;
    }

    if (pExpansionData->bIsIteratorInitialized)
    {
        pHashEntry = LwHashNext(&pExpansionData->GroupsToExpandIterator);
    }

    if (!pHashEntry)
    {
        // Either the iterator is not initialized or we
        // reached the end of the hash table and need to start over.
        dwError = LwHashGetIterator(
                    pExpansionData->pGroupsToExpand,
                    &pExpansionData->GroupsToExpandIterator);
        BAIL_ON_LSA_ERROR(dwError);

        pExpansionData->bIsIteratorInitialized = TRUE;

        pHashEntry = LwHashNext(&pExpansionData->GroupsToExpandIterator);
        if (!pHashEntry)
        {
            dwError = LW_ERROR_INTERNAL;
            BAIL_ON_LSA_ERROR(dwError);
        }
    }

    pGroupToExpand = (PLSA_SECURITY_OBJECT) pHashEntry->pKey;
    dwGroupToExpandDepth = (size_t) pHashEntry->pValue;
    dwGroupToExpandDepth++;

    // Move the object to the expanded list.  Note that the object is
    // not necessarily expanded yet, but we must remove it from
    // the "to expand" list.  It does not hurt to track it in the
    // "expanded" list.

    dwError = LwHashSetValue(pExpansionData->pExpandedGroups,
                              pGroupToExpand,
                              (PVOID)(size_t)dwGroupToExpandDepth);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwHashRemoveKey(pExpansionData->pGroupsToExpand, pGroupToExpand);
    if (dwError)
    {
        LSA_LOG_DEBUG("ASSERT: cannot fail");
    }
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    *ppGroupToExpand = pGroupToExpand;
    *pdwGroupToExpandDepth = dwGroupToExpandDepth;

    return dwError;

error:
    ADCacheSafeFreeObject(&pGroupToExpand);
    dwGroupToExpandDepth = 0;

    if (dwError && !pExpansionData->dwLastError)
    {
        pExpansionData->dwLastError = dwError;
    }
    goto cleanup;
}
Esempio n. 6
0
DWORD
LsaSetSMBCreds(
    IN PCSTR pszUserPrincipalName,
    IN PCSTR pszPassword,
    IN BOOLEAN bSetDefaultCachePath,
    OUT PLSA_CREDS_FREE_INFO* ppFreeInfo
    )
{
    DWORD dwError = 0;
    krb5_error_code ret = 0;
    PSTR pszNewCachePath = NULL;
    PCSTR  pszCacheName = NULL;
    PCSTR  pszCacheType = NULL;
    krb5_context ctx = 0;
    krb5_ccache cc = 0;
    LW_PIO_CREDS pNewCreds = NULL;
    LW_PIO_CREDS pOldCreds = NULL;
    PLSA_CREDS_FREE_INFO pFreeInfo = NULL;
    PSTR pszOldCachePath = NULL;
    BOOLEAN bSwitchedPath = FALSE;

    BAIL_ON_INVALID_POINTER(ppFreeInfo);
    BAIL_ON_INVALID_STRING(pszUserPrincipalName);

    ret = krb5_init_context(&ctx);
    BAIL_ON_KRB_ERROR(ctx, ret);

    /* Generates a new filed based credentials cache in /tmp. The file will
     * be owned by root and only accessible by root.
     */
    ret = krb5_cc_new_unique(
            ctx,
            "FILE",
            "hint",
            &cc);
    BAIL_ON_KRB_ERROR(ctx, ret);

    pszCacheType = krb5_cc_get_type(ctx, cc);
    pszCacheName = krb5_cc_get_name(ctx, cc);
    dwError = LwAllocateStringPrintf(&pszNewCachePath, "%s:%s", pszCacheType, pszCacheName);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwKrb5GetTgt(
                pszUserPrincipalName,
                pszPassword,
                pszNewCachePath,
                NULL);
    BAIL_ON_LSA_ERROR(dwError);

    if (bSetDefaultCachePath)
    {
        LSA_LOG_DEBUG("Switching default credentials path for new access token"); 
        dwError = LwKrb5SetThreadDefaultCachePath(
                  pszNewCachePath,
                  &pszOldCachePath);
        BAIL_ON_LSA_ERROR(dwError);
        bSwitchedPath = TRUE;
    }

    dwError = LwIoCreateKrb5CredsA(
        pszUserPrincipalName,
        pszNewCachePath,
        &pNewCreds);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwAllocateMemory(sizeof(*pFreeInfo), (PVOID*)&pFreeInfo);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwIoGetThreadCreds(&pOldCreds);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LwIoSetThreadCreds(pNewCreds);
    BAIL_ON_LSA_ERROR(dwError);

    pFreeInfo->ctx = ctx;
    pFreeInfo->cc = cc;
    pFreeInfo->pRestoreCreds = pOldCreds;
    pFreeInfo->pszRestoreCache = pszOldCachePath;
    pFreeInfo->bKrbCreds = TRUE;
    pOldCreds = NULL;

cleanup:
    *ppFreeInfo = pFreeInfo;
    if (pOldCreds != NULL)
    {
        LwIoDeleteCreds(pOldCreds);
    }

    if (pNewCreds != NULL)
    {
        LwIoDeleteCreds(pNewCreds);
    }
    LW_SAFE_FREE_STRING(pszNewCachePath);

    return dwError;

error:
    if (ctx != NULL)
    {
        if (cc != NULL)
        {
            krb5_cc_destroy(ctx, cc);
        }
        krb5_free_context(ctx);
    }

    if (pFreeInfo)
    {
        LwFreeMemory(pFreeInfo);
        pFreeInfo = NULL;
    }
    if (bSwitchedPath)
    {
        LwKrb5SetThreadDefaultCachePath(
                  pszOldCachePath,
                  NULL);
        LW_SAFE_FREE_STRING(pszOldCachePath);
    }

    goto cleanup;
}
Esempio n. 7
0
DWORD
SELinuxCreate(
    PSELINUX *ppSELinux
    )
{
    DWORD dwError = 0;
    PSELINUX pSELinux = NULL;
 
    dwError = LwAllocateMemory(sizeof(SELINUX), (PVOID*)&pSELinux);
    BAIL_ON_LSA_ERROR(dwError);

    pSELinux->bEnabled = FALSE;

#if ENABLE_SELINUX
    BOOLEAN bFileExists = FALSE;

    dwError = LsaCheckFileExists(LIBSELINUX, &bFileExists);
    BAIL_ON_LSA_ERROR(dwError);

    if (bFileExists == FALSE)
    {
        LSA_LOG_DEBUG("Could not find %s", LIBSELINUX);
        goto error;
    }

    pSELinux->dlhandle = dlopen(LIBSELINUX, RTLD_LAZY | RTLD_LOCAL);
    if (pSELinux->dlhandle == NULL)
    {
        LSA_LOG_ERROR("Could not load " LIBSELINUX ": %s", dlerror());
        goto cleanup;
    }
    else
    {
        pSELinux->is_selinux_enabled = dlsym(pSELinux->dlhandle, "is_selinux_enabled");
        pSELinux->matchpathcon_init = dlsym(pSELinux->dlhandle, "matchpathcon_init");
        pSELinux->matchpathcon_fini = dlsym(pSELinux->dlhandle, "matchpathcon_fini");
        pSELinux->matchpathcon = dlsym(pSELinux->dlhandle, "matchpathcon");
        pSELinux->setfilecon= dlsym(pSELinux->dlhandle, "setfilecon");
        pSELinux->freecon = dlsym(pSELinux->dlhandle, "freecon");
        if (!pSELinux->is_selinux_enabled ||
            !pSELinux->matchpathcon ||
            !pSELinux->setfilecon ||
            !pSELinux->freecon)
        {
            LSA_LOG_ERROR("Could not find symbol in " LIBSELINUX);
            dwError = LW_ERROR_LOOKUP_SYMBOL_FAILED;
            BAIL_ON_LSA_ERROR(dwError);
        }

        if (pSELinux->is_selinux_enabled() == 1)
        {
            LSA_LOG_DEBUG("SELinux is enabled.");
            if(pSELinux->matchpathcon_init != NULL)
            {
                pSELinux->matchpathcon_init(NULL);
            }            
            pSELinux->bEnabled = TRUE;
        }
    }
#endif
    *ppSELinux = pSELinux;

cleanup:
    return dwError;

error:
    LW_SAFE_FREE_MEMORY(pSELinux);
    goto cleanup;
}
Esempio n. 8
0
DWORD
LsaSetSystemTime(
    time_t ttCurTime
    )
{
    DWORD dwError = 0;
    BOOLEAN bTimeset = FALSE;
    DWORD dwCount = 0;

    // The aix implementation of clock_settime segfaults
#ifdef __LWI_AIX__
#undef HAVE_CLOCK_SETTIME
#endif

#if !defined(HAVE_CLOCK_SETTIME) && !defined(HAVE_SETTIMEOFDAY)
#error Either clock_settime or settimeofday is needed
#endif

#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME)
    struct timespec systemspec;
#endif
#if HAVE_SETTIMEOFDAY || HAVE_GETTIMEOFDAY
    struct timeval systemval;
#endif
    long long readTime = -1;

#ifdef HAVE_CLOCK_SETTIME
    memset(&systemspec, 0, sizeof(systemspec));
    systemspec.tv_sec = ttCurTime;
#endif
#if HAVE_SETTIMEOFDAY
    memset(&systemval, 0, sizeof(systemval));
    systemval.tv_sec = ttCurTime;
#endif

#ifdef HAVE_CLOCK_SETTIME
    if (!bTimeset)
    {
        if (clock_settime(CLOCK_REALTIME, &systemspec) == -1)
        {
            LSA_LOG_VERBOSE("Setting time with clock_settime failed %d", errno);
        }
        else
        {
            LSA_LOG_VERBOSE("Setting time with clock_settime worked");
            bTimeset = TRUE;
        }
    }
#endif
    
#ifdef HAVE_SETTIMEOFDAY
    if (!bTimeset)
    {
        if (settimeofday(&systemval, NULL) == -1)
        {
            LSA_LOG_VERBOSE("Setting time with settimeofday failed %d", errno);
        }
        else
        {
            LSA_LOG_VERBOSE("Setting time with settimeofday worked");
            bTimeset = TRUE;
        }
    }
#endif
    
    if (!bTimeset)
    {
        dwError = LW_ERROR_FAILED_TO_SET_TIME;
        BAIL_ON_LSA_ERROR(dwError);
    }

    //Verify the clock got set
    bTimeset = FALSE;
#ifdef HAVE_CLOCK_GETTIME
    if (!bTimeset && clock_gettime(CLOCK_REALTIME, &systemspec) >= 0)
    {
        bTimeset = TRUE;
        readTime = systemspec.tv_sec;
    }
#endif
    
#ifdef HAVE_GETTIMEOFDAY
    if (!bTimeset && gettimeofday(&systemval, NULL) >= 0)
    {
        bTimeset = TRUE;
        readTime = systemval.tv_sec;
    }
#endif
    
    if (!bTimeset) {
        dwError = LW_ERROR_FAILED_TO_SET_TIME;
        BAIL_ON_LSA_ERROR(dwError);
    }
        
    //Make sure the time is now within 5 seconds of what we set
    if (labs(readTime - ttCurTime) > 5)
    {
        LSA_LOG_ERROR("Attempted to set time to %ld, but it is now %ld.", ttCurTime, readTime);
        dwError = LW_ERROR_FAILED_TO_SET_TIME;
        BAIL_ON_LSA_ERROR(dwError);
    }

    //Make sure the time reported by time() is now within 5 seconds of
    //what we set.  On virtual systems it may be slow to update.
    for ( dwCount = 0 ; dwCount < 5 ; dwCount++ )
    {
        readTime = time(NULL);

        if (labs(readTime - ttCurTime) > 5)
        {
            LSA_LOG_DEBUG("Time is slow to update...waiting");
            sleep(1);
        }
        else
        {
            break;
        }
    }

cleanup:

    return dwError;      
    
error:

    goto cleanup;
}
Esempio n. 9
0
static
DWORD
LsaAdBatchGatherNonSchemaModeUser(
    IN OUT PLSA_AD_BATCH_ITEM pItem,
    IN DWORD dwKeywordValuesCount,
    IN PSTR* ppszKeywordValues
    )
{
    DWORD dwError = 0;
    DWORD dwValue = 0;

    dwError = ADNonSchemaKeywordGetUInt32(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_UID_TAG,
                    &dwValue);
    if (LW_ERROR_INVALID_LDAP_ATTR_VALUE == dwError)
    {
        SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED);
        dwError = LW_ERROR_SUCCESS;
    }
    BAIL_ON_LSA_ERROR(dwError);

    if (IsSetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED))
    {
        goto cleanup;
    }

    if (!dwValue)
    {
        LSA_LOG_DEBUG("uid must be non-zero for SID '%s'", pItem->pszSid);
        // SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_SKIP);
        dwError = LW_ERROR_DATA_ERROR;
        BAIL_ON_LSA_ERROR(dwError);
    }

    pItem->UserInfo.uid = (uid_t)dwValue;

    dwError = ADNonSchemaKeywordGetUInt32(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_GID_TAG,
                    &dwValue);
    BAIL_ON_LSA_ERROR(dwError);

    if (!dwValue)
    {
        LSA_LOG_DEBUG("gid must be non-zero for SID '%s'", pItem->pszSid);
        // SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_SKIP);
        dwError = LW_ERROR_DATA_ERROR;
        BAIL_ON_LSA_ERROR(dwError);
    }

    pItem->UserInfo.gid = (gid_t)dwValue;

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_ALIAS_TAG,
                    &pItem->UserInfo.pszAlias);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_PASSWD_TAG,
                    &pItem->UserInfo.pszPasswd);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_GECOS_TAG,
                    &pItem->UserInfo.pszGecos);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_HOMEDIR_TAG,
                    &pItem->UserInfo.pszHomeDirectory);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_SHELL_TAG,
                    &pItem->UserInfo.pszShell);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = ADNonSchemaKeywordGetString(
                    ppszKeywordValues,
                    dwKeywordValuesCount,
                    AD_LDAP_LOCALWINDOWSHOMEFOLDER_TAG,
                    &pItem->UserInfo.pszLocalWindowsHomeFolder);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    return dwError;

error:
    goto cleanup;
}
Esempio n. 10
0
DWORD
LsaSrvGetLsassVersion(
    PLSA_VERSION pVersion
    )
{  
    DWORD dwError = 0;
    PSTR pszVersion = NULL;
    DWORD iVerComp = 0;
    PSTR  pszToken = NULL;
    PSTR  pszTokenState = NULL;
    DWORD dwMajor = 0;
    DWORD dwMinor = 0;
    DWORD dwBuild = 0;
    DWORD dwRevision = 0;
    
    if (LW_IS_NULL_OR_EMPTY_STR(COMPONENT_VERSION))
    {
        dwError = LW_ERROR_INVALID_AGENT_VERSION;
        BAIL_ON_LSA_ERROR(dwError);
    }
    
    dwError = LwAllocateString(
                    COMPONENT_VERSION,
                    &pszVersion);
    BAIL_ON_LSA_ERROR(dwError);
    
    pszToken = strtok_r(pszVersion, ".",  &pszTokenState);
    
    while (!LW_IS_NULL_OR_EMPTY_STR(pszVersion) && (iVerComp < 4))
    {
        int i = 0;
        
        for (; i < strlen(pszVersion); i++)
        {
            if (!isdigit((int)pszVersion[i]))
            {
                dwError = LW_ERROR_INVALID_AGENT_VERSION;
                BAIL_ON_LSA_ERROR(dwError);
            }
        }
        
        switch (iVerComp++)
        {
            case 0:
                
                dwMajor = atoi(pszToken);
                break;
                
            case 1:
                
                dwMinor = atoi(pszToken);
                break;
                
            case 2:
                
                dwBuild = atoi(pszToken);
                break;

            case 3:

                errno = 0;
                dwRevision = strtoul(pszToken, NULL, 10);
                dwError = LwMapErrnoToLwError(errno);
                if (dwError != 0)
                {
                    LSA_LOG_DEBUG("Unable to parse revision due to error %u", dwError);
                    dwRevision = 0;
                    dwError = 0;
                }
                break;

            default:
                
                dwError = LW_ERROR_INTERNAL;
                BAIL_ON_LSA_ERROR(dwError);
        }
        
        pszToken = strtok_r(NULL, ".", &pszTokenState);
    }
    
    if (iVerComp < 4)
    {
        dwError = LW_ERROR_INVALID_AGENT_VERSION;
        BAIL_ON_LSA_ERROR(dwError);
    }
    
    pVersion->dwMajor = dwMajor;
    pVersion->dwMinor = dwMinor;
    pVersion->dwBuild = dwBuild;
    pVersion->dwRevision = dwRevision;
    
cleanup:

    LW_SAFE_FREE_MEMORY(pszVersion);

    return dwError;
    
error:

    memset(pVersion, 0, sizeof(*pVersion));

    goto cleanup;
}
Esempio n. 11
0
static OSStatus
AuthMechanismCreate(
        IN AuthorizationPluginRef pPluginRef,
        IN AuthorizationEngineRef pEngineRef,
        IN AuthorizationMechanismId mechanismId,
        OUT AuthorizationMechanismRef *ppMechanismRef
        )
{
    PLW_AUTH_MECHANISM pAuthMechanism = NULL;
    PLW_AUTH_MECHANISM_INSTANCE pMechanismInstance = NULL;
    OSStatus osStatus = noErr;
    DWORD dwError = LW_ERROR_SUCCESS;

    LSA_LOG_DEBUG("Creating auth mechanism Likewise:%s", mechanismId);

    for (pAuthMechanism = gpAuthMechanisms;
            pAuthMechanism != NULL;
            pAuthMechanism = pAuthMechanism->pNext)
    {
        if (!strcmp(pAuthMechanism->name, mechanismId))
        {
            break;
        }
    }

    if (pAuthMechanism == NULL)
    {
        LSA_LOG_DEBUG("Auth mechanism Likewise:%s not found", mechanismId);
        goto error;
    }

    dwError = AUTH_PLUGIN_ALLOCATE(pMechanismInstance);
    BAIL_ON_LSA_ERROR(dwError);

    pMechanismInstance->pAuthPlugin = pPluginRef;
    pMechanismInstance->pAuthEngine = pEngineRef;
    pMechanismInstance->pAuthMechanism = pAuthMechanism;
    pMechanismInstance->pMechanismData = NULL;

    if (pAuthMechanism->Create)
    {
        if (pAuthMechanism->Create(pMechanismInstance) != noErr)
        {
            goto error;
        }
    }

cleanup:
    *ppMechanismRef = pMechanismInstance;
    return osStatus;

error:
    if (pMechanismInstance)
    {
        if (pMechanismInstance->pAuthMechanism &&
                pMechanismInstance->pAuthMechanism->Destroy)
        {
            pMechanismInstance->pAuthMechanism->Destroy(pMechanismInstance);
        }

        LwFreeMemory(pMechanismInstance);
    }

    /*
     * The documentation says all errors should return
     * errAuthorizationInternal.
     */
    osStatus = errAuthorizationInternal;
    goto cleanup;
}
Esempio n. 12
0
int
main(int argc, const char **argv)
{
    poptContext poptContext;
    int poptResult;
    uid_t uid;
    int kq;
    HANDLE lsaConnection = (HANDLE) NULL;
    PVOID pUserInfo = NULL;
    struct kevent event = { 0 };
    int numChanges = 1;
    krb5_context krb5Context = NULL;
    char krb5FileCachePath[PATH_MAX];
    krb5_ccache krb5FileCache = NULL;
    krb5_ccache krb5MemoryCache = NULL;
    krb5_cc_cursor krb5Cursor = NULL;
    krb5_creds krb5Credentials = { 0 };
    krb5_principal krb5Principal = NULL;
    krb5_error_code krb5Error;
    int exitStatus = 0;
    DWORD dwError = LW_ERROR_SUCCESS;

    poptContext = poptGetContext(NULL, argc, argv, Options, 0);
    while ((poptResult = poptGetNextOpt(poptContext)) >= 0)
    {
        /* All options are processed automatically. */
    }

    if (poptResult < -1)
    {
        fprintf(stderr, "%s: %s: %s\n", getprogname(),
                poptBadOption(poptContext, POPT_BADOPTION_NOALIAS),
                poptStrerror(poptResult));
        exitStatus = 1;
        goto error;
    }

    uid = getuid();

    /* Make sure we're running as an AD user. */
    dwError = LsaOpenServer(&lsaConnection);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LsaFindUserById(
                  lsaConnection,
                  uid,
                  0,
                  &pUserInfo);
    if (dwError == LW_ERROR_NO_SUCH_USER)
    {
        /*
         * Running as a non-AD user; exit 0 so launchd doesn't restart
         * the ticketcopy program (see com.beyondtrust.pbis.ticketcopy.plist).
         */
        LSA_LOG_DEBUG(
            "uid %lu is not an AD user; exiting",
            (unsigned long) uid);
        dwError = LW_ERROR_SUCCESS;
        goto cleanup;
    }
    BAIL_ON_LSA_ERROR(dwError);

    kq = kqueue();
    BAIL_ON_UNIX_ERROR(kq == -1);

    krb5Error = krb5_init_context(&krb5Context);
    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

    krb5Error = krb5_cc_default(krb5Context, &krb5MemoryCache);
    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

    snprintf(
        krb5FileCachePath,
        sizeof(krb5FileCachePath),
        "FILE:/tmp/krb5cc_%lu",
        (unsigned long) uid);

    while (1) /* Forever (or until an error occurs) */
    {
        while ((event.ident = open(krb5FileCachePath + 5, O_RDONLY)) == -1)
        {
            sleep(5);
        }

        event.filter = EVFILT_VNODE;
        event.flags = EV_ADD | EV_ENABLE | EV_CLEAR;
        event.fflags = NOTE_DELETE | NOTE_WRITE;
        numChanges = 1;

        krb5Error = krb5_cc_resolve(
                        krb5Context,
                        krb5FileCachePath,
                        &krb5FileCache);
        BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

        while (1) /* While the file continues to exist. */
        {
            /*
             * Turn off KRB5_TC_OPENCLOSE so the file will be opened once
             * and kept open.  This causes it to actually attempt to open
             * the file, so this is where we check for the file not
             * existing and retry after sleeping a bit.
             */
            krb5Error = krb5_cc_set_flags(krb5Context, krb5FileCache, 0);
            if (krb5Error == KRB5_FCC_NOFILE)
            {
                break;
            }
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            /* Copy all credentials from the file to the memory cache. */
            krb5Error = krb5_cc_start_seq_get(
                            krb5Context,
                            krb5FileCache,
                            &krb5Cursor);
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            while ((krb5Error = krb5_cc_next_cred(
                                    krb5Context,
                                    krb5FileCache,
                                    &krb5Cursor,
                                    &krb5Credentials)) == 0)
            {
                krb5Error = krb5_cc_store_cred(
                                krb5Context,
                                krb5MemoryCache,
                                &krb5Credentials);
                if (krb5Error == KRB5_FCC_NOFILE)
                {
                    krb5Error = krb5_cc_get_principal(
                                    krb5Context,
                                    krb5FileCache,
                                    &krb5Principal);
                    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

                    /* The memory cache was destroyed; re-create it. */
                    krb5Error = krb5_cc_initialize(
                                    krb5Context,
                                    krb5MemoryCache,
                                    krb5Principal);
                    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

                    krb5_free_principal(krb5Context, krb5Principal);
                    krb5Principal = NULL;

                    krb5Error = krb5_cc_store_cred(
                                    krb5Context,
                                    krb5MemoryCache,
                                    &krb5Credentials);
                }
                BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

                krb5_free_cred_contents(krb5Context, &krb5Credentials);
            }

            if (krb5Error != KRB5_CC_END)
            {
                BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);
            }

            krb5Error = krb5_cc_end_seq_get(
                            krb5Context,
                            krb5FileCache,
                            &krb5Cursor);
            krb5Cursor = NULL;
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            /*
             * Turn KRB5_TC_OPENCLOSE back on; this will cause
             * the file to be closed and any locks to be
             * released.
             */
            krb5Error = krb5_cc_set_flags(
                            krb5Context,
                            krb5FileCache,
                            KRB5_TC_OPENCLOSE);
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            /*
             * Wait for the file to be modified or deleted.  The first
             * time this is called after the file is opened, numChanges
             * will be 1, which will install the fd into the event
             * list.  After that numChanges is changed to 0, so it will
             * just report events from the existing list.
             */
            if (kevent(kq, &event, numChanges, &event, 1, NULL) != 1)
            {
                fprintf(stderr, "kevent failed\n");
                exitStatus = 1;
                goto cleanup;
            }

            if (event.fflags & NOTE_DELETE)
            {
                break;
            }

            numChanges = 0;
        }

        krb5Error = krb5_cc_close(krb5Context, krb5FileCache);
        BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);
        krb5FileCache = NULL;

        close(event.ident);
        event.ident = -1;

        /*
         * The cache file is usually removed as part of a
         * rename(2) system call, so only wait a short
         * time before the first attempt to re-open it.
         */
        usleep(100000);
    }

error:
cleanup:
    krb5_free_cred_contents(krb5Context, &krb5Credentials);

    if (krb5Cursor)
    {
        krb5_cc_end_seq_get(krb5Context, krb5FileCache, &krb5Cursor);
    }

    if (krb5FileCache)
    {
        krb5_cc_close(krb5Context, krb5FileCache);
    }

    if (krb5Principal)
    {
        krb5_free_principal(krb5Context, krb5Principal);
    }

    if (krb5Context)
    {
        krb5_free_context(krb5Context);
    }

    if (event.ident != -1)
    {
        close(event.ident);
    }

    if (pUserInfo)
    {
        LsaFreeUserInfo(0, pUserInfo);
    }

    if (lsaConnection != (HANDLE) NULL)
    {
        LsaCloseServer(lsaConnection);
    }

    if (dwError)
    {
        exitStatus = 1;
    }

    return exitStatus;
}