View | Details | Raw Unified | Return to bug 51079
Collapse All | Expand All

(-)httpd-2.2.17_orig/modules/generators/fcgid_conf.c (+56 lines)
Lines 60-65 Link Here
60
#define DEFAULT_WRAPPER_KEY "ALL"
60
#define DEFAULT_WRAPPER_KEY "ALL"
61
#define WRAPPER_FLAG_VIRTUAL "virtual"
61
#define WRAPPER_FLAG_VIRTUAL "virtual"
62
62
63
#define DEFAULT_IMPERSONATION_FLAG_OFF 0
63
void *create_fcgid_server_config(apr_pool_t * p, server_rec * s)
64
void *create_fcgid_server_config(apr_pool_t * p, server_rec * s)
64
{
65
{
65
    fcgid_server_conf *config = apr_pcalloc(p, sizeof(*config));
66
    fcgid_server_conf *config = apr_pcalloc(p, sizeof(*config));
Lines 85-90 Link Here
85
        config->termination_score = DEFAULT_TERMINATION_SCORE;
86
        config->termination_score = DEFAULT_TERMINATION_SCORE;
86
        config->time_score = DEFAULT_TIME_SCORE;
87
        config->time_score = DEFAULT_TIME_SCORE;
87
        config->zombie_scan_interval = DEFAULT_ZOMBIE_SCAN_INTERVAL;
88
        config->zombie_scan_interval = DEFAULT_ZOMBIE_SCAN_INTERVAL;
89
90
        config->bImpersonation = DEFAULT_IMPERSONATION_FLAG_OFF;
91
        config->pszImpersonationCredentialProviderPath = NULL;
92
93
#ifdef WIN32
94
        config->hJobObjectForAutoCleanup = NULL;
95
#endif /*WIN32*/
88
    }
96
    }
89
    /* Redundant; pcalloc creates this structure;
97
    /* Redundant; pcalloc creates this structure;
90
     * config->default_init_env = NULL;
98
     * config->default_init_env = NULL;
Lines 749-754 Link Here
749
    return NULL;
757
    return NULL;
750
}
758
}
751
759
760
/* FcgidImpersonation   <On|Off>
761
 *                      
762
 *              On  ->  Impersonation is set to On, 
763
 *                      Requires FcgidImpersonationCredentialProvider
764
 *              Off ->  Default setting. Impersonation is set to off.
765
 *                      
766
 */
767
const char *set_impersonation(cmd_parms * cmd,
768
                              void *dummy, int arg)
769
{
770
    server_rec *s = cmd->server;
771
    fcgid_server_conf *config =
772
        ap_get_module_config(s->module_config, &fcgid_module);
773
774
    config->bImpersonation = arg;
775
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL,
776
                 "INFO: Fcgid Impersonation flag: %d ",
777
                 arg);
778
779
    return NULL;
780
}
781
782
/* FcgidImpersonationCredentialProvider  <module path> <entry point/function>
783
 *                      
784
 *    <module path>  -> DLL path that provides Username and password for 
785
 *                      impersonation. Can be absolute or relative path.
786
 *    <entry point>  -> Function name that provides Username and password.
787
 *                      
788
 */    
789
const char *set_impersonation_provider_info(cmd_parms * cmd, void *dummmy,
790
                                            const char *arg1, const char *arg2)
791
{
792
    server_rec *s = cmd->server;
793
    fcgid_server_conf *config =
794
        ap_get_module_config(s->module_config, &fcgid_module);
795
796
    if ((strlen(arg1)) > 0 && (strlen(arg2) > 0)){
797
        
798
        config->pszImpersonationCredentialProviderPath = ap_server_root_relative(s->process->pool, arg1);
799
        config->pszImpersonatorFunctionName = apr_pstrdup(s->process->pool, arg2);     
800
    }
801
    
802
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL,
803
        "mod_fcgid: ImpersonationHelper module %s, %s()", config->pszImpersonationCredentialProviderPath, arg2);
804
805
    return NULL; 
