@@ -31,35 +31,65 @@ class KerberosApacheAuth extends KerberosAuth implements IAuth {
3131 /** @var string */
3232 private $ ticketPath = "" ;
3333
34- // only working with specific library (mod_auth_kerb, krb5, smbclient) versions
35- /** @var bool */
36- private $ saveTicketInMemory = false ;
37-
3834 /** @var bool */
3935 private $ init = false ;
4036
37+ /** @var string|false */
38+ private $ ticketName ;
39+
40+ public function __construct () {
41+ $ this ->ticketName = getenv ("KRB5CCNAME " );
42+ }
43+
44+
45+ /**
46+ * Copy the ticket to a temporary location and use that ticket for authentication
47+ *
48+ * @return void
49+ */
50+ public function copyTicket (): void {
51+ if (!$ this ->checkTicket ()) {
52+ return ;
53+ }
54+ $ krb5 = new \KRB5CCache ();
55+ $ krb5 ->open ($ this ->ticketName );
56+ $ tmpFilename = tempnam ("/tmp " , "krb5cc_php_ " );
57+ $ tmpCacheFile = "FILE: " . $ tmpFilename ;
58+ $ krb5 ->save ($ tmpCacheFile );
59+ $ this ->ticketPath = $ tmpFilename ;
60+ $ this ->ticketName = $ tmpCacheFile ;
61+ }
62+
4163 /**
42- * @param bool $saveTicketInMemory
64+ * Pass the ticket to smbclient by memory instead of path
65+ *
66+ * @return void
4367 */
44- public function __construct (bool $ saveTicketInMemory = false ) {
45- $ this ->saveTicketInMemory = $ saveTicketInMemory ;
68+ public function passTicketFromMemory (): void {
69+ if (!$ this ->checkTicket ()) {
70+ return ;
71+ }
72+ $ krb5 = new \KRB5CCache ();
73+ $ krb5 ->open ($ this ->ticketName );
74+ $ this ->ticketName = (string )$ krb5 ->getName ();
4675 }
4776
4877 /**
4978 * Check if a valid kerberos ticket is present
5079 *
5180 * @return bool
81+ * @psalm-assert-if-true string $this->ticketName
5282 */
5383 public function checkTicket (): bool {
5484 //read apache kerberos ticket cache
55- $ cacheFile = getenv ("KRB5CCNAME " );
56- if (!$ cacheFile ) {
85+ if (!$ this ->ticketName ) {
5786 return false ;
5887 }
5988
6089 $ krb5 = new \KRB5CCache ();
61- $ krb5 ->open ($ cacheFile );
62- return (bool )$ krb5 ->isValid ();
90+ $ krb5 ->open ($ this ->ticketName );
91+ /** @psalm-suppress MixedArgument */
92+ return count ($ krb5 ->getEntries ()) > 0 ;
6393 }
6494
6595 private function init (): void {
@@ -75,28 +105,13 @@ private function init(): void {
75105 }
76106
77107 //read apache kerberos ticket cache
78- $ cacheFile = getenv ("KRB5CCNAME " );
79- if (!$ cacheFile ) {
108+ if (!$ this ->checkTicket ()) {
80109 throw new Exception ('No kerberos ticket cache environment variable (KRB5CCNAME) found. ' );
81110 }
82111
83- $ krb5 = new \KRB5CCache ();
84- $ krb5 ->open ($ cacheFile );
85- if (!$ krb5 ->isValid ()) {
86- throw new Exception ('Kerberos ticket cache is not valid. ' );
87- }
88-
89-
90- if ($ this ->saveTicketInMemory ) {
91- putenv ("KRB5CCNAME= " . (string )$ krb5 ->getName ());
92- } else {
93- //workaround: smbclient is not working with the original apache ticket cache.
94- $ tmpFilename = tempnam ("/tmp " , "krb5cc_php_ " );
95- $ tmpCacheFile = "FILE: " . $ tmpFilename ;
96- $ krb5 ->save ($ tmpCacheFile );
97- $ this ->ticketPath = $ tmpFilename ;
98- putenv ("KRB5CCNAME= " . $ tmpCacheFile );
99- }
112+ // note that even if the ticketname is the value we got from `getenv("KRB5CCNAME")` we still need to set the env variable ourselves
113+ // this is because `getenv` also reads the variables passed from the SAPI (apache-php) and we need to set the variable in the OS's env
114+ putenv ("KRB5CCNAME= " . $ this ->ticketName );
100115 }
101116
102117 public function getExtraCommandLineArguments (): string {
@@ -106,7 +121,11 @@ public function getExtraCommandLineArguments(): string {
106121
107122 public function setExtraSmbClientOptions ($ smbClientState ): void {
108123 $ this ->init ();
109- parent ::setExtraSmbClientOptions ($ smbClientState );
124+ try {
125+ parent ::setExtraSmbClientOptions ($ smbClientState );
126+ } catch (Exception $ e ) {
127+ // suppress
128+ }
110129 }
111130
112131 public function __destruct () {
0 commit comments