diff --git a/lib/classes/api/commands/class.Certificates.php b/lib/classes/api/commands/class.Certificates.php index c49869ec..6d40ee6b 100644 --- a/lib/classes/api/commands/class.Certificates.php +++ b/lib/classes/api/commands/class.Certificates.php @@ -41,23 +41,23 @@ class Certificates extends ApiCommand implements ResourceEntity $domainid = $this->getParam('domainid', true, 0); $dn_optional = ($domainid <= 0 ? false : true); $domainname = $this->getParam('domainname', $dn_optional, ''); - + if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) { throw new Exception("You cannot access this resource", 405); } - + $domain = $this->apiCall('SubDomains.get', array( 'id' => $domainid, 'domainname' => $domainname )); $domainid = $domain['id']; - + // parameters $ssl_cert_file = $this->getParam('ssl_cert_file'); $ssl_key_file = $this->getParam('ssl_key_file'); $ssl_ca_file = $this->getParam('ssl_ca_file', true, ''); $ssl_cert_chainfile = $this->getParam('ssl_cert_chainfile', true, ''); - + // validate whether the domain does not already have an entry $result = $this->apiCall('Certificates.get', array( 'id' => $domainid @@ -90,17 +90,17 @@ class Certificates extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $dn_optional = ($id <= 0 ? false : true); $domainname = $this->getParam('domainname', $dn_optional, ''); - + if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) { throw new Exception("You cannot access this resource", 405); } - + $domain = $this->apiCall('SubDomains.get', array( 'id' => $id, 'domainname' => $domainname )); $domainid = $domain['id']; - + $stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid`= :domainid"); $this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] get ssl-certificate for '" . $domain['domain'] . "'"); $result = Database::pexecute_first($stmt, array( @@ -116,6 +116,12 @@ class Certificates extends ApiCommand implements ResourceEntity * optional, the domain-id * @param string $domainname * optional, the domainname + * @param string $ssl_cert_file + * @param string $ssl_key_file + * @param string $ssl_ca_file + * optional + * @param string $ssl_cert_chainfile + * optional * * @access admin, customer * @throws Exception @@ -126,16 +132,16 @@ class Certificates extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $dn_optional = ($id <= 0 ? false : true); $domainname = $this->getParam('domainname', $dn_optional, ''); - + if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'domains')) { throw new Exception("You cannot access this resource", 405); } - + $domain = $this->apiCall('SubDomains.get', array( 'id' => $id, 'domainname' => $domainname )); - + // parameters $ssl_cert_file = $this->getParam('ssl_cert_file'); $ssl_key_file = $this->getParam('ssl_key_file'); @@ -164,9 +170,9 @@ class Certificates extends ApiCommand implements ResourceEntity LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `d`.`customerid` WHERE "; - + $qry_params = array(); - + if ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '0') { // admin with only customer-specific permissions $certs_stmt_query .= "d.adminid = :adminid "; @@ -206,7 +212,7 @@ class Certificates extends ApiCommand implements ResourceEntity public function delete() { $id = $this->getParam('id'); - + $chk = ($this->isAdmin() && $this->getUserDetail('customers_see_all') == '1') ? true : false; if ($this->isAdmin() == false) { $chk_stmt = Database::prepare(" @@ -261,7 +267,7 @@ class Certificates extends ApiCommand implements ResourceEntity if ($ssl_cert_file != '' && $ssl_key_file == '') { standard_error('sslcertificateismissingprivatekey', '', true); } - + $do_verify = true; // no cert-file given -> forget everything if ($ssl_cert_file == '') { @@ -270,21 +276,21 @@ class Certificates extends ApiCommand implements ResourceEntity $ssl_cert_chainfile = ''; $do_verify = false; } - + // verify certificate content if ($do_verify) { // array openssl_x509_parse ( mixed $x509cert [, bool $shortnames = true ] ) // openssl_x509_parse() returns information about the supplied x509cert, including fields such as // subject name, issuer name, purposes, valid from and valid to dates etc. $cert_content = openssl_x509_parse($ssl_cert_file); - + if (is_array($cert_content) && isset($cert_content['subject']) && isset($cert_content['subject']['CN'])) { // bool openssl_x509_check_private_key ( mixed $cert , mixed $key ) // Checks whether the given key is the private key that corresponds to cert. if (openssl_x509_check_private_key($ssl_cert_file, $ssl_key_file) === false) { standard_error('sslcertificateinvalidcertkeypair', '', true); } - + // check optional stuff if ($ssl_ca_file != '') { $ca_content = openssl_x509_parse($ssl_ca_file); @@ -304,7 +310,7 @@ class Certificates extends ApiCommand implements ResourceEntity standard_error('sslcertificateinvalidcert', '', true); } } - + // Add/Update database entry $qrystart = "UPDATE "; $qrywhere = "WHERE "; diff --git a/lib/classes/api/commands/class.Customers.php b/lib/classes/api/commands/class.Customers.php index 6f8da50e..75e3dd32 100644 --- a/lib/classes/api/commands/class.Customers.php +++ b/lib/classes/api/commands/class.Customers.php @@ -22,6 +22,7 @@ class Customers extends ApiCommand implements ResourceEntity * lists all customer entries * * @access admin + * @throws Exception * @return array count|list */ public function listing() @@ -71,7 +72,7 @@ class Customers extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $ln_optional = ($id <= 0 ? false : true); $loginname = $this->getParam('loginname', $ln_optional, ''); - + if ($this->isAdmin()) { $result_stmt = Database::prepare(" SELECT `c`.*, `a`.`loginname` AS `adminname` @@ -110,17 +111,108 @@ class Customers extends ApiCommand implements ResourceEntity /** * create a new customer with default ftp-user and standard-subdomain (if wanted) * + * @param string $email + * @param string $name + * optional if company is set, else required + * @param string $firstname + * optional if company is set, else required + * @param string $company + * optional but required if name/firstname empty + * @param string $street + * optional + * @param string $zipcode + * optional + * @param string $city + * optional + * @param string $phone + * optional + * @param string $fax + * optional + * @param int $customernumber + * optional + * @param string $def_language, + * optional, default is system-default language + * @param int $gender + * optional, 0 = no-gender, 1 = male, 2 = female + * @param string $custom_notes + * optional notes + * @param bool $custom_notes_show + * optional, whether to show the content of custom_notes to the customer, default 0 (false) + * @param string $new_loginname + * optional, if empty generated automatically using customer-prefix and increasing number + * @param string $password + * optional, if empty generated automatically and send to the customer's email if $sendpassword is 1 + * @param bool $sendpassword + * optional, whether to send the password to the customer after creation, default 0 (false) + * @param int $diskspace + * optional disk-space available for customer in MB, default 0 + * @param bool $diskspace_ul + * optional, whether customer should have unlimited diskspace, default 0 (false) + * @param int $traffic + * optional traffic available for customer in GB, default 0 + * @param bool $traffic_ul + * optional, whether customer should have unlimited traffic, default 0 (false) + * @param int $subdomains + * optional amount of subdomains available for customer, default 0 + * @param bool $subdomains_ul + * optional, whether customer should have unlimited subdomains, default 0 (false) + * @param int $emails + * optional amount of emails available for customer, default 0 + * @param bool $emails_ul + * optional, whether customer should have unlimited emails, default 0 (false) + * @param int $email_accounts + * optional amount of email-accounts available for customer, default 0 + * @param bool $email_accounts_ul + * optional, whether customer should have unlimited email-accounts, default 0 (false) + * @param int $email_forwarders + * optional amount of email-forwarders available for customer, default 0 + * @param bool $email_forwarders_ul + * optional, whether customer should have unlimited email-forwarders, default 0 (false) + * @param int $email_quota + * optional size of email-quota available for customer in MB, default is system-setting mail_quota + * @param bool $email_quota_ul + * optional, whether customer should have unlimited email-quota, default 0 (false) + * @param bool $email_imap + * optional, whether to allow IMAP access, default 0 (false) + * @param bool $email_pop3 + * optional, whether to allow POP3 access, default 0 (false) + * @param int $ftps + * optional amount of ftp-accounts available for customer, default 0 + * @param bool $ftps_ul + * optional, whether customer should have unlimited ftp-accounts, default 0 (false) + * @param int $tickets + * optional amount of tickets available for customer if enabled, default 0 + * @param bool $tickets_ul + * optional, whether customer should have unlimited tickets if enabled, default 0 (false) + * @param int $mysqls + * optional amount of mysql-databases available for customer, default 0 + * @param bool $mysqls_ul + * optional, whether customer should have unlimited mysql-databases, default 0 (false) + * @param bool $createstdsubdomain + * optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false) + * @param bool $phpenabled + * optional, whether to allow usage of PHP, default 0 (false) + * @param array $allowed_phpconfigs + * optional, array of IDs of php-config that the customer is allowed to use, default empty (none) + * @param bool $perlenabled + * optional, whether to allow usage of Perl/CGI, default 0 (false) + * @param bool $dnsenabled + * optional, ether to allow usage of the DNS editor (requires activated nameserver in settings) + * @param bool $store_defaultindex + * optional, whether to store the default index file to customers homedir + * * @access admin + * @throws Exception * @return array */ public function add() { if ($this->isAdmin()) { if ($this->getUserDetail('customers_used') < $this->getUserDetail('customers') || $this->getUserDetail('customers') == '-1') { - + // required parameters $email = $this->getParam('email'); - + // parameters $name = $this->getParam('name', true, ''); $firstname = $this->getParam('firstname', true, ''); @@ -136,14 +228,14 @@ class Customers extends ApiCommand implements ResourceEntity $gender = intval_ressource($this->getParam('gender', true, 0)); $custom_notes = $this->getParam('custom_notes', true, ''); $custom_notes_show = $this->getParam('custom_notes_show', true, 0); - + $diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, 0); $traffic = $this->getUlParam('traffic', 'traffic_ul', true, 0); $subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, 0); $emails = $this->getUlParam('emails', 'emails_ul', true, 0); $email_accounts = $this->getUlParam('email_accounts', 'email_accounts_ul', true, 0); $email_forwarders = $this->getUlParam('email_forwarders', 'email_forwarders_ul', true, 0); - $email_quota = $this->getUlParam('email_quota', 'email_quota_ul', true, 0); + $email_quota = $this->getUlParam('email_quota', 'email_quota_ul', true, Settings::Get('system.mail_quota')); $email_imap = $this->getParam('email_imap', true, 0); $email_pop3 = $this->getParam('email_pop3', true, 0); $ftps = $this->getUlParam('ftps', 'ftps_ul', true, 0); @@ -158,7 +250,7 @@ class Customers extends ApiCommand implements ResourceEntity $dnsenabled = $this->getParam('dnsenabled', true, 0); $store_defaultindex = $this->getParam('store_defaultindex', true, 0); $loginname = $this->getParam('new_loginname', true, ''); - + // validation $name = validate($name, 'name', '', '', array(), true); $firstname = validate($firstname, 'first name', '', '', array(), true); @@ -173,27 +265,27 @@ class Customers extends ApiCommand implements ResourceEntity $customernumber = validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true); $def_language = validate($def_language, 'default language', '', '', array(), true); $custom_notes = validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true); - + if (Settings::Get('system.mail_quota_enabled') != '1') { $email_quota = - 1; } - + if (Settings::Get('ticket.enabled') != '1') { $tickets = - 1; } - + $password = validate($password, 'password', '', '', array(), true); // only check if not empty, // cause empty == generate password automatically if ($password != '') { $password = validatePassword($password, true); } - + // gender out of range? [0,2] if ($gender < 0 || $gender > 2) { $gender = 0; } - + $allowed_phpconfigs = array(); if (! empty($p_allowed_phpconfigs) && is_array($p_allowed_phpconfigs)) { foreach ($p_allowed_phpconfigs as $allowed_phpconfig) { @@ -201,27 +293,27 @@ class Customers extends ApiCommand implements ResourceEntity $allowed_phpconfigs[] = $allowed_phpconfig; } } - + $diskspace = $diskspace * 1024; $traffic = $traffic * 1024 * 1024; - + if (((($this->getUserDetail('diskspace_used') + $diskspace) > $this->getUserDetail('diskspace')) && ($this->getUserDetail('diskspace') / 1024) != '-1') || ((($this->getUserDetail('mysqls_used') + $mysqls) > $this->getUserDetail('mysqls')) && $this->getUserDetail('mysqls') != '-1') || ((($this->getUserDetail('emails_used') + $emails) > $this->getUserDetail('emails')) && $this->getUserDetail('emails') != '-1') || ((($this->getUserDetail('email_accounts_used') + $email_accounts) > $this->getUserDetail('email_accounts')) && $this->getUserDetail('email_accounts') != '-1') || ((($this->getUserDetail('email_forwarders_used') + $email_forwarders) > $this->getUserDetail('email_forwarders')) && $this->getUserDetail('email_forwarders') != '-1') || ((($this->getUserDetail('email_quota_used') + $email_quota) > $this->getUserDetail('email_quota')) && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ((($this->getUserDetail('ftps_used') + $ftps) > $this->getUserDetail('ftps')) && $this->getUserDetail('ftps') != '-1') || ((($this->getUserDetail('tickets_used') + $tickets) > $this->getUserDetail('tickets')) && $this->getUserDetail('tickets') != '-1') || ((($this->getUserDetail('subdomains_used') + $subdomains) > $this->getUserDetail('subdomains')) && $this->getUserDetail('subdomains') != '-1') || (($diskspace / 1024) == '-1' && ($this->getUserDetail('diskspace') / 1024) != '-1') || ($mysqls == '-1' && $this->getUserDetail('mysqls') != '-1') || ($emails == '-1' && $this->getUserDetail('emails') != '-1') || ($email_accounts == '-1' && $this->getUserDetail('email_accounts') != '-1') || ($email_forwarders == '-1' && $this->getUserDetail('email_forwarders') != '-1') || ($email_quota == '-1' && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ($ftps == '-1' && $this->getUserDetail('ftps') != '-1') || ($tickets == '-1' && $this->getUserDetail('tickets') != '-1') || ($subdomains == '-1' && $this->getUserDetail('subdomains') != '-1')) { standard_error('youcantallocatemorethanyouhave', '', true); } - + if (! validateEmail($email)) { standard_error('emailiswrong', $email, true); } else { - + if ($loginname != '') { $accountnumber = intval(Settings::Get('system.lastaccountnumber')); $loginname = validate($loginname, 'loginname', '/^[a-z][a-z0-9\-_]+$/i', '', array(), true); - + // Accounts which match systemaccounts are not allowed, filtering them if (preg_match('/^' . preg_quote(Settings::Get('customer.accountprefix'), '/') . '([0-9]+)/', $loginname)) { standard_error('loginnameissystemaccount', Settings::Get('customer.accountprefix'), true); } - + // Additional filtering for Bug #962 if (function_exists('posix_getpwnam') && ! in_array("posix_getpwnam", explode(",", ini_get('disable_functions'))) && posix_getpwnam($loginname)) { standard_error('loginnameissystemaccount', Settings::Get('customer.accountprefix'), true); @@ -230,7 +322,7 @@ class Customers extends ApiCommand implements ResourceEntity $accountnumber = intval(Settings::Get('system.lastaccountnumber')) + 1; $loginname = Settings::Get('customer.accountprefix') . $accountnumber; } - + // Check if the account already exists // do not check via api as we skip any permission checks for this task $loginname_check_stmt = Database::prepare(" @@ -239,7 +331,7 @@ class Customers extends ApiCommand implements ResourceEntity $loginname_check = Database::pexecute_first($loginname_check_stmt, array( 'login' => $loginname ), true, true); - + // Check if an admin with the loginname already exists // do not check via api as we skip any permission checks for this task $loginname_check_admin_stmt = Database::prepare(" @@ -248,7 +340,7 @@ class Customers extends ApiCommand implements ResourceEntity $loginname_check_admin = Database::pexecute_first($loginname_check_admin_stmt, array( 'login' => $loginname ), true, true); - + if (strtolower($loginname_check['loginname']) == strtolower($loginname) || strtolower($loginname_check_admin['loginname']) == strtolower($loginname)) { standard_error('loginnameexists', $loginname, true); } elseif (! validateUsername($loginname, Settings::Get('panel.unix_names'), 14 - strlen(Settings::Get('customer.mysqlprefix')))) { @@ -258,36 +350,36 @@ class Customers extends ApiCommand implements ResourceEntity standard_error('loginnameiswrong', $loginname, true); } } - + $guid = intval(Settings::Get('system.lastguid')) + 1; $documentroot = makeCorrectDir(Settings::Get('system.documentroot_prefix') . '/' . $loginname); - + if (file_exists($documentroot)) { standard_error('documentrootexists', $documentroot, true); } - + if ($createstdsubdomain != '1') { $createstdsubdomain = '0'; } - + if ($phpenabled != '0') { $phpenabled = '1'; } - + if ($perlenabled != '0') { $perlenabled = '1'; } - + if ($dnsenabled != '0') { $dnsenabled = '1'; } - + if ($password == '') { $password = generatePassword(); } - + $_theme = Settings::Get('panel.default_theme'); - + $ins_data = array( 'adminid' => $this->getUserDetail('adminid'), 'loginname' => $loginname, @@ -326,7 +418,7 @@ class Customers extends ApiCommand implements ResourceEntity 'custom_notes' => $custom_notes, 'custom_notes_show' => $custom_notes_show ); - + $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_CUSTOMERS . "` SET `adminid` = :adminid, @@ -368,69 +460,69 @@ class Customers extends ApiCommand implements ResourceEntity `custom_notes_show` = :custom_notes_show "); Database::pexecute($ins_stmt, $ins_data, true, true); - + $customerid = Database::lastInsertId(); $ins_data['customerid'] = $customerid; - + // update admin resource-usage $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` + 1"; - + if ($mysqls != '-1') { $admin_update_query .= ", `mysqls_used` = `mysqls_used` + 0" . (int) $mysqls; } - + if ($emails != '-1') { $admin_update_query .= ", `emails_used` = `emails_used` + 0" . (int) $emails; } - + if ($email_accounts != '-1') { $admin_update_query .= ", `email_accounts_used` = `email_accounts_used` + 0" . (int) $email_accounts; } - + if ($email_forwarders != '-1') { $admin_update_query .= ", `email_forwarders_used` = `email_forwarders_used` + 0" . (int) $email_forwarders; } - + if ($email_quota != '-1') { $admin_update_query .= ", `email_quota_used` = `email_quota_used` + 0" . (int) $email_quota; } - + if ($subdomains != '-1') { $admin_update_query .= ", `subdomains_used` = `subdomains_used` + 0" . (int) $subdomains; } - + if ($ftps != '-1') { $admin_update_query .= ", `ftps_used` = `ftps_used` + 0" . (int) $ftps; } - + if ($tickets != '-1' && Settings::Get('ticket.enabled') == 1) { $admin_update_query .= ", `tickets_used` = `tickets_used` + 0" . (int) $tickets; } - + if (($diskspace / 1024) != '-1') { $admin_update_query .= ", `diskspace_used` = `diskspace_used` + 0" . (int) $diskspace; } - + $admin_update_query .= " WHERE `adminid` = '" . (int) $this->getUserDetail('adminid') . "'"; Database::query($admin_update_query); - + // update last guid Settings::Set('system.lastguid', $guid, true); - + if ($accountnumber != intval(Settings::Get('system.lastaccountnumber'))) { // update last account number Settings::Set('system.lastaccountnumber', $accountnumber, true); } - + $this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] added customer '" . $loginname . "'"); unset($ins_data); - + // insert task to create homedir etc. inserttask('2', $loginname, $guid, $guid, $store_defaultindex); - + // Using filesystem - quota, insert a task which cleans the filesystem - quota inserttask('10'); - + // Add htpasswd for the stats-pages if (CRYPT_STD_DES == 1) { $saltfordescrypt = substr(md5(uniqid(microtime(), 1)), 4, 2); @@ -438,7 +530,7 @@ class Customers extends ApiCommand implements ResourceEntity } else { $htpasswdPassword = crypt($password); } - + $ins_stmt = Database::prepare(" INSERT INTO `" . TABLE_PANEL_HTPASSWDS . "` SET `customerid` = :customerid, @@ -451,15 +543,15 @@ class Customers extends ApiCommand implements ResourceEntity 'username' => $loginname, 'passwd' => $htpasswdPassword ); - + $stats_folder = 'webalizer'; if (Settings::Get('system.awstats_enabled') == '1') { $stats_folder = 'awstats'; } $ins_data['path'] = makeCorrectDir($documentroot . '/' . $stats_folder . '/'); - $this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] automatically added ".$stats_folder." htpasswd for user '" . $loginname . "'"); + $this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] automatically added " . $stats_folder . " htpasswd for user '" . $loginname . "'"); Database::pexecute($ins_stmt, $ins_data, true, true); - + inserttask('1'); $cryptPassword = makeCryptPassword($password); // add FTP-User @@ -488,7 +580,7 @@ class Customers extends ApiCommand implements ResourceEntity 'guid' => $guid, 'members' => $loginname . ',' . Settings::Get('system.httpuser') ); - + // also, add froxlor-local user to ftp-group (if exists!) to // allow access to customer-directories from within the panel, which // is necessary when pathedit = Dropdown @@ -505,7 +597,7 @@ class Customers extends ApiCommand implements ResourceEntity } } Database::pexecute($ins_stmt, $ins_data, true, true); - + // FTP-Quotatallies // @fixme use Ftp-ApiCommand later $ins_stmt = Database::prepare(" @@ -516,7 +608,7 @@ class Customers extends ApiCommand implements ResourceEntity 'name' => $loginname ), true, true); $this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] automatically added ftp-account for user '" . $loginname . "'"); - + $_stdsubdomain = ''; if ($createstdsubdomain == '1') { if (Settings::Get('system.stdsubdomain') !== null && Settings::Get('system.stdsubdomain') != '') { @@ -524,7 +616,7 @@ class Customers extends ApiCommand implements ResourceEntity } else { $_stdsubdomain = $loginname . '.' . Settings::Get('system.hostname'); } - + $ins_data = array( 'domain' => $_stdsubdomain, 'customerid' => $customerid, @@ -540,7 +632,7 @@ class Customers extends ApiCommand implements ResourceEntity } catch (Exception $e) { $this->logger()->logAction(ADM_ACTION, LOG_ERR, "[API] Unable to add standard-subdomain: " . $e->getMessage()); } - + if ($domainid > 0) { $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `standardsubdomain` = :domainid WHERE `customerid` = :customerid @@ -553,14 +645,14 @@ class Customers extends ApiCommand implements ResourceEntity inserttask('1'); } } - + if ($sendpassword == '1') { - + $srv_hostname = Settings::Get('system.hostname'); if (Settings::Get('system.froxlordirectlyviahostname') == '0') { $srv_hostname .= '/' . basename(FROXLOR_INSTALL_DIR); } - + $srv_ip_stmt = Database::prepare(" SELECT ip, port FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE `id` = :defaultip @@ -570,7 +662,7 @@ class Customers extends ApiCommand implements ResourceEntity $srv_ip = Database::pexecute_first($srv_ip_stmt, array( 'defaultip' => reset($default_ips) ), true, true); - + $replace_arr = array( 'FIRSTNAME' => $firstname, 'NAME' => $name, @@ -587,7 +679,7 @@ class Customers extends ApiCommand implements ResourceEntity 'SERVER_PORT' => isset($srv_ip['port']) ? $srv_ip['port'] : '', 'DOMAINNAME' => $_stdsubdomain ); - + // get template for mail subject $mail_subject = $this->getMailTemplate(array( 'adminid' => $this->getUserDetail('adminid'), @@ -617,18 +709,18 @@ class Customers extends ApiCommand implements ResourceEntity $mailerr_msg = $e->getMessage(); $_mailerror = true; } - + if ($_mailerror) { $this->logger()->logAction(ADM_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg); standard_error('errorsendingmail', $email, true); } - + $this->mailer()->ClearAddresses(); $this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] automatically sent password to user '" . $loginname . "'"); } } $this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] added customer '" . $loginname . "'"); - + $result = $this->apiCall('Customers.get', array( 'loginname' => $loginname )); @@ -640,12 +732,103 @@ class Customers extends ApiCommand implements ResourceEntity } /** - * update customer entry by either id or loginname + * update customer entry by either id or loginname, customer can only change language, password and theme * * @param int $id * optional, the customer-id * @param string $loginname * optional, the loginname + * @param string $email + * @param string $name + * optional if company is set, else required + * @param string $firstname + * optional if company is set, else required + * @param string $company + * optional but required if name/firstname empty + * @param string $street + * optional + * @param string $zipcode + * optional + * @param string $city + * optional + * @param string $phone + * optional + * @param string $fax + * optional + * @param int $customernumber + * optional + * @param string $def_language, + * optional, default is system-default language + * @param int $gender + * optional, 0 = no-gender, 1 = male, 2 = female + * @param string $custom_notes + * optional notes + * @param bool $custom_notes_show + * optional, whether to show the content of custom_notes to the customer, default 0 (false) + * @param string $new_customer_password + * optional, iset new password + * @param bool $sendpassword + * optional, whether to send the password to the customer after creation, default 0 (false) + * @param int $move_to_admin + * optional, if valid admin-id is given here, the customer's admin/reseller can be changed + * @param bool $deactivated + * optional, if 1 (true) the customer can be deactivated/suspended + * @param int $diskspace + * optional disk-space available for customer in MB, default 0 + * @param bool $diskspace_ul + * optional, whether customer should have unlimited diskspace, default 0 (false) + * @param int $traffic + * optional traffic available for customer in GB, default 0 + * @param bool $traffic_ul + * optional, whether customer should have unlimited traffic, default 0 (false) + * @param int $subdomains + * optional amount of subdomains available for customer, default 0 + * @param bool $subdomains_ul + * optional, whether customer should have unlimited subdomains, default 0 (false) + * @param int $emails + * optional amount of emails available for customer, default 0 + * @param bool $emails_ul + * optional, whether customer should have unlimited emails, default 0 (false) + * @param int $email_accounts + * optional amount of email-accounts available for customer, default 0 + * @param bool $email_accounts_ul + * optional, whether customer should have unlimited email-accounts, default 0 (false) + * @param int $email_forwarders + * optional amount of email-forwarders available for customer, default 0 + * @param bool $email_forwarders_ul + * optional, whether customer should have unlimited email-forwarders, default 0 (false) + * @param int $email_quota + * optional size of email-quota available for customer in MB, default is system-setting mail_quota + * @param bool $email_quota_ul + * optional, whether customer should have unlimited email-quota, default 0 (false) + * @param bool $email_imap + * optional, whether to allow IMAP access, default 0 (false) + * @param bool $email_pop3 + * optional, whether to allow POP3 access, default 0 (false) + * @param int $ftps + * optional amount of ftp-accounts available for customer, default 0 + * @param bool $ftps_ul + * optional, whether customer should have unlimited ftp-accounts, default 0 (false) + * @param int $tickets + * optional amount of tickets available for customer if enabled, default 0 + * @param bool $tickets_ul + * optional, whether customer should have unlimited tickets if enabled, default 0 (false) + * @param int $mysqls + * optional amount of mysql-databases available for customer, default 0 + * @param bool $mysqls_ul + * optional, whether customer should have unlimited mysql-databases, default 0 (false) + * @param bool $createstdsubdomain + * optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false) + * @param bool $phpenabled + * optional, whether to allow usage of PHP, default 0 (false) + * @param array $allowed_phpconfigs + * optional, array of IDs of php-config that the customer is allowed to use, default empty (none) + * @param bool $perlenabled + * optional, whether to allow usage of Perl/CGI, default 0 (false) + * @param bool $dnsenabled + * optional, ether to allow usage of the DNS editor (requires activated nameserver in settings) + * @param string $theme + * optional, change theme * * @access admin, customer * @throws Exception @@ -656,17 +839,17 @@ class Customers extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $ln_optional = ($id <= 0 ? false : true); $loginname = $this->getParam('loginname', $ln_optional, ''); - + $result = $this->apiCall('Customers.get', array( 'id' => $id, 'loginname' => $loginname )); $id = $result['customerid']; - + if ($this->isAdmin()) { // parameters $move_to_admin = intval_ressource($this->getParam('move_to_admin', true, 0)); - + $idna_convert = new idna_convert_wrapper(); $email = $this->getParam('email', true, $idna_convert->decode($result['email'])); $name = $this->getParam('name', true, $result['name']); @@ -683,7 +866,7 @@ class Customers extends ApiCommand implements ResourceEntity $gender = intval_ressource($this->getParam('gender', true, $result['gender'])); $custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']); $custom_notes_show = $this->getParam('custom_notes_show', true, $result['custom_notes_show']); - + $dec_places = Settings::Get('panel.decimal_places'); $diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, round($result['diskspace'] / 1024, $dec_places)); $traffic = $this->getUlParam('traffic', 'traffic_ul', true, round($result['traffic'] / (1024 * 1024), $dec_places)); @@ -711,7 +894,7 @@ class Customers extends ApiCommand implements ResourceEntity $password = $this->getParam('new_customer_password', true, ''); $theme = $this->getParam('theme', true, $result['theme']); } - + // validation if ($this->isAdmin()) { $idna_convert = new idna_convert_wrapper(); @@ -729,28 +912,28 @@ class Customers extends ApiCommand implements ResourceEntity } $def_language = validate($def_language, 'default language', '', '', array(), true); $theme = validate($theme, 'theme', '', '', array(), true); - + if (Settings::Get('system.mail_quota_enabled') != '1') { $email_quota = - 1; } - + if (Settings::Get('ticket.enabled') != '1') { $tickets = - 1; } - + if (empty($theme)) { $theme = Settings::Get('panel.default_theme'); } - + if ($this->isAdmin()) { - + $diskspace = $diskspace * 1024; $traffic = $traffic * 1024 * 1024; - + if (((($this->getUserDetail('diskspace_used') + $diskspace - $result['diskspace']) > $this->getUserDetail('diskspace')) && ($this->getUserDetail('diskspace') / 1024) != '-1') || ((($this->getUserDetail('mysqls_used') + $mysqls - $result['mysqls']) > $this->getUserDetail('mysqls')) && $this->getUserDetail('mysqls') != '-1') || ((($this->getUserDetail('emails_used') + $emails - $result['emails']) > $this->getUserDetail('emails')) && $this->getUserDetail('emails') != '-1') || ((($this->getUserDetail('email_accounts_used') + $email_accounts - $result['email_accounts']) > $this->getUserDetail('email_accounts')) && $this->getUserDetail('email_accounts') != '-1') || ((($this->getUserDetail('email_forwarders_used') + $email_forwarders - $result['email_forwarders']) > $this->getUserDetail('email_forwarders')) && $this->getUserDetail('email_forwarders') != '-1') || ((($this->getUserDetail('email_quota_used') + $email_quota - $result['email_quota']) > $this->getUserDetail('email_quota')) && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ((($this->getUserDetail('ftps_used') + $ftps - $result['ftps']) > $this->getUserDetail('ftps')) && $this->getUserDetail('ftps') != '-1') || ((($this->getUserDetail('tickets_used') + $tickets - $result['tickets']) > $this->getUserDetail('tickets')) && $this->getUserDetail('tickets') != '-1') || ((($this->getUserDetail('subdomains_used') + $subdomains - $result['subdomains']) > $this->getUserDetail('subdomains')) && $this->getUserDetail('subdomains') != '-1') || (($diskspace / 1024) == '-1' && ($this->getUserDetail('diskspace') / 1024) != '-1') || ($mysqls == '-1' && $this->getUserDetail('mysqls') != '-1') || ($emails == '-1' && $this->getUserDetail('emails') != '-1') || ($email_accounts == '-1' && $this->getUserDetail('email_accounts') != '-1') || ($email_forwarders == '-1' && $this->getUserDetail('email_forwarders') != '-1') || ($email_quota == '-1' && $this->getUserDetail('email_quota') != '-1' && Settings::Get('system.mail_quota_enabled') == '1') || ($ftps == '-1' && $this->getUserDetail('ftps') != '-1') || ($tickets == '-1' && $this->getUserDetail('tickets') != '-1') || ($subdomains == '-1' && $this->getUserDetail('subdomains') != '-1')) { standard_error('youcantallocatemorethanyouhave', '', true); } - + if ($email == '') { standard_error(array( 'stringisempty', @@ -760,27 +943,27 @@ class Customers extends ApiCommand implements ResourceEntity standard_error('emailiswrong', $email, true); } } - + if ($password != '') { $password = validatePassword($password, true); $password = makeCryptPassword($password); } else { $password = $result['password']; } - + if ($this->isAdmin()) { if ($createstdsubdomain != '1') { $createstdsubdomain = '0'; } - + if ($createstdsubdomain == '1' && $result['standardsubdomain'] == '0') { - + if (Settings::Get('system.stdsubdomain') !== null && Settings::Get('system.stdsubdomain') != '') { $_stdsubdomain = $result['loginname'] . '.' . Settings::Get('system.stdsubdomain'); } else { $_stdsubdomain = $result['loginname'] . '.' . Settings::Get('system.hostname'); } - + $ins_data = array( 'domain' => $_stdsubdomain, 'customerid' => $result['customerid'], @@ -796,7 +979,7 @@ class Customers extends ApiCommand implements ResourceEntity } catch (Exception $e) { $this->logger()->logAction(ADM_ACTION, LOG_ERR, "[API] Unable to add standard-subdomain: " . $e->getMessage()); } - + if ($domainid > 0) { $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `standardsubdomain` = :domainid WHERE `customerid` = :customerid @@ -809,7 +992,7 @@ class Customers extends ApiCommand implements ResourceEntity inserttask('1'); } } - + if ($createstdsubdomain == '0' && $result['standardsubdomain'] != '0') { try { $std_domain = $this->apiCall('Domains.delete', array( @@ -822,34 +1005,34 @@ class Customers extends ApiCommand implements ResourceEntity $this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] automatically deleted standardsubdomain for user '" . $result['loginname'] . "'"); inserttask('1'); } - + if ($deactivated != '1') { $deactivated = '0'; } - + if ($phpenabled != '0') { $phpenabled = '1'; } - + if ($perlenabled != '0') { $perlenabled = '1'; } - + if ($dnsenabled != '0') { $dnsenabled = '1'; } - + if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled']) { inserttask('1'); } - + // activate/deactivate customer services if ($deactivated != $result['deactivated']) { - + $yesno = ($deactivated ? 'N' : 'Y'); $pop3 = ($deactivated ? '0' : (int) $result['pop3']); $imap = ($deactivated ? '0' : (int) $result['imap']); - + $upd_stmt = Database::prepare(" UPDATE `" . TABLE_MAIL_USERS . "` SET `postfix`= :yesno, `pop3` = :pop3, `imap` = :imap WHERE `customerid` = :customerid "); @@ -859,7 +1042,7 @@ class Customers extends ApiCommand implements ResourceEntity 'imap' => $imap, 'customerid' => $id )); - + $upd_stmt = Database::prepare(" UPDATE `" . TABLE_FTP_USERS . "` SET `login_enabled` = :yesno WHERE `customerid` = :customerid "); @@ -867,37 +1050,37 @@ class Customers extends ApiCommand implements ResourceEntity 'yesno' => $yesno, 'customerid' => $id )); - + $upd_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `deactivated`= :deactivated WHERE `customerid` = :customerid"); Database::pexecute($upd_stmt, array( 'deactivated' => $deactivated, 'customerid' => $id )); - + // Retrieve customer's databases $databases_stmt = Database::prepare("SELECT * FROM " . TABLE_PANEL_DATABASES . " WHERE customerid = :customerid ORDER BY `dbserver`"); Database::pexecute($databases_stmt, array( 'customerid' => $id )); - + Database::needRoot(true); $last_dbserver = 0; - + $dbm = new DbManager($this->logger()); - + // For each of them while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) { - + if ($last_dbserver != $row_database['dbserver']) { $dbm->getManager()->flushPrivileges(); Database::needRoot(true, $row_database['dbserver']); $last_dbserver = $row_database['dbserver']; } - + foreach (array_unique(explode(',', Settings::Get('system.mysql_access_host'))) as $mysql_access_host) { $mysql_access_host = trim($mysql_access_host); - + // Prevent access, if deactivated if ($deactivated) { // failsafe if user has been deleted manually (requires MySQL 4.1.2+) @@ -908,11 +1091,11 @@ class Customers extends ApiCommand implements ResourceEntity } } } - + // At last flush the new privileges $dbm->getManager()->flushPrivileges(); Database::needRoot(false); - + // reactivate/deactivate api-keys $valid_until = $deactivated ? 0 : - 1; $stmt = Database::prepare("UPDATE `" . TABLE_API_KEYS . "` SET `valid_until` = :vu WHERE `customerid` = :id"); @@ -920,11 +1103,11 @@ class Customers extends ApiCommand implements ResourceEntity 'id' => $id, 'vu' => $valid_until ), true, true); - + $this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] " . ($deactivated ? 'deactivated' : 'reactivated') . " user '" . $result['loginname'] . "'"); inserttask('1'); } - + // Disable or enable POP3 Login for customers Mail Accounts if ($email_pop3 != $result['pop3']) { $upd_stmt = Database::prepare("UPDATE `" . TABLE_MAIL_USERS . "` SET `pop3` = :pop3 WHERE `customerid` = :customerid"); @@ -933,7 +1116,7 @@ class Customers extends ApiCommand implements ResourceEntity 'customerid' => $id )); } - + // Disable or enable IMAP Login for customers Mail Accounts if ($email_imap != $result['imap']) { $upd_stmt = Database::prepare("UPDATE `" . TABLE_MAIL_USERS . "` SET `imap` = :imap WHERE `customerid` = :customerid"); @@ -943,14 +1126,14 @@ class Customers extends ApiCommand implements ResourceEntity )); } } - + $upd_data = array( 'customerid' => $id, 'passwd' => $password, 'lang' => $def_language, 'theme' => $theme ); - + if ($this->isAdmin()) { $admin_upd_data = array( 'name' => $name, @@ -986,12 +1169,12 @@ class Customers extends ApiCommand implements ResourceEntity ); $upd_data = $upd_data + $admin_upd_data; } - + $upd_query = "UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `def_language` = :lang, `password` = :passwd, `theme` = :theme"; - + if ($this->isAdmin()) { $admin_upd_query = ", `name` = :name, @@ -1029,16 +1212,16 @@ class Customers extends ApiCommand implements ResourceEntity $upd_query .= " WHERE `customerid` = :customerid"; $upd_stmt = Database::prepare($upd_query); Database::pexecute($upd_stmt, $upd_data); - + if ($this->isAdmin()) { // Using filesystem - quota, insert a task which cleans the filesystem - quota inserttask('10'); - + $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` "; - + if ($mysqls != '-1' || $result['mysqls'] != '-1') { $admin_update_query .= ", `mysqls_used` = `mysqls_used` "; - + if ($mysqls != '-1') { $admin_update_query .= " + 0" . (int) $mysqls . " "; } @@ -1046,10 +1229,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['mysqls'] . " "; } } - + if ($emails != '-1' || $result['emails'] != '-1') { $admin_update_query .= ", `emails_used` = `emails_used` "; - + if ($emails != '-1') { $admin_update_query .= " + 0" . (int) $emails . " "; } @@ -1057,10 +1240,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['emails'] . " "; } } - + if ($email_accounts != '-1' || $result['email_accounts'] != '-1') { $admin_update_query .= ", `email_accounts_used` = `email_accounts_used` "; - + if ($email_accounts != '-1') { $admin_update_query .= " + 0" . (int) $email_accounts . " "; } @@ -1068,10 +1251,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['email_accounts'] . " "; } } - + if ($email_forwarders != '-1' || $result['email_forwarders'] != '-1') { $admin_update_query .= ", `email_forwarders_used` = `email_forwarders_used` "; - + if ($email_forwarders != '-1') { $admin_update_query .= " + 0" . (int) $email_forwarders . " "; } @@ -1079,10 +1262,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['email_forwarders'] . " "; } } - + if ($email_quota != '-1' || $result['email_quota'] != '-1') { $admin_update_query .= ", `email_quota_used` = `email_quota_used` "; - + if ($email_quota != '-1') { $admin_update_query .= " + 0" . (int) $email_quota . " "; } @@ -1090,10 +1273,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['email_quota'] . " "; } } - + if ($subdomains != '-1' || $result['subdomains'] != '-1') { $admin_update_query .= ", `subdomains_used` = `subdomains_used` "; - + if ($subdomains != '-1') { $admin_update_query .= " + 0" . (int) $subdomains . " "; } @@ -1101,10 +1284,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['subdomains'] . " "; } } - + if ($ftps != '-1' || $result['ftps'] != '-1') { $admin_update_query .= ", `ftps_used` = `ftps_used` "; - + if ($ftps != '-1') { $admin_update_query .= " + 0" . (int) $ftps . " "; } @@ -1112,10 +1295,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['ftps'] . " "; } } - + if ($tickets != '-1' || $result['tickets'] != '-1') { $admin_update_query .= ", `tickets_used` = `tickets_used` "; - + if ($tickets != '-1') { $admin_update_query .= " + 0" . (int) $tickets . " "; } @@ -1123,10 +1306,10 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['tickets'] . " "; } } - + if (($diskspace / 1024) != '-1' || ($result['diskspace'] / 1024) != '-1') { $admin_update_query .= ", `diskspace_used` = `diskspace_used` "; - + if (($diskspace / 1024) != '-1') { $admin_update_query .= " + 0" . (int) $diskspace . " "; } @@ -1134,13 +1317,13 @@ class Customers extends ApiCommand implements ResourceEntity $admin_update_query .= " - 0" . (int) $result['diskspace'] . " "; } } - + $admin_update_query .= " WHERE `adminid` = '" . (int) $result['adminid'] . "'"; Database::query($admin_update_query); } - + $this->logger()->logAction($this->isAdmin() ? ADM_ACTION : USR_ACTION, LOG_INFO, "[API] edited user '" . $result['loginname'] . "'"); - + /* * move customer to another admin/reseller; #1166 */ @@ -1155,7 +1338,7 @@ class Customers extends ApiCommand implements ResourceEntity } } } - + $result = $this->apiCall('Customers.get', array( 'id' => $result['customerid'] )); @@ -1183,13 +1366,13 @@ class Customers extends ApiCommand implements ResourceEntity $ln_optional = ($id <= 0 ? false : true); $loginname = $this->getParam('loginname', $ln_optional, ''); $delete_userfiles = $this->getParam('delete_userfiles', true, 0); - + $result = $this->apiCall('Customers.get', array( 'id' => $id, 'loginname' => $loginname )); $id = $result['customerid']; - + // @fixme use Databases-ApiCommand later $databases_stmt = Database::prepare(" SELECT * FROM `" . TABLE_PANEL_DATABASES . "` @@ -1200,9 +1383,9 @@ class Customers extends ApiCommand implements ResourceEntity )); Database::needRoot(true); $last_dbserver = 0; - + $dbm = new DbManager($this->logger()); - + while ($row_database = $databases_stmt->fetch(PDO::FETCH_ASSOC)) { if ($last_dbserver != $row_database['dbserver']) { Database::needRoot(true, $row_database['dbserver']); @@ -1213,19 +1396,19 @@ class Customers extends ApiCommand implements ResourceEntity } $dbm->getManager()->flushPrivileges(); Database::needRoot(false); - + // delete customer itself $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // delete customer databases $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DATABASES . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // first gather all domain-id's to clean up panel_domaintoip and dns-entries accordingly $did_stmt = Database::prepare("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id"); Database::pexecute($did_stmt, array( @@ -1249,49 +1432,49 @@ class Customers extends ApiCommand implements ResourceEntity 'id' => $id ), true, true); $domains_deleted = $stmt->rowCount(); - + // delete htpasswds $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTPASSWDS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // delete htaccess options $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_HTACCESS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // delete potential existing sessions $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `userid` = :id AND `adminsession` = '0'"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // delete traffic information $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // remove diskspace analysis $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DISKSPACE . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // delete mail-accounts $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // delete mail-addresses $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // gather ftp-user names $result2_stmt = Database::prepare("SELECT `username` FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :id"); Database::pexecute($result2_stmt, array( @@ -1304,25 +1487,25 @@ class Customers extends ApiCommand implements ResourceEntity 'name' => $row['username'] ), true, true); } - + // remove ftp-group $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_GROUPS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // remove ftp-users $stmt = Database::prepare("DELETE FROM `" . TABLE_FTP_USERS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // remove api-keys $stmt = Database::prepare("DELETE FROM `" . TABLE_API_KEYS . "` WHERE `customerid` = :id"); Database::pexecute($stmt, array( 'id' => $id ), true, true); - + // Delete all waiting "create user" -tasks for this user, #276 // Note: the WHERE selects part of a serialized array, but it should be safe this way $del_stmt = Database::prepare(" @@ -1332,64 +1515,64 @@ class Customers extends ApiCommand implements ResourceEntity Database::pexecute($del_stmt, array( 'loginname' => "%:{$result['loginname']};%" ), true, true); - + // update admin-resource-usage $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` - 1 "; $admin_update_query .= ", `domains_used` = `domains_used` - 0" . (int) ($domains_deleted - $result['subdomains_used']); - + if ($result['mysqls'] != '-1') { $admin_update_query .= ", `mysqls_used` = `mysqls_used` - 0" . (int) $result['mysqls']; } - + if ($result['emails'] != '-1') { $admin_update_query .= ", `emails_used` = `emails_used` - 0" . (int) $result['emails']; } - + if ($result['email_accounts'] != '-1') { $admin_update_query .= ", `email_accounts_used` = `email_accounts_used` - 0" . (int) $result['email_accounts']; } - + if ($result['email_forwarders'] != '-1') { $admin_update_query .= ", `email_forwarders_used` = `email_forwarders_used` - 0" . (int) $result['email_forwarders']; } - + if ($result['email_quota'] != '-1') { $admin_update_query .= ", `email_quota_used` = `email_quota_used` - 0" . (int) $result['email_quota']; } - + if ($result['subdomains'] != '-1') { $admin_update_query .= ", `subdomains_used` = `subdomains_used` - 0" . (int) $result['subdomains']; } - + if ($result['ftps'] != '-1') { $admin_update_query .= ", `ftps_used` = `ftps_used` - 0" . (int) $result['ftps']; } - + if ($result['tickets'] != '-1') { $admin_update_query .= ", `tickets_used` = `tickets_used` - 0" . (int) $result['tickets']; } - + if (($result['diskspace'] / 1024) != '-1') { $admin_update_query .= ", `diskspace_used` = `diskspace_used` - 0" . (int) $result['diskspace']; } - + $admin_update_query .= " WHERE `adminid` = '" . (int) $result['adminid'] . "'"; Database::query($admin_update_query); - + // rebuild configs inserttask('1'); - + // Using nameserver, insert a task which rebuilds the server config inserttask('4'); - + if ($delete_userfiles == 1) { // insert task to remove the customers files from the filesystem inserttask('6', $result['loginname']); } - + // Using filesystem - quota, insert a task which cleans the filesystem - quota inserttask('10'); - + // move old tickets to archive $tickets = ticket::customerHasTickets($id); if ($tickets !== false && isset($tickets[0])) { @@ -1404,7 +1587,7 @@ class Customers extends ApiCommand implements ResourceEntity $this->logger()->logAction(ADM_ACTION, LOG_NOTICE, "[API] archived ticket '" . $mainticket->Get('subject') . "'"); } } - + $this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'"); return $this->response(200, "successfull", $result); } @@ -1429,13 +1612,13 @@ class Customers extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $ln_optional = ($id <= 0 ? false : true); $loginname = $this->getParam('loginname', $ln_optional, ''); - + $result = $this->apiCall('Customers.get', array( 'id' => $id, 'loginname' => $loginname )); $id = $result['customerid']; - + $result_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `loginfail_count` = '0' @@ -1446,7 +1629,7 @@ class Customers extends ApiCommand implements ResourceEntity ), true, true); // set the new value for result-array $result['loginfail_count'] = 0; - + $this->logger()->logAction(ADM_ACTION, LOG_WARNING, "[API] unlocked customer '" . $result['loginname'] . "'"); return $this->response(200, "successfull", $result); } @@ -1458,7 +1641,9 @@ class Customers extends ApiCommand implements ResourceEntity * and update all its references accordingly * * @param int $id - * customer-id + * optional, the customer-id + * @param string $loginname + * optional, the loginname * @param int $adminid * target-admin-id * @@ -1473,23 +1658,23 @@ class Customers extends ApiCommand implements ResourceEntity $id = $this->getParam('id', true, 0); $ln_optional = ($id <= 0 ? false : true); $loginname = $this->getParam('loginname', $ln_optional, ''); - + $c_result = $this->apiCall('Customers.get', array( 'id' => $id, 'loginname' => $loginname )); $id = $c_result['customerid']; - + // check if target-admin is the current admin if ($adminid == $c_result['adminid']) { throw new Exception("Cannot move customer to the same admin/reseller as he currently is assigned to", 406); } - + // get target admin $a_result = $this->apiCall('Admins.get', array( 'id' => $adminid )); - + // Update customer entry $updCustomer_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET `adminid` = :adminid WHERE `customerid` = :cid @@ -1498,7 +1683,7 @@ class Customers extends ApiCommand implements ResourceEntity 'adminid' => $adminid, 'cid' => $id ), true, true); - + // Update customer-domains $updDomains_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `adminid` = :adminid WHERE `customerid` = :cid @@ -1507,7 +1692,7 @@ class Customers extends ApiCommand implements ResourceEntity 'adminid' => $adminid, 'cid' => $id ), true, true); - + // Update customer-tickets $updTickets_stmt = Database::prepare(" UPDATE `" . TABLE_PANEL_TICKETS . "` SET `adminid` = :adminid WHERE `customerid` = :cid @@ -1516,12 +1701,12 @@ class Customers extends ApiCommand implements ResourceEntity 'adminid' => $adminid, 'cid' => $id ), true, true); - + // now, recalculate the resource-usage for the old and the new admin updateCounters(false); - + $this->logger()->logAction(ADM_ACTION, LOG_INFO, "[API] moved user '" . $c_result['loginname'] . "' from admin/reseller '" . $c_result['adminname'] . " to admin/reseller '" . $a_result['loginname'] . "'"); - + $result = $this->apiCall('Customers.get', array( 'id' => $c_result['customerid'] ));