← Back to team overview

debcrafters-packages team mailing list archive

[Bug 2099917] Re: cifs.upcall: If kerberos credential cache already contains a valid service ticket, use that even if TGT is expired

 

** Summary changed:

- cifs.upcall program in the cifs-utils package fails to use a valid service ticket from the credential cache if the TGT is expired or not exist
+ cifs.upcall: If kerberos credential cache already contains a valid service ticket, use that even if TGT is expired

** Description changed:

- cifs.upcall program in the cifs-utils package fails to use a valid
- service ticket from the credential cache if the TGT is expired or not
- exist
+ [Impact]
  
+ When mounting an SMB file share using the kernel client with Kerberos 
+ authentication, cifs.ko module makes an upcall to user space during the session
+ setup phase to retrieve the Kerberos service ticket from the credential cache.
  
- When mounting an SMB file share on Linux using the kernel client with Kerberos authentication, the Linux kernel's cifs.ko module makes an upcall to user space during the session setup phase to retrieve the Kerberos service ticket from the credential cache. However, the current cifs.upcall fails to retrieve the service ticket even if it is valid, but instead it makes check to TGT to see if its valid and then retrieve the service ticket, but if we already have valid service ticket we shouldn't need to check for TGT.
+ cifs.upcall first checks if the TGT is valid, and only if it is, checks if a
+ service ticket exists, and if it does if it is valid.
  
- i.e in cases where the kernel handles upcalls for SMB session setup
- requests with Kerberos authentication, if the credential cache already
- contains a valid service ticket, it should be used directly without
- needing to check the TGT again.
+ If we already have a valid service ticket, it should not matter if the TGT is
+ valid or not, so we should just directly use the service ticket instead of
+ trying to get a new TGT / force the user to kinit again.
  
+ [Testcase]
  
