FM

//usr/sbin UP

#!/opt/cloudlinux/venv/bin/python3 -sbb
# -*- coding: utf-8 -*-
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2025 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
"""
User-level CLI utility for managing website isolation.

This script runs via proxyexec with root privileges but operates on behalf
of the calling user. It validates that the user only manages domains they own.

Commands:
    site-isolation-enable --domain DOMAIN[,DOMAIN2,...]   Enable site isolation for domain(s)
    site-isolation-disable --domain DOMAIN[,DOMAIN2,...]  Disable site isolation for domain(s)
    site-isolation-list                                   List domains with site isolation enabled

All commands output JSON:
    Success: {"result": "success", "enabled_sites": ["domain1", "domain2"]}
    Error:   {"result": "ERROR_CODE"}
"""

import argparse
import json
import logging
import os
import sys
import pwd

from clcommon.cpapi import domain_owner
from clcommon.cpapi.cpapiexceptions import NoDomain

from clcagefslib.cli import (
    call_via_proxyexec,
    in_cagefs,
    is_running_via_proxyexec,
)
from clcagefslib.domain import (
    enable_website_isolation,
    disable_website_isolation,
    get_websites_with_enabled_isolation,
    is_website_isolation_allowed_server_wide,
    is_website_isolation_allowed_for_user,
)
from clcagefslib.fs import user_exists

# Logging configuration
LOG_FILE = "/var/log/cloudlinux/cagefsctl-user.log"

# Proxyexec alias for all cagefsctl-user commands
PROXYEXEC_ALIAS = "CAGEFSCTL_USER"


def setup_logger():
    """
    Set up logging to file only (no console output).

    Returns:
        logging.Logger: Configured logger instance
    """
    logger = logging.getLogger("cagefsctl-user")
    logger.setLevel(logging.INFO)
    # Disable propagation to root logger to prevent console output
    logger.propagate = False
    try:
        fh = logging.FileHandler(LOG_FILE)
        fh.setFormatter(logging.Formatter(
            "[%(levelname)s | %(asctime)s]: %(message)s"
        ))
        logger.addHandler(fh)
    except (IOError, OSError):
        # Cannot write to log file, continue without file logging
        pass
    return logger


logger = setup_logger()


class ErrorCodes:
    """Error codes for JSON responses."""
    SITE_ISOLATION_NOT_ALLOWED = "Site isolation feature is not allowed"
    DOMAIN_NOT_FOUND = "Specified domain is not found"
    USER_NOT_FOUND = "User not found"
    INTERNAL_ERROR = "Internal error"
    MISSING_DOMAIN = "Domain is not specified"
    ROOT_NOT_ALLOWED = "Utility cannot be run as root"


def get_calling_user():
    """
    Get the username of the calling user from proxyexec environment.

    When running via proxyexec, PROXYEXEC_UID contains the original user's UID.
    Falls back to current process UID if not set.

    Returns:
        str: Username of the calling user
        None: If user cannot be determined
    """
    proxyexec_uid = os.environ.get("PROXYEXEC_UID")
    if not proxyexec_uid:
        return None
    try:
        uid = int(proxyexec_uid)
        pw = pwd.getpwuid(uid)
        return pw.pw_name
    except (ValueError, KeyError):
        return None


def json_response(result, enabled_sites=None, message=None):
    """
    Create a JSON response dictionary.

    Args:
        result: "success" or error code
        enabled_sites: Optional list of enabled sites (for success responses)
        message: Optional error message with additional details

    Returns:
        dict: Response dictionary
    """
    response = {"result": result}
    if enabled_sites is not None:
        response["enabled_sites"] = enabled_sites
    if message is not None:
        response["message"] = message
    return response


def output_json(response):
    """Print JSON response to stdout."""
    print(json.dumps(response))


