Description of problem: I can only setup domain wide access control to the Fedora Management Console (via nsAdminAccessHosts) for one domain. If I include two domains, I get "Authorization Require" errors from both domains. Version-Release number of selected component (if applicable): v1.0 Build #: 2005.342.1550 How reproducible: 100% Steps to Reproduce: This can be reproduced in one of two ways (a.)through the FMC or b.)via directly manipulating the ldap database). (For brevity I will describe scenario a.): 1. From a working Fedora Directory Server setup (in which nsAdminAccessHosts is set to *.birdstep.com) log in to the Java FCM applet. 2. Open the "Administration Server" window and select the "Tasks" tab. 3. Click "Configure Admin Server" 4. Under "Connection Restrictions" the following are currently configured: a.)"Host Names to allow": *.birdstep.com b.)"IP Addresses to allow": * 5. Add the following to "Host Names to allow": *.alicesystems.com 6. Click "Ok" to close the dialog. 7. Click "Ok" to aknowledge that the FDS must be restarted. 8. On the "Administration Server" window, click "Restart Server". Actual results: The FDS appears to restart, but the Java applet hangs because access to the Fedora Management Console is denied from everywhere now. All attempts to access the FMC via browser are blocked as well. The log entry for /opt/fedora-ds/admin-serv/logs/error states: [Thu Feb 23 10:53:44 2006] [notice] [client 10.0.12.214] admserv_host_ip_check: host [dhcp-12-214.birdstep.com] did not match pattern [(*.alicesystems.com|*.birdstep.com)] -will scan aliases Expected results: Access is allowd for all machines from .birdstep.com and .alicesystems.com domains. Additional info: In the ldiff file for the server configuration, the following entry allows access for all machines in the birdstep.com domain: nsAdminAccessHosts: *.birdstep.com but the following entry denies access for all machines, including those in the birdstep.com and alicesystems.com domain: nsAdminAccessHosts: (*.alicesystems.com|*.birdstep.com)
Yep. We use apr_fnmatch which is a really simple regex match. Can you use nsAdminAccessAddresses e.g. 10.0.12.*?
Reviewed by: Nathan (Thanks!) Files: mod_admserv.c Branch: HEAD Fix Description: The adminserver console uses a pattern like (pat1|pat2|...|patN) to encode the host and IP address access allowed lists. apr_fnmatch is not smart enough to grok this pattern, so we have to have mod_admserv pre-digest it. The strdup is because strtok modifies it's argument. apr_strdup allocates memory out of a per request pool, and automatically frees it at the end of the request, so we don't have to free it here. Platforms tested: Fedora Core 4 Flag Day: no Doc impact: no QA impact: should be covered by regular nightly and manual testing New Tests integrated into TET: none Checking in mod_admserv.c; /cvs/dirsec/mod_admserv/mod_admserv.c,v <-- mod_admserv.c new revision: 1.20; previous revision: 1.19 done *** mod_admserv.c.~1.19.~ 2006-01-17 12:25:07.000000000 -0700 --- mod_admserv.c 2006-02-23 16:40:14.000000000 -0700 *************** *** 1822,1829 **** return 1; } ! /* Check if the caller hostname or ip address is disallowed */ static int admserv_host_ip_check(request_rec *r) { --- 1822,1850 ---- return 1; } ! /* pattern is (pat1|pat2|...|patN) where patN is a simple apr_fnmatch pattern ! if we get a match, just return immediately with success, otherwise, loop ! through all the patterns and return a failure code if no match ! */ ! static apr_status_t ! admserv_match_list(char *patterns, const char *string, int flags) ! { ! apr_status_t rc = APR_SUCCESS; ! char *last = NULL; ! char *pattern = apr_strtok(patterns, "()|", &last); ! ! while (pattern) { ! rc = apr_fnmatch(pattern, string, flags); ! if (rc == APR_SUCCESS) { ! return rc; ! } ! pattern = apr_strtok(NULL, "()|", &last); ! } + return rc; + } + + /* Check if the caller hostname or ip address is disallowed */ static int admserv_host_ip_check(request_rec *r) { *************** *** 1845,1851 **** const char *maxdns = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, NULL); if (maxdns) { ! apr_status_t rc = apr_fnmatch(accessHosts, maxdns, matchflags); if (rc != APR_SUCCESS) { } else { return DECLINED; --- 1866,1872 ---- const char *maxdns = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, NULL); if (maxdns) { ! apr_status_t rc = admserv_match_list(apr_pstrdup(r->pool, accessHosts), maxdns, matchflags); if (rc != APR_SUCCESS) { } else { return DECLINED; *************** *** 1858,1870 **** char buf[PR_NETDB_BUF_SIZE]; PRHostEnt hEntry; if (PR_SUCCESS == PR_GetHostByAddr(&addr, buf, sizeof(buf), &hEntry)) { ! if (APR_SUCCESS != apr_fnmatch(accessHosts, hEntry.h_name, matchflags)) { char ** x; ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "admserv_host_ip_check: host [%s] did not match pattern [%s] -" "will scan aliases", hEntry.h_name, accessHosts); for (x = hEntry.h_aliases; x && *x; x++) { ! if (APR_SUCCESS != apr_fnmatch(accessHosts, *x, matchflags)) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "admserv_host_ip_check: host alias [%s] did not match pattern [%s]", *x, accessHosts); --- 1879,1893 ---- char buf[PR_NETDB_BUF_SIZE]; PRHostEnt hEntry; if (PR_SUCCESS == PR_GetHostByAddr(&addr, buf, sizeof(buf), &hEntry)) { ! if (APR_SUCCESS != admserv_match_list(apr_pstrdup(r->pool, accessHosts), ! hEntry.h_name, matchflags)) { char ** x; ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "admserv_host_ip_check: host [%s] did not match pattern [%s] -" "will scan aliases", hEntry.h_name, accessHosts); for (x = hEntry.h_aliases; x && *x; x++) { ! if (APR_SUCCESS != admserv_match_list(apr_pstrdup(r->pool, accessHosts), ! *x, matchflags)) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "admserv_host_ip_check: host alias [%s] did not match pattern [%s]", *x, accessHosts); *************** *** 1889,1895 **** if (accessAddresses && *accessAddresses) { int matchflags = APR_FNM_PERIOD; ! apr_status_t rc = apr_fnmatch(accessAddresses, clientIP, matchflags); if (rc == APR_SUCCESS) { } else { return DECLINED; --- 1912,1918 ---- if (accessAddresses && *accessAddresses) { int matchflags = APR_FNM_PERIOD; ! apr_status_t rc = admserv_match_list(apr_pstrdup(r->pool, accessAddresses), clientIP, matchflags); if (rc == APR_SUCCESS) { } else { return DECLINED;
Seems to work for me. Verified aginst: 1195517861 redhat-ds-base-8.0.0-11.el5dsrv Mon Nov 19 2007 1195517864 redhat-ds-admin-8.0.0-1.15.el5dsrv Mon Nov 19 2007 1195517865 redhat-ds-console-8.0.0-8.el5dsrv Mon Nov 19 2007 1195517866 redhat-admin-console-8.0.0-9.el5dsrv Mon Nov 19 2007
Created attachment 513753 [details] SS Tested based on comment#0, Hence marking as VERIFIED.