Return-Path: Delivered-To: apmail-httpd-cvs-archive@httpd.apache.org Received: (qmail 6720 invoked by uid 500); 10 Sep 2001 16:49:16 -0000 Mailing-List: contact cvs-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cvs@httpd.apache.org Received: (qmail 6697 invoked by uid 500); 10 Sep 2001 16:49:16 -0000 Delivered-To: apmail-apache-1.3-cvs@apache.org Date: 10 Sep 2001 16:45:21 -0000 Message-ID: <20010910164521.8617.qmail@icarus.apache.org> From: coar@apache.org To: apache-1.3-cvs@apache.org Subject: cvs commit: apache-1.3/src/modules/standard mod_auth.c X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N coar 01/09/10 09:45:21 Modified: src CHANGES src/modules/standard mod_auth.c Log: Add support for 'Require file-owner' and 'Require file-group'. Revision Changes Path 1.1704 +7 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1703 retrieving revision 1.1704 diff -u -u -r1.1703 -r1.1704 --- CHANGES 2001/09/07 12:46:16 1.1703 +++ CHANGES 2001/09/10 16:45:20 1.1704 @@ -1,5 +1,12 @@ Changes with Apache 1.3.21 + *) Enhancement of mod_auth to handle 'Require file-owner' and + 'Require file-group'. This allows access IFF the authenticated + username (from the appropriate AuthUserFile database) matches + the username of the UID that owns the document (and equivalent + checking for file GID and user's membership in AuthGroupFile). + See the mod_auth documentation for examples. [Ken Coar] + *) Addition of the AcceptMutex runtime directive. The accept mutex method is now runtime controllable. The suite of available methods per platform is defined at compile time (with HAVE_FOO_SERIALIZED_ACCEPT 1.52 +110 -20 apache-1.3/src/modules/standard/mod_auth.c Index: mod_auth.c =================================================================== RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_auth.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -u -r1.51 -r1.52 --- mod_auth.c 2001/01/15 17:05:36 1.51 +++ mod_auth.c 2001/09/10 16:45:21 1.52 @@ -111,7 +111,8 @@ {"AuthAuthoritative", ap_set_flag_slot, (void *) XtOffsetOf(auth_config_rec, auth_authoritative), OR_AUTHCFG, FLAG, - "Set to 'off' to allow access control to be passed along to lower modules if the UserID is not known to this module"}, + "Set to 'off' to allow access control to be passed along to " + "lower modules if the UserID is not known to this module"}, {NULL} }; @@ -247,43 +248,129 @@ /* BUG FIX: tadc, 11-Nov-1995. If there is no "requires" directive, * then any user will do. */ - if (!reqs_arr) + if (reqs_arr == NULL) { return (OK); + } reqs = (require_line *) reqs_arr->elts; - if (sec->auth_grpfile) + if (sec->auth_grpfile) { grpstatus = groups_for_user(r->pool, user, sec->auth_grpfile); - else + } + else { grpstatus = NULL; + } for (x = 0; x < reqs_arr->nelts; x++) { - if (!(reqs[x].method_mask & (1 << m))) - continue; + if (! (reqs[x].method_mask & (1 << m))) { + continue; + } method_restricted = 1; t = reqs[x].requirement; w = ap_getword_white(r->pool, &t); - if (!strcmp(w, "valid-user")) + if (strcmp(w, "valid-user") == 0) { return OK; - if (!strcmp(w, "user")) { - while (t[0]) { + } + /* + * If requested, allow access if the user is valid and the + * owner of the document. + */ + if (strcmp(w, "file-owner") == 0) { + struct passwd *pwent; + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "checking for 'owner' access for file '%s'", + r->filename); + if (r->finfo.st_ino == 0) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "no stat info for '%s'", r->filename); + continue; + } + pwent = getpwuid(r->finfo.st_uid); + if (pwent == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "no username for UID %d (owner of '%s')", + r->finfo.st_uid, r->filename); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "checking authenticated user '%s' " + "against owner '%s' of '%s'", + user, pwent->pw_name, r->filename); + if (strcmp(user, pwent->pw_name) == 0) { + return OK; + } + else { + return HTTP_UNAUTHORIZED; + } + } + } + if (strcmp(w, "file-group") == 0) { + struct group *grent; + if (sec->auth_grpfile == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, + "no AuthGroupFile, so 'file-group' " + "requirement fails for file '%s'", + r->filename); + return HTTP_UNAUTHORIZED; + } + if (grpstatus == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, + "authenticated user '%s' not a member of " + "any groups, so 'file-group' requirement " + "fails for file '%s'", + user, r->filename); + return HTTP_UNAUTHORIZED; + } + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "checking for 'group' access for file '%s'", + r->filename); + if (r->finfo.st_ino == 0) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "no stat info for '%s'", r->filename); + continue; + } + grent = getgrgid(r->finfo.st_gid); + if (grent == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "no group name for GID %d (owner of '%s')", + r->finfo.st_gid, r->filename); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r, + "checking groups of authenticated user '%s' " + "against owner group '%s' of '%s'", + user, grent->gr_name, r->filename); + if (ap_table_get(grpstatus, grent->gr_name) != NULL) { + return OK; + } + else { + return HTTP_UNAUTHORIZED; + } + } + } + if (strcmp(w, "user") == 0) { + while (t[0] != '\0') { w = ap_getword_conf(r->pool, &t); - if (!strcmp(user, w)) + if (strcmp(user, w) == 0) { return OK; + } } } - else if (!strcmp(w, "group")) { - if (!grpstatus) + else if (strcmp(w, "group") == 0) { + if (grpstatus == NULL) { return DECLINED; /* DBM group? Something else? */ + } while (t[0]) { w = ap_getword_conf(r->pool, &t); - if (ap_table_get(grpstatus, w)) + if (ap_table_get(grpstatus, w)) { return OK; + } } - } else if (sec->auth_authoritative) { + } + else if (sec->auth_authoritative) { /* if we aren't authoritative, any require directive could be * valid even if we don't grok it. However, if we are * authoritative, we can warn the user they did something wrong. @@ -291,20 +378,23 @@ * more likely is a typo in the require directive. */ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "access to %s failed, reason: unknown require directive:" - "\"%s\"", r->uri, reqs[x].requirement); + "access to %s failed, " + "reason: unknown require directive:" + "\"%s\"", r->uri, reqs[x].requirement); } } - if (!method_restricted) + if (! method_restricted) { return OK; + } - if (!(sec->auth_authoritative)) + if (! sec->auth_authoritative) { return DECLINED; + } ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "access to %s failed, reason: user %s not allowed access", - r->uri, user); + "access to %s failed, reason: user %s not allowed access", + r->uri, user); ap_note_basic_auth_failure(r); return AUTH_REQUIRED;