Shar1er80
Shar1er80

Reputation: 9041

Performing DHCP on linux using Java

I'm trying to develop a DHCP client application in java that can receive DHCP Offers and Acks on port 68 without running as root. I'm aware of the linux limitation of binding to ports <1024. What options are available?

[Edit] The application can send DHCP Discovers and Requests. It needs to be able to receive DHCP Offers and Acks from a DHCP Server that uses custom DHCP options. The application will not be modifying any system information once the DHCP process is complete, but it will perform "custom" actions.

[Edit] Is there a way to configure the DHCP daemon to forward received packets to an application like how you can configure the SNMP daemon?

Upvotes: 2

Views: 2700

Answers (2)

favoretti
favoretti

Reputation: 30167

Well, you're a bit limited in options in your case.

According to RFC both client and server need to listen on privileged ports.

Other thing is - DHCP client normally alters system information, such as IP address, domain name, host name and so on, so if your client doesn't run as root, the only thing it will be able to achieve is just receiving offers and acks and doing nothing much with that information.

[edit]

And another thing - DHCP server won't send you an offer just all by itself. Normally client sends a DHCP request and server tries to match its MAC address to a configured host and/or hostgroup and then sends an offer.

I found a DHCP implementation for non-privileged users: http://code.google.com/p/ndhcp/wiki/ClientREADME

It uses the following C-code for dropping privileges:

void drop_root(uid_t uid, gid_t gid)
{
    if (uid == 0 || gid == 0) {
        log_line("FATAL - drop_root: attempt to drop root to root?\n");
        exit(EXIT_FAILURE);
    }

    if (getgid() == 0) {
        if (setregid(gid, gid) == -1) {
            log_line("FATAL - drop_root: failed to drop real gid == root!\n");
            exit(EXIT_FAILURE);
        }
    }

    if (getuid() == 0) {
        if (setreuid(uid, uid) == -1) {
            log_line("FATAL - drop_root: failed to drop real uid == root!\n");
            exit(EXIT_FAILURE);
        }
    }

    /* be absolutely sure */
    if (getgid() == 0 || getuid() == 0) {
        log_line("FATAL - drop_root: tried to drop root, but still have root!\n");
        exit(EXIT_FAILURE);
    }
}

I suppose the suggestion of Jon Lin should work in this case. One caveat - I assume it will need to start as root and later will auto-switch to a non-privileged user, so if you don't have root access at all, I'm afraid you're out of luck.

Upvotes: 2

Jon Lin
Jon Lin

Reputation: 143886

There is an Apache Commons Daemon service that might help you. It allows you to do something privileged, like bind to port 68, then switch to a non-priviledged user.

Upvotes: 1

Related Questions