mirror of
https://github.com/rclone/rclone.git
synced 2025-08-14 07:49:00 +02:00
smb: refresh Kerberos credentials when ccache file changes
This change enhances the SMB backend in Rclone to automatically refresh Kerberos credentials when the associated ccache file is updated. Previously, credentials were only loaded once per path and cached indefinitely, which caused issues when service tickets expired or the cache was renewed on the server.
This commit is contained in:
@ -4,7 +4,11 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jcmturner/gokrb5/v8/client"
|
||||
"github.com/jcmturner/gokrb5/v8/config"
|
||||
"github.com/jcmturner/gokrb5/v8/credentials"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -77,3 +81,62 @@ func TestResolveCcachePath(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKerberosFactory_GetClient_ReloadOnCcacheChange(t *testing.T) {
|
||||
// Create temp ccache file
|
||||
tmpFile, err := os.CreateTemp("", "krb5cc_test")
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
if err := os.Remove(tmpFile.Name()); err != nil {
|
||||
t.Logf("Failed to remove temp file %s: %v", tmpFile.Name(), err)
|
||||
}
|
||||
}()
|
||||
|
||||
unixPath := filepath.ToSlash(tmpFile.Name())
|
||||
ccachePath := "FILE:" + unixPath
|
||||
|
||||
initialContent := []byte("CCACHE_VERSION 4\n")
|
||||
_, err = tmpFile.Write(initialContent)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, tmpFile.Close())
|
||||
|
||||
// Setup mocks
|
||||
loadCallCount := 0
|
||||
mockLoadCCache := func(path string) (*credentials.CCache, error) {
|
||||
loadCallCount++
|
||||
return &credentials.CCache{}, nil
|
||||
}
|
||||
|
||||
mockNewClient := func(cc *credentials.CCache, cfg *config.Config, opts ...func(*client.Settings)) (*client.Client, error) {
|
||||
return &client.Client{}, nil
|
||||
}
|
||||
|
||||
mockLoadConfig := func() (*config.Config, error) {
|
||||
return &config.Config{}, nil
|
||||
}
|
||||
factory := &KerberosFactory{
|
||||
loadCCache: mockLoadCCache,
|
||||
newClient: mockNewClient,
|
||||
loadConfig: mockLoadConfig,
|
||||
}
|
||||
|
||||
// First call — triggers loading
|
||||
_, err = factory.GetClient(ccachePath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, loadCallCount, "expected 1 load call")
|
||||
|
||||
// Second call — should reuse cache, no additional load
|
||||
_, err = factory.GetClient(ccachePath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, loadCallCount, "expected cached reuse, no new load")
|
||||
|
||||
// Simulate file update
|
||||
time.Sleep(1 * time.Second) // ensure mtime changes
|
||||
err = os.WriteFile(tmpFile.Name(), []byte("CCACHE_VERSION 4\n#updated"), 0600)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Third call — should detect change, reload
|
||||
_, err = factory.GetClient(ccachePath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 2, loadCallCount, "expected reload on changed ccache")
|
||||
}
|
||||
|
Reference in New Issue
Block a user