Experience sharing and questions for NIS migration from Solaris 8 to Linux

I'd like to share some experiences and what I found for NIS migration from Solaris 8 NIS to Linux platform.
I'm not an expert for both platforms, it's just when I tested both systems and found something really tricky. That might takes a lot of time for you to find the root cause. So, I think I can share some experiences from what I've found to help you saving time if you have the same need as me. And still, I have some questions unsolved, maybe some experts can give me suggestions.

Original NIS server: Solaris 8
New NIS server: Red hat Linux 6.5

I have to say that my experiences are built on Solaris 8 migrating to RHEL, Solaris 8 is an outdated system, Solaris 9, 10 above should be more advanced than 8, so I am not sure if it can works for other versions.

To save words, there were two questions I posted earlier.

  1. Linux 6.5 supports SHA512 password encryption as default, however, Solaris only supports DES encryption. There is no doubt that you have to modify Linux NIS encryption to support DES, otherwise, you may face the issue to authenticate a NIS user when you login to a solaris client.
A. run the following command to change the default encryption.
# authconfig --passalgo=descrypt --update.

B. run the following command to check if the above setting works.
# authconfig --test
pam_unix is always enabled
 shadow passwords are enabled
 password hashing algorithm is descrypt

C. check the following line of /etc/pam.d/system-auth,
change
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
to
password    sufficient    pam_unix.so shadow nullok try_first_pass use_authtok
  1. If you still have Solaris 8 clients, /var/yp/Makefile has to be modified as the following,
A. MERGE_PASSWD=true  --> a shadow map won't be generated.

After that, restart your ypserv service and re-make your /var/yp/Makefile, it should works for a Solaris client to login a NIS user with no issues.

If you need a NIS slave server, it's recommended to build it under the same platform as NIS master has. A cross-platform method between two platforms may face the issue of ypfxrd synchronization since Solaris uses ndbm package instead of GNU dbm or Berkeley DB.

If you need password aging, that's the problem I am still working on it.

I found if you have Solaris clients in your domain, it is necessary to set "MERGE_PASSWD=true" to make NIS users can login from Solaris clients.
However, that won't generate a shadow map for NIS, and it's a MUST existence if you want password aging.

It seems like a conflict if you want both of them works. I still don't find a way out of this. Does someone has any workaround or solution for this issue??

I've been stuck on this task for couple weeks. If anyone is willing to share some experiences, I'll be appreciated.

Thanks.

2 Likes

Google for "passwd.adjunct".
This was Sun's solution to hide the pw crypts. But later they encouraged to replace NIS, first with NIS+ then with LDAP.
And please continue with sharing your results here :slight_smile:

Sorry for delay response since I did some works to test passwd.adjunct.
I know passwd.adjunct is the Sun's solution to hide password encryption.
It's just I'm not sure if it can satisfy what I need.

My goals are,

  1. NIS users can login from both Linux and Solaris clients.
  2. hide password encryption from ypcat
  3. be able to change NIS user passwords from any host in our domain.
  4. password aging can be provided to NIS users.

From what I've done, it seems like there is no perfect way to do them all neither using shadow nor passwd.adjunct.

When using shadow,

  1. NIS users can login from both Linux and Solaris clients.
  2. In order to satisfy #1, "MERGE_PASSWD" in the /var/yp/Makefile has to be set to "true" while it dissatisfies #4. And, this makes ypcat can get pw encrypts.
  3. be able to change NIS user passwords from any host in our domain.
  4. conflict with #2.

When using passwd.adjunct,

  1. NIS users can login from both Linux and Solaris clients.
  2. pw encypts can be hid from ypcat.
  3. can use yppasswd to change a NIS user pwd. However, it fails to use a NIS user to login NIS master. I' ll describe it later.
  4. password aging needs the shadow file instead of passwd.adjunct. I'm not sure if it's right. I failed to test this issue, maybe something I missed.

---------- Post updated at 07:34 PM ---------- Previous update was at 05:50 PM ----------

As for passwd.adjunct, I did some works trying to fit my needs.
To make passwd.adjunct works, there are something need to be done on both server/client.

on the client:

  1. Edit /etc/default/nss config and set ADJUNCT_AS_SHADOW=TRUE.

on the server:

  1. Create the file /var/yp/securenets

  2. check /etc/ypserv.conf for the following settings,

