From: Oliver Kurth Date: Thu, 30 Nov 2017 23:17:27 +0000 (-0800) Subject: VGAuth changes: X-Git-Tag: stable-10.2.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa59fb2fd5f15b2514b1494171de40e082e46ba5;p=thirdparty%2Fopen-vm-tools.git VGAuth changes: - add calling LoadUserProfile()/UnloadUserProfile() in VGAuth impersonation/unimpersonation code paths - VGAuth part of code change plus tools vix plugin make file. --- diff --git a/open-vm-tools/vgauth/lib/VGAuthInt.h b/open-vm-tools/vgauth/lib/VGAuthInt.h index 9bd6499f4..564233a29 100644 --- a/open-vm-tools/vgauth/lib/VGAuthInt.h +++ b/open-vm-tools/vgauth/lib/VGAuthInt.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2011-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2011-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -97,6 +97,8 @@ typedef struct VCAGComm { char *pipeName; } VGAuthComm; +struct VGAuthUserHandle; + struct VGAuthContext { /* * Needed for pam(3) initialization. @@ -125,6 +127,11 @@ struct VGAuthContext { */ gboolean isImpersonating; + /* + * Impersonated user. + */ + VGAuthUserHandle *impersonatedUser; + /* * XXX optimization -- keep a comm channel alive for superuser? * @@ -165,9 +172,11 @@ struct VGAuthUserHandle { AuthDetails details; #ifdef _WIN32 HANDLE token; + HANDLE hProfile; #else uid_t uid; #endif + int refCount; }; @@ -252,7 +261,8 @@ VGAuthError VGAuth_SetUserHandleSamlInfo(VGAuthContext *ctx, VGAuthAliasInfo *si); VGAuthError VGAuthImpersonateImpl(VGAuthContext *ctx, - VGAuthUserHandle *handle); + VGAuthUserHandle *handle, + gboolean loadUserProfile); VGAuthError VGAuthEndImpersonationImpl(VGAuthContext *ctx); @@ -316,6 +326,17 @@ VGAuthError VGAuthValidateExtraParamsImpl(const char *funcName, int numExtraParams, const VGAuthExtraParams *params); +#define VGAuthGetBoolExtraParam(numEP, ep, name, defValue, value) \ + VGAuthGetBoolExtraParamImpl(__FUNCTION__, (numEP), ep, \ + name, defValue, (value)) + +VGAuthError VGAuthGetBoolExtraParamImpl(const char *funcName, + int numExtraParams, + const VGAuthExtraParams *params, + const char *paramName, + gboolean defValue, + gboolean *paramValue); + void VGAuth_FreeAliasInfoContents(VGAuthAliasInfo *si); void VGAuth_CopyAliasInfo(const VGAuthAliasInfo *src, VGAuthAliasInfo *dst); diff --git a/open-vm-tools/vgauth/lib/auth.c b/open-vm-tools/vgauth/lib/auth.c index 3eede1a03..e9b048572 100644 --- a/open-vm-tools/vgauth/lib/auth.c +++ b/open-vm-tools/vgauth/lib/auth.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2011-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2011-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -452,8 +452,7 @@ VGAuth_ValidateSamlBearerToken(VGAuthContext *ctx, { VGAuthError err; VGAuthUserHandle *newHandle = NULL; - int validateOnly = -1; - int i; + gboolean validateOnly; /* * arg check @@ -485,45 +484,20 @@ VGAuth_ValidateSamlBearerToken(VGAuthContext *ctx, return err; } - /* - * XXX - * - * Should be generalized once we have more use cases. - */ - for (i = 0; i < numExtraParams; i++) { - if (g_strcmp0(extraParams[i].name, - VGAUTH_PARAM_VALIDATE_INFO_ONLY) == 0) { - // only allow it to be set once - if (validateOnly != -1) { - Warning("%s: extraParam '%s' passed multiple times\n", - __FUNCTION__, extraParams[i].name); - return VGAUTH_E_INVALID_ARGUMENT; - } - if (extraParams[i].value) { - if (g_ascii_strcasecmp(VGAUTH_PARAM_VALUE_TRUE, - extraParams[i].value) == 0) { - validateOnly = 1; - } else if (g_ascii_strcasecmp(VGAUTH_PARAM_VALUE_FALSE, - extraParams[i].value) == 0) { - validateOnly = 0; - } else { - Warning("%s: Unrecognized value '%s' for boolean param %s\n", - __FUNCTION__, extraParams[i].value, extraParams[i].name); - return VGAUTH_E_INVALID_ARGUMENT; - } - } else { - return VGAUTH_E_INVALID_ARGUMENT; - } - } + err = VGAuthGetBoolExtraParam(numExtraParams, extraParams, + VGAUTH_PARAM_VALIDATE_INFO_ONLY, + FALSE, + &validateOnly); + if (VGAUTH_E_OK != err) { + return err; } err = VGAuth_SendValidateSamlBearerTokenRequest(ctx, - (validateOnly == 1) ? - TRUE : FALSE, + validateOnly, samlToken, userName, &newHandle); - if (err != VGAUTH_E_OK) { + if (VGAUTH_E_OK != err) { goto done; } diff --git a/open-vm-tools/vgauth/lib/common.c b/open-vm-tools/vgauth/lib/common.c index fe503f56f..181b972b6 100644 --- a/open-vm-tools/vgauth/lib/common.c +++ b/open-vm-tools/vgauth/lib/common.c @@ -88,6 +88,82 @@ VGAuthValidateExtraParamsImpl(const char *funcName, } +/* + ****************************************************************************** + * VGAuthGetBoolExtraParamImpl -- */ /** + * + * Get the boolean value of the specified extra param in the params array. + * + * @param[in] funcName The name of the calling function. + * @param[in] numParams The number of elements in the params array. + * @param[in] params The params array to get param value from. + * @param[in] paramName The param name to get its value. + * @param[in] defValue The param default value if not set in the array. + * @param[out] paramValue Returned param value, TRUE or FALSE. + * + * @retval VGAUTH_E_INVALID_ARGUMENT If incomplete arguments are passed in, + * the specified extra parameter is passed + * in the array multiple times or the + * parameter value is invalid. + * @reval VGAUTH_E_OK If no error is encountered. + * + ****************************************************************************** + */ + +VGAuthError +VGAuthGetBoolExtraParamImpl(const char *funcName, + int numParams, + const VGAuthExtraParams *params, + const char *paramName, + gboolean defValue, + gboolean *paramValue) +{ + gboolean paramSet = FALSE; + int i; + + if ((numParams < 0) || (numParams > 0 && NULL == params)) { + Warning("%s: invalid number of parameters: %d.\n", funcName, numParams); + return VGAUTH_E_INVALID_ARGUMENT; + } + + if (NULL == paramName || NULL == paramValue) { + return VGAUTH_E_INVALID_ARGUMENT; + } + + *paramValue = defValue; + + for (i = 0; i < numParams; i++) { + if (g_strcmp0(params[i].name, paramName) == 0) { + // only allow it to be set once + if (paramSet) { + Warning("%s: extraParam '%s' passed multiple times.\n", + funcName, params[i].name); + return VGAUTH_E_INVALID_ARGUMENT; + } + if (params[i].value) { + if (g_ascii_strcasecmp(VGAUTH_PARAM_VALUE_TRUE, + params[i].value) == 0) { + *paramValue = TRUE; + paramSet = TRUE; + } else if (g_ascii_strcasecmp(VGAUTH_PARAM_VALUE_FALSE, + params[i].value) == 0) { + *paramValue = FALSE; + paramSet = TRUE; + } else { + Warning("%s: Unrecognized value '%s' for boolean param %s\n", + funcName, params[i].value, params[i].name); + return VGAUTH_E_INVALID_ARGUMENT; + } + } else { + return VGAUTH_E_INVALID_ARGUMENT; + } + } + } + + return VGAUTH_E_OK; +} + + /* ****************************************************************************** * VGAuth_Init -- */ /** @@ -153,6 +229,7 @@ VGAuth_Init(const char *applicationName, newCtx->applicationName = g_strdup(applicationName); newCtx->isImpersonating = FALSE; + newCtx->impersonatedUser = NULL; /* * Only init prefs, i18n and auditing once. diff --git a/open-vm-tools/vgauth/lib/impersonate.c b/open-vm-tools/vgauth/lib/impersonate.c index e07fd8c45..8d1505f80 100644 --- a/open-vm-tools/vgauth/lib/impersonate.c +++ b/open-vm-tools/vgauth/lib/impersonate.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2011-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2011-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -115,10 +115,14 @@ VGAuth_CreateHandleForUsername(VGAuthContext *ctx, #ifdef _WIN32 newHandle->token = token; + newHandle->hProfile = NULL; #endif + newHandle->refCount = 1; *handle = newHandle; + Debug("%s: Created handle %p\n", __FUNCTION__, newHandle); + return err; } @@ -292,6 +296,19 @@ VGAuth_UserHandleFree(VGAuthUserHandle *handle) return; } + ASSERT(handle->refCount > 0); + if (handle->refCount <= 0) { + Warning("%s: invalid user handle reference count %d\n", + __FUNCTION__, handle->refCount); + return; + } + + handle->refCount--; + + if (handle->refCount > 0) { + return; + } + WIN32_ONLY(CloseHandle(handle->token)); g_free(handle->userName); @@ -303,6 +320,8 @@ VGAuth_UserHandleFree(VGAuthUserHandle *handle) } g_free(handle); + + Debug("%s: Freed handle %p\n", __FUNCTION__, handle); } @@ -323,6 +342,10 @@ VGAuth_UserHandleFree(VGAuthUserHandle *handle) * before another call to VGAuth_Impersonate() is made. * * @remark Must be called by superuser. + * One @a extraParams is supported for Windows: + * VGAUTH_PARAM_LOAD_USER_PROFILE, which must have the value + * VGAUTH_PARAM_VALUE_TRUE or VGAUTH_PARAM_VALUE_FALSE. + * If set true, load user profile before impersonation. * * @param[in] ctx The VGAuthContext. * @param[in] handle The handle representing the user to be @@ -346,6 +369,7 @@ VGAuth_Impersonate(VGAuthContext *ctx, const VGAuthExtraParams *extraParams) { VGAuthError err; + gboolean loadUserProfile; if ((NULL == ctx) || (NULL == handle)) { return VGAUTH_E_INVALID_ARGUMENT; @@ -362,13 +386,25 @@ VGAuth_Impersonate(VGAuthContext *ctx, return err; } + err = VGAuthGetBoolExtraParam(numExtraParams, extraParams, + VGAUTH_PARAM_LOAD_USER_PROFILE, + FALSE, + &loadUserProfile); + if (VGAUTH_E_OK != err) { + return err; + } + if (ctx->isImpersonating) { return VGAUTH_E_ALREADY_IMPERSONATING; } - err = VGAuthImpersonateImpl(ctx, handle); + err = VGAuthImpersonateImpl(ctx, + handle, + loadUserProfile); if (VGAUTH_E_OK == err) { ctx->isImpersonating = TRUE; + handle->refCount++; + ctx->impersonatedUser = handle; } return err; @@ -409,6 +445,8 @@ VGAuth_EndImpersonation(VGAuthContext *ctx) err = VGAuthEndImpersonationImpl(ctx); if (VGAUTH_E_OK == err) { ctx->isImpersonating = FALSE; + VGAuth_UserHandleFree(ctx->impersonatedUser); + ctx->impersonatedUser = NULL; } return err; diff --git a/open-vm-tools/vgauth/lib/impersonateLinux.c b/open-vm-tools/vgauth/lib/impersonateLinux.c index 1556bd28e..240a96d5c 100644 --- a/open-vm-tools/vgauth/lib/impersonateLinux.c +++ b/open-vm-tools/vgauth/lib/impersonateLinux.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2011-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2011-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -82,8 +82,10 @@ setresgid(gid_t ruid, * however, no $SHELL startup files are run, so you cannot assume that * other environment variables have been changed. * - * @param[in] ctx The VGAuthContext. - * @param[in] handle The handle representing the user to be impersonated. + * @param[in] ctx The VGAuthContext. + * @param[in] handle The handle representing the user to be + * impersonated. + * @param[in] loadUserProfile Unused parameter. * * @return VGAUTH_E_OK on success, VGAuthError on failure * @@ -92,7 +94,8 @@ setresgid(gid_t ruid, VGAuthError VGAuthImpersonateImpl(VGAuthContext *ctx, - VGAuthUserHandle *handle) + VGAuthUserHandle *handle, + UNUSED_PARAM(gboolean loadUserProfile)) { char buffer[BUFSIZ]; struct passwd pw; diff --git a/open-vm-tools/vgauth/public/VGAuthAuthentication.h b/open-vm-tools/vgauth/public/VGAuthAuthentication.h index 97a21de33..f578c60aa 100644 --- a/open-vm-tools/vgauth/public/VGAuthAuthentication.h +++ b/open-vm-tools/vgauth/public/VGAuthAuthentication.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2011-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2011-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -194,6 +194,8 @@ VGAuthError VGAuth_ValidateSamlBearerToken(VGAuthContext *ctx, /* Impersonation APIs */ +#define VGAUTH_PARAM_LOAD_USER_PROFILE "loadUserProfile" + /* * Start impersonating the user described by VGAuthUserHandle. */