Skip to content

Commit

Permalink
fix: ensure landscape homedir and broker.bpickle are owned by landsca…
Browse files Browse the repository at this point in the history
…pe (LP: #2065879) (#264)
  • Loading branch information
Perfect5th authored Aug 29, 2024
1 parent ec5ce26 commit 9b6719c
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 30 deletions.
20 changes: 10 additions & 10 deletions debian/landscape-client.postinst
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ case "$1" in
if [ ! -f $CONFIG_FILE ]; then
# Create new configuration, with private mode
TEMPFILE=$(mktemp -p /etc/landscape)
cat > $TEMPFILE <<END
cat > "$TEMPFILE" <<END
[client]
log_level = info
url = https://landscape.canonical.com/message-system
ping_url = http://landscape.canonical.com/ping
data_path = /var/lib/landscape/client
END
chown landscape $TEMPFILE
mv $TEMPFILE $CONFIG_FILE
chown landscape:landscape "$TEMPFILE"
mv "$TEMPFILE" "$CONFIG_FILE"

# Get configuration values from debconf
db_get $PACKAGE/computer_title
Expand All @@ -65,7 +65,7 @@ END
TAGS="${RET}"

# If we got the needed information, actually do the registration.
if [ -n "$ACCOUNT_NAME" -a -n "$COMPUTER_TITLE" ]; then
if [ -n "$ACCOUNT_NAME" ] && [ -n "$COMPUTER_TITLE" ]; then
landscape-config --silent --ok-no-register \
--computer-title "$COMPUTER_TITLE" \
--account-name "$ACCOUNT_NAME" \
Expand All @@ -82,7 +82,7 @@ END
else
# Fix non-private permissions
chmod 0600 $CONFIG_FILE
chown landscape $CONFIG_FILE
chown landscape:landscape $CONFIG_FILE
fi

# Remove statoverride for smart-update, if there's one
Expand All @@ -101,14 +101,14 @@ END
# In response to bug 1508110 we need to trigger a complete update of
# user information. The flag file will be removed by the client when
# the update completes.
DATA_PATH="`grep ^data_path /etc/landscape/client.conf | cut -d= -f2 | tr -d '[[:space:]]'`"
DATA_PATH="$(grep ^data_path /etc/landscape/client.conf | cut -d= -f2 | tr -d '[:space:]')"
if [ -z "$DATA_PATH" ]; then
DATA_PATH=/var/lib/landscape/client
fi
install --owner=landscape --directory $DATA_PATH
install --owner=landscape --group=landscape --directory "$DATA_PATH"
USER_UPDATE_FLAG_FILE="$DATA_PATH/user-update-flag"
install --owner=landscape /dev/null $USER_UPDATE_FLAG_FILE
echo "This file indicates that the Landscape client needs to send updated user information to the server." >> $USER_UPDATE_FLAG_FILE
install --owner=landscape --group=landscape /dev/null "$USER_UPDATE_FLAG_FILE"
echo "This file indicates that the Landscape client needs to send updated user information to the server." >> "$USER_UPDATE_FLAG_FILE"

# To work around bug #1735100 we rewrite file-local landscape sources
# with the trusted flag, as they have no release file, thus are
Expand All @@ -133,7 +133,7 @@ END
# Migrate old sysvinit config to systemd
DEFAULTS=/etc/default/landscape-client
if [ -f $DEFAULTS ]; then
RUN=$(. $DEFAULTS; echo $RUN)
RUN=$(. "$DEFAULTS"; echo "$RUN")
if [ "$RUN" = "1" ]; then
systemctl enable landscape-client.service
fi
Expand Down
10 changes: 8 additions & 2 deletions landscape/client/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ def setup(config) -> Identity:
config.data_path,
f"{BrokerService.service_name}.bpickle",
),
user=USER,
group=GROUP,
)

return Identity(config, persist)
Expand All @@ -687,7 +689,7 @@ def restart_client(config):
def bootstrap_tree(config):
"""Create the client directories tree."""
bootstrap_list = [
BootstrapDirectory("$data_path", USER, "root", 0o755),
BootstrapDirectory("$data_path", USER, GROUP, 0o755),
BootstrapDirectory("$annotations_path", USER, GROUP, 0o755),
]
BootstrapList(bootstrap_list).bootstrap(
Expand Down Expand Up @@ -760,7 +762,7 @@ def is_registered(config):
config.data_path,
f"{BrokerService.service_name}.bpickle",
)
persist = Persist(filename=persist_filename)
persist = Persist(filename=persist_filename, user=USER, group=GROUP)
identity = Identity(config, persist)
return bool(identity.secure_id)

