Skip to content

Commit 1011c54

Browse files
committed
Adjust fed token dirs and their perms
- Setup the permanent and temporary directory for the federation token file and sets proper perms. - The permanent directory is always owned by xrootd user. - In normal mode, the temporary directory is owned by the root. While in drop privileges mode, it is owned by the pelican user.
1 parent c167476 commit 1011c54

3 files changed

Lines changed: 87 additions & 40 deletions

File tree

cache/advertise.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,12 @@ func LaunchFedTokManager(ctx context.Context, egrp *errgroup.Group, cache server
297297
// gives us a bit of buffer in the event the Director is down for a short period of time.
298298
tickerRate := getTickerRate(tok)
299299

300+
// Set up the federation token directories in the cache
301+
err = server_utils.SetupFedTokDirs(cache)
302+
if err != nil {
303+
log.Errorf("Failed to setup federation token directory: %v", err)
304+
}
305+
300306
// Set the token in the cache
301307
err = server_utils.SetFedTok(ctx, cache, tok, copyToXrootdDir)
302308
if err != nil {

config/config.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,13 @@ func InitServer(ctx context.Context, currentServers server_structs.ServerType) e
16611661
if (currentServers.IsEnabled(server_structs.OriginType) || currentServers.IsEnabled(server_structs.CacheType)) && param.Shoveler_Enable.GetBool() {
16621662
pelicanLocationsNoRecursive = append(pelicanLocationsNoRecursive, param.Shoveler_AMQPTokenLocation.GetString())
16631663
}
1664+
if currentServers.IsEnabled(server_structs.CacheType) {
1665+
tokLoc := param.Cache_FedTokenLocation.GetString()
1666+
tokDir := filepath.Dir(tokLoc)
1667+
dir := filepath.Dir(tokDir)
1668+
tempTokDir := filepath.Join(dir, "fed-token-temp")
1669+
pelicanLocationsNoRecursive = append(pelicanLocationsNoRecursive, tempTokDir)
1670+
}
16641671
if err = setFileAndDirPerms(pelicanLocationsNoRecursive, 0750, 0640, puser.Uid, 0, false); err != nil {
16651672
return errors.Wrap(err, "failure when setting up the file permissions for pelican")
16661673
}
@@ -1918,10 +1925,10 @@ func InitServer(ctx context.Context, currentServers server_structs.ServerType) e
19181925
// Origin (2025-02-04), but they may be soon for things like third party copy.
19191926
configDir := viper.GetString("ConfigDir")
19201927
if currentServers.IsEnabled(server_structs.OriginType) {
1921-
viper.SetDefault(param.Origin_FedTokenLocation.GetName(), filepath.Join(configDir, "origin-fed-token"))
1928+
viper.SetDefault(param.Origin_FedTokenLocation.GetName(), filepath.Join(configDir, "fed-token", "origin-fed-token"))
19221929
}
19231930
if currentServers.IsEnabled(server_structs.CacheType) {
1924-
viper.SetDefault(param.Cache_FedTokenLocation.GetName(), filepath.Join(configDir, "cache-fed-token"))
1931+
viper.SetDefault(param.Cache_FedTokenLocation.GetName(), filepath.Join(configDir, "fed-token", "cache-fed-token"))
19251932
os.Setenv("XRD_PELICANCACHETOKENLOCATION", param.Cache_FedTokenLocation.GetString())
19261933
}
19271934

server_utils/server_utils.go

Lines changed: 72 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,53 @@ func CreateFedTok(ctx context.Context, server server_structs.XRootDServer) (tok
531531
return
532532
}
533533

534+
// getFedTokenTempDir returns the temporary directory for fed token writes
535+
// This func is placed here to avoid circular dependencies.
536+
func getFedTokenTempDir(server server_structs.XRootDServer) string {
537+
tokLoc := server.GetFedTokLocation()
538+
tokDir := filepath.Dir(tokLoc)
539+
dir := filepath.Dir(tokDir)
540+
return filepath.Join(dir, "fed-token-temp")
541+
}
542+
543+
// SetupFedTokDirs creates the permanent and temporary directory for the federation token file
544+
// and sets proper perms. It intends to be called once at server startup. The permanent directory
545+
// is always owned by xrootd user. In normal mode, the temporary directory is owned by the root.
546+
// While in drop privileges mode, it is owned by the pelican user.
547+
func SetupFedTokDirs(server server_structs.XRootDServer) error {
548+
// Permanent directory
549+
xrootdUid, err := config.GetDaemonUID()
550+
if err != nil {
551+
return errors.Wrap(err, "failed to get xrootd user")
552+
}
553+
xrootdGid, err := config.GetDaemonGID()
554+
if err != nil {
555+
return errors.Wrap(err, "failed to get xrootd group")
556+
}
557+
permanentDir := filepath.Dir(server.GetFedTokLocation())
558+
err = config.MkdirAll(permanentDir, 0700, xrootdUid, xrootdGid)
559+
if err != nil {
560+
return errors.Wrapf(err, "failed to create directory %s", permanentDir)
561+
}
562+
563+
// Temporary directory
564+
puser, err := config.GetPelicanUser()
565+
if err != nil {
566+
return errors.Wrap(err, "failed to get pelican user")
567+
}
568+
569+
tempDir := getFedTokenTempDir(server)
570+
if tempDir == "" {
571+
return errors.New("the temporary directory for federation token writes is an empty string")
572+
}
573+
574+
err = config.MkdirAll(tempDir, 0750, puser.Uid, puser.Gid)
575+
if err != nil {
576+
return errors.Wrapf(err, "failed to create directory %s", tempDir)
577+
}
578+
return nil
579+
}
580+
534581
// FedTokCopyToXrootdFunc is an optional callback used when Server.DropPrivileges is true.
535582
// It is defined here so that server_utils does not import the xrootd package; the caller
536583
// (e.g. launchers/cache_serve) wires in xrootd.FileCopyToXrootdDir to avoid import cycles.
@@ -543,14 +590,9 @@ func SetFedTok(ctx context.Context, server server_structs.XRootDServer, tok stri
543590
return errors.New("token location is empty")
544591
}
545592

546-
dir := filepath.Dir(tokLoc)
547-
if err := os.MkdirAll(dir, 0755); err != nil {
548-
return errors.Wrap(err, "failed to create fed token directories")
549-
}
550-
551593
// Create a temporary file for storing the token. Later we'll do an atomic rename
552594
filenamePattern := fmt.Sprintf(".fedtoken.%d.*", time.Now().UnixNano())
553-
tmpFile, err := os.CreateTemp(dir, filenamePattern)
595+
tmpFile, err := os.CreateTemp(getFedTokenTempDir(server), filenamePattern)
554596
if err != nil {
555597
return errors.Wrap(err, "failed to create temporary token file")
556598
}
@@ -561,49 +603,41 @@ func SetFedTok(ctx context.Context, server server_structs.XRootDServer, tok stri
561603
os.Remove(tmpName)
562604
}()
563605

564-
// Change ownership to xrootd user
565-
uid, err := config.GetDaemonUID()
566-
if err != nil {
567-
return errors.Wrap(err, "failed to get daemon UID")
568-
}
569-
gid, err := config.GetDaemonGID()
570-
if err != nil {
571-
return errors.Wrap(err, "failed to get daemon GID")
572-
}
573-
574-
if err := os.Chown(tmpName, uid, gid); err != nil {
575-
return errors.Wrapf(err, "failed to change token file ownership of %s to %d:%d", tmpName, uid, gid)
576-
}
577-
578606
if _, err := tmpFile.WriteString(tok); err != nil {
579607
return errors.Wrap(err, "failed to write token to temporary file")
580608
}
581609

582-
if param.Server_DropPrivileges.GetBool() && copyToXrootdDir != nil {
610+
if !param.Server_DropPrivileges.GetBool() {
611+
// Change ownership to xrootd user
612+
uid, err := config.GetDaemonUID()
613+
if err != nil {
614+
return errors.Wrap(err, "failed to get daemon UID")
615+
}
616+
gid, err := config.GetDaemonGID()
617+
if err != nil {
618+
return errors.Wrap(err, "failed to get daemon GID")
619+
}
620+
621+
if err := os.Chown(tmpName, uid, gid); err != nil {
622+
return errors.Wrapf(err, "failed to change token file ownership of %s to %d:%d", tmpName, uid, gid)
623+
}
624+
625+
if err := tmpFile.Sync(); err != nil {
626+
return errors.Wrap(err, "failed to sync token file")
627+
}
628+
629+
if err := os.Rename(tmpName, tokLoc); err != nil {
630+
return errors.Wrap(err, "failed to move token file to final location")
631+
}
632+
} else if param.Server_DropPrivileges.GetBool() && copyToXrootdDir != nil {
583633
// After writing the token content to the file, the file pointer remains at the end.
584634
// Seek back to the beginning so the copy operation reads from the start.
585635
if _, err := tmpFile.Seek(0, io.SeekStart); err != nil {
586636
return errors.Wrap(err, "failed to seek to beginning of the file")
587637
}
588638
if err := copyToXrootdDir(tmpFile); err != nil {
589-
return errors.Wrapf(err, "failed to copy token file to xrootd directory")
590-
}
591-
if err := tmpFile.Close(); err != nil {
592-
return errors.Wrap(err, "failed to close temporary token file")
639+
return errors.Wrapf(err, "failed to rename the federation token file via the xrdhttp-pelican plugin")
593640
}
594-
return nil
595-
}
596-
597-
if err := tmpFile.Sync(); err != nil {
598-
return errors.Wrap(err, "failed to sync token file")
599-
}
600-
601-
if err := tmpFile.Close(); err != nil {
602-
return errors.Wrap(err, "failed to close temporary token file")
603-
}
604-
605-
if err := os.Rename(tmpName, tokLoc); err != nil {
606-
return errors.Wrap(err, "failed to move token file to final location")
607641
}
608642

609643
return nil

0 commit comments

Comments
 (0)