def validate_domain_ownership(username, domain):
    """
    Validate that a domain belongs to the specified user.

    Args:
        username: The username to check ownership for
        domain: The domain to validate

    Returns:
        tuple: (is_valid, error_code)
            is_valid: True if domain belongs to user
            error_code: Error code if validation fails, None otherwise
    """
    try:
        owner = domain_owner(domain)
        if owner is None:
            return False, ErrorCodes.DOMAIN_NOT_FOUND
        if owner != username:
            return False, ErrorCodes.DOMAIN_NOT_FOUND
        return True, None
    except NoDomain:
        return False, ErrorCodes.DOMAIN_NOT_FOUND
    except Exception:
        return False, ErrorCodes.INTERNAL_ERROR


def get_validated_user():
    """
    Get the calling user and validate they exist.

    Returns:
        tuple: (username, error_code)
            username: The validated username, or None if validation failed
            error_code: Error code if validation failed, or None if successful
    """
    username = get_calling_user()
    if not username:
        logger.error("User not found")
        return None, ErrorCodes.USER_NOT_FOUND

    if not user_exists(username):
        logger.error("User %s does not exist", username)
        return None, ErrorCodes.USER_NOT_FOUND

    return username, None


def validate_domain_for_user(username, domain):
    """
    Validate domain argument and ownership for a user.

    Args:
        username: The username to check ownership for
        domain: The domain to validate

    Returns:
        tuple: (is_valid, error_code)
            is_valid: True if domain is valid and belongs to user
            error_code: Error code if validation failed, None otherwise
    """
    if not domain:
        logger.error("Missing domain argument")
        return False, ErrorCodes.MISSING_DOMAIN

    is_valid, error_code = validate_domain_ownership(username, domain)
    if not is_valid:
        logger.error("Domain validation failed: user=%s, domain=%s, error=%s",
                     username, domain, error_code)
        return False, error_code

    return True, None


def parse_domains(domain_arg):
    """
    Parse comma-separated domain argument into a list of domains.

    Args:
        domain_arg: Comma-separated domain string (e.g., "domain1.com,domain2.com")

    Returns:
        list: List of domain names, with whitespace stripped
    """
    if not domain_arg:
        return []
    return [d.strip() for d in domain_arg.split(",") if d.strip()]


def cmd_site_isolation_enable(args):
    """Handle site-isolation-enable command."""
    domains = parse_domains(args.domain)
    logger.info("site-isolation-enable called: domains=%s", domains)

    if not domains:
        logger.error("No domains specified")
        output_json(json_response(ErrorCodes.MISSING_DOMAIN))
        return 1

    username, error = get_validated_user()
    if error:
        output_json(json_response(error))
        return 1

    if not is_website_isolation_allowed_server_wide():
        logger.error("Site isolation not allowed server-wide")
        output_json(json_response(ErrorCodes.SITE_ISOLATION_NOT_ALLOWED))
        return 1

    if not is_website_isolation_allowed_for_user(username):
        logger.error("Site isolation not allowed for user %s", username)
        output_json(json_response(ErrorCodes.SITE_ISOLATION_NOT_ALLOWED))
        return 1

    # Validate all domains first
    for domain in domains:
        is_valid, error = validate_domain_for_user(username, domain)
        if not is_valid:
            output_json(json_response(error))
            return 1

    try:
        for domain in domains:
            enable_website_isolation(username, domain)
        enabled_sites = get_websites_with_enabled_isolation(username)
        logger.info("Site isolation enabled: user=%s, domains=%s, enabled_sites=%s",
                    username, domains, enabled_sites)
        output_json(json_response("success", enabled_sites))
        return 0
    except Exception as e:
        logger.exception("Failed to enable site isolation: user=%s, domains=%s, error=%s",
                         username, domains, e)
        output_json(json_response(ErrorCodes.INTERNAL_ERROR, message=str(e)))
        return 1