* : * : shadow.byname : port
* : * : passwd.adjunct.byname : port
  1. change /etc/sysconfig/yppasswdd settings,
PASSWDFILE=/var/yp/passwd
SHADOWFILE=/var/yp/passwd.adjunct
  1. set my environment hash variable to DES encryption.
    setenv YP_PASSWD_HASH des

  2. copy /etc/shadow and /etc/passwd to /var/yp, modify /var/yp/passwd format as below,
    username:##username:.....

  3. change /var/yp/Makefile setting,

NOPUSH=false
...
...
MERGE_PASSWD=false
...
...
YPSRCDIR = /etc
YPPWDDIR = /etc
YPPWDDIR_ADJ = /var/yp
YPBINDIR = /usr/lib64/yp
YPSBINDIR = /usr/sbin
YPDIR = /var/yp
YPMAPDIR = $(YPDIR)/$(DOMAIN)
...
GROUP       = $(YPPWDDIR)/group
PASSWD      = $(YPPWDDIR_ADJ)/passwd
SHADOW      = $(YPPWDDIR)/shadow
GSHADOW     = $(YPPWDDIR)/gshadow
ADJUNCT     = $(YPPWDDIR_ADJ)/passwd.adjunct
...
...
# If you don't want some of these maps built, feel free to comment
# them out from this list.

all:  passwd group hosts rpc services netid protocols mail \
        auto.master auto.direct passwd.adjunct

...
ethers:         ethers.byname ethers.byaddr
hosts:          hosts.byname hosts.byaddr
networks:       networks.byaddr networks.byname
protocols:      protocols.bynumber protocols.byname
rpc:            rpc.byname rpc.bynumber
services:       services.byname services.byservicename
passwd:         passwd.byname passwd.byuid
group:          group.byname group.bygid
shadow:         passwd.adjunct
passwd.adjunct: passwd.adjunct.byname
netid:          netid.byname
netgrp:         netgroup netgroup.byhost netgroup.byuser
...

  1. After finishing settings, restart ypserv and yppasswdd services.

After those,

  1. a NIS user can login from both Linux/Solaris clients.

  2. only root can get user password encryption.

  3. You can change a NIS user password using yppasswd from any client and re-login. But, it fails to re-login from the NIS master server.

I do more tests and find when I login to the NIS master as a NIS user, it is authenticated to the /etc/shadow instead of /var/yp/passwd.adjunct, and if I use yppasswd to change the user password, it fails to change the NIS passwd.
Then I use passwd to do it again, it succeeds, but only to change /etc/shadow.

I believe it results from the nsswitch.conf setting authentication only to files,

passwd:     files
shadow:     files
group:      files

So, when I login as a NIS user, it authenticates through /etc/passwd and /etc/shadow.
It's rational settings cause this is NIS master server, and there is no way to set "nis" in front of "files" which will cause the ypserv issue.

From what I tested, this is a gap between /etc/shadow and passwd.adjunct that I don't know how to fix it.

  1. Because of #3, I have no chance to test password aging from NIS master. chage/chfn/chsh change /etc/shadow instead of /var/yp/passwd.adjunct.

I'm at my wit's end with this. Does anyone have any idea?

The best setting for NIS is

passwd:     files nis
shadow:     files
group:      files nis

It first looks for local users in /etc/passwd; if not found it consults NIS.
On the NIS master, if you want it to work like a NIS client, you should put the NIS source files outside of /etc/ e.g. create a directory /etc/yp-maps/ for them and adapt the Makefile.

Could you please be more clear? That confused me a little.
As I know, /etc/passwd and /etc/shadow is not recommended to move to other places since there are many built-in libraries and applications running as root bound to these files. Is there any way to change default system settings toward other source files?

However, I still manage to do some tests for this idea.
I left /etc/passwd and /etc/shadow to where they are and just separated NIS users info to other source files located in /etc/yp, i.e., /etc/yp/passwd and /etc/yp/shadow for NIS service.

Then I adapted the following files.

  1. /etc/pam.d/system-auth and /etc/pam.d/password-auth
password    sufficient    pam_unix.so shadow nis nullok try_first_pass use_authtok
  1. /etc/nsswitch.conf
passwd:     files nis
shadow:     files nis
group:      files nis

