make sure we're explicitly capturing return codes in places where they are tested...
[monkeysphere.git] / src / share / ma / update_users
1 # -*-shell-script-*-
2 # This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
3
4 # Monkeysphere authentication update-users subcommand
5 #
6 # The monkeysphere scripts are written by:
7 # Jameson Rollins <jrollins@finestructure.net>
8 # Jamie McClelland <jm@mayfirst.org>
9 # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
10 #
11 # They are Copyright 2008-2009, and are all released under the GPL,
12 # version 3 or later.
13
14 update_users() {
15
16 local unames
17 local uname
18 local authorizedKeysDir
19 local authorizedUserIDs
20
21 if [ "$1" ] ; then
22     # get users from command line
23     unames="$@"
24 else         
25     # or just look at all users if none specified
26     unames=$(getent passwd | cut -d: -f1)
27 fi
28
29 RETURN=0
30
31 # set mode
32 MODE="authorized_keys"
33
34 # set gnupg home
35 GNUPGHOME="$GNUPGHOME_SPHERE"
36
37 # the authorized_keys directory
38 authorizedKeysDir="${SYSDATADIR}/authorized_keys"
39
40 # check to see if the gpg trust database has been initialized
41 if [ ! -s "${GNUPGHOME}/trustdb.gpg" ] ; then
42     failure "GNUPG trust database uninitialized.  Please see MONKEYSPHERE-SERVER(8)."
43 fi
44
45 # make sure the authorized_keys directory exists
46 mkdir -p "${authorizedKeysDir}"
47
48 # loop over users
49 for uname in $unames ; do
50     # check all specified users exist
51     if ! id "$uname" >/dev/null ; then
52         log error "----- unknown user '$uname' -----"
53         continue
54     fi
55
56     log verbose "----- user: $uname -----"
57
58     # make temporary directory
59     TMPLOC=$(mktemp -d ${MATMPDIR}/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!"
60
61     # trap to delete temporary directory on exit
62     trap "rm -rf $TMPLOC" EXIT
63
64     # create temporary authorized_user_ids file
65     TMP_AUTHORIZED_USER_IDS="${TMPLOC}/authorized_user_ids"
66     touch "$TMP_AUTHORIZED_USER_IDS"
67
68      # create temporary authorized_keys file
69     AUTHORIZED_KEYS="${TMPLOC}/authorized_keys"
70     touch "$AUTHORIZED_KEYS"
71
72     # set restrictive permissions on the temporary files
73     # FIXME: is there a better way to do this?
74     chmod 0700 "$TMPLOC"
75     chmod 0600 "$AUTHORIZED_KEYS"
76     chmod 0600 "$TMP_AUTHORIZED_USER_IDS"
77     chown -R "$MONKEYSPHERE_USER" "$TMPLOC"
78
79     # process authorized_user_ids file
80     log debug "checking for authorized_user_ids..."
81     # translating ssh-style path variables
82     authorizedUserIDs=$(translate_ssh_variables "$uname" "$AUTHORIZED_USER_IDS")
83     if [ -s "$authorizedUserIDs" ] ; then
84         # check permissions on the authorized_user_ids file path
85         if check_key_file_permissions "$uname" "$authorizedUserIDs" ; then
86             # copy user authorized_user_ids file to temporary
87             # location
88             cat "$authorizedUserIDs" > "$TMP_AUTHORIZED_USER_IDS"
89
90             # export needed variables
91             export AUTHORIZED_KEYS
92             export TMP_AUTHORIZED_USER_IDS
93
94             # process authorized_user_ids file, as monkeysphere user
95             su_monkeysphere_user \
96                 ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS" \
97                 || RETURN="$?"
98         else
99             log debug "not processing authorized_user_ids."
100         fi
101     else
102         log debug "empty or absent authorized_user_ids file."
103     fi
104
105     # add user-controlled authorized_keys file if specified translate
106     # ssh-style path variables
107     rawAuthorizedKeys=$(translate_ssh_variables "$uname" "$RAW_AUTHORIZED_KEYS")
108     if [ "$rawAuthorizedKeys" != 'none' ] ; then
109         log debug "checking for raw authorized_keys..."
110         if [ -s "$rawAuthorizedKeys" ] ; then
111             # check permissions on the authorized_keys file path
112             if check_key_file_permissions "$uname" "$rawAuthorizedKeys" ; then
113                 log verbose "adding raw authorized_keys file... "
114                 cat "$rawAuthorizedKeys" >> "$AUTHORIZED_KEYS"
115             else
116                 log debug "not adding raw authorized_keys file."                
117             fi
118         else
119             log debug "empty or absent authorized_keys file."
120         fi
121     fi
122
123     # move the new authorized_keys file into place
124     if [ -s "$AUTHORIZED_KEYS" ] ; then
125         # openssh appears to check the contents of the authorized_keys
126         # file as the user in question, so the file must be readable
127         # by that user at least.
128
129         # but in general, we don't want the user tampering with this
130         # file directly, so we'll adopt this approach: Own the file by
131         # the monkeysphere-server invoker (usually root, but should be
132         # the same uid that sshd is launched as); change the group of
133         # the file so that members of the user's group can read it.
134
135         # FIXME: is there a better way to do this?
136         chown $(whoami) "$AUTHORIZED_KEYS" && \
137             chgrp $(id -g "$uname") "$AUTHORIZED_KEYS" && \
138             chmod g+r "$AUTHORIZED_KEYS" && \
139             mv -f "$AUTHORIZED_KEYS" "${authorizedKeysDir}/${uname}" || \
140             { 
141             log error "Failed to install authorized_keys for '$uname'!"
142             rm -f "${authorizedKeysDir}/${uname}"
143             # indicate that there has been a failure:
144             RETURN=1
145         }
146     else
147         rm -f "${authorizedKeysDir}/${uname}"
148     fi
149
150     # unset the trap
151     trap - EXIT
152
153     # destroy temporary directory
154     rm -rf "$TMPLOC"
155 done
156
157 return $RETURN
158 }