Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added a Traffic Ops endpoint and Traffic Portal page to view all CDNi configuration update requests and approve or deny.
- Added layered profile feature to 4.0 for `GET` /deliveryservices/{id}/servers/ and /deliveryservices/{id}/servers/eligible.
- Change to t3c regex_revalidate so that STALE is no longer explicitly added for default revalidate rule for ATS version backwards compatibility.
- Change to t3c diff to flag a config file for replacement if owner/group settings are not `ats` [#6879](https://github.com/apache/trafficcontrol/issues/6879).

### Fixed
- [#6291](https://github.com/apache/trafficcontrol/issues/6291) Prevent Traffic Ops from modifying and/or deleting reserved statuses.
Expand Down
4 changes: 3 additions & 1 deletion cache-config/t3c-apply/torequest/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,14 @@ func sendUpdate(cfg config.Cfg, configApplyTime, revalApplyTime *time.Time, conf
// diff calls t3c-diff to diff the given new file and the file on disk. Returns whether they're different.
// Logs the difference.
// If the file on disk doesn't exist, returns true and logs the entire file as a diff.
func diff(cfg config.Cfg, newFile []byte, fileLocation string, reportOnly bool, perm os.FileMode) (bool, error) {
func diff(cfg config.Cfg, newFile []byte, fileLocation string, reportOnly bool, perm os.FileMode, uid int, gid int) (bool, error) {
diffMsg := ""
args := []string{
"--file-a=stdin",
"--file-b=" + fileLocation,
"--file-mode=" + fmt.Sprintf("%#o", perm),
"--file-uid=" + fmt.Sprint(uid),
"--file-gid=" + fmt.Sprint(gid),
}

stdOut, stdErr, code := t3cutil.DoInput(newFile, `t3c-diff`, args...)
Expand Down
2 changes: 1 addition & 1 deletion cache-config/t3c-apply/torequest/torequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func (r *TrafficOpsReq) checkConfigFile(cfg *ConfigFile, filesAdding []string) e
}
}

changeNeeded, err := diff(r.Cfg, cfg.Body, cfg.Path, r.Cfg.ReportOnly, cfg.Perm)
changeNeeded, err := diff(r.Cfg, cfg.Body, cfg.Path, r.Cfg.ReportOnly, cfg.Perm, cfg.Uid, cfg.Gid)

if err != nil {
return errors.New("getting diff: " + err.Error())
Expand Down
27 changes: 26 additions & 1 deletion cache-config/t3c-diff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ t3c-diff - Traffic Control Cache Configuration contextual diff tool

# SYNOPSIS

t3c-diff \<file-a\> \<file-a\>
t3c-diff \-a \<file-a\> \-b \<file-b\> \-l \<line_comment\> \-m \<file-mode\> \-u \<file-uid\> \-g \<file-gid\>

[\-\-help]

Expand All @@ -58,12 +58,37 @@ If one file exists but the other doesn't, it will always be a diff.
Note this means there may be no diff text printed to stdout but still exit 1 indicating a diff
if the file being created or deleted is semantically empty.

Mode is file permissions in octal format, default is 0644.
Line comment is a character that signals the line is a comment, default is #

Uid is the User id the file being checked should have, default is running process's uid.
Gid is the Group id the file being checked should have, default is running process's gid.`

# OPTIONS

-a, -\-file-a

Path to first diff file, can also be stdin.

-b, -\-file-b
Path to second diff file, can also be stdin.

-g, -\-file-gid
Group id the file being checked should have.
Comment thread
jpappa200 marked this conversation as resolved.

-h, -\-help

Print usage info and exit.

-l, -\-line_comment
Symbol used to denote the line is a comment.

-m, -\-file-mode
Octal permissions mode for file being checked.

-u, -\-file-uid
User id the file being checked should have.

-V, -\-version

Print version information and exit.
Expand Down
23 changes: 22 additions & 1 deletion cache-config/t3c-diff/t3c-diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func main() {
version := getopt.BoolLong("version", 'V', "Print version information and exit")
lineComment := getopt.StringLong("line_comment", 'l', "#", "Comment symbol")
mode := getopt.IntLong("file-mode", 'm', 0644, "file mode default is 644")
uid := getopt.IntLong("file-uid", 'u', 0, "User id the file being checked should have, default is running process's uid")
gid := getopt.IntLong("file-gid", 'g', 0, "Group id the file being checked should have, default is running process's gid")
fa := getopt.StringLong("file-a", 'a', "", "first diff file")
fb := getopt.StringLong("file-b", 'b', "", "second diff file")
getopt.ParseV2()
Expand Down Expand Up @@ -76,6 +78,14 @@ func main() {
os.Exit(4)
}

if *uid == 0 {
*uid = os.Geteuid()
}

if *gid == 0 {
*gid = os.Getgid()
}

fileA, fileAExisted, err := readFileOrStdin(fileNameA)
if err != nil {
log.Errorf("error reading first: %s\n", err.Error())
Expand Down Expand Up @@ -116,18 +126,26 @@ func main() {
log.Infoln("File permissions are incorrect, should be ", fmt.Sprintf("%#o", *mode))
os.Exit(1)
}
if t3cutil.OwnershipCk(fileNameA, *uid, *gid) {
log.Infoln("user or group ownership are incorrect, should be ", fmt.Sprintf("Uid:%d Gid:%d", *uid, *gid))
os.Exit(1)
}
case fileNameB != "stdin":
if t3cutil.PermCk(fileNameB, *mode) {
log.Infoln("File permissions are incorrect, should be ", fmt.Sprintf("%#o", *mode))
os.Exit(1)
}
if t3cutil.OwnershipCk(fileNameB, *uid, *gid) {
log.Infoln("user or group ownership are incorrect, should be ", fmt.Sprintf("Uid:%d Gid:%d", *uid, *gid))
os.Exit(1)
}
}
os.Exit(0)

}

const usageStr = `usage: t3c-diff [--help]
-a <file-a> -b <file-b> -l <line comment> -m <file mode>
-a <file-a> -b <file-b> -l <line comment> -m <file mode> -u <file uid> -g <file gid>

Either file may be 'stdin', in which case that file is read from stdin.
Either file may not exist.
Expand All @@ -138,6 +156,9 @@ If one file exists but the other doesn't, it will always be a diff.
Mode is file permissions in octal format, default is 0644.
Line comment is a character that signals the line is a comment, default is #

Uid is the User id the file being checked should have, default is running process's uid.
Gid is the Group id the file being checked should have, default is running process's gid.

Note this means there may be no diff text printed to stdout but still exit 1 indicating a diff
if the file being created or deleted is semantically empty.`

Expand Down
14 changes: 14 additions & 0 deletions cache-config/t3cutil/t3cutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"os/exec"
"regexp"
"strings"
"syscall"
)

type ATSConfigFile struct {
Expand Down Expand Up @@ -86,6 +87,19 @@ func PermCk(path string, perm int) bool {
return false
}

// OwnershipCk will compare owner and group settings against existing file and owner/group settings provided.
func OwnershipCk(path string, uid int, gid int) bool {
file, err := os.Stat(path)
if err != nil {
fmt.Println("error getting file status", path)
}
stat := file.Sys().(*syscall.Stat_t)
if uid != int(stat.Uid) || gid != int(stat.Gid) {
return true
}
return false
}

// NewLineFilter removes carriage returns
// from config files while making comparisons.
func NewLineFilter(str string) string {
Expand Down