summaryrefslogtreecommitdiff
path: root/xauth_switch_to_sun-des-1
blob: b2a68d8467cb5a6bd247a3fde454b6de05cf0d87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/bin/ksh
# X11 MIT-MAGIC-COOKIE to SUN-DES-1 auth.
# this script switched the current Xservers authentication
# (usually MIT-MAGIC-COOKIE-1) to SUN-DES-1.
#
#
# Copyright 2002-2004 by Roland Mainz <roland.mainz@nrubsig.org>.
#
#
# Requirements:
# - Solaris/Linux/AIX running as NIS+ client (YP/LDAP not supported yet)
# - user must have proper credentials ("SecureRPC")
# - script must be able to "guess" the UID of the Xserver
#
# Advantages:
# - User may allow other users to gain access via
#   % xhost +jigsaw@
#   instead of moving 128bit cookies
#
# Known bugs:
# - Was not tested on Linux since several months


umask 077
# force POSIX binaries
export PATH=/usr/xpg4/bin:/usr/bin:/usr/dt/bin:/usr/openwin/bin

# debug
alias xxdebug=true
# alias xxdebug=

# get full qualified domain name
getFQDN()
{
    getent hosts ${1} | awk "{print \$2}" -
}

user2netname()
{
    UID=$(id -u $1)
    DOMAINNAME=$(domainname)
    if [ $UID != 0 ] ; then
        netname=unix.$UID@$DOMAINNAME
    else
        netname=unix.$HOSTNAME@$DOMAINNAME
    fi

    # BUG: SecureRPC isn't limited to NIS+
    #      (but there is no "getent publickey ...") ...
    # ToDo:
    # - YP name is "publickey.byname"
    # - What name does LDAP use ?
    if [ "`nismatch "auth_name=$netname" cred.org_dir`" != "" ] ; then
        echo "$netname"
    else
        echo "user ${UID} has no entry in cred.org_dir" >&2
        return 1
    fi

    return 0
}


# pid to username
getUserOfPID()
{
    ps -p $1 -o user,pid | awk "NR != 1 {print \$1}" -
}

# test if we can access $DISPLAY via SUN-DES-1 auth. using a temporary
# Xauthority file
dry_run()
{
(
  principal="$1"
  # XAUTHORITY may not be defined
  if [ "$XAUTHORITY" = "" ] ; then
      export XAUTHORITY=~/.Xauthority
  fi

  ORIGINAL_XAUTHORITY="${XAUTHORITY:-~/.Xauthority}"
  TMP_XAUTHORITY=/tmp/mit-cookie2sun-des-1tmpxauth_${LOGNAME}_${RANDOM}.xauth
  export XAUTHORITY="$TMP_XAUTHORITY"
  touch "$XAUTHORITY"

  (echo "add $displayhost/unix:$displaynum SUN-DES-1 $principal" ;
   echo "add $displayhost:$displaynum SUN-DES-1 $principal"
  ) | xauth source -

  # check if a sample X11 app. (/usr/openwin/bin/xset) can access Xserver...
  if ! xset q 2>/dev/null 1>/dev/null ; then
    # clean-up
    rm -f "$TMP_XAUTHORITY"
    return 1
  fi

  rm -f "$TMP_XAUTHORITY"

  return 0
)
}

# main

HOSTNAME=$(hostname)
FQDN=$(getFQDN $HOSTNAME)

# be sure that DISPLAY contains the host name
# BUGs:
# - this does _not_ catch non-tcp connections (like DECnet).
# - this may not work with IPv6 addresses
displayhost=${DISPLAY%:*}
displaynum=$(x=${DISPLAY#*:}; echo ${x%.*})
if [ "$displayhost" == "" -o "$displayhost" == "localhost" ] ; then
    # fix DISPLAY
    export DISPLAY="${FQDN}:${DISPLAY#*:}"
    displayhost=${DISPLAY%:*}
fi


# grant access for current user and for user root
# (a bug in /usr/dt/bin/dtaction requires this for user "root", too -
# Solaris 7/8 dtaction runs setuid root and opens a display connection
# before changing the EUID to the "destination uid"... ;-( ).
xhost +${LOGNAME}@ +$(user2netname root)

# get X server principal(=user)
# this may fail if user isn't local
# unfortunately we cannot get the Xserver PID with a simply API - we
# have to "guess" in this case. "pgrep" creates a list of PIDs which may
# match. Then we create a list of all matching "principals" and test
# them - item by item...
# ... step 1: Create list of principals
principal_list=""          # you can add "most common" principals here...
fallback_principal_list="" # you can add "fallback" principals here
                           # (for example, principals for Xterminals (where
                           # the Xserver always runs under the same UID)
                           # which use SUN-DES-1)
for i in $(pgrep -f ".*X.* :$displaynum*") ; do
    principal_list="$(user2netname `getUserOfPID $i`) ${principal_list}"
done

xxdebug echo "principal_list=${principal_list}"

# ... step 2: Test the list of principals
for PRINCIPAL in ${principal_list} ${fallback_principal_list} ; do
    # make a "dry run" and test whether we really can use SUN-DES-1 auth.
    # for this display using the given principal
    if dry_run "${PRINCIPAL}" ; then
        # remove old MIT-MAGIC-COOKIES and insert SUN-DES-1 cookies
        # Users ~/.Xauthority _must_ be changed in _one_ step to avoid
        # possible race conditions when switching auth. on a "live"
        # $DISPLAY...
        (echo "remove $displayhost/unix:$displaynum" ;
         echo "remove $displayhost:$displaynum" ;
         echo "add $displayhost/unix:$displaynum SUN-DES-1 $PRINCIPAL" ;
         echo "add $displayhost:$displaynum SUN-DES-1 $PRINCIPAL"
        ) | xauth source -

        # success.
        xxdebug echo "success."
        exit 0
    fi
done

echo "${0}: failure; could not establish SUN-DES-1 auth. on $DISPLAY" >&2
xhost -$LOGNAME@ -$(user2netname root)

# failure.
xxdebug echo failure.
exit 1
# EOF.