def cmd_site_isolation_disable(args):
    """Handle site-isolation-disable command."""
    domains = parse_domains(args.domain)
    logger.info("site-isolation-disable called: domains=%s", domains)

    if not domains:
        logger.error("No domains specified")
        output_json(json_response(ErrorCodes.MISSING_DOMAIN))
        return 1

    username, error = get_validated_user()
    if error:
        output_json(json_response(error))
        return 1

    # Validate all domains first
    for domain in domains:
        is_valid, error = validate_domain_for_user(username, domain)
        if not is_valid:
            output_json(json_response(error))
            return 1

    try:
        for domain in domains:
            disable_website_isolation(username, domain)
        enabled_sites = get_websites_with_enabled_isolation(username)
        logger.info("Site isolation disabled: user=%s, domains=%s, enabled_sites=%s",
                    username, domains, enabled_sites)
        output_json(json_response("success", enabled_sites))
        return 0
    except Exception as e:
        logger.exception("Failed to disable site isolation: user=%s, domains=%s, error=%s",
                         username, domains, e)
        output_json(json_response(ErrorCodes.INTERNAL_ERROR, message=str(e)))
        return 1


def cmd_site_isolation_list(args):
    """Handle site-isolation-list command."""
    logger.info("site-isolation-list called")

    username, error = get_validated_user()
    if error:
        output_json(json_response(error))
        return 1

    try:
        enabled_sites = get_websites_with_enabled_isolation(username)
        logger.info("Site isolation list: user=%s, enabled_sites=%s", username, enabled_sites)
        output_json(json_response("success", enabled_sites))
        return 0
    except Exception as e:
        logger.exception("Failed to list site isolation: user=%s, error=%s", username, e)
        output_json(json_response(ErrorCodes.INTERNAL_ERROR, message=str(e)))
        return 1


def create_parser():
    """Create argument parser for cagefsctl-user."""
    parser = argparse.ArgumentParser(
        prog="cagefsctl-user",
        description="User-level CLI utility for managing website isolation.",
    )

    subparsers = parser.add_subparsers(
        title="commands",
        dest="command",
        help="Available commands",
    )

    # site-isolation-enable command
    enable_parser = subparsers.add_parser(
        "site-isolation-enable",
        help="Enable site isolation for domain(s)",
    )
    enable_parser.add_argument(
        "--domain",
        required=True,
        help="Domain name(s) to enable site isolation for (comma-separated)",
    )
    enable_parser.set_defaults(func=cmd_site_isolation_enable)

    # site-isolation-disable command
    disable_parser = subparsers.add_parser(
        "site-isolation-disable",
        help="Disable site isolation for domain(s)",
    )
    disable_parser.add_argument(
        "--domain",
        required=True,
        help="Domain name(s) to disable site isolation for (comma-separated)",
    )
    disable_parser.set_defaults(func=cmd_site_isolation_disable)

    # site-isolation-list command
    list_parser = subparsers.add_parser(
        "site-isolation-list",
        help="List domains with site isolation enabled",
    )
    list_parser.set_defaults(func=cmd_site_isolation_list)

    return parser


def main(argv=None):
    """Main entry point."""
    parser = create_parser()
    args = parser.parse_args(argv)

    # Guard: do not allow running as root unless via proxyexec
    # When running via proxyexec, PROXYEXEC_UID is set
    if os.getuid() == 0 and not is_running_via_proxyexec():
        logger.error("Direct root invocation not allowed")
        output_json(json_response(ErrorCodes.ROOT_NOT_ALLOWED))
        return 1

    # If running as user (not root via proxyexec)
    if os.getuid() != 0:
        if not in_cagefs():
            print("This utility is only available inside CageFS.\n"
                  "Please run it via: cagefs_enter cagefsctl-user <command>",
                  file=sys.stderr)
            return 1

        # Inside CageFS - call via proxyexec to get root privileges
        if not args.command:
            parser.print_help()
            return 1

        # Build args list for proxyexec
        args_list = sys.argv[1:]  # Pass all original args
        result = call_via_proxyexec(PROXYEXEC_ALIAS, args_list)
        if result is None:
            output_json(json_response(
                ErrorCodes.INTERNAL_ERROR,
                message="Failed to execute via proxyexec"
            ))
            return 1
        return result

    # Running as root via proxyexec - execute the command
    if not hasattr(args, "func"):
        parser.print_help()
        return 1

    return args.func(args)


