Samba share with freeipa auth

Use FreeIPA Authentication for Samba CIFS Shares for Non-domain Windows Clients

I couldn’t find a singular place on the Internet for a descriptive guide of how to configure samba to use freeipa authentication for cifs shares for non-domain Windows clients.
There are guides out there for freeipa cross-domain trust, so you can share with a domain-joined Windows client, including https://www.freeipa.org/page/Howto/Integrating_a_Samba_File_Server_With_IPA.

This document will show you how to set up Samba 4.4.4 to use FreeIPA 4.4.0 usernames and passwords to allow Windows clients to connect to cifs shares.

Example environment

  • Freeipa domain is vm.example.com.
  • A freeipa master on CentOS7 host1.vm.example.com 192.168.100.10
  • A freeipa replica on CentOS7 host2.vm.example.com 192.168.100.11
  • Samba server will go on host2.vm.examplecom.
  • Windows client is horatio.vm.example.com.
update 2020-02-12

For the past few months, I have had to keep certain samba packages back to keep myfreeipa auth working.
Between these package versions, something happens that prevents samba from properly using the freeipa authentication. I have to keep to 4.8.3 of samba* and lib(sm|w)bclient packages so my samba share can accept my freeipa domain users for smb:// access.

---> Package samba-libs.x86_64 0:4.8.3-6.el7_6 will be updated
---> Package samba-libs.x86_64 0:4.9.1-10.el7_7 will be an update
update 2020-03-03

With the information shared by Alexander NA below, by changing a few lines in smb.conf, samba 4.9.1 will work with freeipa! You need to comment out these lines:

#domain master = Yes
#domain logons = Yes

I actually filed a bug a while ago in CentOS, but I need to go update it now.

Samba share with freeipa auth

Install freeipa server (and replica)

You need a working freeipa environment, which is outside the scope of this document. A quick sample installation process is:

### INSTALL FREEIPA host1.vm.example.com
firewall-cmd --permanent --add-service=freeipa-ldap --add-service=freeipa-ldaps --add-service=ntp --add-service=dns --add-service=dhcp --add-service=kerberos
firewall-cmd --reload

yum install -y ipa-server ipa-client
ipa-server-install -r VM.EXAMPLE.COM -n vm.example.com --mkhomedir --hostname="$( hostname --fqdn )" --admin-password='adminpassword' --ds-password='dspassword'

### INSTALL REPLICA host2.vm.example.com
firewall-cmd --permanent --add-service=freeipa-ldap --add-service=freeipa-ldaps --add-service=ntp --add-service=dns --add-service=dhcp --add-service=kerberos
firewall-cmd --reload

yum install -y ipa-server ipa-client
ipa-client-install --mkhomedir --force-ntpd --enable-dns-updates
ipa-replica-install --setup-ca --mkhomedir

Install samba server

Install the samba packages.

yum -y install samba samba-client sssd-libwbclient

Create the cifs principal for samba on one of the ipa controllers.

# run on an ipa controller. This principal name is "service/hostname"
ipa service-add cifs/host2.vm.example.com

Fetch the keytab to the samba server. In this example, it’s the same as the replica.

# on samba server
kinit -kt /etc/krb5.keytab
ipa-getkeytab -s host1.vm.example.com -p cifs/host2.vm.example.com -k /etc/samba/samba.keytab
setsebool -P samba_enable_home_dirs on &

Reference: https://www.freeipa.org/page/Howto/Integrating_a_Samba_File_Server_With_IPA

Install adtrust components

On the freeipa controller

yum -y install ipa-server-trust-ad
ipa-adtrust-install --add-sids

I recommend running this interactively, as shown above. Let it overwrite your samba config. It will configure it to use the registry, and we will rewrite it to suit the demands here.
The ipa-adtrust-install command generates the records you need to add to dns. They will look like:

Add the following service records to your DNS server for DNS zone vm.example.com: 
_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.vm.example.com. 86400 IN SRV 0 100 389 host2.vm.example.com.
_kerberos._udp.dc._msdcs.vm.example.com. 86400 IN SRV 0 100 88 host2.vm.example.com.
_kerberos._udp.Default-First-Site-Name._sites.dc._msdcs.vm.example.com. 86400 IN SRV 0 100 88 host2.vm.example.com.
_ldap._tcp.dc._msdcs.vm.example.com. 86400 IN SRV 0 100 389 host2.vm.example.com.
_kerberos._tcp.dc._msdcs.vm.example.com. 86400 IN SRV 0 100 88 host2.vm.example.com.
_kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs.vm.example.com. 86400 IN SRV 0 100 88 host2.vm.example.com.

