UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C
  • » Why my sudo command wrapper doesn't work correctly?

#1 2007-08-16 03:18 AM

eltoncold
Member
Registered: 2007-08-16
Posts: 5

Re: Why my sudo command wrapper doesn't work correctly?

Hi, all!

I wrote a toy program which is a sudo command wrapper.
Using this command, there is no need to enter password when
invoking sudo command every time.
In my program, libexpect is used. But my program doesn't work
properly. For example, when invoking
./mysudo cat somefile.txt
only part of somefile.txt is print to screen.
My program is listed below, thank you for your help!

########################################

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <expect.h>

#define SUDO_CMD "/usr/bin/sudo"
#define BUF_SIZE 100
#define SPACE " "
#define PASSWD "aaa"

enum match_result_type {
    matched = 1,
};

struct exppair {
    const char *expect;
    const char *reply;
};

static const struct exppair system_sudo_seq[] = {
    {"Password:", PASSWD},
    {NULL, NULL},
};

int main (int argc, char **argv) {
    int fd;
    int ret;
    FILE *fp;
    char *spawn;
    int status;
    static const struct exppair *pitr = system_sudo_seq;
    char cmd_str[BUF_SIZE];
    int i;

    /*
     * Don't echo user input passwd.
     */
    exp_stty_init = "-echo";
    /*
     * Construct user input command string.
     */
    strcpy(cmd_str, SUDO_CMD);
    strcat(cmd_str, SPACE);
    for (i = 1; i < argc; i++) {
        strcat (cmd_str, argv[i]);
        strcat (cmd_str, SPACE);
    }
    spawn = cmd_str;
    fp = exp_popen(spawn);
    if(!fp) {
        fprintf(stderr, "Unable to spawn process %s: %s\n",
                spawn, strerror(errno));
        return errno;
    }
    fd = fileno(fp);
    printf("Running %s under pid %i exp_timeout is %i)\n", 
           spawn, exp_pid, exp_timeout);

    for (; !((pitr->expect == NULL) && (pitr->reply == NULL)); pitr++) {
        if(pitr->expect) {
            ret = exp_fexpectl(fp, exp_exact, pitr->expect, matched, exp_end);
            if (ret != matched)
                break;
        }
        /*
         * enter password automatically.
         */
        if(pitr->reply) {
            write(fd, pitr->reply, strlen(PASSWD));
            write(fd, "\n", 1);
        }
    }
    if (ret != matched) {
        fprintf(stderr, "failed to expect input (%i)\n", ret);
    }
    else {
        waitpid(exp_pid, &status, 0);
    }
    /*
     * Check the return status of child process.
     */
    if (WIFEXITED(status)) {
        printf("exited, status=%d\n", WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
        printf("killed by signal %d\n", WTERMSIG(status));
    } else if (WIFSTOPPED(status)) {
        printf("stopped by signal %d\n", WSTOPSIG(status));
    } else if (WIFCONTINUED(status)) {
        printf("continued\n");
    }

    fflush(fp);
    fclose(fp);
    return (ret != matched);
}

Offline

#2 2007-08-16 08:09 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: Why my sudo command wrapper doesn't work correctly?

Just edit /etc/sudoers to have an entry

username   ALL=(ALL)       NOPASSWD: ALL

or something more finegrained.

Offline

#3 2007-08-16 08:13 AM

eltoncold
Member
Registered: 2007-08-16
Posts: 5

Re: Why my sudo command wrapper doesn't work correctly?

Thank you for your reply!
But I would like to know why this program doesn't work properly.

Offline

#4 2007-08-16 12:44 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: Why my sudo command wrapper doesn't work correctly?

Because, you're never reading and displaying the output from the exp_popen()'d
process...  I can't even believe you get even partial output, which you claim...  You
shouldn't get any visible output at all, I wouldn't think, based on that code...  I think
the exp_fexpectl() might print the output up to the matching prompt, but nothing
after that should be printed by any means I can see...  Basically, after you've
matched (before you do your waitpid()), you want a loop just reading from "fp" and
printing the data to stdout...  (You could also probably just call exp_fexpectl() again
without any pattern to look for, and let it run until EOF...)  Also, technically, you
should fclose(fp) BEFORE doing waitpid()...

However, like i3839 said: this is a VERY bad way of doing what you want to do...
sudo already supports passwordless use, so it's best to configure it properly, if
that's what you want to do...

Offline

#5 2007-08-20 04:00 AM

eltoncold
Member
Registered: 2007-08-16
Posts: 5

Re: Why my sudo command wrapper doesn't work correctly?

Offline

#6 2007-08-20 11:26 AM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: Why my sudo command wrapper doesn't work correctly?

Just because it's the technically proper order...  Let's say your spawned process
doesn't terminate until it gets an EOF from its stdin; in that case, you'll be sitting in
waitpid() forever...  In this particular case, it doesn't matter, but it might for a
different case...  (Eg: if you just spawn "cat" instead of "cat file.txt"...)

Offline

  • Index
  • » C
  • » Why my sudo command wrapper doesn't work correctly?

Board footer

Powered by FluxBB