- Fixed commit: https://git.samba.org/?p=cifs-utils.git;a=commit;h=af76bf2a11a060afdfd97104617a701d19d5890d
+ Follow the entire testcase of https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2099914
+ first.
+ 
+ Get a new TGT and krb5 credential cache.
+ 
+ # kinit Administrator@xxxxxxxxxxxxxxxxxxxx
+ Password for Administrator@xxxxxxxxxxxxxxxxxxxx: 
+ Warning: Your password will expire in 29 days on Wed Jun 11 05:01:22 2025
+ 
+ # klist
+ Ticket cache: FILE:/tmp/krb5cc_0
+ Default principal: Administrator@xxxxxxxxxxxxxxxxxxxx
+ 
+ Valid starting     Expires            Service principal
+ 05/12/25 11:56:59  05/12/25 21:56:59  krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
+ 	renew until 05/13/25 11:56:55
+ 
+ # mount -t cifs -o
+ cruid=root,user=root,sec=krb5i,uid=0,gid=0,cred=/tmp/krb5cc_0 //samba-
+ dc.example.com/demo /mnt/testshare1
+ 
+ # klist
+ Ticket cache: FILE:/tmp/krb5cc_0
+ Default principal: Administrator@xxxxxxxxxxxxxxxxxxxx
+ 
+ Valid starting     Expires            Service principal
+ 05/12/25 11:56:59  05/12/25 21:56:59  krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
+ 	renew until 05/13/25 11:56:55
+ 05/12/25 11:58:21  05/12/25 21:56:59  cifs/samba-dc.example.com@
+ 	renew until 05/13/25 11:56:55
+ 	Ticket server: cifs/samba-dc.example.com@xxxxxxxxxxxxxxxxxxxx
+ 
+ # umount /mnt/testshare1
+ 
+ Next, we need to perform some surgery to remove the TGT, using this neat
+ tool:
+ 
+ # git clone https://git.nullroute.lt/hacks/python-krb5ccparse.git
+ # cd python-krb5ccparse
+ # ./kremovetkt -c /tmp/krb5cc_0 -o /tmp/removed -p krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
+ Keeping ticket for krb5_ccache_conf_data/fast_avail/krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx@X-CACHECONF:
+ Keeping ticket for krb5_ccache_conf_data/pa_type/krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx@X-CACHECONF:
+ Skipping ticket for krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
+ Keeping ticket for cifs/samba-dc.example.com@
+ 
+ # kdestroy
+ # mv /tmp/removed /tmp/krb5cc_0
+ # klist -c /tmp/removed 
+ Ticket cache: FILE:/tmp/removed
+ Default principal: Administrator@xxxxxxxxxxxxxxxxxxxx
+ 
+ Valid starting     Expires            Service principal
+ 05/12/25 11:58:21  05/12/25 21:56:59  cifs/samba-dc.example.com@
+ 	renew until 05/13/25 11:56:55
+ 	Ticket server: cifs/samba-dc.example.com@xxxxxxxxxxxxxxxxxxxx
+ 	
+ Now we have a kerberos credential cache with a service ticket only, and no
+ TGT.
+ 
+ If we try and mount now:
+ 
+ # mount -t cifs -o cruid=root,user=root,sec=krb5i,uid=0,gid=0,cred=/tmp/krb5cc_0 //samba-dc.example.com/demo /mnt/testshare1
+ mount error(126): Required key not available
+ Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)
+ 
+ kernel: CIFS: enabling forceuid mount option implicitly because uid= option is specified
+ kernel: CIFS: enabling forcegid mount option implicitly because gid= option is specified
+ kernel: CIFS: Attempting to mount //samba-dc.example.com/demo
+ cifs.upcall[2206]: key description: cifs.spnego;0;0;39010000;ver=0x2;host=samba-dc.example.com;ip4=192.168.122.191;sec=krb5;uid=0x0;creduid=>
+ cifs.upcall[2207]: ver=2
+ cifs.upcall[2207]: host=samba-dc.example.com
+ cifs.upcall[2207]: ip=192.168.122.191
+ cifs.upcall[2207]: sec=1
+ cifs.upcall[2207]: uid=0
+ cifs.upcall[2207]: creduid=0
+ cifs.upcall[2207]: user=root
+ cifs.upcall[2207]: pid=2202
+ cifs.upcall[2206]: get_cachename_from_process_env: pid == 0
+ cifs.upcall[2206]: get_existing_cc: default ccache is FILE:/tmp/krb5cc_0
+ cifs.upcall[2206]: krb5_get_init_creds_keytab: -1765328378
+ cifs.upcall[2206]: handle_krb5_mech: getting service ticket for samba-dc.example.com
+ cifs.upcall[2206]: handle_krb5_mech: using GSS-API
+ cifs.upcall[2206]: GSS-API error init_sec_context: Unspecified GSS failure.  Minor code may provide more information
+ cifs.upcall[2206]: GSS-API error init_sec_context: Matching credential not found (filename: /tmp/krb5cc_0)
+ cifs.upcall[2206]: handle_krb5_mech: failed to obtain service ticket via GSS (851968)
+ cifs.upcall[2206]: Unable to obtain service ticket
+ cifs.upcall[2206]: Exit status 851968
+ kernel: CIFS: VFS: Verify user has a krb5 ticket and keyutils is installed
+ kernel: CIFS: VFS: \\samba-dc.example.com Send error in SessSetup = -126
+ kernel: CIFS: VFS: cifs_mount failed w/return code = -126
+ 
+ If you install the test packages available in the following ppa:
+ 
+ https://launchpad.net/~mruffell/+archive/ubuntu/sf407276-test
+ 
+ The mount completes as expected.
+ 
+ [Where problems could occur]
+ 
+ We are removing the check to see if there is a valid TGT before checking if
+ there is a valid service ticket. If the TGT is expired, then previously it would
+ have forced the user to intervene to get a new TGT before being able to
+ mount or connect to SMB shares with the service ticket. 
+ 
+ Now, we just need a service ticket only. For the most part, this won't make
+ much of a difference, as usually the service ticket is set to expire at the
+ same time as a TGT, so we would have to get a TGT anyway. But if they happen to
+ have different expiration schedules, or if we have a custom credential cache
+ with no TGT, we can now just go straight to using the service ticket.
+ 
+ If a regression were to occur, it would affect the mounting of cifs / SMB
+ shares, and ticket renegotiation if a ticket were to expire. 
+ 
+ [Other info]
+ 
+ Fixed in upstream in cifs-utils 7.2 by:
+ 
+ commit af76bf2a11a060afdfd97104617a701d19d5890d
+ From: Bharath SM <bharathsm@xxxxxxxxxxxxx>
+ Date: Tue, 26 Nov 2024 22:57:44 +0530
+ Subject: cifs-utils: Skip TGT check if valid service ticket is already available
+ Link: https://git.samba.org/?p=cifs-utils.git;a=commit;h=af76bf2a11a060afdfd97104617a701d19d5890d