I successfully added them just fine by pasting them into my zone file and running rndc reconfig or systemctl restart named.
The adtrust mechanism adds new attributes to each user and group, specifically ipaNTSecurityIdentifier (the SID) and ipaNTHash. Technically the ipaNTHash can only be generated when the user changes passwords.
Reference: https://www.redhat.com/archives/freeipa-users/2015-September/msg00052.html

On the samba server

Install the ipa-server-trust-ad package on the samba server. You need this package there to get the ipasam config option in smb.conf.

yum -y install ipa-server-trust-ad

Open the firewall for the ports mentioned in the output of the command. You can use this script.

tf=/lib/firewalld/services/freeipa-samba.xml
touch "${tf}"; chmod 0644 "${tf}"; chown root:root "${tf}"; restorecon "${tf}"
cat <<EOFXML > "${tf}"
<?xml version="1.0" encoding="utf-8"?>
 <service>
  <short>IPA and Samba</short>
  <description>This service provides the ports required by the ipa-adtrust-install command.</description>
  <port protocol="tcp" port="135"/>
  <port protocol="tcp" port="138"/>
  <port protocol="tcp" port="139"/>
  <port protocol="tcp" port="445"/>
  <port protocol="tcp" port="1024-1300"/>
  <port protocol="udp" port="138"/>
  <port protocol="udp" port="139"/>
  <port protocol="udp" port="389"/>
  <port protocol="udp" port="445"/>
 </service>
EOFXML
systemctl restart firewalld
firewall-cmd --permanent --add-service=freeipa-samba
firewall-cmd --reload
echo done

Allow samba to read passwords

This is the magic part that is so hard to find on the Internet.
You will need to give special permissions to the samba service to read user passwords.

ipa permission-add "CIFS server can read user passwords" \
   --attrs={ipaNTHash,ipaNTSecurityIdentifier} \
   --type=user --right={read,search,compare} --bindtype=permission
ipa privilege-add "CIFS server privilege"
ipa privilege-add-permission "CIFS server privilege" \
   --permission="CIFS server can read user passwords"
ipa role-add "CIFS server"
ipa role-add-privilege "CIFS server" --privilege="CIFS server privilege"
ipa role-add-member "CIFS server" --services=cifs/host2.vm.example.com

Reference: http://freeipa-users.redhat.narkive.com/ez2uKpFS/authenticate-samba-3-or-4-with-freeipa

Explanation

If you use ldapsearch with kerberos authentication (after a kinit admin, of course), you can see attributes about users.

ldapsearch -Y gssapi "(uid=username)"

Even if the user has generated a new password since the adtrust installation, even the admin cannot see the ipaNTHash attribute.
To confirm the samba service can read the ipaNTHash, use its keytab and search for that attribute.

# on the samba server, so host2.vm.example.com
kdestroy -A
kinit -kt /etc/samba/samba.keytab cifs/host2.vm.example.com
ldapsearch -Y gssapi "(ipaNTHash=*)" ipaNTHash

Configure samba to use freeipa auth

When freeipa adjusts the samba config, it will just make it use the registry backend. You can view the equivalent conf file with testparm.
Here is a complete /etc/samba/smb.conf.

tf=/etc/samba/smb.conf
touch "${tf}"; chmod 0644 "${tf}"; chown root:root "${tf}"; restorecon "${tf}"
cat < "${tf}"
[global]
	debug pid = yes
	realm = VM.EXAMPLE.COM
	workgroup = VM
	#domain master = Yes
	ldap group suffix = cn=groups,cn=accounts
	ldap machine suffix = cn=computers,cn=accounts
	ldap ssl = off
	ldap suffix = dc=vm,dc=example,dc=com
	ldap user suffix = cn=users,cn=accounts
	log file = /var/log/samba/log
	max log size = 100000
	#domain logons = Yes
	registry shares = Yes
	disable spoolss = Yes
	dedicated keytab file = FILE:/etc/samba/samba.keytab
	kerberos method = dedicated keytab
	#passdb backend = ipasam:ldapi://%2fvar%2frun%2fslapd-VM-EXAMPLE-COM.socket
	#passdb backend = ldapsam:ldapi://%2fvar%2frun%2fslapd-VM-EXAMPLE-COM.socket
	passdb backend = ipasam:ldap://host2.vm.example.com ldap://host1.vm.example.com
	security = USER
	create krb5 conf = No
	rpc_daemon:lsasd = fork
	rpc_daemon:epmd = fork
	rpc_server:tcpip = yes
	rpc_server:netlogon = external
	rpc_server:samr = external
	rpc_server:lsasd = external
	rpc_server:lsass = external
	rpc_server:lsarpc = external
	rpc_server:epmapper = external
	ldapsam:trusted = yes
	idmap config * : backend = tdb

	ldap admin dn = cn=Directory Manager

