Tilde prefix returns invalid home directory.

I am trying to find the home directory of users on a UNIX (Solaris/AIX) box using

echo ~username

This does return the home directory for all valid users. For some reason this command also outputs home directory which are non-existent for few users who seem not to have logon access to that server.

For eg. the above command would return below for a non-existent user - /home/username

What I expected was - ~username as the output for a user with no access and that does happen with certain usernames.

This makes me think what could be causing a difference between different users who do not have access to this server. Has this something to do with LDAP?

Nothing I can find in /etc/passwd either.

The ~username does the same as a

getent passwd username

(then prints the home directory field), or

perl -e 'printf "%s\n", (getpwnam ("username"))[7]'

The getpwnam() is a function of the libc, and normally acts according to the passwd entry in /etc/nsswitch.conf

Yeah I had tried getent but not sure if Solaris/AIX could get a default home directory from LDAP. How does that work? The reason its not clear is that, it hits a common LDAP and has different behavior for users who are not provided access to the same server(non-existent user). So things are like:

Common LDAP -
--- non-existent user1 - echo ~user1 outputs ~user1
--- non-existent user2 - echo ~user2 - says non-existent user.

An ldap directory used to authenticate users is storing all fields traditionally found in the /etc/passwd plain file. The home directory is definitely one of them but one should only be returned if there is an entry matching the username requested, unless you have a non standard directory server or a custom plugin.
What says:

ldaplist -v user1

?

Read the man page of your shell on each OS!
For example

man bash

under Tilde Expansion
tells that it simply returns the ~user1 if not found.

@MadeInGermany The OP has likely read the manual page as he is expecting the behavior the bash manual is describing.
However, for some reason, he seems to observe inconsistent results.

Because the man pages are different?
A deviation between the shell and its man page would be a bug.

All the shells I know that support the tilde expansion do exhibit on every OS the same behavior as the one bash is documenting.

I suspect either a user mistake or a directory related configuration or error.

Then you don't know csh.
tcsh 6.12 on Solaris:

> set nonomatch
> echo ~nonsense
~nonsense
> unset nonomatch
> echo ~nonsense
Unknown user: nonsense.

Good catch. I have to admit I avoid and disregard csh for any purpose since 30 years or so ...

Actually ldaplist isn't available. I suspect this to be an implementation issue where in LDAP may have a default home directory specified for certain non-existent users on the server?

---------- Post updated at 03:34 PM ---------- Previous update was at 03:28 PM ----------

Its KSH on both AIX/Solaris but it looks to be a problem with the way it was configured. directory? Again I am suspecting this for the reason that certain users when echoed do have a default home directory but has not been granted access to that machine and neither does the home directory exist.

Also I would like to expand on previous post with one more behavior for clarity which I had originally posted in the query:

Common LDAP -
--- non-existent user1 - echo ~user1 outputs ~user1
--- non-existent user2 - echo ~user2 - says non-existent user.
--- non-existent user3 - echo ~user3 outputs /home/user3 .

on the Solaris machine ?? If you have not ldaplist installed, you are unlikely to have any ldap authentication in the first place.

What directory server are you using ?

"non-existent" doesn't seem to appear in ksh error messages. What ksh version are you using ? Is this really the precise error message you get ? on Solaris ? What Solaris release ?

My bad - I didn't try that on Solaris - its available and I do get a response like below

+++ database=user1
+++ filter=objectclass=*
+++ template for merging SSD filter=%s
ldaplist: Object not found (LDAP ERROR (32): No such object.)

But this gives a valid output for getent. Is that same grepping the /etc/passwd file?

Directory Server as far as I know is a Windows AD server but not sure of the exact version.

The error message was something like no valid user. I am unable to reproduce that error message now it just prints ~xxxxx. So something has changed.

ksh version is M-11/16/88i and Solaris is 5.10.

getent is not the same as grepping /etc/password. getent looks to the backend databases listed in the /etc/nsswitch.conf files in order and report the first match, if any. Might be from /etc/passwd or not.

The ~xxxxx behavior is the one expected with unknown users.

1 Like

But I still wonder how could getent pull up default home directory for a non-existent user for which ldaplist doesn't work. I am not seeing anything apart from ldap and /etc/passwd references in nsswitch.conf file.

Also finger returns the same default home directory.

Please copy/paste factual data. It is unclear what you are observing.

For user1:

Display home directory - echo ~user1 below is the output :

/home/user1 

Although a default home directory is returned it doesn't exist.

getent has below output:

user1:x:33000:5460:user123, user01, , /home/user1:/bin/ksh

finger has below output:

Login name: user1                     In real life: user123
Directory: /home/user1                Shell: /bin/ksh

nsswitch.conf:

passwd:     files nis
group:      files nis
hosts:      files nis dns 

Output for ldaplist is same as in th previous post. And /etc/passwd has nothing specifc to this user.

Observe - getent and finger return default home directory for a non-existent user. While ldaplist says Object not found.

Assuming this user does have access, he tried logging in with LDAP credentials to authenticate which I would assume use the same sources as in nsswitch.conf but failed.

So I am not sure what makes this non-existent user different than other non-existent accounts?

Well, the root cause is you are confusing NIS and LDAP.

You'll get this user's entry with:

ypmatch user1 passwd

Thanks. I am completely new to Solaris. I tried that and it gave me following message:

Can't match key user1 in map passwd.byname. Reason: can't communicate with ypbind.

I am not sure what ypmatch/ypbind does. Trying to look that up now.

NIS (known as the yellow pages in the last century) is a protocol available with almost all if not all Unix implementations, it is not Solaris specific.
What says:

grep user1 /etc/passwd

?