Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
cjsmeele committed Aug 15, 2017
2 parents 2cbe52a + 7472f6c commit fea08d8
Show file tree
Hide file tree
Showing 12 changed files with 445 additions and 84 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project(davrods C)

set(IRODS_VERSION "4.2.1" CACHE STRING "iRODS client library version")

set(DAVRODS_VERSION "${IRODS_VERSION}_1.1.1")
set(DAVRODS_VERSION "${IRODS_VERSION}_1.2.0")

find_program(APXS apxs DOC "Apache/HTTPD extension tool location")
if(NOT APXS)
Expand Down Expand Up @@ -88,6 +88,7 @@ if(INSTALLABLE_ON_THIS_SYSTEM)
RENAME 10-davrods.conf)

install(FILES davrods-vhost.conf
davrods-anonymous-vhost.conf
DESTINATION /etc/httpd/conf.d/)

install(FILES irods_environment.json
Expand Down Expand Up @@ -132,6 +133,7 @@ if(INSTALLABLE_ON_THIS_SYSTEM)
"%doc /usr/share/doc/davrods-${DAVRODS_VERSION}/COPYING.LESSER"
"%config(noreplace) /etc/httpd/conf.modules.d/10-davrods.conf"
"%config(noreplace) /etc/httpd/conf.d/davrods-vhost.conf"
"%config(noreplace) /etc/httpd/conf.d/davrods-anonymous-vhost.conf"
"%config(noreplace) /etc/httpd/irods/irods_environment.json"
"%attr(700,apache,apache) /var/lib/davrods")

Expand Down
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ Notable features include:
- Supports PAM and Native (a.k.a. STANDARD) iRODS authentication.
- Supports SSL encryption for the entire iRODS connection.
- Easy to configure using Apache configuration directives.
- Supports an anonymous access mode for password-less public access.
- Supports iRODS server versions 4+ and is backwards compatible with 3.3.1.

## Download ##

There are currently two supported Davrods versions:

- [`davrods-4.1_1.1.1`](https://github.com/UtrechtUniversity/davrods/releases/tag/4.1_1.1.1), branch `irods-4.1-libs`
- [`davrods-4.2.1_1.1.1`](https://github.com/UtrechtUniversity/davrods/releases/tag/4.2.1_1.1.1), branch `master`
- [`davrods-4.2.1_1.2.0`](https://github.com/UtrechtUniversity/davrods/releases/tag/4.2.1_1.2.0), branch `master`

The left side of the version number indicates the version of the iRODS
client libraries that Davrods uses.
Expand Down Expand Up @@ -81,11 +82,25 @@ icommands.

### HTTPD vhost configuration ###

The Davrods RPM distribution installs a commented out vhost template
in `/etc/httpd/conf.d/davrods-vhost.conf`. With the comment marks
(`#`) removed, this provides you with a sane default configuration
that you can tune to your needs. All Davrods configuration options are
documented in this file and can be changed to your liking.
The Davrods RPM distribution installs two vhost template files:

1. `/etc/httpd/conf.d/davrods-vhost.conf`
2. `/etc/httpd/conf.d/davrods-anonymous-vhost.conf`

These files are provided completely commented out. To enable either
configuration, simply remove the first column of `#` signs, and then
tune the settings to your needs.

The normal vhost configuration (1) provides sane defaults for
authenticated access.

The anonymous vhost configuration (2) allows password-less public
access using the `anonymous` iRODS account.

You can enable both configurations simultaneously, as long as their
ServerName values are unique (for example, you might use
`dav.example.com` for authenticated access and
`public.dav.example.com` for anonymous access).

### The iRODS environment file ###

Expand Down Expand Up @@ -180,7 +195,8 @@ For this reason you will need to install the files manually:

- Copy `mod_davrods.so` to your Apache module directory.
- Copy `davrods.conf` to your Apache module configuration/load directory.
- Copy `davrods-vhost.conf` to your Apache vhost configuration directory.
- Copy `davrods-vhost.conf` and `davrods-anonymous-vhost.conf` to your
Apache vhost configuration directory.
- Create an `irods` directory in a location where Apache HTTPD has read
access.
- Copy `irods_environment.json` to the `irods` directory.
Expand Down
23 changes: 15 additions & 8 deletions auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ static int do_rods_login_pam(

/**
* \brief Connect to iRODS and attempt to login.
*
* \param[in] r request record
* \param[in] username
* \param[in] password
* \param[out] rods_conn will be filled with the new iRODS connection, if auth is succesful.
*
* \return An authn status code, AUTH_GRANTED if succesful.
*/
static authn_status rods_login(
request_rec *r,
Expand Down Expand Up @@ -151,19 +158,19 @@ static authn_status rods_login(

// Whether to use SSL for the entire connection.
// Note: SSL is always in effect during PAM auth, regardless of negotiation results.
bool useSsl = false;
bool use_ssl = false;

if ((*rods_conn)->negotiation_results
&& !strcmp((*rods_conn)->negotiation_results, "CS_NEG_USE_SSL")) {
useSsl = true;
use_ssl = true;
} else {
// Negotiation was disabled or resulted in CS_NEG_USE_TCP (i.e. no SSL).
}

ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
"SSL negotiation result: <%s>: %s",
(*rods_conn)->negotiation_results,
useSsl
use_ssl
? "will use SSL for the entire connection"
: "will NOT use SSL (if using PAM, SSL will only be used during auth)"
);
Expand All @@ -173,7 +180,7 @@ static authn_status rods_login(
" (ignore ssl_on, it seems 4.x does not update it after SSL is turned on automatically during rcConnect)",
(*rods_conn)->ssl?1:0, (*rods_conn)->ssl_on);

if (useSsl) {
if (use_ssl) {
// Verify that SSL is in effect in compliance with the
// negotiation result, to prevent any unencrypted
// information (password or data) to be sent in the clear.
Expand All @@ -190,7 +197,7 @@ static authn_status rods_login(
// If the negotiation result requires plain TCP, but we are
// using the PAM auth scheme, we need to turn on SSL during
// auth.
if (!useSsl && conf->rods_auth_scheme == DAVRODS_AUTH_PAM) {
if (!use_ssl && conf->rods_auth_scheme == DAVRODS_AUTH_PAM) {
if ((*rods_conn)->ssl) {
// This should not happen.
// In this situation we don't know if we should stop
Expand Down Expand Up @@ -267,7 +274,7 @@ static authn_status rods_login(

// Disable SSL if it was in effect during auth but negotiation (or lack
// thereof) demanded plain TCP for the rest of the connection.
if (!useSsl && (*rods_conn)->ssl) {
if (!use_ssl && (*rods_conn)->ssl) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
"Disabling SSL (was used for PAM only)");

Expand Down Expand Up @@ -306,7 +313,7 @@ static authn_status rods_login(
return result;
}

static authn_status check_rods(request_rec *r, const char *username, const char *password) {
authn_status check_rods(request_rec *r, const char *username, const char *password) {
int status;

// Obtain davrods directory config.
Expand Down Expand Up @@ -343,7 +350,7 @@ static authn_status check_rods(request_rec *r, const char *username, const char

if (status || !pool) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
"Could not create davrods apr pool");
"Could not create Davrods apr pool");
return HTTP_INTERNAL_SERVER_ERROR;
}

Expand Down
3 changes: 3 additions & 0 deletions auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#define _RODS_AUTH_H

#include "mod_davrods.h"
#include <mod_auth.h>

authn_status check_rods(request_rec *r, const char *username, const char *password);

void davrods_auth_register(apr_pool_t *p);

Expand Down
15 changes: 0 additions & 15 deletions common.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,6 @@ const char *get_rods_error_msg(int rods_error_code) {
return rodsErrorName(rods_error_code, &submsg);
}

/**
* \brief Extract the davrods pool from a request, as set by the rods_auth component.
*
* \param r an apache request record.
*
* \return the davrods memory pool
*/
apr_pool_t *get_davrods_pool_from_req(request_rec *r) {
// TODO: Remove function, move apr call to the single caller.
apr_pool_t *pool = NULL;
int status = apr_pool_userdata_get((void**)&pool, "davrods_pool", r->connection->pool);
assert(status == 0);
return pool;
}

// }}}
// DAV provider definition and registration {{{

Expand Down
9 changes: 0 additions & 9 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,6 @@
*/
const char *get_rods_error_msg(int rods_error_code);

/**
* \brief Extract the davrods pool from a request, as set by the rods_auth component.
*
* \param r an apache request record.
*
* \return the davrods memory pool
*/
apr_pool_t *get_davrods_pool_from_req(request_rec *r);

void davrods_dav_register(apr_pool_t *p);

#endif /* _DAVRODS_COMMON_H_ */
75 changes: 67 additions & 8 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,33 @@ void *davrods_create_dir_config(apr_pool_t *p, char *dir) {
conf->rods_default_resource = "";
conf->rods_env_file = "/etc/httpd/irods/irods_environment.json";
conf->rods_auth_scheme = DAVRODS_AUTH_NATIVE;

// Default to having the user's home directory as the exposed root
// because that collection is more or less guaranteed to be readable by
// the current user (as opposed to the /<zone>/home directory, which
// seems to be hidden for rodsusers by default).
// is hidden for rodsusers by default).
conf->rods_exposed_root = "User"; // NOTE: Keep this in sync with the option below.
conf->rods_exposed_root_type = DAVRODS_ROOT_USER_DIR;

// Default to 4 MiB buffer sizes, which is a good balance
// between resource usage and transfer performance in common
// setups.
conf->rods_tx_buffer_size = 4 * 1024 * 1024;
conf->rods_rx_buffer_size = 4 * 1024 * 1024;

conf->tmpfile_rollback = DAVRODS_TMPFILE_ROLLBACK_NO;
conf->tmpfile_rollback = DAVRODS_TMPFILE_ROLLBACK_OFF;
conf->locallock_lockdb_path = "/var/lib/davrods/lockdb_locallock";

conf->anonymous_mode = DAVRODS_ANONYMOUS_MODE_OFF;
conf->anonymous_auth_username = "anonymous";
conf->anonymous_auth_password = "";

// Use the minimum PAM temporary password TTL. We
// re-authenticate using PAM on every new HTTP connection, so
// there's no use keeping the temporary password around for
// longer than the maximum keepalive time. (We don't ever use
// a temporary password more than once).
conf->rods_auth_ttl = 1; // In hours.
conf->rods_auth_ttl = 1; // In hours.
}
return conf;
}
Expand Down Expand Up @@ -107,6 +115,10 @@ void *davrods_merge_dir_config(apr_pool_t *p, void *_parent, void *_child) {
DAVRODS_PROP_MERGE(tmpfile_rollback);
DAVRODS_PROP_MERGE(locallock_lockdb_path);

DAVRODS_PROP_MERGE(anonymous_mode);
DAVRODS_PROP_MERGE(anonymous_auth_username);
DAVRODS_PROP_MERGE(anonymous_auth_password);

assert(set_exposed_root(conf, exposed_root) >= 0);

#undef DAVRODS_PROP_MERGE
Expand Down Expand Up @@ -258,12 +270,12 @@ static const char *cmd_davrodstmpfilerollback(
) {
davrods_dir_conf_t *conf = (davrods_dir_conf_t*)config;

if (!strcasecmp(arg1, "yes")) {
conf->tmpfile_rollback = DAVRODS_TMPFILE_ROLLBACK_YES;
} else if (!strcasecmp(arg1, "no")) {
conf->tmpfile_rollback = DAVRODS_TMPFILE_ROLLBACK_NO;
if (!strcasecmp(arg1, "on") || !strcasecmp(arg1, "yes")) {
conf->tmpfile_rollback = DAVRODS_TMPFILE_ROLLBACK_ON;
} else if (!strcasecmp(arg1, "off") || !strcasecmp(arg1, "no")) {
conf->tmpfile_rollback = DAVRODS_TMPFILE_ROLLBACK_OFF;
} else {
return "This directive accepts only 'Yes' and 'No' values";
return "This directive accepts only 'On' and 'Off' values";
}

return NULL;
Expand All @@ -280,6 +292,45 @@ static const char *cmd_davrodslockdb(
return NULL;
}

static const char *cmd_davrodsanonymousmode(
cmd_parms *cmd, void *config,
const char *arg1
) {
davrods_dir_conf_t *conf = (davrods_dir_conf_t*)config;

if (!strcasecmp(arg1, "on")) {
conf->anonymous_mode = DAVRODS_ANONYMOUS_MODE_ON;
} else if (!strcasecmp(arg1, "off")) {
conf->anonymous_mode = DAVRODS_ANONYMOUS_MODE_OFF;
} else {
return "This directive accepts only 'On' and 'Off' values";
}

return NULL;
}

static const char *cmd_davrodsanonymouslogin(
cmd_parms *cmd, void *config,
int argc, char * const *argv
) {
davrods_dir_conf_t *conf = (davrods_dir_conf_t*)config;

if (argc < 1 || argc > 2)
return "Specify a username and optionally a password";

if (!strlen(argv[0]))
return "Username must not be empty";

conf->anonymous_auth_username = argv[0];

if (argc == 2)
conf->anonymous_auth_password = argv[1];
else
conf->anonymous_auth_password = "";

return NULL;
}

// }}}

const command_rec davrods_directives[] = {
Expand Down Expand Up @@ -327,6 +378,14 @@ const command_rec davrods_directives[] = {
DAVRODS_CONFIG_PREFIX "LockDB", cmd_davrodslockdb,
NULL, ACCESS_CONF, "Lock database location, used by the davrods-locallock DAV provider"
),
AP_INIT_TAKE1(
DAVRODS_CONFIG_PREFIX "AnonymousMode", cmd_davrodsanonymousmode,
NULL, ACCESS_CONF, "Anonymous mode On/Off switch"
),
AP_INIT_TAKE_ARGV(
DAVRODS_CONFIG_PREFIX "AnonymousLogin", cmd_davrodsanonymouslogin,
NULL, ACCESS_CONF, "Anonymous mode auth method, username and optional password"
),

{ NULL }
};
14 changes: 11 additions & 3 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ typedef struct {

enum {
// Need to have something other than a bool to recognize an 'unset' state.
DAVRODS_TMPFILE_ROLLBACK_YES = 1,
DAVRODS_TMPFILE_ROLLBACK_NO,
DAVRODS_TMPFILE_ROLLBACK_OFF = 1,
DAVRODS_TMPFILE_ROLLBACK_ON,
} tmpfile_rollback;

const char *locallock_lockdb_path;
Expand All @@ -50,6 +50,14 @@ typedef struct {
DAVRODS_AUTH_PAM,
} rods_auth_scheme;

enum {
DAVRODS_ANONYMOUS_MODE_OFF = 1,
DAVRODS_ANONYMOUS_MODE_ON,
} anonymous_mode;

const char *anonymous_auth_username;
const char *anonymous_auth_password;

int rods_auth_ttl; // In hours.

enum {
Expand All @@ -58,7 +66,7 @@ typedef struct {
DAVRODS_ROOT_CUSTOM_DIR = 1, // <path> => <path>
DAVRODS_ROOT_ZONE_DIR, // Zone => /<zone>
DAVRODS_ROOT_HOME_DIR, // Home => /<zone>/home (not the user's home collection!)
DAVRODS_ROOT_USER_DIR, // User => /<zone>/home/<user>
DAVRODS_ROOT_USER_DIR, // User => /<zone>/home/<username>
} rods_exposed_root_type;

} davrods_dir_conf_t;
Expand Down
Loading

0 comments on commit fea08d8

Please sign in to comment.