[homes]
	comment = Home Directories
	valid users = %S, %D%w%S
	browseable = No
	read only = No
	inherit acls = Yes
EOFCONF
systemctl restart smb.service

Appendices

Get localsid

Get the local SID

net getlocalsid

Changing ipa domains

It’s possible that if you change ipa domains, the sssd cache is not cleared and you will have cached information for the old domain which can prevent user authentication from happening. You can just clear the cache directory manually and restart sssd.

rm -rf /var/lib/sss/db/*
systemctl restart sssd.service

Reference: https://bgstack15.wordpress.com/2017/05/07/freeipa-client-uninstall-and-reinstall/

References

Weblinks

  1. install samba and kerberize it https://sites.google.com/site/wikirolanddelepper/directory-services/ipa-server-with-samba
  2. add cifs/servername entry https://www.freeipa.org/page/Howto/Integrating_a_Samba_File_Server_With_IPA
  3. cifs service needs custom privilege to read password http://freeipa-users.redhat.narkive.com/ez2uKpFS/authenticate-samba-3-or-4-with-freeipa
  4. Each user must generate a new password https://www.redhat.com/archives/freeipa-users/2015-September/msg00052.html
  5. Seminal article about freeipa and samba integration https://techslaves.org/2011/08/24/freeipa-and-samba-3-integration/
  6. Changing ipa domains https://bgstack15.wordpress.com/2017/05/07/freeipa-client-uninstall-and-reinstall/

35 thoughts on “Samba share with freeipa auth

  1. Thanks for documenting this; we have just started experimenting with FreeIPA and Samba integration without an AD was a must-have for us.

  2. Thanks for this. Previous attempts at this were hard to find and involved modifying IPA backend via LDAP which made me nervous.

    I recently changed my IPA servers ip address so I have to find out how to renew my certificates, then I will try this.

  3. Worked like charm, and to echo everyone else’s responses, thank you for documenting and sharing this!
    I wish the folks over at freeipa.org would include this use case with their online HowTos.

  4. Great article, but if i already have an established free environment and samaba server and i cannot change that, how can i get samba to auth against freeip?

    • You can start under the “Install samba server” heading. You need to kerberize samba, and then configure the ipa server to trust AD and allow samba to read the passwords, and then configure samba. You will have to experiment with which changes will be necessary for your environment.

  5. Great article ; you save my year man.
    i had an issue with using PWM against a FreeIpa server ; but i couldn’t reset normal users password from the portal; your article just unlocked what i was looking for weeks now. especially the part that creates ipNTHash permission;
    Anyway , thanks a lot

  6. My understanding is that the server acting as a file server must also be an IPA replica server, is that correct?

    • No, the file server does not need to be an IPA replica. However, it does need the packages indicated here, which are used to install a replica. You need the ipasam.so (shared objects) file for the passdb backend in smb.conf.

  7. Great tutorial, but I got problem.
    My IPA server dan SAMBA in same machine, IPA without DNS as the DNS is in cloudflare.

    My problem is can’t start samba.
    This is the log :
    [2019/01/28 13:47:18.684151, 0, pid=110413] ipa_sam.c:4606(pdb_init_ipasam)
    Jan 28 13:47:18 server.x.com smbd[110413]: pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain. We cannot work reliably without it.
    Jan 28 13:47:18 server.x.com smbd[110413]: [2019/01/28 13:47:18.684233, 0, pid=110413] ../source3/passdb/pdb_interface.c:180(make_pdb_method_name)
    Jan 28 13:47:18 server.x.com smbd[110413]: pdb backend ipasam:ldap://server.x.com did not correctly init (error was NT_STATUS_CANT_ACCESS_DOMAIN_INFO)
    Jan 28 13:47:18 server.x.com systemd[1]: smb.service: main process exited, code=exited, status=1/FAILURE
    Jan 28 13:47:18 server.x.com systemd[1]: Failed to start Samba SMB Daemon.
    Jan 28 13:47:18 server.x.com systemd[1]: Unit smb.service entered failed state.
    Jan 28 13:47:18 server.x.com systemd[1]: smb.service failed.

    • I manage to find the problem.
      There were one line in smb.conf that I still used example from yours.

      Now I can run the SMB but I can’t login the network share from Windows.
      But I can login from cli in computer server.
      I try using :

      kinit user@MY.REALM

      smbclient -k -L sambatest.my.realm

      smbclient -k //sambatest.my.realm/shared

    • Sorry, my mistake.
      I tried login without using @REALM that’s why I can’t never login to samba server.
      But what annoying was no error at log file so I can’t find where was wrong.

      Thank you for the article

  8. Thanks very much for the guide @bgstack15. Just wondering about the last step. I’ve got the output of testparm.

    Do I need to put that in an smb.conf file on the samba server or the freeipa server? (in my case the samba server is not a freeipa replica).

      • Thanks. I still can’t connect from a windows machine. Any tips for getting to the bottom of the problem would be much appreciated.

        I can connect from Linux clients.

        The only change that I’ve made on my windows machine is to change the workgroup from ‘WORKGROUP’ to ‘VM’ (well my equivalent of ‘VM’ anyway). Is there something else I need to do on the Windows side?

        I’ve cranked up the samba logging to 10, but am not sufficiently well versed to understand the problem.

        For others following these steps, I copied the testparm output from the freeipa server into the smb.conf on the samba server, but the samba service wouldn’t start until I edited the ‘passdb backend’ line:
        from something like:
        passdb backend = ipasam:ldapi://%2fvar%2frun%2fslapd-VM-EXAMPLE-COM.socket
        to:
        passdb backend = ipasam:ldap://freeipaserver.vm.example.com

  9. Just passing a helpful hint on from @bgstack15 which might be obvious to many but was not to me. When trying to connect to the share from the windows machine, enter your username as ‘WORKGROUP\username’, substituting for the workgroup that’s specified in your smb.conf (which should match the appropriate part of your domain), and the username that you’ve set up in your freeipa server.

    • you can comment out “domain logons = Yes” and no need providing WORKGROUP in username part

  10. Anyone else using this setup successfully but getting thousands of GSSAPI client step [12] messages?

      • I’ve been researching this for a while and found the same items. Was hoping I was alone in this which might mean some config issue. It does appear to be putting some stress on the ldap server, but the load is being handled. Appreciate the response, quick one at that. 🙂

        Also, didn’t mention it before, but thanks for the write up as well. Now I just need to figure out why one system keeps coming up with missing socket / pipe. Identical config, will figure it out, just a nuisance on a failover server. Yes, reinstalled, checked perms, checked config, etc…..

        connect(/run/samba/ncalrpc/EPMAPPER) failed: No such file or directory

      • Samba might one of those packages in CentOS 7 that just didn’t always generate some of its required directories. (Actually, the one I’m remembering was either/both bind and dhcpd). Chances are EPMAPPER is in a different directory or that one doesn’t exist yet, blah blah blah. And of course, check with SELinux disabled…

  11. Following your guide (thank you!) I’ve running samba 4.9.1 now without issues (at this time, i think):
    [root@smb-test samba]# rpm -qa|grep samba
    samba-common-libs-4.9.1-10.el7_7.x86_64
    samba-common-tools-4.9.1-10.el7_7.x86_64
    samba-winbind-modules-4.9.1-10.el7_7.x86_64
    samba-python-4.9.1-10.el7_7.x86_64
    samba-client-4.9.1-10.el7_7.x86_64
    samba-common-4.9.1-10.el7_7.noarch
    samba-libs-4.9.1-10.el7_7.x86_64
    samba-4.9.1-10.el7_7.x86_64
    samba-winbind-4.9.1-10.el7_7.x86_64
    samba-client-libs-4.9.1-10.el7_7.x86_64
    [root@smb-test samba]#
    [root@smb-test samba]# rpm -qa|grep ipa-
    ipa-client-common-4.6.5-11.el7.centos.4.noarch
    ipa-common-4.6.5-11.el7.centos.4.noarch
    sssd-ipa-1.16.4-21.el7_7.1.x86_64
    ipa-client-4.6.5-11.el7.centos.4.x86_64
    ipa-server-4.6.5-11.el7.centos.4.x86_64
    ipa-server-trust-ad-4.6.5-11.el7.centos.4.x86_64
    ipa-server-common-4.6.5-11.el7.centos.4.noarch

    Only two changes – commenting out “domain master = Yes” and “domain logons = Yes”

    • By commenting out the lines you mention, I am able to get my non-domain Windows clients to connect to the SMB shares. Thank you very much!

  12. I’ve followed the directions and everything seems to work, but I can’t mount shares. I keep getting this in the logs:

    check_sam_security: Couldn’t find user ‘test’ in in passdb

    and

    FAILED with error NT_STATUS_NO_SUCH_USER, authoritative=1

    I know the users are valid accounts but they keep failing.

    any ideas?

    • Whatever backend you chose (probably ipasam) does not appear to be able to find the username “test.” Of course check your ldap connection string. Ensure the port is open, and valid ldap queries can return responses.

      • It started working as soon as I recreated my accounts. Accounts created before ipa-adtrust-install –add-sids didn’t have ipaNTHash::

  13. Separate issue I’ve noticed that mounted smb shares only seem to recognize FreeIPA users but not existing groups. when I mount a share with 775 permissions as a user and go to a directory owned by a group the user is part of, it won’t allow write.
    However, if I create a new group and make the same user a member it has no problem with the permissions and it can write. I’ve tried deleting and recreating existing groups, but it doesn’t seem to work.

    Is there anything I can do to make existing groups work with this?

    • I have not worked with groups in this arrangement at all. It’s probably related to the ipaNTHash problem. There’s probably something that has to be generated for the group, to be registered as a group for samba. I didn’t read the schema changes for the groups at all.

    • Check and change your directory permissions:
      ls -al /your_dir
      ls -aln /your_dir
      getfacl /your_dir

      after that align your smb.conf settings, like write list = @local_group, @ipa_group

      • Thanks for the suggestion, unfortunately it’s not entirely practical in my situation. I’ve got 70+ groups and add more all the time, so Samba really needs to be aware of groups/GIDs directly from FreeIPA the same way it does for users.

  14. Hello

    Very good and informative site

    We run a (free) IPA environment and additionally a file server, which is accessible via NFSv4 and SAMBA 4.9.1. NFS is no problem, but SAMBA does. Server OS is CentOS 7.7 (IPA server and fileserver)
    We can observe a very slow authentication for Windows and Mac clients when the backend runs via “passdb backend = ipasam:ldaps://xxx.xxx.xx”. Every time a user logs on and interacts with a file, one of the IPA servers is contacted, which takes time (between 10 and 15 seconds) and generates a significant load on the IPA server. The file server does not seem to use a local cache.
    Strangely enough, the whole thing works very fast for Linux and MacOS clients without a suitable backend, but then it doesn’t work for Windows clients anymore.

    Slow config with Windows clients

    [global]
    debug pid = yes
    realm = EXAMPLE.COM
    workgroup = EXAMPLE.COM
    ldap group suffix = cn=groups,cn=accounts
    ldap machine suffix = cn=computers,cn=accounts
    ldap ssl = off
    ldap suffix = dc=example,dc=com
    ldap user suffix = cn=users,cn=accounts
    log file = /var/log/samba/log.%m
    log level = 3
    max log size = 10000
    registry shares = Yes
    disable spoolss = Yes
    dedicated keytab file = FILE:/etc/samba/samba.keytab
    kerberos method = dedicated keytab
    passdb backend = ipasam: “ldap://ipa-1.example.com ldap://ipa-2.example.com
    security = USER
    create krb5 conf = No
    rpc_daemon:lsasd = fork
    rpc_daemon:epmd = fork
    rpc_server:tcpip = yes
    rpc_server:netlogon = external
    rpc_server:samr = external
    rpc_server:lsasd = external
    rpc_server:lsass = external
    rpc_server:lsarpc = external
    rpc_server:epmapper = external
    ldapsam:trusted = yes
    idmap config *: backend = tdb
    ldap admin dn = cn=Directory Manager
    min protocol = SMB2

    Fast config without Windows clients
    [global]
    dedicated keytab file = FILE:/etc/samba/samba.keytab
    kerberos method = dedicated keytab
    realm = IPA.EXAMPLE.COM
    server role = member server
    workgroup = IPA
    idmap config * : backend = tdb
    idmap config * : range =10000-99999
    idmap config EXAMPLE : range = 878800000-8790000
    idmap config EXAMPLE : backend = sss

    any ideas?

  15. Thanks for the guide!
    I’ve followed the directions and everything seems to work. The only downside that I’m experiencing is that all my usernames are now displayed with “@domain”. I’m playing with FreeIPA mostly for learning and also tried to export linux user directories through NFS. On the linux side everything works, but when a user tries to acces his home directory through samba it fails cause samba tries to find user@domain.

    Does someone have an idea how I can revert back to just showing “user” on the linux boxes and getting that through samba?

    As a side note, the samba domain is also set to my main FreeIPA domain so there shouldn’t be multiple domains active on the network.

    Thanks in advance!

      • Thanks for the fast response. I tried the options you gave but they only have an effect on what format of username you need to use at login. What I’m trying to get is that when executing ls I get my user name listed without domain. Any idea how to get that?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.