/* 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 program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program 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 General Public License * for more details. You should have received a copy of the GNU 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 * 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: * * main.c * * Abstract: * * Likewise Security and Authentication Subsystem (LSASS) * * Tool to get status from LSA Server * * Authors: Krishna Ganugapati (krishnag@likewisesoftware.com) * Sriram Nambakam (snambakam@likewisesoftware.com) */ #define _POSIX_PTHREAD_SEMANTICS 1 #include "config.h" #include "lsasystem.h" #include "lsadef.h" #include "lsa/lsa.h" #include "lsaclient.h" #include "lsaipc.h" #define LSA_MODE_STRING_UNKNOWN "Unknown" #define LSA_MODE_STRING_UNPROVISIONED "Un-provisioned" #define LSA_MODE_STRING_DEFAULT_CELL "Default Cell" #define LSA_MODE_STRING_NON_DEFAULT_CELL "Non-default Cell" #define LSA_MODE_STRING_LOCAL "Local system" #define LSA_SUBMODE_STRING_UNKNOWN "Unknown" #define LSA_SUBMODE_STRING_SCHEMA "Schema" #define LSA_SUBMODE_STRING_NON_SCHEMA "Non-schema" #define LSA_STATUS_STRING_UNKNOWN "Unknown" #define LSA_STATUS_STRING_ONLINE "Online" #define LSA_STATUS_STRING_OFFLINE "Offline" #define LSA_TRUST_TYPE_STRING_UNKNOWN "Unknown" #define LSA_TRUST_TYPE_STRING_DOWNLEVEL "Down Level" #define LSA_TRUST_TYPE_STRING_UPLEVEL "Up Level" #define LSA_TRUST_TYPE_STRING_MIT "MIT" #define LSA_TRUST_TYPE_STRING_DCE "DCE" #define LW_PRINTF_STRING(x) ((x) ? (x) : "") static VOID ParseArgs( int argc, char* argv[] ); static VOID ShowUsage(); static VOID PrintStatus( PLSASTATUS pStatus ); static PCSTR GetStatusString( LsaAuthProviderStatus status ); static PCSTR GetModeString( LsaAuthProviderMode mode ); static PCSTR GetSubmodeString( LsaAuthProviderSubMode subMode ); static PCSTR GetTrustTypeString( DWORD dwTrustType ); static DWORD MapErrorCode( DWORD dwError ); int get_status_main( int argc, char* argv[] ) { DWORD dwError = 0; PLSASTATUS pLsaStatus = NULL; HANDLE hLsaConnection = (HANDLE)NULL; size_t dwErrorBufferSize = 0; BOOLEAN bPrintOrigError = TRUE; ParseArgs(argc, argv); dwError = LsaOpenServer(&hLsaConnection); BAIL_ON_LSA_ERROR(dwError); dwError = LsaGetStatus( hLsaConnection, &pLsaStatus); BAIL_ON_LSA_ERROR(dwError); PrintStatus(pLsaStatus); cleanup: if (pLsaStatus) { LsaFreeStatus(pLsaStatus); } if (hLsaConnection != (HANDLE)NULL) { LsaCloseServer(hLsaConnection); } return (dwError); error: dwError = MapErrorCode(dwError); dwErrorBufferSize = LwGetErrorString(dwError, NULL, 0); if (dwErrorBufferSize > 0) { DWORD dwError2 = 0; PSTR pszErrorBuffer = NULL; dwError2 = LwAllocateMemory( dwErrorBufferSize, (PVOID*)&pszErrorBuffer); if (!dwError2) { DWORD dwLen = LwGetErrorString(dwError, pszErrorBuffer, dwErrorBufferSize); if ((dwLen == dwErrorBufferSize) && !LW_IS_NULL_OR_EMPTY_STR(pszErrorBuffer)) { fprintf( stderr, "Failed to query status from LSA service. Error code %u (%s).\n%s\n", dwError, LW_PRINTF_STRING(LwWin32ExtErrorToName(dwError)), pszErrorBuffer); bPrintOrigError = FALSE; } } LW_SAFE_FREE_STRING(pszErrorBuffer); } if (bPrintOrigError) { fprintf( stderr, "Failed to query status from LSA service. Error code %u (%s).\n", dwError, LW_PRINTF_STRING(LwWin32ExtErrorToName(dwError))); } goto cleanup; } VOID ParseArgs( int argc, char* argv[] ) { typedef enum { PARSE_MODE_OPEN = 0 } ParseMode; int iArg = 1; PSTR pszArg = NULL; ParseMode parseMode = PARSE_MODE_OPEN; do { pszArg = argv[iArg++]; if (pszArg == NULL || *pszArg == '\0') { break; } switch (parseMode) { case PARSE_MODE_OPEN: if ((strcmp(pszArg, "--help") == 0) || (strcmp(pszArg, "-h") == 0)) { ShowUsage(); exit(0); } else { ShowUsage(); exit(1); } break; } } while (iArg < argc); } void ShowUsage() { printf("Usage: lw-get-status\n"); } VOID PrintStatus( PLSASTATUS pStatus ) { DWORD iCount = 0; DWORD dwDays = pStatus->dwUptime/LSA_SECONDS_IN_DAY; DWORD dwHours = (pStatus->dwUptime - (dwDays * LSA_SECONDS_IN_DAY))/LSA_SECONDS_IN_HOUR; DWORD dwMins = (pStatus->dwUptime - (dwDays * LSA_SECONDS_IN_DAY) - (dwHours * LSA_SECONDS_IN_HOUR))/LSA_SECONDS_IN_MINUTE; DWORD dwSecs = (pStatus->dwUptime - (dwDays * LSA_SECONDS_IN_DAY) - (dwHours * LSA_SECONDS_IN_HOUR) - (dwMins * LSA_SECONDS_IN_MINUTE)); printf("LSA Server Status:\n\n"); printf("Compiled daemon version: %u.%u.%u.%u\n", pStatus->lsassVersion.dwMajor, pStatus->lsassVersion.dwMinor, pStatus->lsassVersion.dwBuild, pStatus->lsassVersion.dwRevision); printf("Packaged product version: %u.%u.%u.%u\n", pStatus->productVersion.dwMajor, pStatus->productVersion.dwMinor, pStatus->productVersion.dwBuild, pStatus->productVersion.dwRevision); printf("Uptime: %u days %u hours %u minutes %u seconds\n", dwDays, dwHours, dwMins, dwSecs); for (iCount = 0; iCount < pStatus->dwCount; iCount++) { PLSA_AUTH_PROVIDER_STATUS pProviderStatus = &pStatus->pAuthProviderStatusList[iCount]; printf("\n[Authentication provider: %s]\n\n", LW_IS_NULL_OR_EMPTY_STR(pProviderStatus->pszId) ? "" : pProviderStatus->pszId); printf("\tStatus: %s\n", GetStatusString(pProviderStatus->status)); printf("\tMode: %s\n", GetModeString(pProviderStatus->mode)); switch (pProviderStatus->mode) { case LSA_PROVIDER_MODE_LOCAL_SYSTEM: break; case LSA_PROVIDER_MODE_UNPROVISIONED: case LSA_PROVIDER_MODE_DEFAULT_CELL: case LSA_PROVIDER_MODE_NON_DEFAULT_CELL: printf("\tDomain: %s\n", LW_IS_NULL_OR_EMPTY_STR(pProviderStatus->pszDomain) ? "" : pProviderStatus->pszDomain); printf("\tForest: %s\n", LW_IS_NULL_OR_EMPTY_STR(pProviderStatus->pszForest) ? "" : pProviderStatus->pszForest); printf("\tSite: %s\n", LW_IS_NULL_OR_EMPTY_STR(pProviderStatus->pszSite) ? "" : pProviderStatus->pszSite); printf("\tOnline check interval: %d seconds\n", pProviderStatus->dwNetworkCheckInterval); break; default: break; } switch (pProviderStatus->mode) { case LSA_PROVIDER_MODE_DEFAULT_CELL: printf("\tSub mode: %s\n", GetSubmodeString(pProviderStatus->subMode)); break; case LSA_PROVIDER_MODE_NON_DEFAULT_CELL: printf("\tSub mode: %s\n", GetSubmodeString(pProviderStatus->subMode)); printf("\tCell: %s\n", LW_IS_NULL_OR_EMPTY_STR(pProviderStatus->pszCell) ? "" : pProviderStatus->pszCell); break; default: break; } if (pProviderStatus->pTrustedDomainInfoArray) { DWORD iDomain = 0; printf("\t[Trusted Domains: %d]\n\n", pProviderStatus->dwNumTrustedDomains); for (; iDomain < pProviderStatus->dwNumTrustedDomains; iDomain++) { PLSA_TRUSTED_DOMAIN_INFO pDomainInfo = &pProviderStatus->pTrustedDomainInfoArray[iDomain]; printf("\n\t[Domain: %s]\n\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszNetbiosDomain) ? "" : pDomainInfo->pszNetbiosDomain); printf("\t\tDNS Domain: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszDnsDomain) ? "" : pDomainInfo->pszDnsDomain); printf("\t\tNetbios name: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszNetbiosDomain) ? "" : pDomainInfo->pszNetbiosDomain); printf("\t\tForest name: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszForestName) ? "" : pDomainInfo->pszForestName); printf("\t\tTrustee DNS name: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszTrusteeDnsDomain) ? "" : pDomainInfo->pszTrusteeDnsDomain); printf("\t\tClient site name: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszClientSiteName) ? "" : pDomainInfo->pszClientSiteName); printf("\t\tDomain SID: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszDomainSID) ? "" : pDomainInfo->pszDomainSID); printf("\t\tDomain GUID: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pszDomainGUID) ? "" : pDomainInfo->pszDomainGUID); printf("\t\tTrust Flags: [0x%.04x]\n", pDomainInfo->dwTrustFlags); if (pDomainInfo->dwTrustFlags & LSA_TRUST_FLAG_IN_FOREST) printf("\t\t [0x%.04x - In forest]\n", LSA_TRUST_FLAG_IN_FOREST); if (pDomainInfo->dwTrustFlags & LSA_TRUST_FLAG_OUTBOUND) printf("\t\t [0x%.04x - Outbound]\n", LSA_TRUST_FLAG_OUTBOUND); if (pDomainInfo->dwTrustFlags & LSA_TRUST_FLAG_TREEROOT) printf("\t\t [0x%.04x - Tree root]\n", LSA_TRUST_FLAG_TREEROOT); if (pDomainInfo->dwTrustFlags & LSA_TRUST_FLAG_PRIMARY) printf("\t\t [0x%.04x - Primary]\n", LSA_TRUST_FLAG_PRIMARY); if (pDomainInfo->dwTrustFlags & LSA_TRUST_FLAG_NATIVE) printf("\t\t [0x%.04x - Native]\n", LSA_TRUST_FLAG_NATIVE); if (pDomainInfo->dwTrustFlags & LSA_TRUST_FLAG_INBOUND) printf("\t\t [0x%.04x - Inbound]\n", LSA_TRUST_FLAG_INBOUND); printf("\t\tTrust type: %s\n", GetTrustTypeString(pDomainInfo->dwTrustType)); printf("\t\tTrust Attributes: [0x%.04x]\n", pDomainInfo->dwTrustAttributes); if (pDomainInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) printf("\t\t [0x%.04x - Non-transitive]\n", LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE); if (pDomainInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_UPLEVEL_ONLY) printf("\t\t [0x%.04x - Uplevel only]\n", LSA_TRUST_ATTRIBUTE_UPLEVEL_ONLY); if (pDomainInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_FILTER_SIDS) printf("\t\t [0x%.04x - Filter SIDs]\n", LSA_TRUST_ATTRIBUTE_FILTER_SIDS); if (pDomainInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) printf("\t\t [0x%.04x - Forest transitive]\n", LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE); if (pDomainInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_CROSS_ORGANIZATION) printf("\t\t [0x%.04x - Cross organization]\n", LSA_TRUST_ATTRIBUTE_CROSS_ORGANIZATION); if (pDomainInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) printf("\t\t [0x%.04x - Within forest]\n", LSA_TRUST_ATTRIBUTE_WITHIN_FOREST); printf("\t\tTrust Direction: "); switch (pDomainInfo->dwTrustDirection) { case LSA_TRUST_DIRECTION_ZERO_WAY: printf("Zeroway Trust\n"); break; case LSA_TRUST_DIRECTION_ONE_WAY: printf("Oneway Trust\n"); break; case LSA_TRUST_DIRECTION_TWO_WAY: printf("Twoway Trust\n"); break; case LSA_TRUST_DIRECTION_SELF: printf("Primary Domain\n"); break; default: printf("Unknown trust direction\n"); } printf("\t\tTrust Mode: "); switch (pDomainInfo->dwTrustMode) { case LSA_TRUST_MODE_EXTERNAL: printf("External Trust (ET)\n"); break; case LSA_TRUST_MODE_MY_FOREST: printf("In my forest Trust (MFT)\n"); break; case LSA_TRUST_MODE_OTHER_FOREST: printf("In other forest Trust (OFT)\n"); break; default: printf("Unknown trust mode\n"); } printf("\t\tDomain flags: [0x%.04x]\n", pDomainInfo->dwDomainFlags); if (pDomainInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_PRIMARY) printf("\t\t [0x%.04x - Primary]\n", LSA_DM_DOMAIN_FLAG_PRIMARY); if (pDomainInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_OFFLINE) printf("\t\t [0x%.04x - Offline]\n", LSA_DM_DOMAIN_FLAG_OFFLINE); if (pDomainInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_FORCE_OFFLINE) printf("\t\t [0x%.04x - Force offline]\n", LSA_DM_DOMAIN_FLAG_FORCE_OFFLINE); if (pDomainInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_TRANSITIVE_1WAY_CHILD) printf("\t\t [0x%.04x - Transitive 1 way child]\n", LSA_DM_DOMAIN_FLAG_TRANSITIVE_1WAY_CHILD); if (pDomainInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_FOREST_ROOT) printf("\t\t [0x%.04x - Forest root]\n", LSA_DM_DOMAIN_FLAG_FOREST_ROOT); if (pDomainInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_GC_OFFLINE) printf("\t\t [0x%.04x - GC offline]\n", LSA_DM_DOMAIN_FLAG_GC_OFFLINE); if (pDomainInfo->pDCInfo) { printf("\n\t\t[Domain Controller (DC) Information]\n\n"); printf("\t\t\tDC Name: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pDCInfo->pszName) ? "" : pDomainInfo->pDCInfo->pszName); printf("\t\t\tDC Address: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pDCInfo->pszAddress) ? "" : pDomainInfo->pDCInfo->pszAddress); printf("\t\t\tDC Site: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pDCInfo->pszSiteName) ? "" : pDomainInfo->pDCInfo->pszSiteName); printf("\t\t\tDC Flags: [0x%.08x]\n", pDomainInfo->pDCInfo->dwFlags); printf("\t\t\tDC Is PDC: %s\n", (pDomainInfo->pDCInfo->dwFlags & LSA_DS_PDC_FLAG) ? "yes" : "no"); printf("\t\t\tDC is time server: %s\n", (pDomainInfo->pDCInfo->dwFlags & LSA_DS_TIMESERV_FLAG) ? "yes" : "no"); printf("\t\t\tDC has writeable DS: %s\n", (pDomainInfo->pDCInfo->dwFlags & LSA_DS_WRITABLE_FLAG) ? "yes" : "no"); printf("\t\t\tDC is Global Catalog: %s\n", (pDomainInfo->pDCInfo->dwFlags & LSA_DS_GC_FLAG) ? "yes" : "no"); printf("\t\t\tDC is running KDC: %s\n", (pDomainInfo->pDCInfo->dwFlags & LSA_DS_KDC_FLAG) ? "yes" : "no"); } if (pDomainInfo->pGCInfo) { printf("\n\t\t[Global Catalog (GC) Information]\n\n"); printf("\t\t\tGC Name: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pGCInfo->pszName) ? "" : pDomainInfo->pGCInfo->pszName); printf("\t\t\tGC Address: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pGCInfo->pszAddress) ? "" : pDomainInfo->pGCInfo->pszAddress); printf("\t\t\tGC Site: %s\n", LW_IS_NULL_OR_EMPTY_STR(pDomainInfo->pGCInfo->pszSiteName) ? "" : pDomainInfo->pGCInfo->pszSiteName); printf("\t\t\tGC Flags: [0x%.08x]\n", pDomainInfo->pGCInfo->dwFlags); printf("\t\t\tGC Is PDC: %s\n", (pDomainInfo->pGCInfo->dwFlags & LSA_DS_PDC_FLAG) ? "yes" : "no"); printf("\t\t\tGC is time server: %s\n", (pDomainInfo->pGCInfo->dwFlags & LSA_DS_TIMESERV_FLAG) ? "yes" : "no"); printf("\t\t\tGC has writeable DS: %s\n", (pDomainInfo->pGCInfo->dwFlags & LSA_DS_WRITABLE_FLAG) ? "yes" : "no"); printf("\t\t\tGC is running KDC: %s\n", (pDomainInfo->pGCInfo->dwFlags & LSA_DS_KDC_FLAG) ? "yes" : "no"); } } } } } PCSTR GetStatusString( LsaAuthProviderStatus status ) { PCSTR pszStatusString = NULL; switch (status) { case LSA_AUTH_PROVIDER_STATUS_ONLINE: pszStatusString = LSA_STATUS_STRING_ONLINE; break; case LSA_AUTH_PROVIDER_STATUS_OFFLINE: pszStatusString = LSA_STATUS_STRING_OFFLINE; break; default: pszStatusString = LSA_STATUS_STRING_UNKNOWN; break; } return pszStatusString; } PCSTR GetModeString( LsaAuthProviderMode mode ) { PCSTR pszModeString = NULL; switch (mode) { case LSA_PROVIDER_MODE_UNPROVISIONED: pszModeString = LSA_MODE_STRING_UNPROVISIONED; break; case LSA_PROVIDER_MODE_DEFAULT_CELL: pszModeString = LSA_MODE_STRING_DEFAULT_CELL; break; case LSA_PROVIDER_MODE_NON_DEFAULT_CELL: pszModeString = LSA_MODE_STRING_NON_DEFAULT_CELL; break; case LSA_PROVIDER_MODE_LOCAL_SYSTEM: pszModeString = LSA_MODE_STRING_LOCAL; break; default: pszModeString = LSA_MODE_STRING_UNKNOWN; break; } return pszModeString; } PCSTR GetSubmodeString( LsaAuthProviderSubMode subMode ) { PCSTR pszSubmodeString = NULL; switch(subMode) { case LSA_AUTH_PROVIDER_SUBMODE_SCHEMA: pszSubmodeString = LSA_SUBMODE_STRING_SCHEMA; break; case LSA_AUTH_PROVIDER_SUBMODE_NONSCHEMA: pszSubmodeString = LSA_SUBMODE_STRING_NON_SCHEMA; break; default: pszSubmodeString = LSA_SUBMODE_STRING_UNKNOWN; break; } return pszSubmodeString; } PCSTR GetTrustTypeString( DWORD dwTrustType ) { PCSTR pszTrustTypeString = NULL; switch (dwTrustType) { case LSA_TRUST_TYPE_DOWNLEVEL: pszTrustTypeString = LSA_TRUST_TYPE_STRING_DOWNLEVEL; break; case LSA_TRUST_TYPE_UPLEVEL: pszTrustTypeString = LSA_TRUST_TYPE_STRING_UPLEVEL; break; case LSA_TRUST_TYPE_MIT: pszTrustTypeString = LSA_TRUST_TYPE_STRING_MIT; break; case LSA_TRUST_TYPE_DCE: pszTrustTypeString = LSA_TRUST_TYPE_STRING_DCE; break; default: pszTrustTypeString = LSA_TRUST_TYPE_STRING_UNKNOWN; break; } return pszTrustTypeString; } DWORD MapErrorCode( DWORD dwError ) { DWORD dwError2 = dwError; switch (dwError) { case ECONNREFUSED: case ENETUNREACH: case ETIMEDOUT: dwError2 = LW_ERROR_LSA_SERVER_UNREACHABLE; break; default: break; } return dwError2; }