if __name__ == "__main__":
    sys.exit(main())
cagefs_enter_site1877V
cagefsctl-user13203V
chroot42448V
consoletype12160V
cracklib-check13360V
cracklib-format251V
cracklib-packer13368V
cracklib-unpacker9248V
create-cracklib-dict990V
ddns-confgen20944V
dnssec-checkds936V
dnssec-coverage938V
dnssec-dsfromkey62304V
dnssec-importkey62304V
dnssec-keyfromlabel66312V
dnssec-keygen74592V
dnssec-keymgr934V
dnssec-revoke58104V
dnssec-settime62296V
dnssec-signzone120016V
dnssec-verify54112V
exim1280V
faillock21016V
genrandom12672V
hsendmail7510347V
ip709944V
isc-hmac-fixup12136V
ldconfig1009752V
lvdctl5555V
mkhomedir_helper25024V
named-checkzone37512V
named-compilezone37512V
nsec3hash12584V
pam_console_apply46280V
pam_timestamp_check12152V
pluginviewer21064V
proxyexec21680V
pwhistory_helper20928V
saslauthd96688V
sasldblistusers221264V
saslpasswd216816V
sendmail7510347V
sendmail.bak1048V
sendmail.exim1280V
testsaslauthd17056V
tmpwatch36320V
tsig-keygen20944V
unix_chkpwd37744V
unix_update37744V
MyMelon - Digital Marketing and Creative Agency in Delhi, India
Skip to content Skip to footer

MyMelon Home Page

Bored Of Old School Strategies?

Conventional strategies do no justice to complex modern problems. Bringing in kickass blueprints to escalate your exclusive ideas to the growth trajectory.

MyMelon Home Page (1)

Falling In Love With Your Problems

Your problems are our play! You get to decide which ‘solutions’ feel like an astounding fuck yes!

Discover pitch-perfect marketing strategies to deliver complex ideas into simplified solutions. 

Diversity in our problem solving approach makes us who we are!

You Do You

For us every client and their offerings are unique. We offer tailored and hot-off-the-press strategies to produce a unique brand identity. Listening, evolving, and promoting your articles of faith is what makes our work kickass and compelling too!

#
Award
Type
Project
01
Best Project
Art Business
Business Style
2017
02
Best Design
Creative Work
Best Designers
2018
03
Best Concept
New Strategy
Branding Concept
2019
04
Best Picture
Visualization
Small Figures
2020

Our Inspirations

Vivekanand

Arise, awake, and stop not until the goal is achieved

Dr APJ Abdul Kalam

Creativity is seeing the same thing but thinking differently

Christopher Columbus

By prevailing over all obstacles one may unfailingly arrive at his chosen goal.

JRD Tata

Uncommon thinkers reuse what common thinkers refuse.

Lead The Way With Your New Digital Partners

Waiting to get viral? Don’t worry we’ve got your back!

Leading your way through business acumen and business strategies tailored to your needs.

Handholding you since your first lightbulb moment to making a mark in the industry through unique formulas.  Bringing unexpected things to the table is in our DNA.

Producing Tailored Solutions

One solution for multiple solutions is hard to swallow. Creating tailored solutions for your unique problems

Setting Benchmarks

Doesn’t carving a path for others give the best kick ever?

Making A Difference

You can’t wait for a case study. You will be too late!

Blogs

Contact Us

We work hard and then succeed on purpose.

We are constantly looking for a needle in a haystack and connecting to get the deal to happen!

