-2

I am looking to parse an /etc/passwd file and take out only the users within a range of UIDs. I am not very good with functions it seems.

I found the following function, but can not seem to make it work. from how to make PHP lists all Linux Users?

function getUsers() {
    $result = [];
    /** @see http://php.net/manual/en/function.posix-getpwnam.php */
    $keys = ['name', 'passwd', 'uid', 'gid', 'gecos', 'dir', 'shell'];
    $handle = fopen('/etc/passwd', 'r');
    if(!$handle){
    throw new \RuntimeException("failed to open /etc/passwd for reading! ".print_r(error_get_last(),true));
    }
    while ( ($values = fgetcsv($handle, 1000, ':')) !== false ) {
        $result[] = array_combine($keys, $values);
    }
    fclose($handle);
    return $result;
}

Now I believe I need only put the function in the page then later call it with

getUsers()

This is still not a complete solution however, only a part as I then need to get the UIDs that are within a $min and $max range but if I can not get past the above step it is hard to more on to getting the users in the range mentioned.

Perhaps there is a better way to do this?

UPDATE---------------------------

I got this part,my bad

Now i need to parse the /etc/passwd file

(naysayers go away I do not need your security lecture, as there are NO PASSWORDS in /etc/passwrd. if you knew anything about security you would know that!)

The file looks like this

[24] => Array
    (
        [name] => lightdm
        [passwd] => x
        [uid] => 107
        [gid] => 115
        [gecos] => Light Display Manager
        [dir] => /var/lib/lightdm
        [shell] => /bin/false
    )

[25] => Array
    (
        [name] => kodi
        [passwd] => x
        [uid] => 1000
        [gid] => 1000
        [gecos] => ,,,
        [dir] => /home/kodi
        [shell] => /bin/bash
    )

[26] => Array
    (
        [name] => saned
        [passwd] => x
        [uid] => 108
        [gid] => 119
        [gecos] => 
        [dir] => /var/lib/saned
        [shell] => /bin/false
    )

[27] => Array
    (
        [name] => statd
        [passwd] => x
        [uid] => 109
        [gid] => 65534
        [gecos] => 
        [dir] => /var/lib/nfs
        [shell] => /bin/false
    )

[28] => Array
    (
        [name] => sshd
        [passwd] => x
        [uid] => 110
        [gid] => 65534
        [gecos] => 
        [dir] => /var/run/sshd
        [shell] => /usr/sbin/nologin
    )

[29] => Array
    (
        [name] => pulse
        [passwd] => x
        [uid] => 111
        [gid] => 121
        [gecos] => PulseAudio daemon,,,
        [dir] => /var/run/pulse
        [shell] => /bin/false
    )

[30] => Array
    (
        [name] => rtkit
        [passwd] => x
        [uid] => 112
        [gid] => 123
        [gecos] => RealtimeKit,,,
        [dir] => /proc
        [shell] => /bin/false
    )

[31] => Array
    (
        [name] => avahi
        [passwd] => x
        [uid] => 113
        [gid] => 124
        [gecos] => Avahi mDNS daemon,,,
        [dir] => /var/run/avahi-daemon
        [shell] => /bin/false
    )

[32] => Array
    (
        [name] => hplip
        [passwd] => x
        [uid] => 114
        [gid] => 7
        [gecos] => HPLIP system user,,,
        [dir] => /var/run/hplip
        [shell] => /bin/false
    )

[33] => Array
    (
        [name] => spanish
        [passwd] => x
        [uid] => 1001
        [gid] => 1001
        [gecos] => spanish,,,,
        [dir] => /home/spanish
        [shell] => /bin/bash
    )

I think for greatest effeciency is to parse the file once creating a new array . I have set a $minuid and $maxuid that selects the users I want based on the 'uid' key.

WHat I need to get back is a smaller array with ONLY those users with a UID that falls between $maxuid and $minuid then easily be able to get 'name' and 'dir' fields for those relevant users.

I seem kind of lost at how to do this.

Mark
  • 39
  • 1
  • 6
  • 2
    Hopefully for your systems security you cannot or maybe I shoud say you should not do this – RiggsFolly Mar 18 '19 at 19:09
  • I agree with @RiggsFolly, bad idea to do this. – blupointmedia Mar 18 '19 at 19:17
  • this is for a LAN only app. besides the passwd file does not have any passwords anyway . – Mark Mar 18 '19 at 19:20
  • `can not seem to make it work` What problems did you have? (Any error messages, how have you tried to debug it, ...) Is the question simply "how do I use the value returned from a function"? – Joni Mar 18 '19 at 19:30
  • You're returning something from the function. What are you doing with it? – miken32 Mar 18 '19 at 19:30
  • i tried to print_r($result) and get nothinfg out of it. Maybe that is wrong? getUsers(); print_r($result); – Mark Mar 18 '19 at 20:40
  • i got it like this: $test= getUsers(); print_r($test); – Mark Mar 18 '19 at 20:49
  • So the question really was "how do I use the value returned from a function"? By the way, by exposing the list of users on the machine, you have revealed what services and what shell user accounts exist on the machine. Now potential attackers know they can try to log in as `kodi` or as `spanish` over ssh, and that they could take advantage of vulnerabilities in lightdm, x.org, pulseaudio, avahi, etc. While everyone with access to the system can read /etc/passwd it doesn't mean it's a good idea to publish it on an internet accessible service – Joni Mar 19 '19 at 11:34
  • Joni, I guess you have never heard of numerous tools , to name just one fail2ban. I also said this is for a LAN app. If someone has a kid hacker or a malicios employee that is a problem they need to deal with . This app is for use on a LAN. Not everything is to use on the Internet. EMail me I will gladly give you the address of a server to try to hack a PAM user and password. If you can, probably not through this script. – Mark Mar 20 '19 at 19:55

1 Answers1

0

First, anyone who wants to complain about security needs to consider the following:

/etc/passwd is world readable. This is the required state of the file.

If this is new and/or surprising to you, then you need to brush up on basic security and Linux administration.


OP, you're going to want to use array_filter(), eg:

$min = 500;
$max = 1000;
$filtered_users = array_filter(
    $input,
    function($a) use ($min, $max) {
        return $a['uid'] >= $min && $a['uid'] <= $max;
    }
);
Sammitch
  • 30,782
  • 7
  • 50
  • 77
  • Sammitch , that works! thanks. And right on about the security business Iguess they deleted my similar comment I had made. – Mark Mar 19 '19 at 05:23
  • @Mark You need to get in the habit of [accepting answers](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) which help you to solve your issues. You'll earn points and others will be encouraged to help you. – Jay Blanchard Apr 05 '19 at 17:33