#hosts:     db files nisplus nis dns
hosts:      files dns nis
  1. adapted /var/yp/Makefile, redirect shadow and passwd sources to /etc/yp, and then re-make.

  2. restart ypserv/yppasswdd/ypbind services

After that, I can successfully queried a NIS user info from database as below

# ypmatch testuser passwd
testuser:##testuser:10124:4000:19-Aug-2002:/nas/testuser:/bin/tcsh
# ypmatch testuser passwd.adjunct.byname
testuser:7abi0uUn./pOk:17290::::::

Unfortunately, I still can't login as a NIS user on master server.

# ssh testuser@mastest
testuser@mastest's password: 
Permission denied, please try again.

I have no idea what went wrong....

for more information,

  1. /etc/default/nss
ADJUNCT_AS_SHADOW=TRUE
  1. /etc/sysconfig/yppasswdd
# The passwd and shadow files are located under the specified
# directory path. rpc.yppasswdd will use these files, not /etc/passwd
# and /etc/shadow.
#ETCDIR=/etc

# This options tells rpc.yppasswdd to use a different source file
# instead of /etc/passwd
# You can't mix usage of this with ETCDIR
#PASSWDFILE=/etc/passwd
PASSWDFILE=/var/yp/passwd

# This  options  tells rpc.yppasswdd to use a different source file
# instead of /etc/passwd.
# You can't mix usage of this with ETCDIR
#SHADOWFILE=/etc/shadow
SHADOWFILE=/var/yp/passwd.adjunct

# Additional arguments passed to yppasswd
YPPASSWDD_ARGS="--port 1012"

Correct, the local users like root must stay in the /etc files.
nsswitch.conf is correct when

getent passwd

lists both local and NIS users.
The actual login authentication via PAM I do not have much experience with.

--------
Information update.

I found something strange. I turned ypserv debug mode on, then It seemed ypserv recognized NIS domain and tried to find the user info, however, it did check passwd.adjunct.byname and then skipped and kept searching info from shadow.byname.

I tried to copy /var/yp/`domainname`/passwd.adjunct.byname to /var/yp/`domainname`/shadow.byname and re-login from NIS master again, and it worked.

I just don't know why is that? It supposed to authenticate a NIS user just like the client did.

This is ypserv debug log as below, I'm kind of week analyzing this log, maybe someone can help to find the key.

# ypserv -d
[ypserv (ypserv) 2.19]

Find securenet: 255.255.255.255 127.0.0.1
Find securenet: 255.255.248.0 172.26.80.0
ypserv.conf: dns: 0
ypserv.conf: files: 30
ypserv.conf: xfr_check_port: 1
ypserv.conf: 0.0.0.0/0.0.0.0:*:shadow.byname:2
ypserv.conf: 0.0.0.0/0.0.0.0:*:passwd.adjunct.byname:2
ypproc_domain_nonack("nistest") [From: 127.0.0.1:42028]
connect from 127.0.0.1
        -> OK.
ypproc_match(): [From: 127.0.0.1:923]
                domainname = "nistest"
                mapname = "passwd.byname"
                keydat = "testuser"
        ypdb_open("nistest", "passwd.byname")
                ->Returning OK!
Opening: nistest/passwd.byname (0) 577519b0
ypdb_close() called
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (0)
ypdb_close() called
        -> Value = "testuser:##testuser:10124:4000:19-Aug-2002:/nas/testuser:/bin/tcsh"
ypproc_match(): [From: 127.0.0.1:924]
                domainname = "nistest"
                mapname = "passwd.byname"
                keydat = "testuser"
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (0)
ypdb_close() called
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (0)
ypdb_close() called
        -> Value = "testuser:##testuser:10124:4000:19-Aug-2002:/nas/testuser:/bin/tcsh"
ypproc_match(): [From: 127.0.0.1:925]
                domainname = "nistest"
                mapname = "shadow.byname"
                keydat = "testuser"
connect from 127.0.0.1
        ypdb_open("nistest", "shadow.byname")
gdbm_open: GDBM Error Code #3
        -> Error #-1
ypproc_match(): [From: 127.0.0.1:926]
                domainname = "nistest"
                mapname = "passwd.adjunct.byname"
                keydat = "testuser"
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.adjunct.byname")
                ->Returning OK!
Opening: nistest/passwd.adjunct.byname (1) 577b9760
ypdb_close() called
        -> Value = "testuser:7abi0uUn./pOk:17290::::::"