806
}
807
752
fcgid_cmd_conf *get_access_info(request_rec * r, int *authoritative)
808
fcgid_cmd_conf *get_access_info(request_rec * r, int *authoritative)
753
{
809
{
754
    fcgid_dir_conf *config =
810
    fcgid_dir_conf *config =
(-)httpd-2.2.17_orig/modules/generators/fcgid_conf.h (+4 lines)
Lines 71-76 Link Here
71
    int termination_score;
71
    int termination_score;
72
    int time_score;
72
    int time_score;
73
    int zombie_scan_interval;
73
    int zombie_scan_interval;
74
    /* FcgiImpersonation* - CGI process impersonation */
75
    BOOL bImpersonation;
76
    char *pszImpersonationCredentialProviderPath;
77
    char *pszImpersonatorFunctionName;
74
    /* global or vhost
78
    /* global or vhost
75
     * scalar values have corresponding _set field to aid merging
79
     * scalar values have corresponding _set field to aid merging
76
     */
80
     */
(-)httpd-2.2.17_orig/modules/generators/fcgid_pm.h (+24 lines)
Lines 57-60 Link Here
57
apr_status_t procmgr_stop_procmgr(void *dummy);
57
apr_status_t procmgr_stop_procmgr(void *dummy);
58
int procmgr_must_exit(void);
58
int procmgr_must_exit(void);
59
59
60
/* For Win32 process impersonation */
61
#ifdef _WIN32
62
63
/* Holds the Custom DLL handle that is responsible for providing Username 
64
 * and password details to mod_fcgid.so
65
 */
66
extern HMODULE g_hImpersonationCredentialProviderDLL;
67
68
/* Function signature that Impersonation Helper module/DLL should export in 
69
 * order to provide Username and password details for security token 
70
 * impersonation
71
 */
72
typedef apr_uint32_t (FAR WINAPI *PFNGETUSERCREDENTIALS)(
73
                                    IN OUT apr_byte_t* pUtf8UserNameBuffer,
74
                                    IN OUT apr_uint32_t* pdwUserNameBufferLen,
75
                                    IN OUT apr_byte_t* pUtf8PasswordBuffer,
76
                                    IN OUT apr_uint32_t* pdwPasswordBufferLen);            
77
78
/* Function pointer to export present in Custom DLL which provides Username 
79
 * and password
80
 */
81
extern PFNGETUSERCREDENTIALS g_pfnGetUserCredentials;
82
#endif /*_WIN32*/
83
60
#endif
84
#endif
(-)httpd-2.2.17_orig/modules/generators/fcgid_pm_win.c (+38 lines)
Lines 32-37 Link Here
32
static int g_must_exit = 0;
32
static int g_must_exit = 0;
33
static int g_wakeup_timeout = 0;
33
static int g_wakeup_timeout = 0;
34
34
35
/* For cgi process impersonation */
36
HMODULE g_hImpersonationCredentialProviderDLL = NULL;
37
PFNGETUSERCREDENTIALS g_pfnGetUserCredentials = NULL;
38
35
static void *APR_THREAD_FUNC wakeup_thread(apr_thread_t * thd, void *data)
39
static void *APR_THREAD_FUNC wakeup_thread(apr_thread_t * thd, void *data)
36
{
40
{
37
    while (!g_must_exit) {
41
    while (!g_must_exit) {
Lines 124-129 Link Here
124
        exit(1);
128
        exit(1);
125
    }
129
    }
126
130
131
132
    /* Initialize ImpersonationHelper module refereces*/
133
     if (sconf->bImpersonation == TRUE && 
134
         g_hImpersonationCredentialProviderDLL == NULL){
135
136
         g_hImpersonationCredentialProviderDLL = LoadLibrary(sconf->pszImpersonationCredentialProviderPath);
137
138
         if (g_hImpersonationCredentialProviderDLL == NULL){
139
             rv = apr_get_os_error();
140
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
141
                 "mod_fcgid: can't load ImpersonationCredentialProviderDLL %s", sconf->pszImpersonationCredentialProviderPath);
142
             return rv;
143
         }
144
145
         g_pfnGetUserCredentials 
146
             = (PFNGETUSERCREDENTIALS) GetProcAddress(
147
                                        g_hImpersonationCredentialProviderDLL,
148
                                        sconf->pszImpersonatorFunctionName);
149
         if (g_pfnGetUserCredentials == NULL){
150
             rv = apr_get_os_error();
151
             ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_server,
152
                 "mod_fcgid: can't load ImpersonationCredentialProviderDLL function %s", sconf->pszImpersonatorFunctionName);
153
             return rv;
154
         }
155
     }
156
127
    return APR_SUCCESS;
157
    return APR_SUCCESS;
128
}
158
}
129
159
Lines 279-284 Link Here
279
        }
309
        }
280
    }
310
    }
281
311
312
    /* Release the impersonation's credential provider helper DLL */
313
    if (g_hImpersonationCredentialProviderDLL != NULL) {
314
        FreeLibrary(g_hImpersonationCredentialProviderDLL);
315
316
        g_hImpersonationCredentialProviderDLL = NULL;
317
        g_pfnGetUserCredentials = NULL;
318
    }
