You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by mt...@apache.org on 2005/01/16 08:30:48 UTC
svn commit: r125349 - in apr/apr/trunk: . include include/arch/unix include/arch/win32 threadproc/beos threadproc/netware threadproc/os2 threadproc/unix threadproc/win32
Author: mturk
Date: Sat Jan 15 23:30:46 2005
New Revision: 125349
URL: http://svn.apache.org/viewcvs?view=rev&rev=125349
Log:
Added apr_procattr_user_set and apr_procattr_group_set to allow setting uid/gid for newly created processes using apr_proc_create.
Modified:
apr/apr/trunk/CHANGES
apr/apr/trunk/include/apr.h.in
apr/apr/trunk/include/apr.hnw
apr/apr/trunk/include/apr.hw
apr/apr/trunk/include/apr_thread_proc.h
apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h
apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h
apr/apr/trunk/threadproc/beos/proc.c
apr/apr/trunk/threadproc/netware/proc.c
apr/apr/trunk/threadproc/os2/proc.c
apr/apr/trunk/threadproc/unix/proc.c
apr/apr/trunk/threadproc/win32/proc.c
Modified: apr/apr/trunk/CHANGES
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/CHANGES?view=diff&rev=125349&p1=apr/apr/trunk/CHANGES&r1=125348&p2=apr/apr/trunk/CHANGES&r2=125349
==============================================================================
--- apr/apr/trunk/CHANGES (original)
+++ apr/apr/trunk/CHANGES Sat Jan 15 23:30:46 2005
@@ -1,5 +1,8 @@
Changes for APR 1.1.0
+ *) Added apr_procattr_user_set and apr_procattr_group_set
+ setting the user and group for new processes. [Mladen Turk]
+
*) Add APR Multicast functions; including support for
Source-Specific Multicast from Colm MacCarthaigh. [Paul Querna]
Modified: apr/apr/trunk/include/apr.h.in
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/apr.h.in?view=diff&rev=125349&p1=apr/apr/trunk/include/apr.h.in&r1=125348&p2=apr/apr/trunk/include/apr.h.in&r2=125349
==============================================================================
--- apr/apr/trunk/include/apr.h.in (original)
+++ apr/apr/trunk/include/apr.h.in Sat Jan 15 23:30:46 2005
@@ -227,6 +227,8 @@
#define APR_HAS_XTHREAD_FILES 0
#define APR_HAS_OS_UUID @osuuid@
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
+
/* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
* to poll on files/pipes.
*/
Modified: apr/apr/trunk/include/apr.hnw
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/apr.hnw?view=diff&rev=125349&p1=apr/apr/trunk/include/apr.hnw&r1=125348&p2=apr/apr/trunk/include/apr.hnw&r2=125349
==============================================================================
--- apr/apr/trunk/include/apr.hnw (original)
+++ apr/apr/trunk/include/apr.hnw Sat Jan 15 23:30:46 2005
@@ -194,6 +194,8 @@
#define APR_HAS_XTHREAD_FILES 0
#define APR_HAS_OS_UUID 0
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
+
/* Netware can poll on files/pipes.
*/
#define APR_FILES_AS_SOCKETS 1
Modified: apr/apr/trunk/include/apr.hw
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/apr.hw?view=diff&rev=125349&p1=apr/apr/trunk/include/apr.hw&r1=125348&p2=apr/apr/trunk/include/apr.hw&r2=125349
==============================================================================
--- apr/apr/trunk/include/apr.hw (original)
+++ apr/apr/trunk/include/apr.hw Sat Jan 15 23:30:46 2005
@@ -223,9 +223,11 @@
#ifndef _WIN32_WCE
#define APR_HAVE_STRICMP 1
#define APR_HAVE_STRNICMP 1
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 1
#else
#define APR_HAVE_STRICMP 0
#define APR_HAVE_STRNICMP 0
+#define APR_PROCATTR_USER_SET_REQUIRES_PASSWORD 0
#endif
/** @} */
Modified: apr/apr/trunk/include/apr_thread_proc.h
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/apr_thread_proc.h?view=diff&rev=125349&p1=apr/apr/trunk/include/apr_thread_proc.h&r1=125348&p2=apr/apr/trunk/include/apr_thread_proc.h&r2=125349
==============================================================================
--- apr/apr/trunk/include/apr_thread_proc.h (original)
+++ apr/apr/trunk/include/apr_thread_proc.h Sat Jan 15 23:30:46 2005
@@ -529,6 +529,27 @@
APR_DECLARE(apr_status_t) apr_procattr_addrspace_set(apr_procattr_t *attr,
apr_int32_t addrspace);
+/**
+ * Set the username used for running process
+ * @param attr The procattr we care about.
+ * @param username The username used
+ * @param password User password if needed. Password is needed on WIN32
+ * or any other platform having
+ * APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
+ */
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password);
+
+/**
+ * Set the group used for running process
+ * @param attr The procattr we care about.
+ * @param groupname The group name used
+ */
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname);
+
+
#if APR_HAS_FORK
/**
* This is currently the only non-portable call in APR. This executes
Modified: apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h?view=diff&rev=125349&p1=apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h&r1=125348&p2=apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h&r2=125349
==============================================================================
--- apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h (original)
+++ apr/apr/trunk/include/arch/unix/apr_arch_threadproc.h Sat Jan 15 23:30:46 2005
@@ -97,6 +97,8 @@
#endif
apr_child_errfn_t *errfn;
apr_int32_t errchk;
+ apr_uid_t uid;
+ apr_gid_t gid;
};
#endif /* ! THREAD_PROC_H */
Modified: apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h?view=diff&rev=125349&p1=apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h&r1=125348&p2=apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h&r2=125349
==============================================================================
--- apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h (original)
+++ apr/apr/trunk/include/arch/win32/apr_arch_threadproc.h Sat Jan 15 23:30:46 2005
@@ -56,6 +56,11 @@
apr_int32_t detached;
apr_child_errfn_t *errfn;
apr_int32_t errchk;
+#ifndef _WIN32_WCE
+ HANDLE user_token;
+ LPSECURITY_ATTRIBUTES sa;
+ LPVOID sd;
+#endif
};
struct apr_thread_once_t {
Modified: apr/apr/trunk/threadproc/beos/proc.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/threadproc/beos/proc.c?view=diff&rev=125349&p1=apr/apr/trunk/threadproc/beos/proc.c&r1=125348&p2=apr/apr/trunk/threadproc/beos/proc.c&r2=125349
==============================================================================
--- apr/apr/trunk/threadproc/beos/proc.c (original)
+++ apr/apr/trunk/threadproc/beos/proc.c Sat Jan 15 23:30:46 2005
@@ -403,3 +403,16 @@
{
return APR_ENOTIMPL;
}
+
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname)
+{
+ return APR_ENOTIMPL;
+}
Modified: apr/apr/trunk/threadproc/netware/proc.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/threadproc/netware/proc.c?view=diff&rev=125349&p1=apr/apr/trunk/threadproc/netware/proc.c&r1=125348&p2=apr/apr/trunk/threadproc/netware/proc.c&r2=125349
==============================================================================
--- apr/apr/trunk/threadproc/netware/proc.c (original)
+++ apr/apr/trunk/threadproc/netware/proc.c Sat Jan 15 23:30:46 2005
@@ -435,3 +435,15 @@
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname)
+{
+ return APR_ENOTIMPL;
+}
Modified: apr/apr/trunk/threadproc/os2/proc.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/threadproc/os2/proc.c?view=diff&rev=125349&p1=apr/apr/trunk/threadproc/os2/proc.c&r1=125348&p2=apr/apr/trunk/threadproc/os2/proc.c&r2=125349
==============================================================================
--- apr/apr/trunk/threadproc/os2/proc.c (original)
+++ apr/apr/trunk/threadproc/os2/proc.c Sat Jan 15 23:30:46 2005
@@ -601,3 +601,16 @@
{
return APR_ENOTIMPL;
}
+
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname)
+{
+ return APR_ENOTIMPL;
+}
Modified: apr/apr/trunk/threadproc/unix/proc.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/threadproc/unix/proc.c?view=diff&rev=125349&p1=apr/apr/trunk/threadproc/unix/proc.c&r1=125348&p2=apr/apr/trunk/threadproc/unix/proc.c&r2=125349
==============================================================================
--- apr/apr/trunk/threadproc/unix/proc.c (original)
+++ apr/apr/trunk/threadproc/unix/proc.c Sat Jan 15 23:30:46 2005
@@ -29,6 +29,7 @@
}
(*new)->pool = pool;
(*new)->cmdtype = APR_PROGRAM;
+ (*new)->uid = (*new)->gid = -1;
return APR_SUCCESS;
}
@@ -280,6 +281,36 @@
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password)
+{
+ apr_status_t rv;
+ apr_gid_t gid;
+
+ if ((rv = apr_uid_get(&attr->uid, &gid, username,
+ attr->pool)) != APR_SUCCESS) {
+ attr->uid = -1;
+ return rv;
+ }
+
+ /* Use default user group if not already set */
+ if (attr->gid == -1) {
+ attr->gid = gid;
+ }
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname)
+{
+ apr_status_t rv;
+
+ if ((rv = apr_gid_get(&attr->gid, groupname, attr->pool)) != APR_SUCCESS)
+ attr->gid = -1;
+ return rv;
+}
+
APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
const char *progname,
const char * const *args,
@@ -380,6 +411,27 @@
if (chdir(attr->currdir) == -1) {
if (attr->errfn) {
attr->errfn(pool, errno, "change of working directory failed");
+ }
+ exit(-1); /* We have big problems, the child should exit. */
+ }
+ }
+
+ /* Only try to switch if we are running as root */
+ if (attr->gid != -1 && !geteuid()) {
+ apr_status_t rv;
+ if ((status = setgid(attr->gid))) {
+ if (attr->errfn) {
+ attr->errfn(pool, errno, "setting of group failed");
+ }
+ exit(-1); /* We have big problems, the child should exit. */
+ }
+ }
+
+ if (attr->uid != -1 && !geteuid()) {
+ apr_status_t rv;
+ if ((status = setuid(attr->uid))) {
+ if (attr->errfn) {
+ attr->errfn(pool, errno, "setting of user failed");
}
exit(-1); /* We have big problems, the child should exit. */
}
Modified: apr/apr/trunk/threadproc/win32/proc.c
Url: http://svn.apache.org/viewcvs/apr/apr/trunk/threadproc/win32/proc.c?view=diff&rev=125349&p1=apr/apr/trunk/threadproc/win32/proc.c&r1=125348&p2=apr/apr/trunk/threadproc/win32/proc.c&r2=125349
==============================================================================
--- apr/apr/trunk/threadproc/win32/proc.c (original)
+++ apr/apr/trunk/threadproc/win32/proc.c Sat Jan 15 23:30:46 2005
@@ -200,6 +200,116 @@
return APR_SUCCESS;
}
+static apr_status_t attr_cleanup(void *theattr)
+{
+ apr_procattr_t *attr = (apr_procattr_t *)theattr;
+ if (attr->user_token)
+ CloseHandle(attr->user_token);
+ attr->user_token = NULL;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr,
+ const char *username,
+ const char *password)
+{
+#ifdef _WIN32_WCE
+ return APR_ENOTIMPL;
+#else
+ HANDLE user;
+ apr_wchar_t *wusername = NULL;
+ apr_wchar_t *wpassword = NULL;
+ apr_status_t rv;
+ apr_size_t len, wlen;
+
+ if (apr_os_level >= APR_WIN_NT_4)
+ {
+ if (attr->user_token) {
+ /* Cannot set that twice */
+ if (attr->errfn) {
+ attr->errfn(attr->pool, 0,
+ apr_pstrcat(attr->pool,
+ "function called twice"
+ " on username: ", username, NULL));
+ }
+ return APR_EINVAL;
+ }
+ len = strlen(username) + 1;
+ wlen = len;
+ wusername = apr_palloc(attr->pool, wlen * sizeof(apr_wchar_t));
+ if ((rv = apr_conv_utf8_to_ucs2(username, &len, wusername, &wlen))
+ != APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(attr->pool, rv,
+ apr_pstrcat(attr->pool,
+ "utf8 to ucs2 conversion failed"
+ " on username: ", username, NULL));
+ }
+ return rv;
+ }
+ len = strlen(password) + 1;
+ wlen = len;
+ wpassword = apr_palloc(attr->pool, wlen * sizeof(apr_wchar_t));
+ if ((rv = apr_conv_utf8_to_ucs2(password, &len, wpassword, &wlen))
+ != APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(attr->pool, rv,
+ apr_pstrcat(attr->pool,
+ "utf8 to ucs2 conversion failed"
+ " on password: ", password, NULL));
+ }
+ return rv;
+ }
+ if (!LogonUserW(wusername,
+ NULL,
+ wpassword,
+ LOGON32_LOGON_NETWORK,
+ LOGON32_PROVIDER_DEFAULT,
+ &user)) {
+ /* Logon Failed */
+ return apr_get_os_error();
+ }
+ memset(wpassword, 0, wlen * sizeof(apr_wchar_t));
+ /* Get the primary token for user */
+ if (!DuplicateTokenEx(user,
+ TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY,
+ NULL,
+ SecurityImpersonation,
+ TokenPrimary,
+ &(attr->user_token))) {
+ /* Failed to duplicate the user token */
+ rv = apr_get_os_error();
+ CloseHandle(user);
+ return rv;
+ }
+ CloseHandle(user);
+
+ attr->sd = apr_pcalloc(attr->pool, SECURITY_DESCRIPTOR_MIN_LENGTH);
+ InitializeSecurityDescriptor(attr->sd, SECURITY_DESCRIPTOR_REVISION);
+ SetSecurityDescriptorDacl(attr->sd, -1, 0, 0);
+ attr->sa = apr_palloc(attr->pool, sizeof(SECURITY_ATTRIBUTES));
+ attr->sa->nLength = sizeof (SECURITY_ATTRIBUTES);
+ attr->sa->lpSecurityDescriptor = attr->sd;
+ attr->sa->bInheritHandle = TRUE;
+
+ /* register the cleanup */
+ apr_pool_cleanup_register(attr->pool, (void *)attr,
+ attr_cleanup,
+ apr_pool_cleanup_null);
+ return APR_SUCCESS;
+ }
+ else
+ return APR_ENOTIMPL;
+#endif
+}
+
+APR_DECLARE(apr_status_t) apr_procattr_group_set(apr_procattr_t *attr,
+ const char *groupname)
+{
+ /* Always return SUCCESS cause groups are irrelevant */
+ return APR_SUCCESS;
+}
+
static const char* has_space(const char *str)
{
const char *ch;
@@ -614,13 +724,36 @@
? attr->child_err->filehand
: INVALID_HANDLE_VALUE;
}
- rv = CreateProcessW(wprg, wcmd, /* Executable & Command line */
- NULL, NULL, /* Proc & thread security attributes */
- TRUE, /* Inherit handles */
- dwCreationFlags, /* Creation flags */
- pEnvBlock, /* Environment block */
- wcwd, /* Current directory name */
- &si, &pi);
+ if (attr->user_token) {
+ si.lpDesktop = L"Winsta0\\Default";
+ if (!ImpersonateLoggedOnUser(attr->user_token)) {
+ /* failed to impersonate the logged user */
+ rv = apr_get_os_error();
+ CloseHandle(attr->user_token);
+ attr->user_token = NULL;
+ return rv;
+ }
+ rv = CreateProcessAsUserW(attr->user_token,
+ wprg, wcmd,
+ attr->sa,
+ NULL,
+ TRUE,
+ dwCreationFlags,
+ pEnvBlock,
+ wcwd,
+ &si, &pi);
+
+ RevertToSelf();
+ }
+ else {
+ rv = CreateProcessW(wprg, wcmd, /* Executable & Command line */
+ NULL, NULL, /* Proc & thread security attributes */
+ TRUE, /* Inherit handles */
+ dwCreationFlags, /* Creation flags */
+ pEnvBlock, /* Environment block */
+ wcwd, /* Current directory name */
+ &si, &pi);
+ }
#else
rv = CreateProcessW(wprg, wcmd, /* Executable & Command line */
NULL, NULL, /* Proc & thread security attributes */
@@ -753,4 +886,9 @@
return APR_CHILD_NOTDONE;
}
return apr_get_os_error();
+}
+
+APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize)
+{
+ return APR_ENOTIMPL;
}