ypproc_match(): [From: 127.0.0.1:927]
                domainname = "nistest"
                mapname = "passwd.byname"
                keydat = "testuser"
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (1)
ypdb_close() called
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (1)
ypdb_close() called
        -> Value = "testuser:##testuser:10124:4000:19-Aug-2002:/nas/testuser:/bin/tcsh"
ypproc_match(): [From: 127.0.0.1:928]
                domainname = "nistest"
                mapname = "shadow.byname"
                keydat = "testuser"
connect from 127.0.0.1
        ypdb_open("nistest", "shadow.byname")
gdbm_open: GDBM Error Code #3
        -> Error #-1
ypproc_match(): [From: 127.0.0.1:929]
                domainname = "nistest"
                mapname = "passwd.adjunct.byname"
                keydat = "testuser"
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.adjunct.byname")
Found: nistest/passwd.adjunct.byname (0)
ypdb_close() called
        -> Value = "testuser:7abi0uUn./pOk:17290::::::"
ypproc_match(): [From: 127.0.0.1:930]
                domainname = "nistest"
                mapname = "passwd.byname"
                keydat = "testuser"
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (1)
ypdb_close() called
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (1)
ypdb_close() called
        -> Value = "testuser:##testuser:10124:4000:19-Aug-2002:/nas/testuser:/bin/tcsh"
ypproc_match(): [From: 127.0.0.1:931]
                domainname = "nistest"
                mapname = "passwd.byname"
                keydat = "testuser"
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (1)
ypdb_close() called
connect from 127.0.0.1
        ypdb_open("nistest", "passwd.byname")
Found: nistest/passwd.byname (1)
ypdb_close() called
        -> Value = "testuser:##testuser:10124:4000:19-Aug-2002:/nas/testuser:/bin/tcsh"
ypproc_domain_nonack("nistest") [From: 172.26.80.151:59420]
connect from 172.26.80.151
        -> OK.
1 Like

It is quite some time that I dealt with Solaris 8 - and with NIS.
Never attempted to hide the NIS password crypts.
Solaris 10 supports longer crypts, if enabled. Standard in Solaris 11. But with NIS...?

Just like I said, that's one of my target.
If things can't go perfect, It's only to compromise with that.
I know Solaris 9 above provides better solutions, it's just I have no choice.

Actually, I'm ok with not hiding password encrypts.
I set my heart on implementing password aging, using shadow would be easier for me, but those Solaris clients are killing me.

If passwd.adjunct can work with both platforms for this target, I'll stick with that. But it seems like a no go...:frowning:

Just to add to the discussion

  • AFAIK, Solaris 8 only supports password.adjunct, not shadow in nis
  • password.adjunct is extremely weak security and only protects against users if they cannot become root on a client that can approach the NIS server
  • passwd.adjunct works with both Solaris 8 and Linux clients.
  • Solaris 8, when updated to the very latest levels supports TLS/LDAP as long as the LDAP server uses SHA1 certificates (TLS 1.0). This is not an easy feat, but it is possible
  • AFAIK NIS will only work with DES56
  • I do not think password aging is possible on Solaris in combination with NIS, since it does not support shadow over NIS.
  • Solaris 8, even with the latest patches remains of course an insecure and outdated platform.
  • On Linux "nis" does not need to be / cannot be specified in system-auth / password-auth in pam. This is handled by pam_unix.so, since authentication is client side.
1 Like

Nice sharing. Thank you for this. You pretty much help me concluding the whole thing.

I am less concerned with security things since there is no choice with those Solaris 8 clients which are out of maintenance. I'm just trying to find a perfect way to complete whole tasks, if not, I can live with that. I did far more than my boss wanted me to do. He should be glad from what I've done. :smiley:

Based on your sharing, I might stick with using shadow for both platforms and it's compromised for pw hidden to ypcat and password aging though. But I can make a NIS user login to all hosts in the domain at least.

I might think about if it's possible to write a password aging checker for Solaris clients once I decide to enable NIS password aging at the next step.

Anyway, thank you all.

The last chalenge is yppasswdd - it supports changing of NIS passwords on the NIS client.
It receives a pw crypt over RPC and modifies the pw crypt field of the passwd or passwd.adjunct or shadow file (the NIS source file). It can be configured to then run the /var/yp/Makefile.
Consult man yppasswdd .

1 Like