Skip to content

Commit

Permalink
Issue #922252 by Neograph734, anarcat: Prevent clients from hijacking…
Browse files Browse the repository at this point in the history
… each others subdomains
  • Loading branch information
Neograph734 authored and helmo committed Dec 22, 2016
1 parent 93bdf91 commit b4f3a64
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 13 deletions.
5 changes: 2 additions & 3 deletions alias/hosting_alias.module
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function hosting_alias_form_site_node_form_alter(&$form, &$form_state) {
function hosting_alias_site_form_validate($form, &$form_state) {
$aliases = $form_state['values']['aliases'] = array_filter($form_state['values']['aliases']);
foreach ($aliases as $key => $alias) {
hosting_alias_validate_alias($form_state['node'], $alias, $key);
hosting_alias_validate_alias($form_state['values'], $alias, $key);
}
}

Expand Down Expand Up @@ -365,8 +365,7 @@ function hosting_alias_node_revision_delete($node) {
function hosting_alias_validate_alias($site, $alias, $key) {
if ($alias = strtolower(trim($alias))) {
$alias = strtolower(trim($alias));
$params = isset($site->nid) ? array('nid' => $site->nid) : array();
if (!hosting_domain_allowed($alias, $params) || $alias == $site->title) {
if (!hosting_domain_allowed($alias, (array) $site) || $alias == $site->title) {
form_set_error("aliases][$key", t('The domain name @alias is already in use', array('@alias' => $alias)));
}
if (!_hosting_valid_fqdn_wildcard($alias)) {
Expand Down
88 changes: 88 additions & 0 deletions client/hosting_client.module
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ function hosting_client_permission() {
'edit client uname' => array(
'title' => t('edit client uname'),
),
'bypass domain owner check' => array(
'title' => t('bypass domain owner check'),
'description' => t('Allows the client to register a subdomain, even when the above domain is owned by another client.'),
),
);
}

Expand Down Expand Up @@ -991,6 +995,12 @@ function hosting_client_configure($form, &$form_state) {
'#description' => t('If this setting is on, any new client nodes will automatically have a system user account generated for them, and associated with the new client node. Users going through the signup form module have a user created regardless of this setting.'),
'#default_value' => variable_get('hosting_client_register_user', FALSE),
);
$form['hosting_client_subdomain_owner_check'] = array(
'#type' => 'checkbox',
'#title' => t('Check owner upon creating subdomains.'),
'#description' => t("As a policy a hosting_client user is not allowed to create a site on a domain or subdomain thereof that is already in use by another client. (Unles the client has the 'bypass domain owner check' permission)"),
'#default_value' => variable_get('hosting_client_subdomain_owner_check', FALSE),
);

// User e-mail settings.
$form['email'] = array(
Expand Down Expand Up @@ -1175,3 +1185,81 @@ function hosting_client_views_api() {
'path' => drupal_get_path('module', 'hosting_client') . '/includes/views',
);
}

/**
* Implements hook_allow_domain().
*
* Disallow domains already used as any site's title/url, unless the site has
* been deleted.
*
* @see hosting_domain_allowed()
*/
function hosting_client_allow_domain($url, $params = array()) {
// If we do not have to be here, leave ASAP.
if (!variable_get('hosting_client_subdomain_owner_check', FALSE) || user_access('bypass domain owner check')) {
return TRUE;
}

// Get the client node from the client name.
$client = hosting_get_client($params['client']);

// Prepare array.
$subdomains = array();

// Break up url.
$url_array = explode('.', $url);
while ($url_array) {
$subdomains[] = implode('.', $url_array);
array_shift($url_array);
}

// Start query
$query = db_select('node', 'n')
->fields('n', array('nid'))
->condition('n.type', 'site');
$query->leftJoin('hosting_site', 'h', 'h.nid = n.nid');
$query->condition('h.status', HOSTING_SITE_DELETED, '<>');

// Check for either ...
$or = db_or();

$sites = db_or();
$aliases = db_or();

// Iterate over all subdomains and populate sites and aliases checks.
foreach ($subdomains as $domain) {
// Regular site names
$sites->condition('n.title', $domain);

// And aliases
$aliases->condition('a.alias', $domain);
}

// Any of the above domains that do not belong to this client.
$or->condition(
db_and()
->condition($sites)
->condition('h.client', $client->nid, '<>')
);

if (module_exists('hosting_alias')) {
$query->leftJoin('hosting_site_alias', 'a', 'n.vid = a.vid');

// Any of the above domain aliases that do not belong to this client.
$or->condition(
db_and()
->condition($aliases)
->condition('h.client', $client->nid, '<>')
);
}

// Add conditions to the query.
$query->condition($or);

// For existing sites, don't match the site's current url.
if (isset($params['nid'])) {
$query->condition('n.nid', $params['nid'], '<>');
}

return !$query->countQuery()->execute()->fetchField();
}
3 changes: 2 additions & 1 deletion site/hosting_site.form.inc
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,9 @@ function hosting_site_validate($node, &$form) {
}

// TODO: maybe we should allow creation of sites that conflict with HOSTING_SITE_DISABLED (which would then need to be renamed before being re-enabled)
// TODO: This error is also triggered when the user attempts to register a subdomain of a used site. Perhaps we should read the error code and split the errors?
if (!hosting_domain_allowed($url, (array) $node)) {
form_set_error('title', t("The domain name you have specified is already in use."));
form_set_error('title', t("The domain name you have specified is already in use, or does not belong to you."));
}

// If the quota module is loaded and this is a new node, check
Expand Down
20 changes: 11 additions & 9 deletions site/hosting_site.module
Original file line number Diff line number Diff line change
Expand Up @@ -661,18 +661,20 @@ function hosting_site_status_codes($type = NULL) {
* @see hosting_domain_allowed()
*/
function hosting_site_allow_domain($url, $params = array()) {
$query = "SELECT COUNT(n.nid) FROM {node} n
JOIN {hosting_site} h ON n.nid = h.nid
WHERE type = 'site' AND n.title = :title AND h.status <> :status";
$args[':title'] = $url;
$args[':status'] = HOSTING_SITE_DELETED;
$query = db_select('node', 'n')
->fields('n', array('nid'))
->condition('n.type', 'site')
->condition('n.title', $url);

$query->leftJoin('hosting_site', 'h', 'h.nid = n.nid');
$query->condition('h.status', HOSTING_SITE_DELETED, '<>');

// For existing sites, don't match the site's current url.
if (isset($params['nid'])) {
$query .= " AND n.nid <> :nid";
$args[':nid'] = $params['nid'];
$query->condition('n.nid', $params['nid'], '<>');
}
$result = !db_query($query, $args)->fetchField();
return $result;

return !$query->countQuery()->execute()->fetchField();
}

/**
Expand Down

0 comments on commit b4f3a64

Please sign in to comment.