Expand Down Expand Up @@ -798,6 +800,8 @@ def set_secure_id(config, new_id):
config.data_path,
f"{BrokerService.service_name}.bpickle",
),
user=USER,
group=GROUP,
)
identity = Identity(config, persist)
identity.secure_id = new_id
Expand All @@ -810,6 +814,8 @@ def get_secure_id(config):
config.data_path,
f"{BrokerService.service_name}.bpickle",
),
user=USER,
group=GROUP,
)
identity = Identity(config, persist)
return identity.secure_id
Expand Down
8 changes: 7 additions & 1 deletion landscape/client/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

from landscape import VERSION
from landscape.client import DEFAULT_CONFIG
from landscape.client import GROUP
from landscape.client import USER
from landscape.client import snap_http
from landscape.client.snap_utils import get_snap_info
from landscape.client.upgraders import UPGRADE_MANAGERS
Expand Down Expand Up @@ -239,7 +241,11 @@ def get_versioned_persist(service):
Load a L{Persist} database for the given C{service} and upgrade or
mark as current, as necessary.
"""
persist = Persist(filename=service.persist_filename)
persist = Persist(
filename=service.persist_filename,
user=USER,
group=GROUP,
)
upgrade_manager = UPGRADE_MANAGERS[service.service_name]
if os.path.exists(service.persist_filename):
upgrade_manager.apply(persist)
Expand Down
8 changes: 7 additions & 1 deletion landscape/client/manager/keystonetoken.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
import os

from landscape.client import GROUP
from landscape.client import USER
from landscape.client.monitor.plugin import DataWatcher
from landscape.lib.compat import _PY3
from landscape.lib.compat import ConfigParser
Expand Down Expand Up @@ -32,7 +34,11 @@ def register(self, client):
self.registry.config.data_path,
"keystone.bpickle",
)
self._persist = Persist(filename=self._persist_filename)
self._persist = Persist(
filename=self._persist_filename,
user=USER,
group=GROUP,
)
self.registry.reactor.call_every(
self.registry.config.flush_interval,
self.flush,
Expand Down
8 changes: 7 additions & 1 deletion landscape/client/manager/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from twisted.internet.defer import maybeDeferred

from landscape.client import GROUP
from landscape.client import USER
from landscape.client.broker.client import BrokerClientPlugin
from landscape.lib.format import format_object
from landscape.lib.log import log_failure
Expand Down Expand Up @@ -95,7 +97,11 @@ def register(self, registry):
self.registry.config.data_path,
self.message_type + '.manager.bpkl',
)
self._persist = Persist(filename=self._persist_filename)
self._persist = Persist(
filename=self._persist_filename,
user=USER,
group=GROUP
)
self.call_on_accepted(self.message_type, self.send_message)

def run(self):
Expand Down
4 changes: 4 additions & 0 deletions landscape/client/manager/scriptexecution.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
from twisted.python.compat import unicode

from landscape import VERSION
from landscape.client import GROUP
from landscape.client import IS_SNAP
from landscape.client import USER
from landscape.client.manager.plugin import FAILED
from landscape.client.manager.plugin import ManagerPlugin
from landscape.client.manager.plugin import SUCCEEDED
Expand Down Expand Up @@ -319,6 +321,8 @@ def run_script(
self.registry.config.data_path,
"broker.bpickle",
),
user=USER,
group=GROUP,
)
persist = persist.root_at("registration")
computer_id = persist.get("secure-id")
Expand Down
8 changes: 7 additions & 1 deletion landscape/client/manager/snapmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

from twisted.internet import task

from landscape.client import GROUP
from landscape.client import snap_http
from landscape.client import USER
from landscape.client.manager.plugin import FAILED
from landscape.client.manager.plugin import ManagerPlugin
from landscape.client.manager.plugin import SUCCEEDED
Expand Down Expand Up @@ -270,7 +272,11 @@ def register(self, registry):
self.registry.config.data_path,
"snaps.bpickle",
)
self._persist = Persist(filename=self._persist_filename)
self._persist = Persist(
filename=self._persist_filename,
user=USER,
group=GROUP,
)
self.call_on_accepted(self.message_type, self._send_snap_update)

registry.register_message("install-snaps", self._handle_snap_task)
Expand Down
2 changes: 2 additions & 0 deletions landscape/client/tests/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2349,6 +2349,8 @@ def test_function(self, Identity, Persist):

Persist.assert_called_once_with(
filename="/tmp/landscape/broker.bpickle",
user="landscape",
group="landscape",
)
Persist().save.assert_called_once_with()
Identity.assert_called_once_with(config, Persist())
Expand Down
19 changes: 10 additions & 9 deletions landscape/client/watchdog.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from twisted.internet.protocol import ProcessProtocol

from landscape.client import IS_SNAP
from landscape.client import GROUP
from landscape.client import USER
from landscape.client.broker.amp import RemoteBrokerConnector
from landscape.client.broker.amp import RemoteManagerConnector
Expand Down Expand Up @@ -651,26 +652,26 @@ def _remove_pid(self):

bootstrap_list = BootstrapList(
[
BootstrapDirectory("$data_path", USER, "root", 0o755),
BootstrapDirectory("$data_path/package", USER, "root", 0o755),
BootstrapDirectory("$data_path/package/hash-id", USER, "root", 0o755),
BootstrapDirectory("$data_path/package/binaries", USER, "root", 0o755),
BootstrapDirectory("$data_path", USER, GROUP, 0o755),
BootstrapDirectory("$data_path/package", USER, GROUP, 0o755),
BootstrapDirectory("$data_path/package/hash-id", USER, GROUP, 0o755),
BootstrapDirectory("$data_path/package/binaries", USER, GROUP, 0o755),
BootstrapDirectory(
"$data_path/package/upgrade-tool",
USER,
"root",
0o755,
),
BootstrapDirectory("$data_path/messages", USER, "root", 0o755),
BootstrapDirectory("$data_path/sockets", USER, "root", 0o750),
BootstrapDirectory("$data_path/messages", USER, GROUP, 0o755),
BootstrapDirectory("$data_path/sockets", USER, GROUP, 0o750),
BootstrapDirectory(
"$data_path/custom-graph-scripts",
USER,
"root",
GROUP,
0o755,
),
BootstrapDirectory("$log_dir", USER, "root", 0o755),
BootstrapFile("$data_path/package/database", USER, "root", 0o644),
BootstrapDirectory("$log_dir", USER, GROUP, 0o755),
BootstrapFile("$data_path/package/database", USER, GROUP, 0o644),
],
)

Expand Down
19 changes: 15 additions & 4 deletions landscape/lib/persist.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import copy
import os
import re
import shutil
import sys

from twisted.python.compat import StringType # Py2: basestring, Py3: str
Expand Down Expand Up @@ -67,7 +68,7 @@ class Persist:
"""