If you've loved our idea and want to take the road less traveled, reach out to us on …….

Before you take the sure-shots of success, let's take some shots of vodka!

    Polscy gracze coraz częściej wybierają kasyno bez weryfikacji przy wypłacie bez ukrytych opłat, aby cieszyć się szybkim dostępem do gier i przejrzystymi warunkami wypłaty wygranych. Tego typu platformy stawiają na uproszczoną rejestrację, nowoczesne metody płatności oraz jasne zasady dotyczące transakcji. Przed rozpoczęciem gry warto zapoznać się z opiniami innych użytkowników, aby ocenić jakość obsługi i niezawodność serwisu.

    Jeśli chcesz znaleźć rzetelne opinie oraz porównać najlepsze platformy, casino Revolut Pay może pomóc Ci podjąć świadomą decyzję. Znajdziesz tam recenzje użytkowników, szczegóły bonusów oraz informacje o wpłatach i wypłatach w kasynach akceptujących Revolut.

    People searching for gerçek canlı casino usually mean live-dealer roulette, blackjack, baccarat, or game-show tables streamed from a studio with a real dealer, rather than an RNG-only game. To assess authenticity, verify the operator’s licence directly with the regulator, check the named game provider and studio, look for clear rules and table limits, inspect withdrawal terms, and confirm that the service is legal in your jurisdiction; a foreign licence does not automatically make an operator legal in Türkiye.

    [canlı casino lisans rehberi](https://guvenilircanlicasinos.com/)[gerçek krupiyeli oyunlar](https://www.livecasinos.com/tr/) [guvenilircanlicasinos](https://guvenilircanlicasinos.com/)

    Many Dutch players now look for beste online casino iDEAL to benefit from secure iDEAL deposits, low minimum stakes, and quick withdrawals. These casinos integrate trusted Dutch payment infrastructure with streamlined cashout systems, ideal for users who value speed, simplicity, and transparent transactions. By consulting authentic player reviews, gamblers can identify sites that consistently deliver rapid payouts and a seamless gaming experience.

    Gli online casinos with bancoposta sono principalmente operatori che accettano la carta Visa o Mastercard collegata al conto BancoPosta per depositi e, in alcuni casi, prelievi. Tra i nomi più citati in Italia figurano 888casino, SNAI, LeoVegas, Planetwin365, Gioco Digitale, Sisal e StarCasinò, con depositi minimi spesso tra 10€ e 20€ e limiti massimi che possono arrivare a diverse migliaia di euro. Per utilizzare la carta, di solito basta selezionare Visa o Mastercard alla cassa, inserire i dati della carta BancoPosta e completare la verifica 3D Secure; i prelievi possono tornare sulla stessa carta o sul conto tramite bonifico, con tempi tipici da 24 ore a 3–5 giorni lavorativi.

    Gracze poszukujący sprawdzonych platform często wybierają kasyno niemcy, które oferuje przejrzyste zasady wypłat i bezpieczne metody płatności. Przed rejestracją warto porównać limity transakcji, czas realizacji przelewów oraz dostępne opcje wpłat, aby uniknąć niepotrzebnych opóźnień. Opinie innych użytkowników mogą pomóc ocenić rzetelność obsługi, jakość gier i ogólny komfort korzystania z platformy.

    Oferty określane jako zagraniczne kasyna bonus bez depozytu mogą obejmować darmowe spiny lub niewielkie środki promocyjne przyznawane po rejestracji i weryfikacji konta. Przed skorzystaniem z promocji należy dokładnie sprawdzić wymagania obrotu, maksymalną wypłatę, czas ważności bonusu oraz ograniczenia dla użytkowników z Polski. Zagraniczna licencja nie legalizuje automatycznie działalności hazardowej w Polsce, dlatego warto zweryfikować operatora w oficjalnych źródłach i grać odpowiedzialnie .