]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
VGAuth changes:
authorOliver Kurth <okurth@vmware.com>
Thu, 30 Nov 2017 23:17:27 +0000 (15:17 -0800)
committerOliver Kurth <okurth@vmware.com>
Thu, 30 Nov 2017 23:17:27 +0000 (15:17 -0800)
 - add calling LoadUserProfile()/UnloadUserProfile() in VGAuth
   impersonation/unimpersonation code paths
 - VGAuth part of code change plus tools vix plugin make file.

open-vm-tools/vgauth/lib/VGAuthInt.h
open-vm-tools/vgauth/lib/auth.c
open-vm-tools/vgauth/lib/common.c
open-vm-tools/vgauth/lib/impersonate.c
open-vm-tools/vgauth/lib/impersonateLinux.c
open-vm-tools/vgauth/public/VGAuthAuthentication.h

index 9bd6499f4ef9f8d4fe7e9a1fbade9e705999b061..564233a29c7492bf834bf5f81fb34d88c3029c73 100644 (file)
@@ -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);
index 3eede1a0337f673b996bd4b240332f4e6137e6de..e9b0485725255a65c1087a09010607d3523c067e 100644 (file)
@@ -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;
    }
 
index fe503f56f3fd948d8eb71dc72a2e3e375a2a8ee0..181b972b6e5d34ee564de91e792b425cb89ab1b0 100644 (file)
@@ -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.
index e07fd8c4569e8784e5f3ddba71a08bc6910252c4..8d1505f80c1c6486d3bb5c58b8b3b47634582c71 100644 (file)
@@ -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;
index 1556bd28eafeb795e6332d2c9232c20d5e63c091..240a96d5cf90bc5509c6144b5fc699321be48e7c 100644 (file)
@@ -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;
index 97a21de33bc6fa905b230a9ffd5f8c5c6f31c673..f578c60aa8a2b0edecf081d1c45e2c91337dcd18 100644 (file)
@@ -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.
  */