319
282
    if (g_wakeup_thread)
320
    if (g_wakeup_thread)
283
        return apr_thread_join(&status, g_wakeup_thread);
321
        return apr_thread_join(&status, g_wakeup_thread);
284
322
(-)httpd-2.2.17_orig/modules/generators/fcgid_proc_win.c (+101 lines)
Lines 50-55 Link Here
50
50
51
static int g_process_counter = 0;
51
static int g_process_counter = 0;
52
52
53
extern PFNGETUSERCREDENTIALS g_pfnGetUserCredentials;
54
53
static apr_status_t close_finish_event(void *finishevent)
55
static apr_status_t close_finish_event(void *finishevent)
54
{
56
{
55
    HANDLE *finish_event = finishevent;
57
    HANDLE *finish_event = finishevent;
Lines 58-63 Link Here
58
    return APR_SUCCESS;
60
    return APR_SUCCESS;
59
}
61
}
60
62
63
/* CGI process impersonation routine
64
 */
65
apr_status_t proc_impersonate(fcgid_proc_info *procinfo, apr_procattr_t *proc_attr)
66
{
67
#define BUFFERLEN 1024
68
    char szUsername[BUFFERLEN] = {0};    
69
    char szPassword[BUFFERLEN] = {0};
70
    int  nUsernameLen = BUFFERLEN;
71
    int nPasswordLen = BUFFERLEN;    
72
73
    apr_status_t rv = APR_BADARG;
74
    apr_uint32_t dwError = 0;
75
    apr_uint32_t dwTimer = GetTickCount();
76
77
    fcgid_server_conf *sconf = ap_get_module_config(procinfo->main_server->
78
                                                module_config, &fcgid_module);      
79
80
    if (sconf == NULL){
81
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
82
                     "mod_fcgid: fcgi server configuration info unavailable");
83
        return rv;
84
    } 
85
86
    if (sconf->bImpersonation == FALSE){
87
        return APR_SUCCESS;
88
    }
89
90
    ap_log_error(APLOG_MARK, /*APLOG_DEBUG*/APLOG_INFO, 0, procinfo->main_server, 
91
                 "mod_fcgid: Starting Impersonation started");
92
93
    if (proc_attr == NULL){
94
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
95
                     "mod_fcgid: process attribute info unavailable");
96
        return rv;
97
    }
98
99
    if (g_hImpersonationCredentialProviderDLL == NULL){
100
        rv = APR_FROM_OS_ERROR(ERROR_DLL_NOT_FOUND);
101
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
102
                     "mod_fcgid: Credential provider module unavailable");
103
        return rv;
104
    }
105
106
    if (g_pfnGetUserCredentials == NULL){
107
        rv = APR_FROM_OS_ERROR(ERROR_BAD_DLL_ENTRYPOINT);        
108
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
109
                     "mod_fcgid: Credential provider module entry point unavailable");
110
        return rv;
111
    }   
112
113
    
114
    /* Get credentials, note that we expect credential caching to be done by 
115
     * the provider DLL for security reasons
116
     */
117
    dwError = g_pfnGetUserCredentials(szUsername, &nUsernameLen, 
118
                                      szPassword, &nPasswordLen);
119
    if (dwError != ERROR_SUCCESS){          
120
        rv = APR_FROM_OS_ERROR(dwError);
121
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, procinfo->main_server,
122
                     "mod_fcgid: error retreiving credientials from "
123
                     "ImpersonationCredentialProviderDLL %s function %s",
124
                     sconf->pszImpersonationCredentialProviderPath, 
125
                     sconf->pszImpersonatorFunctionName);
126
        return rv;
127
    }    
128
    szUsername[nUsernameLen] = 0;
129
    szPassword[nPasswordLen] = 0;
130
    
131
132
    /* In order for CGI process to access remote DB in Win Authentication 
133
     * mode we raise the impersonation to Delegation level
134
     */
135
    apr_procattr_impersonation_level_set(proc_attr, SecurityDelegation);
136
137
    /* Request imperonsation with delegation rights
138
     */
139
    rv =  apr_procattr_user_set(proc_attr, szUsername, szPassword);    
140
    if (rv != APR_SUCCESS){
141
        ap_log_error(APLOG_MARK, APLOG_WARNING, rv, procinfo->main_server, 
142
                  "mod_fcgid: Impersonation failed for user: %s password: %s",
143
                  szUsername, "*******" /*szPassword*/);		
144
        return rv;
145
    }
