summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/r3/posix/process-posix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/r3/posix/process-posix.cpp')
-rw-r--r--src/VBox/Runtime/r3/posix/process-posix.cpp80
1 files changed, 77 insertions, 3 deletions
diff --git a/src/VBox/Runtime/r3/posix/process-posix.cpp b/src/VBox/Runtime/r3/posix/process-posix.cpp
index 19e857f98..412617bff 100644
--- a/src/VBox/Runtime/r3/posix/process-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/process-posix.cpp
@@ -1,4 +1,4 @@
-/* $Id: process-posix.cpp 29328 2010-05-11 10:14:47Z vboxsync $ */
+/* $Id: process-posix.cpp 29636 2010-05-18 13:43:55Z vboxsync $ */
/** @file
* IPRT - Process, POSIX.
*/
@@ -38,6 +38,11 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
+# include <crypt.h>
+# include <pwd.h>
+# include <shadow.h>
+#endif
#if defined(RT_OS_LINUX) || defined(RT_OS_OS2)
# define HAVE_POSIX_SPAWN 1
#endif
@@ -58,9 +63,77 @@
#include <iprt/pipe.h>
#include <iprt/socket.h>
#include <iprt/string.h>
+#include <iprt/mem.h>
#include "internal/process.h"
+/**
+ * Check the credentials and return the gid/uid of user.
+ *
+ * @param pszUser username
+ * @param pszPasswd password
+ * @param gid where to store the GID of the user
+ * @param uid where to store the UID of the user
+ * @returns IPRT status code
+ */
+static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *gid, uid_t *uid)
+{
+#if defined(RT_OS_LINUX)
+ struct passwd *pw;
+
+ pw = getpwnam(pszUser);
+ if (!pw)
+ return VERR_PERMISSION_DENIED;
+
+ if (!pszPasswd)
+ pszPasswd = "";
+
+ struct spwd *spwd;
+ /* works only if /etc/shadow is accessible */
+ spwd = getspnam(pszUser);
+ if (spwd)
+ pw->pw_passwd = spwd->sp_pwdp;
+
+ /* be reentrant */
+ struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data));
+ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data);
+ if (strcmp(pszEncPasswd, pw->pw_passwd))
+ return VERR_PERMISSION_DENIED;
+ RTMemTmpFree(data);
+
+ *gid = pw->pw_gid;
+ *uid = pw->pw_uid;
+ return VINF_SUCCESS;
+
+#elif defined(RT_OS_SOLARIS)
+ struct passwd *ppw, pw;
+ char szBuf[1024];
+
+ if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL)
+ return VERR_PERMISSION_DENIED;
+
+ if (!pszPasswd)
+ pszPasswd = "";
+
+ struct spwd spwd;
+ char szPwdBuf[1024];
+ /* works only if /etc/shadow is accessible */
+ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL)
+ ppw->pw_passwd = spwd.sp_pwdp;
+
+ char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd);
+ if (strcmp(pszEncPasswd, ppw->pw_passwd))
+ return VERR_PERMISSION_DENIED;
+
+ *gid = ppw->pw_gid;
+ *uid = ppw->pw_uid;
+ return VINF_SUCCESS;
+
+#else
+ return VERR_PERMISSION_DENIED;
+#endif
+}
+
RTR3DECL(int) RTProcCreate(const char *pszExec, const char * const *papszArgs, RTENV Env, unsigned fFlags, PRTPROCESS pProcess)
{
@@ -147,8 +220,9 @@ RTR3DECL(int) RTProcCreateEx(const char *pszExec, const char * const *papszArg
gid_t gid = ~(gid_t)0;
if (pszAsUser)
{
- AssertMsgFailed(("Implement get uid by name lookup\n"));
- return VERR_NOT_IMPLEMENTED;
+ rc = rtCheckCredentials(pszAsUser, pszPassword, &gid, &uid);
+ if (RT_FAILURE(rc))
+ return rc;
}
/*