-- 
You received this bug notification because you are a member of
Debcrafters packages, which is subscribed to cifs-utils in Ubuntu.
https://bugs.launchpad.net/bugs/2099917

Title:
  cifs.upcall: If kerberos credential cache already contains a valid
  service ticket, use that even if TGT is expired

Status in cifs-utils package in Ubuntu:
  Fix Released
Status in cifs-utils source package in Focal:
  In Progress
Status in cifs-utils source package in Jammy:
  In Progress
Status in cifs-utils source package in Noble:
  In Progress
Status in cifs-utils source package in Oracular:
  In Progress
Status in cifs-utils source package in Plucky:
  Fix Released

Bug description:
  [Impact]

  When mounting an SMB file share using the kernel client with Kerberos
  authentication, cifs.ko module makes an upcall to user space during the session
  setup phase to retrieve the Kerberos service ticket from the credential cache.

  cifs.upcall first checks if the TGT is valid, and only if it is, checks if a
  service ticket exists, and if it does if it is valid.

  If we already have a valid service ticket, it should not matter if the TGT is
  valid or not, so we should just directly use the service ticket instead of
  trying to get a new TGT / force the user to kinit again.

  [Testcase]

  Follow the entire testcase of https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2099914
  first.

  Get a new TGT and krb5 credential cache.

  # kinit Administrator@xxxxxxxxxxxxxxxxxxxx
  Password for Administrator@xxxxxxxxxxxxxxxxxxxx:
  Warning: Your password will expire in 29 days on Wed Jun 11 05:01:22 2025

  # klist
  Ticket cache: FILE:/tmp/krb5cc_0
  Default principal: Administrator@xxxxxxxxxxxxxxxxxxxx

  Valid starting     Expires            Service principal
  05/12/25 11:56:59  05/12/25 21:56:59  krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
   renew until 05/13/25 11:56:55

  # mount -t cifs -o
  cruid=root,user=root,sec=krb5i,uid=0,gid=0,cred=/tmp/krb5cc_0 //samba-
  dc.example.com/demo /mnt/testshare1

  # klist
  Ticket cache: FILE:/tmp/krb5cc_0
  Default principal: Administrator@xxxxxxxxxxxxxxxxxxxx

  Valid starting     Expires            Service principal
  05/12/25 11:56:59  05/12/25 21:56:59  krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
   renew until 05/13/25 11:56:55
  05/12/25 11:58:21  05/12/25 21:56:59  cifs/samba-dc.example.com@
   renew until 05/13/25 11:56:55
   Ticket server: cifs/samba-dc.example.com@xxxxxxxxxxxxxxxxxxxx

  # umount /mnt/testshare1

  Next, we need to perform some surgery to remove the TGT, using this
  neat tool:

  # git clone https://git.nullroute.lt/hacks/python-krb5ccparse.git
  # cd python-krb5ccparse
  # ./kremovetkt -c /tmp/krb5cc_0 -o /tmp/removed -p krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
  Keeping ticket for krb5_ccache_conf_data/fast_avail/krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx@X-CACHECONF:
  Keeping ticket for krb5_ccache_conf_data/pa_type/krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx@X-CACHECONF:
  Skipping ticket for krbtgt/SAMBA-DC.EXAMPLE.COM@xxxxxxxxxxxxxxxxxxxx
  Keeping ticket for cifs/samba-dc.example.com@

  # kdestroy
  # mv /tmp/removed /tmp/krb5cc_0
  # klist
  Ticket cache: FILE:/tmp/removed
  Default principal: Administrator@xxxxxxxxxxxxxxxxxxxx

  Valid starting     Expires            Service principal
  05/12/25 11:58:21  05/12/25 21:56:59  cifs/samba-dc.example.com@
   renew until 05/13/25 11:56:55
   Ticket server: cifs/samba-dc.example.com@xxxxxxxxxxxxxxxxxxxx

  Now we have a kerberos credential cache with a service ticket only, and no
  TGT.

  If we try and mount now:

  # mount -t cifs -o cruid=root,user=root,sec=krb5i,uid=0,gid=0,cred=/tmp/krb5cc_0 //samba-dc.example.com/demo /mnt/testshare1
  mount error(126): Required key not available
  Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)

  kernel: CIFS: enabling forceuid mount option implicitly because uid= option is specified
  kernel: CIFS: enabling forcegid mount option implicitly because gid= option is specified
  kernel: CIFS: Attempting to mount //samba-dc.example.com/demo
  cifs.upcall[2206]: key description: cifs.spnego;0;0;39010000;ver=0x2;host=samba-dc.example.com;ip4=192.168.122.191;sec=krb5;uid=0x0;creduid=>
  cifs.upcall[2207]: ver=2
  cifs.upcall[2207]: host=samba-dc.example.com
  cifs.upcall[2207]: ip=192.168.122.191
  cifs.upcall[2207]: sec=1
  cifs.upcall[2207]: uid=0
  cifs.upcall[2207]: creduid=0
  cifs.upcall[2207]: user=root
  cifs.upcall[2207]: pid=2202
  cifs.upcall[2206]: get_cachename_from_process_env: pid == 0
  cifs.upcall[2206]: get_existing_cc: default ccache is FILE:/tmp/krb5cc_0
  cifs.upcall[2206]: krb5_get_init_creds_keytab: -1765328378
  cifs.upcall[2206]: handle_krb5_mech: getting service ticket for samba-dc.example.com
  cifs.upcall[2206]: handle_krb5_mech: using GSS-API
  cifs.upcall[2206]: GSS-API error init_sec_context: Unspecified GSS failure.  Minor code may provide more information
  cifs.upcall[2206]: GSS-API error init_sec_context: Matching credential not found (filename: /tmp/krb5cc_0)
  cifs.upcall[2206]: handle_krb5_mech: failed to obtain service ticket via GSS (851968)
  cifs.upcall[2206]: Unable to obtain service ticket
  cifs.upcall[2206]: Exit status 851968
  kernel: CIFS: VFS: Verify user has a krb5 ticket and keyutils is installed
  kernel: CIFS: VFS: \\samba-dc.example.com Send error in SessSetup = -126
  kernel: CIFS: VFS: cifs_mount failed w/return code = -126

  If you install the test packages available in the following ppa:

  https://launchpad.net/~mruffell/+archive/ubuntu/sf407276-test

  The mount completes as expected.

  [Where problems could occur]

  We are removing the check to see if there is a valid TGT before checking if
  there is a valid service ticket. If the TGT is expired, then previously it would
  have forced the user to intervene to get a new TGT before being able to
  mount or connect to SMB shares with the service ticket.

  Now, we just need a service ticket only. For the most part, this won't make
  much of a difference, as usually the service ticket is set to expire at the
  same time as a TGT, so we would have to get a TGT anyway. But if they happen to
  have different expiration schedules, or if we have a custom credential cache
  with no TGT, we can now just go straight to using the service ticket.

  If a regression were to occur, it would affect the mounting of cifs / SMB
  shares, and ticket renegotiation if a ticket were to expire.

  [Other info]

  Fixed in upstream in cifs-utils 7.2 by:

  commit af76bf2a11a060afdfd97104617a701d19d5890d
  From: Bharath SM <bharathsm@xxxxxxxxxxxxx>
  Date: Tue, 26 Nov 2024 22:57:44 +0530
  Subject: cifs-utils: Skip TGT check if valid service ticket is already available
  Link: https://git.samba.org/?p=cifs-utils.git;a=commit;h=af76bf2a11a060afdfd97104617a701d19d5890d

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/cifs-utils/+bug/2099917/+subscriptions