1#!/bin/sh
2
3#
4# Copyright (C) 2012 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#      http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19# Perform login tasks for shill.  This script is called by the "login"
20# init script.
21
22# Shill expects to find a user profile in /var/run/shill/user_profiles.
23# There are 3 possible places a user profile could exist.  We should
24# use them in the following priority order:
25#
26#  - "New style" cryptohome store -- we create a link to it in
27#    /var/run/shill/user_profiles so if shill restarts while the
28#    user is logged in, shill can regain access to the profile.
29#  - User profile in ~chronos/shill -- if the above does not
30#    exist, we validate this profile and move it to the cryptohome.
31#    We then create a link to it using the step above.
32#  - Old flimflam profile in ~chronos/flimflam -- If the above
33#    does not exist, we move this to ~chronos/shill as an
34#    intermediate step then use the steps above to validate,
35#    and copy to the cryptohome profile.
36
37set -e
38# The login init script calls this script with the login name of the
39# user whose profile is being loaded.
40user=$1
41script_name=$(basename $0)
42
43profile_user=chronos
44profile_name="~${profile_user}/shill"
45shill_state_root=/var/run/shill
46profile_link_root="${shill_state_root}/user_profiles"
47profile_link_dir="$profile_link_root/$profile_user"
48log_link_dir="${shill_state_root}/log"
49username_hash=""
50
51# We should not load multiple network profiles.  If a profile link
52# directory already exists, we should go no further.
53if [ -e "$profile_link_dir" ] ; then
54  logger -t "$script_name" "User already logged in; doing nothing."
55  exit 0
56fi
57
58if [ -n "$user" ] ; then
59  profile_base=$(cryptohome-path system $user)
60  if [ ! -d "$profile_base" ] ; then
61    logger -t "$script_name" \
62      "User cryptohome dir $profile_base does not exist"
63    exit 1
64  fi
65  username_hash=$(basename $profile_base)
66
67  # Make references to the older connection manager profiles that lived
68  # in the user-owned home directory.
69  user_base=$(cryptohome-path user $user)
70  if [ -d "$user_base" ] ; then
71    flimflam_profile_dir="$user_base/flimflam"
72    flimflam_profile="$flimflam_profile_dir/flimflam.profile"
73    old_profile_dir="$user_base/shill"
74    old_profile="$old_profile_dir/shill.profile"
75  fi
76else
77  # If no user is given, create a temporary profile directory which will
78  # be erased on logout.
79  profile_base="${shill_state_root}/guest_user_profile"
80  rm -rf "$profile_base"
81  flimflam_profile=""
82  old_profile=""
83fi
84
85profile_dir="$profile_base/shill"
86profile="$profile_dir/shill.profile"
87log_dir="$profile_base/shill_logs"
88
89if [ ! -d "$profile_dir" ]; then
90  if ! mkdir -p --mode=700 $profile_dir ; then
91    logger -t "$script_name" \
92      "Failed to create shill user profile directory $profile_dir"
93    exit 1
94  fi
95fi
96
97if ! mkdir -p --mode 0700 "$profile_link_root"; then
98  logger -t "$script_name" \
99    "Unable to create shill user profile link directory"
100fi
101
102ln -s "$profile_dir" "$profile_link_dir" ||
103  logger -t "$script_name" \
104    "Failed to create shill user cryptohome link $profile_link_dir"
105
106if ! mkdir -p --mode 0700 "$log_dir"; then
107  logger -t "$script_name" \
108    "Unable to create shill log directory"
109fi
110
111if [ ! -h "$log_link_dir" ]; then
112  ln -s "$log_dir" "$log_link_dir" ||
113    logger -t "$script_name" \
114      "Failed to create shill logs link $log_link_dir"
115fi
116
117if [ ! -f "$profile" ]; then
118  if [ -f "$flimflam_profile" ]; then
119    if [ -f "$old_profile" ]; then
120      logger -t "$script_name" "Removing outdated flimflam user profile"
121      rm -f "$flimflam_profile"
122      rmdir --ignore-fail-on-non-empty "$flimflam_profile_dir"
123    else
124      old_profile="$flimflam_profile"
125      old_profile_dir="$flimflam_profile_dir"
126    fi
127  fi
128
129  if [ -f "$old_profile" ] ; then
130    test_profile="$profile_dir/shill.profile.test"
131    mv "$old_profile" "$test_profile" ||
132      logger -t "$script_name" "Failed to test-move old shill profile"
133    rmdir --ignore-fail-on-non-empty "$old_profile_dir"
134
135    # Inspect profile to make sure it makes sense as a shill profile,
136    # and is properly owned.  Do so while it's in a directory whose
137    # contents are unlikely to be modified underneath us.
138    if [ -h "$test_profile" ] ; then
139      logger -t "$script_name" "Old shill profile is a symlink"
140    elif [ ! -f "$test_profile" ] ; then
141      logger -t "$script_name" "Old shill profile is not a regular file"
142    elif [ ! -O "$test_profile" ] ; then
143      logger -t "$script_name" "Old shill profile was not properly owned"
144    else
145      logger -t "$script_name" "Moving old shill profile from $old_profile"
146      mv "$test_profile" "$profile" ||
147        logger -t "$script_name" "Failed to copy old shill profile"
148    fi
149    rm -rf "$test_profile"
150  fi
151  if [ -e "$old_profile" ] ; then
152    # Old profile exists but does not resolve to a regular file!?
153    logger -t "$script_name" "Old shill profile is not a file or was not moved"
154    rm -rf "$old_profile"
155    rmdir --ignore-fail-on-non-empty "$old_profile_dir"
156  fi
157
158  if [ ! -f "$profile" ]; then
159    # If profile still does not exist, ask shill to create one.
160    dbus-send --system --dest=org.chromium.flimflam --print-reply / \
161      org.chromium.flimflam.Manager.CreateProfile string:$profile_name ||
162        logger -t "$script_name" "Failed to create $profile_name profile"
163  fi
164fi
165
166# Push user's network profile
167dbus-send --system --dest=org.chromium.flimflam --print-reply / \
168  org.chromium.flimflam.Manager.InsertUserProfile \
169      string:$profile_name string:$username_hash ||
170    logger -t "$script_name" "Failed to push $profile_name profile"
171