146
147
    /* Wipe out the username and password details from memory to avoid exposing 
148
     * the same from VM images, crash dumps, etc.
149
     */
150
    SecureZeroMemory(szUsername, sizeof(szUsername));
151
    SecureZeroMemory(szPassword, sizeof(szPassword));
152
153
    ap_log_error(APLOG_MARK, /*APLOG_DEBUG*/ APLOG_INFO, 0, procinfo->main_server,
154
        "mod_fcgid: Impersonation took %u ms", GetTickCount() - dwTimer);
155
156
    return rv;
157
}
61
apr_status_t proc_spawn_process(const char *cmdline, fcgid_proc_info *procinfo,
158
apr_status_t proc_spawn_process(const char *cmdline, fcgid_proc_info *procinfo,
62
                                fcgid_procnode *procnode)
159
                                fcgid_procnode *procnode)
63
{
160
{
Lines 166-171 Link Here
166
        return APR_ENOPROC;
263
        return APR_ENOPROC;
167
    }
264
    }
168
265
266
267
    /* LTAC - FcgidImpersonation feature*/
268
    rv = proc_impersonate(procinfo, proc_attr);                
269
    
169
    /* fork and exec now */
270
    /* fork and exec now */
170
    rv = apr_proc_create(&(procnode->proc_id), wargv[0], wargv,
271
    rv = apr_proc_create(&(procnode->proc_id), wargv[0], wargv,
171
                         proc_environ, proc_attr, procnode->proc_pool);
272
                         proc_environ, proc_attr, procnode->proc_pool);
(-)httpd-2.2.17_orig/modules/generators/mod_fcgid.c (+11 lines)
Lines 802-807 Link Here
802
    return APR_SUCCESS;
802
    return APR_SUCCESS;
803
}
803
}
804
804
805
const char *set_impersonation(cmd_parms * cmd,
806
                              void *config, int arg);
807
const char *set_impersonation_provider_info(cmd_parms * cmd, void *dummmy,
808
                                         const char *name, const char *value);
809
805
static const command_rec fcgid_cmds[] = {
810
static const command_rec fcgid_cmds[] = {
806
    AP_INIT_TAKE1("FcgidAccessChecker", set_access_info, NULL,
811
    AP_INIT_TAKE1("FcgidAccessChecker", set_access_info, NULL,
807
                  ACCESS_CONF | OR_FILEINFO,
812
                  ACCESS_CONF | OR_FILEINFO,
Lines 895-900 Link Here
895
    AP_INIT_TAKE1("FcgidZombieScanInterval", set_zombie_scan_interval, NULL,
900
    AP_INIT_TAKE1("FcgidZombieScanInterval", set_zombie_scan_interval, NULL,
896
                  RSRC_CONF,
901
                  RSRC_CONF,
897
                  "scan interval for zombie process"),
902
                  "scan interval for zombie process"),
903
    AP_INIT_FLAG("FcgidImpersonation", set_impersonation, NULL, RSRC_CONF, 
904
                 "Set to on if CGI process should be impersonated as another user"),
905
    /* Currently we support only Windows DLLs as Credential provider */
906
    AP_INIT_TAKE12("FcgidImpersonationCredentialProvider",
907
                  set_impersonation_provider_info, NULL, RSRC_CONF, 
908
                  "Module path and function name that provides DB user credentials for CGI process impersonation"),
898
909
899
    /* The following directives are all deprecated in favor
910
    /* The following directives are all deprecated in favor
900
     * of a consistent use of the Fcgid prefix.
911
     * of a consistent use of the Fcgid prefix.
(-)httpd-2.2.17_orig/srclib/apr/include/apr_thread_proc.h (+13 lines)
Lines 568-573 Link Here
568
                                                const char *username,
568
                                                const char *username,
569
                                                const char *password);
569
                                                const char *password);
570
570
571
572
#if defined(_WIN32) || defined(DOXYGEN)
573
/**
574
 * Set the running process security impersonation/delegation level  
575
 * @param attr The procattr we care about
576
 * @param si   The security impersonation level the current process
577
 *             should get. 
578
 */
579
APR_DECLARE(apr_status_t) 
580
apr_procattr_impersonation_level_set(apr_procattr_t *attr,
581
                                     SECURITY_IMPERSONATION_LEVEL si);
582
#endif /*_WIN32*/
583
571
/**
584
/**
572
 * Set the group used for running process
585
 * Set the group used for running process
573
 * @param attr The procattr we care about. 
586
 * @param attr The procattr we care about. 
(-)httpd-2.2.17_orig/srclib/apr/include/arch/win32/apr_arch_threadproc.h (+7 lines)
Lines 61-66 Link Here
61
    HANDLE     user_token;
61
    HANDLE     user_token;
62
    LPSECURITY_ATTRIBUTES   sa;
62
    LPSECURITY_ATTRIBUTES   sa;
63
    LPVOID                  sd;
63
    LPVOID                  sd;
64
65
/* LTAC: Contains impersonation level required for impersonating current process 
66
 */
67
    struct _apr_impersonation {
68
        apr_byte_t                      bIsSet;
69
        SECURITY_IMPERSONATION_LEVEL    si;
70
    } impersonationLevel;
64
#endif
71
#endif
65
};
72
};
66
73
(-)httpd-2.2.17_orig/srclib/apr/threadproc/win32/proc.c (-3 / +29 lines)
Lines 237-242 Link Here
237
}
237
}
238
#endif
238
#endif
239
239
240
APR_DECLARE(apr_status_t) 
241
apr_procattr_impersonation_level_set(apr_procattr_t *attr,
242
                                     SECURITY_IMPERSONATION_LEVEL si)
