Configure ACLs in Linux

I came across a need to make files in a folder inherit certain permissions no matter who creates them. Thanks to Stack Overflow for help in figuring this out.
You first set a sticky bit for the parent folder, then use the setfacl command to set the ACL:
chmod g+s -R <folder>
setfacl -d -m "g:<group name>:<permissions>" -R <directory>
Example:
Grants all members of group testgrouprw read,write, and directory permissions to /var/www/html/wordpress:
setfacl -d -m "g:testgrouprw:rwX" -R /var/www/html/wordpress/
Sources:

Rotate videos for WordPress using ffmpeg

WordPress has an extremely annoying issue with reading EXIF data when posting photos and videos. There is a plugin to fix rotated pictures, but I couldn’t find one for rotated videos. If you happen to upload a video from your phone that was shot in portait orientation, it will likely upload to wordpress in landscape orientation (sideways.) Very annoying.

My fix to this is to re-encode the video so it is at the proper orientation before uploading to wordpress. Thanks to this site for the information – ffmpeg does this automatically for you. So the syntax is simple:

ffmpeg -i SOURCE_VIDEO_FILENAME -c:a copy FIXED_VIDEO_FILENAME.mp4

Success.

LDAP nested group membership query

I have a lot of applications at work which do not support Active Directory but instead rely on LDAP queries for granting user access. A problem we have is much of our access is granted to a security group (known as a ROLE) and users are granted to that single security group to get access to things. This allows easier access granting to new hires / transfers. The problem is it makes LDAP queries much more difficult. Things are further complicated by the fact that sometimes users are directly granted access to resources instead of going through their ROLE security group.

Nested LDAP group search

I spent a lot of time researching LDAP nested group queries. I now have a functional way of doing semi-nested LDAP group searches. The scenario: a user could be directly added to a security group granting access to a resource, or could be a member of a security group which has access to the resource. I want the LDAP group search string to account for both. I accomplish this by combining these two queries:

Nested group membership query

Search groups beginning with the name ROLE for a specific member, then return what that ROLE group has access to

(&(objectClass=group)(DisplayName=ROLE*)(member=FQDN_OF_USER_IN_QUESTION)(memberOf=*))

Individually added group query

Search for all groups a specified member is a member of

(&(objectClass=user)(sAMAccountName=USERNAME_OF_USER_IN_QUESTION)(memberOf=*))

I combine these two queries by separating them out with an OR operator (|)

Combined query

Return the group membership of the user in question, as well as the group membership of the group beginning with the name ROLE that the user is a member of

(|(&(objectClass=group)(DisplayName=ROLE*)(member=FQDN_OF_USER_IN_QUESTION)(memberOf=*))(&(objectClass=user)(sAMAccountName=USERNAME_OF_USER_IN_QUESTION)(memberOf=*)))

It has three main parts:

  • Begin with an or operator (|
  • Have a new group with an AND operator (&
    • This requires everything in this query to be true
  • Make a second group with an AND operator

This works for our organization because ROLE groups are not nested within themselves and each user can only have one ROLE group assigned to them.

This combined query allows me to not have to “flatten” security groups for LDAP-bound applications. It makes me so happy.

This was made possible by a flurry of stack overflow posts:

https://stackoverflow.com/questions/32829104/ldap-query-with-wildcard

https://stackoverflow.com/questions/9564120/using-wildcards-in-ldap-search-filters-queries

https://stackoverflow.com/questions/6195812/ldap-nested-group-membership

https://stackoverflow.com/questions/1032351/how-to-write-ldap-query-to-test-if-user-is-member-of-a-group/1032426

https://www.novell.com/coolsolutions/feature/16671.html

Active Directory / LDAP integration with WordPress

I struggled for a while to get WordPress to use Active Directory credentials on CentOS 7. Below is how I finally got it to work.

First, install necessary packages:

sudo yum -y install openldap-clients php-ldap

If you use self-signed certificate for ldaps, you’ll need to modify /etc/openldap/ldap.conf

HOST <HOSTNAME_OF_LDAP_SERVER>
PORT 636
TLS_CACERT <PATH_TO_CA_CERT>
TLS_REQCERT demand

With the above settings you can test your ldap string with ldapsearch

ldapsearch -x -D "<BIND USERNAME>" -b "<BASE_DN>" -H ldaps://<LDAP_SERVER_HOSTNAME> -W sAMAccountName=<USER_TO_QUERY>

Once ldapsearch works properly, install your AD integration plugin.  I use AuthLDAP by Andreas Heigl

I struggled with which LDAP strings and filters to use. This is what finally got everything working with our Active Directory environment:

LDAP URIldaps://<BIND_USERNAME>:<BIND_PASSWORD>@<AD_SERVER_ADDRESS>:636/<BASE DN>

Filter(sAMAccountName=%s)

Name-AttributegivenName

User-ID Attribute: sAMAccountName

Second Name Attributesn

Group-Attribute:memberOf

Group-Separator:  _

Group-Filter: (&(objectClass=user)(sAMAccountName=%s)(memberOf=*))

Role – group mapping

I had to change Group-Separator to _ above, because in Role – group mapping for active directory, you must put the FQDN, which includes commas. Put an underscore separated list of FQDNS for each of these fields you want.

Using expect with the Ansible shell module

In one of my ansible playbooks I need to obtain a file from a Windows share. I can’t find a module that handles this so I’m using the shell module to call the smbclient command to do what I need. The problem with this solution is that smbclient prompts for a password (and I don’t want to supply it on the command itself for security reasons.)

I tried using ansible’s built-in expect module, but frustratingly it only works on systems that have pexpect >= 3.3  , which CentOS 7 & Ubuntu 14.04 do not have.

My solution to this is to install the expect command on the host, and then use the ansible shell module to call it, following the example given in Ansible’s shell module page

Part of the process in my playbook is registering stdout from that command for later use. I then ran into a problem where I would run smbclient -c “ls <filename>” but ansible would register nothing. After some digging I found I also need to include the interact command after sending the password. Without it, anything after sending the password is not registered to stdout. Thanks to rostyslav-fridman on Stack Overflow for the answer.

My final problem was I was sending a password that had a ] character in it. It was causing this error on run:

missing close-bracket\n while executing\n\"send

I found here (thanks glenn-jackman) it was due to  the fact that the expect syntax uses tcl language, which treats those brackets as special characters. To get around this I had to use an ansible filter, specifically regex_escape()

Lastly I ran into an issue specifically with how I was spawning smbclient. I kept getting this message:

"stderr": "send: spawn id exp4 not open\n while executing\n\"send

It boiled down to single vs double quotes. If I put my -c arguments in single quotes it failed; with double quotes, it worked.

My completed play is below. Finally, success!

- name: Get RSA filename 
  shell: |
    set timeout 300
    spawn smbclient {{standards_location}} -W DOMAIN -U {{username}} -c "ls {{file_location}}*.tar"
    expect "password:"
    send {{ password | regex_escape() }}\r
    interact
    exit 0
  args:
    executable: /usr/bin/expect
  changed_when: false
  no_log: true
  register: RSA_filename_raw