1

I want to parse /etc/passwd file to find out if the user can run interactive shell.

I know the 7th field in each line of /etc/passwd file tells the path of shell. But How do you say that, defined shell is interactive?

I am parsing this files in python, I can implement the logic, I just don't know the how to find out how to identify Interactive shell.

PS. I want to find it out using python.

muru
  • 197,895
  • 55
  • 485
  • 740
Kishor Pawar
  • 157
  • 1
  • 2
  • 10
  • Do you want to check if the shell can run interactively? otherwise the question is implementation dependent and ambiguous.. – heemayl Feb 01 '16 at 04:52
  • I didn't read the question like that before... If they can run a shell they can run it interactively. How do you run a shell "non-interactively" (script) without running it from an interactive shell? Unless you mean running a script from a desktop environment. – kos Feb 01 '16 at 04:53
  • @heemayl actually I am new to linux, I will appreciate if you explain what is Interactive shell and how do you identify one. – Kishor Pawar Feb 01 '16 at 04:54
  • 1
    Check this ..as you don't understand the difference it is probably wiser to either remove or rephrase the question.. – heemayl Feb 01 '16 at 04:56
  • 1

2 Answers2

3

I think you have a basic misconception: talking of a shell that you cannot run interactively but that you can run non-interactively is much like talking of a car that you can't drive but that you can use to listen to the radio.

The main purpose of a shell is running interactively, the fact that it can run non-interactively is the optional, not the other way around.

Closer to the concept of a shell that you cannot run interactively but that you can run non-interactively is an interpreted language which can't be interpreted interactively (though one real example is not occuring to me right now: the most common interpreted languages all can run interactive sessions: Perl, Python, PHP, ...)

That been said if you want to find out whether a user is allowed to login through a shell, you can use this command:

shell=$(getent passwd user | cut -d ':' -f 7); [ "$shell" = "/usr/sbin/nologin" -o "$shell" = "/bin/false" ] && printf 'User is not allowed to login\n' || printf '%s\n' "$shell"

(replace user in the getent passwd user command with the user's username)

In Python you could do:

#!/usr/bin/python
user = "user"
with open("/etc/passwd") as file:
    for line in file:
        if line.split(":")[0] == user:
            if line.rstrip("\n").split(":")[6] in ["/usr/sbin/nologin", "/bin/false"]:
                print("User is not allowed to login")
            else:
                print(line.rstrip("\n").split(":")[6])

(replace user in the user = "user" statement with the user's username)

Or, as suggested by muru, better using the pwd module:

#!/usr/bin/python
from pwd import getpwnam

user = "user"
shell = getpwnam(user)[6]
if shell in ["/usr/sbin/nologin", "/bin/false"]:
    print("User is not allowed to login")
else:
    print(shell)

(replace user in the user = "user" statement with the user's username)

In all of the examples above if the seventh field of the user's /etc/passwd entry is either /usr/sbin/nologin or /usr/bin/false a message saying that the user is not allowed to login is printed; otherwise the user's login shell is printed.

But keep in mind that not being able to login through a shell doesn't mean the user is not allowed to login at all, and that there might be bogus shells other than /usr/sbin/nologin or /bin/false used to forbid the user's login. You should watch out for those too.

muru
  • 197,895
  • 55
  • 485
  • 740
kos
  • 35,891
  • Also, there's the pwd library: https://docs.python.org/3/library/pwd.html – muru Feb 01 '16 at 06:28
  • 1
    @muru Huh right, I forgot I was pasting from the terminal. And yeah looks better using in. Thanks. – kos Feb 01 '16 at 06:50
1

Loop through file splitting each line into fields and check if 6th field doesn't contain "no-login" for all the lines where UID is greater than 1000

>>> with open("/etc/passwd") as file:
...     for line in file:
...        if  int(line.split(":")[2])  > 1000  and not str(line.split(":")[6]).__contains__("nologin"):
...            print line
... 
testuser:x:1001:1001:,,,:/home/testuser:/bin/bash

tester:x:1002:1002:TESTER,,,:/home/tester:/bin/bash

newUser:x:1003:1003::/home/newUser:

testUser:x:1004:1004::/home/testUser:

testuser2:x:1005:1005:asdf,asdf,asdf,asdf,asdf:/home/testuser2:/bin/bash

Usernames who have shell set can login with that shell, for instance xieerqi has /bin/mksh, while testUser has /bin/bash. Other users don't have shell set, which will default to /bin/bash

A.B.
  • 90,397
Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • you mean all shells are Interactive except with the no-login? – Kishor Pawar Feb 01 '16 at 05:22
  • Serg, i am afraid the question is pretty ambiguous and your answer is not properly directed too..its not your fault actually as the OP is not clear about differences among shell sessions.. – heemayl Feb 01 '16 at 05:23
  • heemayl exactly I am not clear about the shell concept. – Kishor Pawar Feb 01 '16 at 05:24
  • @KishorPawar All the common shells, such as bash, ksh, csh , dash - all those are interactive if you can type something with keyboard. If you are using them for running a script, that's non-interactive. That's different question though. If a user has a shell set in /etc/passwd that means they can login interactively and control system using keyboard. So every user who has some form of shell set up (or like some of my users - blank ) those will be able to login and work interactively – Sergiy Kolodyazhnyy Feb 01 '16 at 05:30
  • 1
    You can also use /bin/false to disable the shell for a user – Germar Feb 01 '16 at 05:42