Wiki source code of Kerberos
Last modified by Sebastian Marsching on 2022/03/27 14:03
Hide last authors
author | version | line-number | content |
---|---|---|---|
![]() |
1.1 | 1 | # Request a Kerberos ticket on login and renew it automatically |
2 | |||
3 | I wrote a script for retrieving a Kerberos ticket automatically on login and renewing it periodically. This script is intended for Ubuntu 12.04 LTS, but it probably will work in other environments if the necessary tools are present. It uses `kinit` and `kdestroy` from the `krb5-user` package, `krenew` from the `kstart` package, `xprop` from the `x11-utils` package and `zenity` from the `zenity` package. | ||
4 | |||
5 | I run the script by registering it as a [startup application](http://askubuntu.com/questions/48321/how-do-i-start-applications-automatically-on-login) in Unity, but probably it can also be started from `.xinitrc` or some other place, that is run after the X server has been started. If starting it from a script, you want to run it in the background, because otherwise it will block further execution. | ||
6 | |||
7 | Obviously, you have to replace the username and realm in the script with the data that applies to your environment. When the script is started, a dialog that asks you for your password (the one needed to obtain the Kerberos TGT). After obtaining the initial ticket, it will automatically renew it from time to time, so that you will not have to enter your password again. | ||
8 | |||
9 | Their is a section in the script where you can add your own commands, e.g. for mounting a Samba share, that needs a Kerberos TGT to be available. | ||
10 | |||
11 | If you are using KDE instead of an GTK-based environment (like Unity or GNOME), you might want to use `kdedialog` instead of `zenity`. | ||
12 | |||
13 | ```bash | ||
14 | #!/bin/bash | ||
15 | |||
16 | user="myusername" | ||
17 | realm="MY.KERBEROS.REALM.EXAMPLE.COM" | ||
18 | |||
19 | ask_for_password() { | ||
20 | # When using KDE, you might want to use kdedialog instead of zenity | ||
21 | password="`zenity --password --title "Kerberos Authentication"`" | ||
22 | } | ||
23 | |||
24 | request_ticket() { | ||
25 | # Request a renewable ticket that is valid for one day | ||
26 | kinit -r 1d "$user@$realm" <<EOF | ||
27 | $password | ||
28 | EOF | ||
29 | } | ||
30 | |||
31 | rc=1 | ||
32 | while [ $rc -ne 0 ] && ask_for_password; do | ||
33 | request_ticket | ||
34 | rc=$? | ||
35 | done | ||
36 | |||
37 | if [ $rc -ne 0 ]; then | ||
38 | # The user cancelled the operation before a Kerberos ticket could be | ||
39 | # successfully received. | ||
40 | exit 1 | ||
41 | fi | ||
42 | |||
43 | # Optional: Perform actions that depend on a Kerberos ticket being available | ||
44 | # (e.g. gvfs-mount) | ||
45 | #gvfs-mount smb://myserver.example.com/myshare | ||
46 | # We use this process in order to detect when the X session ends. | ||
47 | xprop -root -spy >/dev/null & | ||
48 | xprop_pid=$! | ||
49 | |||
50 | # Function for killing processes and cleaning up the Kerberos tickets | ||
51 | clean_up() { | ||
52 | kill $xprop_pid | ||
53 | kdestroy | ||
54 | exit 0 | ||
55 | } | ||
56 | |||
57 | # If this script receives a HUP, INT or TERM signal, we want to kill the | ||
58 | # child processes immediately. | ||
59 | trap clean_up HUP INT TERM | ||
60 | |||
61 | # Wait for X session to end and occasionally (every minute) try to renew | ||
62 | # ticket, if it is going to expire within the next 15 minutes. | ||
63 | |||
64 | run_with_default_locale() { | ||
65 | LANG=C LC_ALL=C LC_CTYPE=C LC_MESSAGES=C "$@" | ||
66 | } | ||
67 | |||
68 | get_expiration_time_string() { | ||
69 | run_with_default_locale klist | \ | ||
70 | grep -E "^[0-9]+/[0-9]+/[0-9]+[[:space:]]+[0-9]+:[0-9]+:[0-9]+[[:space:]]+[0-9]+/[0-9]+/[0-9]+[[:space:]]+[0-9]+:[0-9]+:[0-9]+[[:space:]]+krbtgt/" | \ | ||
71 | grep -o -E "[0-9]+/[0-9]+/[0-9]+[[:space:]]+[0-9]+:[0-9]+:[0-9]+" | \ | ||
72 | tail -n 1 | ||
73 | } | ||
74 | |||
75 | get_expiration_time() { | ||
76 | local expiration_time | ||
77 | expiration_time="`get_expiration_time_string`" | ||
78 | if [ -n "${expiration_time}" ]; then | ||
79 | run_with_default_locale date --date="${expiration_time}" +%s | ||
80 | else | ||
81 | echo 0 | ||
82 | fi | ||
83 | } | ||
84 | |||
85 | get_remaining_time() { | ||
86 | local expiration_time now remaining_time | ||
87 | expiration_time="`get_expiration_time`" | ||
88 | now="`run_with_default_locale date +%s`" | ||
89 | echo "$(( ${expiration_time} - ${now} ))" | ||
90 | } | ||
91 | |||
92 | last_renew="`date "+%s"`" | ||
93 | while kill -0 $xprop_pid; do | ||
94 | now="`date "+%s"`" | ||
95 | if [ $(( $now - $last_renew)) -ge 60 ]; then | ||
96 | if [ "`get_remaining_time`" -lt 900 ]; then | ||
97 | request_ticket | ||
98 | fi | ||
99 | fi | ||
100 | sleep 1 | ||
101 | done | ||
102 | |||
103 | # Clean up after X session has ended | ||
104 | clean_up | ||
105 | ``` |