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;
 }