| #!/bin/sh |
| |
| # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Perform login tasks for shill. This script is called by the "login" |
| # init script. |
| |
| # Shill expects to find a user profile in /run/shill/user_profiles. We |
| # link this path to the user profile in the user's cryptohome store so |
| # if shill restarts while the user is logged in, shill can regain access |
| # to the profile. |
| |
| set -e |
| # The login init script calls this script with the login name of the |
| # user whose profile is being loaded. |
| user="$1" |
| script_name="$(basename "$0")" |
| |
| profile_user="chronos" |
| profile_name="~${profile_user}/shill" |
| shill_state_root="/run/shill" |
| profile_link_root="${shill_state_root}/user_profiles" |
| profile_link_dir="${profile_link_root}/${profile_user}" |
| username_hash="" |
| |
| if [ -z "${user}" ]; then |
| logger -t "${script_name}" "Unexpected empty user" |
| exit 1 |
| fi |
| |
| # We should not load multiple network profiles. If a profile link |
| # directory already exists, we should go no further. |
| if [ -e "${profile_link_dir}" ]; then |
| logger -t "${script_name}" "User already logged in; doing nothing." |
| exit 0 |
| fi |
| |
| system_path="$(cryptohome-path system "${user}")" |
| profile_base="/run/daemon-store/shill" |
| if [ ! -d "${profile_base}" ]; then |
| logger -t "${script_name}" \ |
| "Daemon-store dir ${profile_base} does not exist" |
| exit 1 |
| fi |
| username_hash="$(basename "${system_path}")" |
| |
| profile_dir="${profile_base}/${username_hash}" |
| profile="${profile_dir}/shill.profile" |
| |
| if [ ! -d "${profile_dir}" ]; then |
| if ! mkdir -p --mode=700 "${profile_dir}"; then |
| logger -t "${script_name}" \ |
| "Failed to create shill user profile directory ${profile_dir}" |
| exit 1 |
| fi |
| fi |
| |
| # We need to ensure this dir (and files within it) are owned by shill:shill, |
| # regardless of whether we are creating it on this login or it already existed |
| # before now. By default, the 'chown -R' command does not follow symlinks, so |
| # there is no way shill can put a symlink in this dir as means of tricking the |
| # system into making other files owned by 'shill'. Also, this being the "shill |
| # user profile directory", it is fine to give shill ownership of all of its |
| # contents. Although 'chown -R' doesn't follow symlinks, it does affect bind |
| # mounts, so this code is only safe as long as shill runs without |
| # CAP_SYS_ADMIN. Ideally we should have some kind of test to make sure shill |
| # capabilities are never widened to include CAP_SYS_ADMIN -- filed |
| # crbug.com/869170 to track this issue in the general sense for CrOS system |
| # services. |
| if ! chown -R shill:shill "${profile_dir}"; then |
| logger -t "${script_name}" \ |
| "Failed to chown shill user profile directory ${profile_dir}" |
| exit 1 |
| fi |
| |
| if ! mkdir -p --mode 0700 "${profile_link_root}"; then |
| logger -t "${script_name}" \ |
| "Unable to create shill user profile link directory" |
| else |
| if ! chown shill:shill "${profile_link_root}"; then |
| logger -t "${script_name}" \ |
| "Unable to chown shill user profile link directory" |
| fi |
| fi |
| |
| ln -s "${profile_dir}" "${profile_link_dir}" || |
| logger -t "${script_name}" \ |
| "Failed to create shill user cryptohome link ${profile_link_dir}" |
| |
| # We don't log here any more. |
| # TODO(crbug.com/1076094): remove this after M-86. |
| rm -rf "${profile_base}/shill_logs" |
| |
| # wait_for_shill_dbus_services polls for the org.chromium.flimflam |
| # in the org.freedesktop.DBus.ListNames list that has all connected |
| # names on the Bus. |
| wait_for_shill_dbus_services() { |
| for _ in $(seq 1 15); do |
| if dbus-send --system --print-reply --dest=org.freedesktop.DBus \ |
| /org/freedesktop/DBus org.freedesktop.DBus.ListNames | |
| grep -q '"org.chromium.flimflam"'; then |
| return 0 |
| fi |
| sleep 0.2 |
| done |
| } |
| |
| # Technically, there's no guarantee that Shill has finished initializing |
| # before a login event happens. In practice, we don't experience that |
| # race unless Shill is actively crashing, but it does occur in tests |
| # (where we may intentionally restart Shill). |
| wait_for_shill_dbus_services |
| |
| if [ ! -f "${profile}" ]; then |
| # If profile does not exist, ask shill to create one. |
| dbus-send --system --dest=org.chromium.flimflam --print-reply / \ |
| org.chromium.flimflam.Manager.CreateProfile string:"${profile_name}" || |
| logger -t "${script_name}" "Failed to create ${profile_name} profile" |
| fi |
| |
| # Push user's network profile |
| dbus-send --system --dest=org.chromium.flimflam --print-reply / \ |
| org.chromium.flimflam.Manager.InsertUserProfile \ |
| string:"${profile_name}" string:"${username_hash}" || |
| logger -t "${script_name}" "Failed to push ${profile_name} profile" |