3 # build -- build version of sudo with Apple-specific patches applied
4 # Copyright (C) 2013 Kyle J. McKay. All rights reserved.
6 # Permission to use, copy, modify, and distribute this software for any
7 # purpose with or without fee is hereby granted, provided that the above
8 # copyright notice and this permission notice appear in all copies.
10 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 while [ -L "$myname" ]; do
23 myname
="$(readlink "$myname")"
24 case "$myname" in /*) :;; *)
25 myname
="$(dirname "$oldname")/$myname"
29 mydir
="$(cd "$
(dirname "$myname")" && pwd -P)"
30 myname
="$(basename "$myname")"
34 echo "error: build directory path contains a space: '$mydir'" >&2
39 : "${osmaj:=$(sysctl -n kern.osrelease | cut -d. -f1)}"
40 if [ $osmaj -lt 8 ]; then
41 echo "error: build os must be at least 10.4" >&2
46 trap 'echo "FAILED COMMAND ($?): ${BASH_COMMAND:-Run $0 using bash -v for details}"' ERR
52 SUDO174p10
='http://www.sudo.ws/sudo/dist/sudo-1.7.10p7.tar.gz'
53 SUDO174p10_MD5
=9faa5ceaf23cca0468d0f5d211bac6e4
54 SUDO174p10_SHA1
=b5beb1a470d1f03b3940aff612f5089244dd773a
56 SUDO_TGZ
="$SUDO174p10"
57 SUDO_MD5
="$SUDO174p10_MD5"
58 SUDO_SHA1
="$SUDO174p10_SHA1"
60 # Match Apple's sudo man pages use of the man macros for maximum compatibility
61 # Note that only 10.6.x embeds /etc/sudoers, all other OS X versions embed /private/etc/sudoers
62 SUDO_CONFIGURE
='--prefix=/usr --sysconfdir=/private/etc --with-timedir=/var/db/sudo --with-man'
63 SUDO_CONFIGURE
="$SUDO_CONFIGURE"' --with-noexec=no --with-bsm-audit --with-libraries=bsm --disable-static'
64 # Since the OS X sudo installation does not include sudoreplay there's little point in allowing io logging
65 SUDO_CONFIGURE
="$SUDO_CONFIGURE"' --without-iologdir'
66 if [ $osmaj -lt 11 ]; then
67 # Prior to OS X 10.7 --disable-setreuid, --with-env-editor and --with-password-timeout=0 were used
68 SUDO_CONFIGURE
="$SUDO_CONFIGURE"' --disable-setreuid --with-env-editor --with-password-timeout=0'
69 # Prior to OS X 10.7 the version of sudo used logged by default to the local2 facility so emulate that
70 SUDO_CONFIGURE
="$SUDO_CONFIGURE"' --with-logfac=local2' # otherwise current default is authpriv facility
72 if [ $osmaj -lt 9 ]; then
73 # The OS X 10.4 compiler does not support -fstack-protector in any form
74 # and neither does the 10.4 linker support -pie
75 SUDO_CONFIGURE
="$SUDO_CONFIGURE"' --disable-hardening --disable-pie'
76 # Also add --disable-env-reset because although env reset by default
77 # is not actually effective until the version of sudo shipped with OS X 10.6
78 # it is activated by the OS X 10.5 /etc/sudoers file so env reset is
79 # effectively active starting with OS X 10.5 and need only be disabled for 10.4
80 SUDO_CONFIGURE
="$SUDO_CONFIGURE"' --disable-env-reset'
83 DOWNLOADS
="$mydir/sources"
86 PATH
="$(getconf PATH)"
91 unset DYLD_LIBRARY_PATH
93 export LDFLAGS
="$LDFLAGS -Wl,-S,-x,-dead_strip"
94 if [ $osmaj -ge 9 ]; then
95 LDFLAGS
="$LDFLAGS -Wl,-dead_strip_dylibs,-exported_symbols_list,/dev/null"
97 # The OS X 10.4 linker needs at least one symbol in the file to strip
98 # and it also needs uninteresting warnings suppressed
99 LDFLAGS
="$LDFLAGS -Wl,-w,-exported_symbols_list,.symbols_list"
103 if ! (tar --strip-path=1 ||
: ) 2>&1 |
grep -Eqi 'unrecognized option|not supported'; then
104 strip1
=--strip-path=1
105 elif ! (tar --strip-components=1 ||
: ) 2>&1 |
grep -Eqi 'unrecognized option|not supported'; then
106 strip1
=--strip-components=1
108 if [ -z "$strip1" ]; then
109 echo "error: Cannot figure out tar option to strip top level path" >&2
113 AGENT1
='Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)'
114 AGENT2
='curl/7.25.0 (unknown-unknown-unknown) libcurl/7.25.0'
115 CURLOPT
="--fail --location --connect-timeout 15 --speed-limit 10240"
116 CURLOPT0
="$CURLOPT -H 'User-Agent:'"
117 CURLOPT1
="$CURLOPT -H 'User-Agent: $AGENT1'"
118 CURLOPT2
="$CURLOPT -H 'User-Agent: $AGENT2'"
128 openssl dgst
-md5 < "$1" 2>/dev
/null |
sed -e 's/^[^ ][^ ]* //'
133 openssl dgst
-sha1 < "$1" 2>/dev
/null |
sed -e 's/^[^ ][^ ]* //'
136 # Usage: downloadfile URL MD5 SHA1
137 # -> output is full path to downloaded file (will be in $DOWNLOADS)
140 local url
file md5 sha1 bad
142 file="$(basename "$url")"
145 local checkmd5 checksha1
146 if [ ! -d "$DOWNLOADS" ]; then
149 if [ -e "$DOWNLOADS/$file" ]; then
150 checkmd5
="$(getmd5 "$DOWNLOADS/$file")"
151 checksha1
="$(getsha1 "$DOWNLOADS/$file")"
152 if [ "$md5" != "$checkmd5" -o "$sha1" != "$checksha1" ]; then
153 echo "Wrong md5/sha1 checksum for $DOWNLOADS/$file -- removing" >&2
154 chmod u
+w
"$DOWNLOADS/$file"
155 rm "$DOWNLOADS/$file"
158 if [ ! -e "$DOWNLOADS/$file" ]; then
159 eval "curl $CURLOPT0 -o '$DOWNLOADS/$file' '$url'"
161 if [ ! -e "$DOWNLOADS/$file" ]; then
162 echo "Failed to download $url" >&2
165 checkmd5
="$(getmd5 "$DOWNLOADS/$file")"
166 checksha1
="$(getsha1 "$DOWNLOADS/$file")"
168 if [ "$md5" != "$checkmd5" ]; then
170 echo "Wrong md5 checksum $checkmd5 (expected $md5) for $DOWNLOADS/$file" >&2
172 if [ "$sha1" != "$checksha1" ]; then
174 echo "Wrong sha1 checksum $checksha1 (expected $sha1) for $DOWNLOADS/$file" >&2
176 if [ -n "$bad" ]; then
177 echo "Checksum verifcation failed for $url" >&2
180 echo "$DOWNLOADS/$file"
184 # return a suitable directory name for a tarball
188 tb
="$(basename "$1")"
196 echo "Fetching/verifying sudo sources tarball" >&2
197 sudotgz
="$(downloadfile "$SUDO_TGZ" "$SUDO_MD5" "$SUDO_SHA1")"
198 sudodir
="$(tgzdir "$sudotgz")"
200 if [ ! -e "$DOWNLOADS/$sudodir/.extracted" ]; then
201 echo "Extracting sudo sources from tarball" >&2
202 rm -rf "$DOWNLOADS/$sudodir" "$BUILD"
203 mkdir
"$DOWNLOADS/$sudodir"
204 tar -xzf "$sudotgz" -C "$DOWNLOADS/$sudodir" "$strip1"
205 touch "$DOWNLOADS/$sudodir/.extracted"
208 if [ ! -e "$DOWNLOADS/$sudodir/.patched" ]; then
209 [ -e "$DOWNLOADS/$sudodir/.extracted" ] || die
"bad extraction"
210 echo "Patching sudo sources with Apple tweaks" >&2
212 cd "$DOWNLOADS/$sudodir"
213 for pf
in "$mydir/patches/"00*.
patch.txt
; do
214 echo "$(basename "$pf")" >&2
217 touch "$DOWNLOADS/$sudodir/.patched"
221 if [ ! -e "$BUILD/.configured" ]; then
222 [ -e "$DOWNLOADS/$sudodir/.patched" ] || die
"bad patching operation"
223 echo "Configuring sudo build for OS X" >&2
227 if [ $osmaj -lt 9 ]; then
228 echo __mh_execute_header
> .symbols_list
230 "$DOWNLOADS/$sudodir/configure" $SUDO_CONFIGURE
231 echo "Stripping CONFIGURE_ARGS to match Apple sudo installation" >&2
232 perl
-i -pe 's/"[^"]+"/""/ if /^#define CONFIGURE_ARGS/' sudo_usage.h
233 echo "Enabling HAVE_TCSETPGRP which is not set properly with --without-iologdir" >&2
234 perl
-i -pe 's,^/[^/]+/,#define HAVE_TCSETPGRP 1, if /HAVE_TCSETPGRP/' config.h
235 touch "$BUILD/.configured"
239 if [ ! -e "$BUILD/.built" ]; then
240 [ -e "$BUILD/.configured" ] || die
"bad configure operation"
241 echo "Making sudo build for OS X" >&2
243 [ -x "$BUILD/sudo" ] || die
"build failed"
244 touch "$BUILD/.built"
248 echo "The newly built sudo executable can be found in the directory:"
251 echo "It can be installed with:"
252 echo " sudo make -C '$BUILD' install"
254 echo "IMPORTANT: running the above install WILL REPLACE YOUR EXISTING sudo!!!"
256 echo "Try the following to see what will be installed without installing:"
257 echo " make -C '$BUILD' -n install"
259 echo "Note that the DESTDIR=/some/dir option can be used to perform a test"
260 echo "install to a different location first like so:"
261 echo " sudo make -C '$BUILD' DESTDIR=/tmp/testsudo install"
263 echo "Using a test installation first can help decide whether or not to go"
264 echo "ahead with a normal installation."