2016-09-22 12:43:57 +00:00
---
title: About the shadow Resource
2018-02-16 00:28:15 +00:00
platform: linux
2016-09-22 12:43:57 +00:00
---
# shadow
Use the `shadow` InSpec audit resource to test the contents of `/etc/shadow`, which contains password details that are only readable by the `root` user. The format for `/etc/shadow` includes:
* A username
2018-06-06 18:13:34 +00:00
* The hashed password for that user
2016-09-22 12:43:57 +00:00
* The last time a password was changed
* The minimum number of days a password must exist, before it may be changed
* The maximum number of days after which a password must be changed
* The number of days a user is warned about an expiring password
* The number of days a user must be inactive before the user account is disabled
* The number of days a user account has been disabled
These entries are defined as a colon-delimited row in the file, one row per user:
dannos:Gb7crrO5CDF.:10063:0:99999:7:::
2017-10-03 21:35:10 +00:00
<br>
2016-09-27 19:03:23 +00:00
## Syntax
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
A `shadow` resource block declares user properties to be tested:
2016-09-22 12:43:57 +00:00
describe shadow do
2018-03-08 22:26:08 +00:00
its('user') { should_not include 'forbidden_user' }
2016-09-22 12:43:57 +00:00
end
2018-06-06 18:13:34 +00:00
Properties can be used as a single query:
2017-10-25 16:23:52 +00:00
2018-03-08 22:26:08 +00:00
describe shadow.user('root') do
2017-10-25 16:23:52 +00:00
its('count') { should eq 1 }
end
2018-06-06 18:13:34 +00:00
Use the `.where` method to find properties that match a value:
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
describe shadow.where { min_days == '0' } do
its ('user') { should include 'nfs' }
end
describe shadow.where { password =~ /[x|!|*]/ } do
its('count') { should eq 0 }
2016-09-22 12:43:57 +00:00
end
2017-10-25 16:23:52 +00:00
The following properties are available:
2018-03-08 22:26:08 +00:00
* `user`
* `password`
* `last_change`
2017-10-25 16:23:52 +00:00
* `min_days`
* `max_days`
* `warn_days`
* `inactive_days`
* `expiry_date`
* `reserved`
2016-09-22 12:43:57 +00:00
2017-10-03 21:35:10 +00:00
<br>
2016-09-22 12:43:57 +00:00
2017-10-03 21:35:10 +00:00
## Examples
The following examples show how to use this InSpec audit resource.
### Test for a forbidden user
describe shadow do
2018-03-08 22:26:08 +00:00
its('user') { should_not include 'forbidden_user' }
2017-10-03 21:35:10 +00:00
end
2016-09-22 12:43:57 +00:00
2017-10-03 21:35:10 +00:00
### Test that a user appears one time
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
describe shadow.user('bin') do
its('password') { should cmp 'x' }
2017-10-03 21:35:10 +00:00
its('count') { should eq 1 }
end
2016-09-22 12:43:57 +00:00
2017-10-03 21:35:10 +00:00
<br>
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
## Properties
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
### user
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `user` property tests if the username exists `/etc/shadow`:
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
its('user') { should eq 'root' }
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
### password
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `password` property returns the encrypted password string from the shadow file. The returned string may not be an encrypted password, but rather a `*` or similar which indicates that direct logins are not allowed.
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
For example:
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
its('password') { should cmp '*' }
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
### last_change
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `last_change` property tests the last time a password was changed:
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
its('last_change') { should be_empty }
2016-09-22 12:43:57 +00:00
2016-09-27 19:03:23 +00:00
### min_days
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `min_days` property tests the minimum number of days a password must exist, before it may be changed:
2016-09-22 12:43:57 +00:00
its('min_days') { should eq 0 }
2018-03-08 22:26:08 +00:00
### max_days
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `max_days` property tests the maximum number of days after which a password must be changed:
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
its('max_days') { should eq 90 }
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
### warn_days
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `warn_days` property tests the number of days a user is warned about an expiring password:
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
its('warn_days') { should eq 7 }
2016-09-22 12:43:57 +00:00
2018-03-08 22:26:08 +00:00
### inactive_days
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
The `inactive_days` property tests the number of days a user must be inactive before the user account is disabled:
2018-03-08 22:26:08 +00:00
its('inactive_days') { should be_empty }
### expiry_date
2018-06-06 18:13:34 +00:00
The `expiry_date` property tests the number of days a user account has been disabled:
2018-03-08 22:26:08 +00:00
its('expiry_date') { should be_empty }
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
### count
The `count` property tests the number of times the named property appears:
describe shadow.user('root') do
its('count') { should eq 1 }
end
This property is best used in conjunction with filters. For example:
2016-09-22 12:43:57 +00:00
2018-06-06 18:13:34 +00:00
describe shadow.where { password =~ /[x|!|*]/ } do
its('count') { should eq 0 }
end
<br>
## Matchers
For a full list of available matchers, please visit our [matchers page](https://www.inspec.io/docs/reference/matchers/).