def __init__(self, backend=None, filename=None):
def __init__(self, backend=None, filename=None, user=None, group=None):
"""
@param backend: The backend to use. If none is specified,
L{BPickleBackend} will be used.
Expand All @@ -85,6 +86,8 @@ def __init__(self, backend=None, filename=None):
self._readonly = False
self._modified = False
self._config = self
self._user = user
self._group = group
self.filename = filename
if filename is not None and os.path.exists(filename):
self.load(filename)
Expand Down Expand Up @@ -170,6 +173,17 @@ def save(self, filepath=None):
os.makedirs(dirname)
self._backend.save(filepath, self._hardmap)

if self._user is not None or self._group is not None:
try:
if dirname:
shutil.chown(dirname, user=self._user, group=self._group)
shutil.chown(filepath, user=self._user, group=self._group)
except PermissionError:
# A perist directory has been selected that can't be owned by
# landscape:landscape. This often happens in /tmp for tests,
# but there could be other reasons. Just leave it be.
pass

def _traverse(self, obj, path, default=NOTHING, setvalue=NOTHING):
if setvalue is not NOTHING:
setvalue = self._backend.copy(setvalue)
Expand Down Expand Up @@ -642,6 +656,3 @@ def load(self, filepath):
def save(self, filepath, map):
with open(filepath, "wb") as fd:
fd.write(self._bpickle.dumps(map))


# vim:ts=4:sw=4:et
2 changes: 1 addition & 1 deletion landscape/lib/tests/test_persist.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ def test_save_and_load(self):
self.format(result, self.set_result),
)

def test_save_on_unexistent_dir(self):
def test_save_on_nonexistent_dir(self):
dirname = self.makePersistFile()
filename = os.path.join(dirname, "foobar")

Expand Down

0 comments on commit 9b6719c

Please sign in to comment.