Skip to content

Commit b4f3a64

Browse files
Neograph734helmo
authored andcommitted
Issue #922252 by Neograph734, anarcat: Prevent clients from hijacking each others subdomains
1 parent 93bdf91 commit b4f3a64

File tree

4 files changed

+103
-13
lines changed

4 files changed

+103
-13
lines changed

alias/hosting_alias.module

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ function hosting_alias_form_site_node_form_alter(&$form, &$form_state) {
7272
function hosting_alias_site_form_validate($form, &$form_state) {
7373
$aliases = $form_state['values']['aliases'] = array_filter($form_state['values']['aliases']);
7474
foreach ($aliases as $key => $alias) {
75-
hosting_alias_validate_alias($form_state['node'], $alias, $key);
75+
hosting_alias_validate_alias($form_state['values'], $alias, $key);
7676
}
7777
}
7878

@@ -365,8 +365,7 @@ function hosting_alias_node_revision_delete($node) {
365365
function hosting_alias_validate_alias($site, $alias, $key) {
366366
if ($alias = strtolower(trim($alias))) {
367367
$alias = strtolower(trim($alias));
368-
$params = isset($site->nid) ? array('nid' => $site->nid) : array();
369-
if (!hosting_domain_allowed($alias, $params) || $alias == $site->title) {
368+
if (!hosting_domain_allowed($alias, (array) $site) || $alias == $site->title) {
370369
form_set_error("aliases][$key", t('The domain name @alias is already in use', array('@alias' => $alias)));
371370
}
372371
if (!_hosting_valid_fqdn_wildcard($alias)) {

client/hosting_client.module

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ function hosting_client_permission() {
8888
'edit client uname' => array(
8989
'title' => t('edit client uname'),
9090
),
91+
'bypass domain owner check' => array(
92+
'title' => t('bypass domain owner check'),
93+
'description' => t('Allows the client to register a subdomain, even when the above domain is owned by another client.'),
94+
),
9195
);
9296
}
9397

@@ -991,6 +995,12 @@ function hosting_client_configure($form, &$form_state) {
991995
'#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.'),
992996
'#default_value' => variable_get('hosting_client_register_user', FALSE),
993997
);
998+
$form['hosting_client_subdomain_owner_check'] = array(
999+
'#type' => 'checkbox',
1000+
'#title' => t('Check owner upon creating subdomains.'),
1001+
'#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)"),
1002+
'#default_value' => variable_get('hosting_client_subdomain_owner_check', FALSE),
1003+
);
9941004

9951005
// User e-mail settings.
9961006
$form['email'] = array(
@@ -1175,3 +1185,81 @@ function hosting_client_views_api() {
11751185
'path' => drupal_get_path('module', 'hosting_client') . '/includes/views',
11761186
);
11771187
}
1188+
1189+
/**
1190+
* Implements hook_allow_domain().
1191+
*
1192+
* Disallow domains already used as any site's title/url, unless the site has
1193+
* been deleted.
1194+
*
1195+
* @see hosting_domain_allowed()
1196+
*/
1197+
function hosting_client_allow_domain($url, $params = array()) {
1198+
// If we do not have to be here, leave ASAP.
1199+
if (!variable_get('hosting_client_subdomain_owner_check', FALSE) || user_access('bypass domain owner check')) {
1200+
return TRUE;
1201+
}
1202+
1203+
// Get the client node from the client name.
1204+
$client = hosting_get_client($params['client']);
1205+
1206+
// Prepare array.
1207+
$subdomains = array();
1208+
1209+
// Break up url.
1210+
$url_array = explode('.', $url);
1211+
while ($url_array) {
1212+
$subdomains[] = implode('.', $url_array);
1213+
array_shift($url_array);
1214+
}
1215+
1216+
// Start query
1217+
$query = db_select('node', 'n')
1218+
->fields('n', array('nid'))
1219+
->condition('n.type', 'site');
1220+
$query->leftJoin('hosting_site', 'h', 'h.nid = n.nid');
1221+
$query->condition('h.status', HOSTING_SITE_DELETED, '<>');
1222+
1223+
// Check for either ...
1224+
$or = db_or();
1225+
1226+
$sites = db_or();
1227+
$aliases = db_or();
1228+
1229+
// Iterate over all subdomains and populate sites and aliases checks.
1230+
foreach ($subdomains as $domain) {
1231+
// Regular site names
1232+
$sites->condition('n.title', $domain);
1233+
1234+
// And aliases
1235+
$aliases->condition('a.alias', $domain);
1236+
}
1237+
1238+
// Any of the above domains that do not belong to this client.
1239+
$or->condition(
1240+
db_and()
1241+
->condition($sites)
1242+
->condition('h.client', $client->nid, '<>')
1243+
);
1244+
1245+
if (module_exists('hosting_alias')) {
1246+
$query->leftJoin('hosting_site_alias', 'a', 'n.vid = a.vid');
1247+
1248+
// Any of the above domain aliases that do not belong to this client.
1249+
$or->condition(
1250+
db_and()
1251+
->condition($aliases)
1252+
->condition('h.client', $client->nid, '<>')
1253+
);
1254+
}
1255+
1256+
// Add conditions to the query.
1257+
$query->condition($or);
1258+
1259+
// For existing sites, don't match the site's current url.
1260+
if (isset($params['nid'])) {
1261+
$query->condition('n.nid', $params['nid'], '<>');
1262+
}
1263+
1264+
return !$query->countQuery()->execute()->fetchField();
1265+
}

site/hosting_site.form.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,9 @@ function hosting_site_validate($node, &$form) {
403403
}
404404

405405
// 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)
406+
// 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?
406407
if (!hosting_domain_allowed($url, (array) $node)) {
407-
form_set_error('title', t("The domain name you have specified is already in use."));
408+
form_set_error('title', t("The domain name you have specified is already in use, or does not belong to you."));
408409
}
409410

410411
// If the quota module is loaded and this is a new node, check

site/hosting_site.module

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -661,18 +661,20 @@ function hosting_site_status_codes($type = NULL) {
661661
* @see hosting_domain_allowed()
662662
*/
663663
function hosting_site_allow_domain($url, $params = array()) {
664-
$query = "SELECT COUNT(n.nid) FROM {node} n
665-
JOIN {hosting_site} h ON n.nid = h.nid
666-
WHERE type = 'site' AND n.title = :title AND h.status <> :status";
667-
$args[':title'] = $url;
668-
$args[':status'] = HOSTING_SITE_DELETED;
664+
$query = db_select('node', 'n')
665+
->fields('n', array('nid'))
666+
->condition('n.type', 'site')
667+
->condition('n.title', $url);
668+
669+
$query->leftJoin('hosting_site', 'h', 'h.nid = n.nid');
670+
$query->condition('h.status', HOSTING_SITE_DELETED, '<>');
669671

672+
// For existing sites, don't match the site's current url.
670673
if (isset($params['nid'])) {
671-
$query .= " AND n.nid <> :nid";
672-
$args[':nid'] = $params['nid'];
674+
$query->condition('n.nid', $params['nid'], '<>');
673675
}
674-
$result = !db_query($query, $args)->fetchField();
675-
return $result;
676+
677+
return !$query->countQuery()->execute()->fetchField();
676678
}
677679

678680
/**

0 commit comments

Comments
 (0)