243
{
244
    if (attr == NULL){
245
        return APR_BADARG;
246
    }
247
248
    attr->impersonationLevel.bIsSet = TRUE;
249
    attr->impersonationLevel.si = si;
250
251
    return APR_SUCCESS;
252
}
253
240
APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr, 
254
APR_DECLARE(apr_status_t) apr_procattr_user_set(apr_procattr_t *attr, 
241
                                                const char *username,
255
                                                const char *username,
242
                                                const char *password)
256
                                                const char *password)
Lines 290-299 Link Here
290
                return rv;
304
                return rv;
291
            }
305
            }
292
        }
306
        }
307
        /* LTAC: For apr_procattr_user_set() API backward compatibility.
308
         * Modules called apr_procattr_user_set() assuming impersonation level 
309
         * is set to 'SecurityImpersonation'. Therefore we still maintain this
310
         * assumption if Impersonation level is not set explicitly by the new 
311
         * apr_procattr_impersonation_level_set() API.
312
         */
313
        if (!attr->impersonationLevel.bIsSet) 
314
        {
315
            apr_procattr_impersonation_level_set(attr, SecurityImpersonation);
316
        }
293
        if (!LogonUserW(wusername, 
317
        if (!LogonUserW(wusername, 
294
                        NULL, 
318
                        NULL, 
295
                        wpassword ? wpassword : L"",
319
                        wpassword ? wpassword : L"",
296
                        LOGON32_LOGON_NETWORK,
320
                        attr->impersonationLevel.si == SecurityDelegation ?
321
                        LOGON32_LOGON_NETWORK_CLEARTEXT :LOGON32_LOGON_NETWORK,
297
                        LOGON32_PROVIDER_DEFAULT,
322
                        LOGON32_PROVIDER_DEFAULT,
298
                        &user)) {
323
                        &user)) {
299
            /* Logon Failed */            
324
            /* Logon Failed */            
Lines 305-311 Link Here
305
        if (!DuplicateTokenEx(user, 
330
        if (!DuplicateTokenEx(user, 
306
                              TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, 
331
                              TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, 
307
                              NULL,
332
                              NULL,
308
                              SecurityImpersonation,
333
                              attr->impersonationLevel.si,
309
                              TokenPrimary,
334
                              TokenPrimary,
310
                              &(attr->user_token))) {
335
                              &(attr->user_token))) {
311
            /* Failed to duplicate the user token */
336
            /* Failed to duplicate the user token */
Lines 321-327 Link Here
321
        attr->sa = apr_palloc(attr->pool, sizeof(SECURITY_ATTRIBUTES));
346
        attr->sa = apr_palloc(attr->pool, sizeof(SECURITY_ATTRIBUTES));
322
        attr->sa->nLength = sizeof (SECURITY_ATTRIBUTES);
347
        attr->sa->nLength = sizeof (SECURITY_ATTRIBUTES);
323
        attr->sa->lpSecurityDescriptor = attr->sd;
348
        attr->sa->lpSecurityDescriptor = attr->sd;
324
        attr->sa->bInheritHandle = FALSE;
349
        attr->sa->bInheritHandle = 
350
            (attr->impersonationLevel.si == SecurityDelegation) ? TRUE : FALSE;
325
351
326
        /* register the cleanup */
352
        /* register the cleanup */
327
        apr_pool_cleanup_register(attr->pool, (void *)attr,
353
        apr_pool_cleanup_register(attr->pool, (void *)attr,

Return to bug 51079