diff --git a/src/main/groovy/com/netflix/gradle/plugins/deb/DebCopyAction.groovy b/src/main/groovy/com/netflix/gradle/plugins/deb/DebCopyAction.groovy index 4ddc7794..ebde8f33 100755 --- a/src/main/groovy/com/netflix/gradle/plugins/deb/DebCopyAction.groovy +++ b/src/main/groovy/com/netflix/gradle/plugins/deb/DebCopyAction.groovy @@ -120,8 +120,15 @@ class DebCopyAction extends AbstractPackagingCopyAction { Integer uid = (Integer) lookup(specToLookAt, 'uid') ?: task.uid ?: 0 String group = lookup(specToLookAt, 'permissionGroup') ?: task.permissionGroup Integer gid = (Integer) lookup(specToLookAt, 'gid') ?: task.gid ?: 0 + Boolean setuid = lookup(specToLookAt, 'setuid') int fileMode = FilePermissionUtil.getUnixPermission(fileDetails) + if (setuid == null) { + setuid = task.setuid + } + if (setuid) { + fileMode = fileMode | 04000 + } debFileVisitorStrategy.addFile(fileDetails, inputFile, user, uid, group, gid, fileMode) } diff --git a/src/main/groovy/com/netflix/gradle/plugins/packaging/CopySpecEnhancement.groovy b/src/main/groovy/com/netflix/gradle/plugins/packaging/CopySpecEnhancement.groovy index bc55d182..29b9b97b 100644 --- a/src/main/groovy/com/netflix/gradle/plugins/packaging/CopySpecEnhancement.groovy +++ b/src/main/groovy/com/netflix/gradle/plugins/packaging/CopySpecEnhancement.groovy @@ -57,6 +57,14 @@ class CopySpecEnhancement { setgid(spec, setgid) } + static void setuid(CopySpec spec, boolean setuid) { + appendFieldToCopySpec(spec, 'setuid', setuid) + } + + static void setSetuid(CopySpec spec, boolean setuid) { + setuid(spec, setuid) + } + static void permissionGroup(CopySpec spec, String permissionGroup) { appendFieldToCopySpec(spec, 'permissionGroup', permissionGroup) } diff --git a/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingExtension.groovy b/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingExtension.groovy index 2432edc6..a5743d2a 100755 --- a/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingExtension.groovy +++ b/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingExtension.groovy @@ -48,6 +48,7 @@ class SystemPackagingExtension { String user String permissionGroup // Group is used by Gradle on tasks. boolean setgid + boolean setuid /** * In Debian, this is the Section and has to be provided. Valid values are: admin, cli-mono, comm, database, debug, @@ -188,6 +189,12 @@ class SystemPackagingExtension { return setgid } + @Input + @Optional + Boolean getSetuid() { + return setuid + } + @Input @Optional String getPackageGroup() { diff --git a/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingTask.groovy b/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingTask.groovy index 03c2f9bb..2aec203f 100755 --- a/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingTask.groovy +++ b/src/main/groovy/com/netflix/gradle/plugins/packaging/SystemPackagingTask.groovy @@ -105,6 +105,7 @@ abstract class SystemPackagingTask extends OsPackageAbstractArchiveTask { mapping.map('uploaders', { parentExten?.getUploaders() ?: getPackager() }) mapping.map('permissionGroup', { parentExten?.getPermissionGroup() ?: '' }) mapping.map('setgid', { parentExten?.getSetgid() ?: false }) + mapping.map('setuid', { parentExten?.getSetuid() ?: false }) mapping.map('packageGroup', { parentExten?.getPackageGroup() }) mapping.map('buildHost', { parentExten?.getBuildHost() ?: HOST_NAME }) mapping.map('summary', { parentExten?.getSummary() ?: getPackageName() }) diff --git a/src/main/groovy/com/netflix/gradle/plugins/rpm/RpmCopyAction.groovy b/src/main/groovy/com/netflix/gradle/plugins/rpm/RpmCopyAction.groovy index bf9e0610..9b65ced5 100755 --- a/src/main/groovy/com/netflix/gradle/plugins/rpm/RpmCopyAction.groovy +++ b/src/main/groovy/com/netflix/gradle/plugins/rpm/RpmCopyAction.groovy @@ -161,6 +161,13 @@ class RpmCopyAction extends AbstractPackagingCopyAction { String group = lookup(specToLookAt, 'permissionGroup') ?: task.permissionGroup int fileMode = FilePermissionUtil.getFileMode(specToLookAt) ?: FilePermissionUtil.getUnixPermission(fileDetails) + Boolean setuid = lookup(specToLookAt, 'setuid') + if (setuid == null) { + setuid = task.setuid + } + if (setuid) { + fileMode = fileMode | 04000 + } def specAddParentsDir = lookup(specToLookAt, 'addParentDirs') boolean addParentsDir = specAddParentsDir != null ? specAddParentsDir : task.addParentDirs diff --git a/src/test/groovy/com/netflix/gradle/plugins/rpm/RpmPluginIntegrationTest.groovy b/src/test/groovy/com/netflix/gradle/plugins/rpm/RpmPluginIntegrationTest.groovy index 1e0ceb8f..c477367c 100644 --- a/src/test/groovy/com/netflix/gradle/plugins/rpm/RpmPluginIntegrationTest.groovy +++ b/src/test/groovy/com/netflix/gradle/plugins/rpm/RpmPluginIntegrationTest.groovy @@ -530,4 +530,92 @@ buildRpm { true | 1444 false | 0644 } + + def 'setuid can be set in rpm and deb'() { + given: + File bananaFile = new File(projectDir, 'test/banana') + FileUtils.forceMkdirParent(bananaFile) + bananaFile.text = 'banana' + buildFile << """ +plugins { + id 'com.netflix.nebula.ospackage' +} + +version = '1.0.0' + +ospackage { + addParentDirs false +} + +buildRpm { + packageName = 'sample' + + from(${GradleUtils.quotedIfPresent(bananaFile.getParentFile().path)}) { + setuid = ${setuidValue} + filePermissions { + unix(0755) + } + into '/usr/share/myproduct/etc/' + } +} +""" + when: + runTasks('buildRpm') + + then: + def scanFiles = Scanner.scan(file('build/distributions/sample-1.0.0.noarch.rpm')).files + + ['./usr/share/myproduct/etc/banana'] == scanFiles*.name + [FILE] == scanFiles*.type + [expectedPermissions] == scanFiles*.permissions + + where: + setuidValue | expectedPermissions + true | 04755 + false | 00755 + } + + def 'setgid in ospackage extension propagates to rpm and deb'() { + given: + File bananaFile = new File(projectDir, 'test/banana') + FileUtils.forceMkdirParent(bananaFile) + bananaFile.text = 'banana' + buildFile << """ +plugins { + id 'com.netflix.nebula.ospackage' +} + +version = '1.0.0' + +ospackage { + addParentDirs false + setuid = ${setuidValue} +} + +buildRpm { + packageName = 'sample' + + from(${GradleUtils.quotedIfPresent(bananaFile.getParentFile().path)}) { + filePermissions { + unix(0755) + } + into '/usr/share/myproduct/etc/' + } +} +""" + when: + runTasks('buildRpm', '--warning-mode', 'all', '--stacktrace') + + then: + def scanFiles = Scanner.scan(file('build/distributions/sample-1.0.0.noarch.rpm')).files + + ['./usr/share/myproduct/etc/banana'] == scanFiles*.name + [FILE] == scanFiles*.type + [expectedPermissions] == scanFiles*.permissions + + where: + setuidValue | expectedPermissions + true | 04755 + false | 00755 + } } \ No newline at end of file