[Spice-devel] [vdagent-win PATCH 1/6] vdagent: add as_user to run tasks with user privileges
Christophe Fergeau
cfergeau at redhat.com
Fri Nov 8 05:14:19 PST 2013
On Fri, Nov 08, 2013 at 12:02:51AM +0200, Uri Lublin wrote:
> The class calls Impersonate upon begin(), and Revert
> upon end() or destruction.
>
> The user is the current user that is logged in.
>
> create mode 100644 vdagent/as_user.cpp
> create mode 100644 vdagent/as_user.h
>
> diff --git a/Makefile.am b/Makefile.am
> index f907031..768e984 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -35,6 +35,8 @@ vdagent_SOURCES = \
> vdagent/file_xfer.cpp \
> vdagent/file_xfer.h \
> vdagent/vdagent.cpp \
> + vdagent/as_user.cpp \
> + vdagent/as_user.h \
> $(NULL)
>
> vdagent_rc.$(OBJEXT): vdagent/vdagent.rc
> diff --git a/vdagent/as_user.cpp b/vdagent/as_user.cpp
> new file mode 100644
> index 0000000..67785eb
> --- /dev/null
> +++ b/vdagent/as_user.cpp
> @@ -0,0 +1,73 @@
> +/*
> + Copyright (C) 2013 Red Hat, Inc.
> +
> + 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 <http://www.gnu.org/licenses/>.
> +*/
> +
> +#include "vdcommon.h"
> +#include "as_user.h"
> +
> +#include <wtsapi32.h>
> +
> +AsUser::AsUser(DWORD session_id):
> + _started(false),
> + _session_id(session_id),
> + _token(INVALID_HANDLE_VALUE)
> +{
> +}
> +
> +bool AsUser::begin()
> +{
> + BOOL ret;
> +
> + if (_session_id == (DWORD)-1) {
> + ret = ProcessIdToSessionId(GetCurrentProcessId(), &_session_id);
> + if (!ret) {
> + vd_printf("ProcessIdToSessionId failed %lu", GetLastError());
> + return false;
> + }
> + }
> + if (_token == INVALID_HANDLE_VALUE) {
> + ret = WTSQueryUserToken(_session_id, &_token);
> + if (!ret) {
> + vd_printf("WTSQueryUserToken failed -- %lu", GetLastError());
> + return false;
> + }
> + }
> +
> + ret = ImpersonateLoggedOnUser(_token);
> + if (!ret) {
> + vd_printf("ImpersonateLoggedOnUser failed: %lu", GetLastError());
> + return false;
> + }
> +
> + _started = true;
> + return true;
> +}
> +
> +void AsUser::end()
> +{
> + if (_started) {
> + RevertToSelf();
> + _started = false;
> + }
> +}
> +
> +AsUser::~AsUser()
> +{
> + if (_token != INVALID_HANDLE_VALUE) {
> + end();
> + CloseHandle(_token);
> + }
I'd tend to call end() unconditionally here as in the rest of the code,
it's _started which controls whether begin() was called or not, not _token
(even though I agree that there are no cases when _token is
INVALID_HANDLE_VALUE and when we need to call end()).
Looks good otherwise.
Christophe
> +}
> diff --git a/vdagent/as_user.h b/vdagent/as_user.h
> new file mode 100644
> index 0000000..6243e98
> --- /dev/null
> +++ b/vdagent/as_user.h
> @@ -0,0 +1,38 @@
> +/*
> + Copyright (C) 2013 Red Hat, Inc.
> +
> + 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 <http://www.gnu.org/licenses/>.
> +*/
> +
> +#ifndef _H_AS_USER_
> +#define _H_AS_USER_
> +
> +/** AsUser runs a task as the user logged on in session_id.
> + * Constructor calls Impersonate, Destructor calls Revert, so
> + * the caller needs not worry about that.
> + */
> +class AsUser {
> +public:
> + ~AsUser();
> + AsUser(DWORD session_id = (DWORD)-1);
> + bool begin();
> + void end();
> +
> +private:
> + DWORD _session_id;
> + HANDLE _token;
> + bool _started;
> +};
> +
> +#endif
> diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
> index 6943e5e..40e2290 100644
> --- a/vdagent/vdagent.vcproj
> +++ b/vdagent/vdagent.vcproj
> @@ -342,6 +342,10 @@
> UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
> >
> <File
> + RelativePath=".\as_user.cpp"
> + >
> + </File>
> + <File
> RelativePath=".\desktop_layout.cpp"
> >
> </File>
> @@ -372,6 +376,10 @@
> UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
> >
> <File
> + RelativePath=".\as_user.h"
> + >
> + </File>
> + <File
> RelativePath=".\desktop_layout.h"
> >
> </File>
> --
> 1.8.3.1
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20131108/ad2b2469/attachment-0001.pgp>
More information about the Spice-devel
mailing list