Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
requestHasSensitiveInfo = true,
responseHasSensitiveInfo = false,
since = "4.23.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
authorized = {RoleType.Admin})
public class AddDnsServerCmd extends BaseCmd {

/////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
entityType = {DnsServer.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
since = "4.23.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
authorized = {RoleType.Admin})
public class DeleteDnsServerCmd extends BaseAsyncCmd {

/////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
entityType = {DnsServer.class},
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false,
since = "4.23.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
authorized = {RoleType.Admin})
public class UpdateDnsServerCmd extends BaseCmd {

/////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.UriUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.component.PluggableService;
import com.cloud.utils.db.Filter;
Expand All @@ -107,9 +108,7 @@
import com.cloud.vm.Nic;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicDetailsDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;

@Component
Expand All @@ -126,10 +125,6 @@
@Inject
DnsZoneNetworkMapDao dnsZoneNetworkMapDao;
@Inject
UserVmDao userVmDao;
@Inject
NicDao nicDao;
@Inject
DomainDao domainDao;
@Inject
DnsZoneJoinDao dnsZoneJoinDao;
Expand Down Expand Up @@ -162,14 +157,36 @@
throw new CloudRuntimeException("No plugin found for DNS provider type: " + type);
}

/**
* Rejects a DNS provider URL that resolves to an illegal address before any provider client
* is given the chance to connect to it. See {@link UriUtils#validateUrl(String)} for the exact rules
* enforced (including the requirement that the URL declares an {@code http}/{@code https} scheme).
*
* @throws InvalidParameterValueException if the URL is blank, fails validation
*/
private void validateDnsServerUrl(String trimmedUrl) {
if (StringUtils.isBlank(trimmedUrl)) {

Check failure on line 168 in server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use static access with "org.apache.commons.lang3.StringUtils" for "isBlank".

See more on https://sonarcloud.io/project/issues?id=apache_cloudstack&issues=AaAEkOQUYEZf7TajSZpo&open=AaAEkOQUYEZf7TajSZpo&pullRequest=13821
throw new InvalidParameterValueException("URL cannot be blank.");
}
try {
UriUtils.validateUrl(trimmedUrl);
} catch (IllegalArgumentException e) {
throw new InvalidParameterValueException(e.getMessage());
}
}

@Override
@ActionEvent(eventType = EventTypes.EVENT_DNS_SERVER_ADD, eventDescription = "Adding a DNS Server")
public DnsServer addDnsServer(AddDnsServerCmd cmd) {
Account caller = CallContext.current().getCallingAccount();
DnsServer existing = dnsServerDao.findByUrlAndAccount(cmd.getUrl(), caller.getId());
enforceRootAdminOnly(caller.getId());

String dnsUrl = StringUtils.trim(cmd.getUrl());

Check failure on line 184 in server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use static access with "org.apache.commons.lang3.StringUtils" for "trim".

See more on https://sonarcloud.io/project/issues?id=apache_cloudstack&issues=AaAVNSjxBuamWNefnd6q&open=AaAVNSjxBuamWNefnd6q&pullRequest=13821
validateDnsServerUrl(dnsUrl);
DnsServer existing = dnsServerDao.findByUrlAndAccount(dnsUrl, caller.getId());
if (existing != null) {
throw new InvalidParameterValueException(
"This Account already has a DNS server integration for URL: " + cmd.getUrl());
"This Account already has a DNS server integration for URL: " + dnsUrl);
}

boolean isDnsPublic = cmd.isPublic();
Expand All @@ -190,7 +207,7 @@
}

DnsProviderType type = cmd.getProvider();
DnsServerVO server = new DnsServerVO(cmd.getName(), cmd.getUrl(), cmd.getPort(), type,
DnsServerVO server = new DnsServerVO(cmd.getName(), dnsUrl, cmd.getPort(), type,
cmd.getDnsUserName(), cmd.getDnsApiKey(), isDnsPublic, publicDomainSuffix, cmd.getNameServers(),
caller.getAccountId(), caller.getDomainId());

Expand Down Expand Up @@ -245,6 +262,8 @@
}

Account caller = CallContext.current().getCallingAccount();
enforceRootAdminOnly(caller.getId());

accountMgr.checkAccess(caller, null, true, dnsServer);

boolean validationRequired = false;
Expand All @@ -255,13 +274,15 @@
dnsServer.setName(cmd.getName());
}

if (cmd.getUrl() != null) {
if (!cmd.getUrl().equals(originalUrl)) {
DnsServer duplicate = dnsServerDao.findByUrlAndAccount(cmd.getUrl(), dnsServer.getAccountId());
if (StringUtils.isNotBlank(cmd.getUrl())) {

Check failure on line 277 in server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use static access with "org.apache.commons.lang3.StringUtils" for "isNotBlank".

See more on https://sonarcloud.io/project/issues?id=apache_cloudstack&issues=AaAkP2qDObA3UIzKsBaa&open=AaAkP2qDObA3UIzKsBaa&pullRequest=13821
String dnsUrl = StringUtils.trim(cmd.getUrl());

Check failure on line 278 in server/src/main/java/org/apache/cloudstack/dns/DnsProviderManagerImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use static access with "org.apache.commons.lang3.StringUtils" for "trim".

See more on https://sonarcloud.io/project/issues?id=apache_cloudstack&issues=AaAVNSjxBuamWNefnd6r&open=AaAVNSjxBuamWNefnd6r&pullRequest=13821
if (!dnsUrl.equals(originalUrl)) {
validateDnsServerUrl(dnsUrl);
DnsServer duplicate = dnsServerDao.findByUrlAndAccount(dnsUrl, dnsServer.getAccountId());
if (duplicate != null && duplicate.getId() != dnsServer.getId()) {
throw new InvalidParameterValueException("Another DNS server with this URL already exists.");
}
dnsServer.setUrl(cmd.getUrl());
dnsServer.setUrl(dnsUrl);
validationRequired = true;
}
}
Expand Down Expand Up @@ -330,6 +351,7 @@
throw new InvalidParameterValueException(String.format("DNS server with ID: %s not found.", dnsServerId));
}
Account caller = CallContext.current().getCallingAccount();
enforceRootAdminOnly(caller.getId());
accountMgr.checkAccess(caller, null, true, dnsServer);
return Transaction.execute((TransactionCallback<Boolean>) status -> {
if (cmd.getCleanup()) {
Expand Down Expand Up @@ -1263,4 +1285,10 @@
provider.addRecord(dnsServer, dnsZone, recordIpv6);
}
}

void enforceRootAdminOnly(Long callerId) {
if (!accountMgr.isRootAdmin(callerId)) {
throw new PermissionDeniedException("This API can only be called by root admin");
}
}
}
Loading
Loading