Mac sudo authorization help



  • From my application I am starting apache using sudo, but sudo command requires password.
    So how can I get this password from user..
    is there any sudo GUI that will ask for the password as soon as the user starts apache or is there any other authorization GUI that will ask for the password and set that password for that particular application session.



  • Hi Ketah,

    I think that this is not a problem of the Qt applicaiton itself but is related to the OS integration. Max Osx is linux so I can suggest that your Qt applicaiton will be able to manage a shell command launch. Tell me if it maybe the solution so I can post you whar piece of bash script / command you need. Then, to obfuscate it you can create the call directly from your application where you save the user password too for sudo.

    Don't forget that despite the application installation you need then that the installing user is member of the sudoers too. In Mac I think that it is by default, while on different Linux plaftorms it will be done manually.



  • Yes, it is fine.
    If I create a window that will ask the user for password, how can I verify it, whether the user has entered a correct password or not, is there any script or command that can help me to verify the password. By the way MAC is an Unix-based operating system(http://en.wikipedia.org/wiki/Mac_OS_X)



  • you can ask with something like QProcess the desred system command, catch the result and the return code (i.e. using the stdio redirection) and manage all from the GUI



  • But how can i verify the password, is there any place where the sudo password are stored.? so that I can check it to verify.
    Is there any shell script that will do this verification.?



  • I think you are following the wrong approach. You should not mind on how does Mac to manage its system strategies: you should thing on how your interface can send and receive parameters, error conditions and results.
    You should read the docuemntation of the linux commands, i.e. login
    then see that are the command parameters and what are the return code.

    In linux commands usually there are "verbose" modes that explain errors, warnings etc. useful when you use the commands from the terminal. but when you need to use them from a GUI you should pass parameters that returns e.g. error codes only.

    As a matter of fact you can "graphicize" almost any linux command with a GUI only managing them. It will be good if you can post the logic of your application and what you want exactly do. So we can be clear with some example.



  • Also I got a solution in the form of "Cocoasudo":http://www.performantdesign.com/2009/10/26/cocoasudo-a-graphical-cocoa-based-alternative-to-sudo/ which is a GUI based sudo.
    But as soon as I run apache with cocoasudo it prompts the user for password every time.
    Is there any way to set the timeout in Cocoasudo atleast for 15 mins, so till next 15mins it wont ask the user for password again.



  • Sorry but to give you a decent answer you should be aware that I need to know at least what are you doing ...



  • From my application I want to start apache but apache starts with sudo only as it is using port 80.
    But sudo requires password that is why I am thinking to use Cocoasudo but it asks for password everytime I start or stop apache. For this reason I want to set the time out of 15 mins in Cocoasudo same like in normal sudo, so after every 15mins when the apache is being started or stopped the user will be prompted for the password.
    And also my application requires that apache should always start on port 80.



  • Yep
    It is clear now

    First ifnore cocasudo. To start apache I think that you should do something like the following:
    @
    $cd /etc/apache2
    $sudo
    insert password:


    $./apache2
    @
    At this point you should know that sudo has more options and try to create a small shell script like the following naming it apachestarter.sh
    @
    #!/bin/bash
    NUMPARMS=1 # Minimum required parameters

    get the current user userId

    ACTUALUSER=$(whoami)

    check for parms

    if [ $# -lt "$NUMPARMS" ]
    then
    echo
    echo "Apache starter"
    echo
    echo "usage: ./apachestarter.sh <password for user $ACTUALUSER>"
    echo "password omitted, so insert manually"
    read PASSWORD
    else
    # read password argument
    PASSWORD=$1
    fi

    The following command will run apache with the sudo password without asking nothing

    echo $PASSWORD | sudo -S /etc/apache2/apache2
    @
    Then save this file in the user home folder or somewhere in the user area. Then remember to change the privileges of this command to be executable, i.e.
    @
    $sudo chmod +x apachestarter.sh
    @
    [Edit: the previous line has been changed as it is now for a correct and secure operation. See the following posts to understand the reasons]
    At this point you can launch your command (that will be part of the package, installed in the installation folder etc.) directly from inside your GUI calling him with the password set by the user.



  • Just for the nitpicking records: Mac OS X is BSD/Darwin based, not Linux. It uses a couple of GNU software though :-)

    Now for something serious:
    Setting a file to mode 777 is a bad idea. Do not do that unless you are in need of everyone on the system changing the file's contents!



  • Hi Volker, I was just waiting you at this party :D

    [quote author="Volker" date="1316174529"]Just for the nitpicking records: Mac OS X is BSD/Darwin based, not Linux. It uses a couple of GNU software though :-)

    Now for something serious:
    Setting a file to mode 777 is a bad idea. Do not do that unless you are in need of everyone on the system changing the file's contents![/quote]

    It is all true, but what I wrote was only an exmple based on my memory and not the command to be created. I think that it can give idea of the concept.

    Then +x or 666 instead of 777 maybe a good idea. But this was and example. The concept is: create a shell program then call it from the GUI and redirect the errio or console to the GUI and see what is the return code then act consequently.

    Just to be precise: sure, Mac OSX is BSD and it is not a linux just like the debian based distributions (Meego, Harmattan, Ubuntu, Debian itself), gentoo, RedHat and many more including those like OpenWRT and Ltib especially dedicated to the embedded Linux platforms?

    Cheers.



  • I know, it was just a quick example, and of course it works. But we all know, that not so experienced users may take the advice literally and end up with a, say suboptimal or dangerous setup. One should keep this always in mind, IMHO.



  • Corrected the post with the example and added a short not. So the problem is solved :)



  • After running the script that you provided I got an error.

    "-bash: ./apachestarter.sh: /bin/bash^M: bad interpreter : No such file or directory".

    What is the solution for this?



  • You should change the file to unix line endings (newlines instead of carriage return).



  • @Volker: are you sure? I exchange continuously files between mac and ubuntu and windows 7 too but the conversions is automatic. It is possible the the folder example that I have suggested can't be applied to the Mac folder structure. I have no idea where apache started is located in the Mac. But I think that Ketan should know.

    If the error is what you mean (I suspect too because of this ^M ...) it is strange that happens. Why ?



  • @alicemirror
    It heavily depends on the editor and it's settings. The rest is guessing from the crystal ball. You're right, my guess comes from the ^M - I stumbled over that myself already.



  • @volker
    Me too, that character worried me too. But I use Mac dayly and just when I open a windows file that for sure has a different coding for the line termination the message that I receive is a fast msgBox "converting to line termination characters" etc. then it disappear. So think we can exclude that the problem is it. I know that the Linux of Mac is different from the Linux of debian in the management of /etc/launcher shell commands. Not only, there are different apache versions. My example was regarding the apache 2 on pure debian machine (always used on servers, not on desktop machines) ...



  • Thanks Alicemirror and Volker, finally the script executed successfully. As Volker told to change the file to Unix line endings. I did that by removing /r from the file and after that the script executed.

    Thanks a lot once again.



  • Well, the important is that this was the correct way.



  • Just a question [O.T.] what method have used to launch the call from inside Qt ? Please can you see few lines of code?

    Thank you



  • Sorry, can you please elaborate what you are exactly asking.



  • You have created the shell command that is called in some conditions from inside your QT GUI, as I have understood correctly. Thus what is the code that you have used to launch the shell program from inside the application ?

    This was my question.



  • Your script worked, but I didnt used it completely in my Qt app.I had used the following code from your script which was very helpful,

    @echo $PASSWORD | sudo -S /Application/apps/apache/bin/httpd@

    Actually what I have done is I have build a dialog that will ask the current user for its password and I have stored that password in a variable. After that I have verified it by using the following code,

    @QProcess *p = new QProcess;
    p->start("bash", QStringList()<<"-c"<<"echo $PASSWORD | sudo -S ls /var/db/shadow/ ; echo $?");
    p->waitForStarted(1000);
    p->waitForFinished(1000);
    QString readcode = p->readAll();@

    if the command is executed successfully it will return 0 or else it will return 1.
    So if the password is correct than I have stored it in the PASSWORD variable and after that have started apache with that password.

    According to you would it be the right procedure to verify the sudo password?



  • Yes, it is correct.
    Just an advice: in this way you wait for a while the process to finish. Maybe best to manage it as a signal. As a matter of fact the shell call is a secondary process launch. With an event-driven it is sure that you return from the task when the process is finished. Then setup a timer too that after a reasonable period (i.e. 30 seconds) stop the process anyway because something was wrong. This is a general consideration, not for a case so simple.
    Add too a Busy indicator so the user see that is waiting for the command sequence compleiton.



  • Thanks for your advice, will surely work on it.



  • @Ketan: please set this thread to [Solved}. Thanks.



  • @Alicemirror: Sorry, but how can I set this thread to solved.



  • :)
    it;s simple: go to the first post (it's your) and click edit.
    Correct the title writing [Solved] in front.

    Cheers



  • Just as a side note, being OSX based on Unix, a getent call could retrieve the hashed password and other user information to check in the Qt application. Of course this means that the application is able to re-cypher the plain password so to perform the check. And this will not give any privilege to the application itself.
    However, a possible solution to avoid similar situations is to configure the sudo application to not request a password for a specific user, and set the suid of the qt application to such user. Never tried, but should work.
    However, the best solution is to let the system ask for the user password!



  • Yes I know this. But as you can read in the specifications of the OS documentation (sudo command etc) the general problem of passing the sudo password in a visible way (i.e. saving it in a text file or leaving all the users with the higher privileges) may have a terrible impact on the entire machine...



  • Well, in any environment having a plain text password saved somewhere is a call for troubles.
    I was not saying to use a plain password, but just to cypher the password via md5 or the os alghoritm and check the result against the getent result to see if it is correct. The password could be asked interactively to the user. Again, this has nothing to do with gaining privileges.
    Configuring sudo to not require a password is another problem, but could be useful if the user has no machine login. I used it in daemon-like applications, that must be of course well trusted and must run with a nologin user, so to avoid (or delay) a privilege escalation. Of course, it depends on how much you trust your application to make it run suid....



  • Ahha ok, this maybe a way. I agree, my post was only an add-on to your previous comment. It will be interesting to require or not the passwor following the directions of the user: if user has setup his machine for auto-login then it should else not.
    Consider alsothat this applicaiton launch a system command and it is normal that it wil be done asking for a password. Like when you launch other commands that involve root privileges to be exectued. With sudo, the effect is that the user is only asked for his password but the reality is that you access root-privilege commands.



  • [quote author="Alicemirror" date="1316166789"]Yep
    It is clear now

    First ifnore cocasudo. To start apache I think that you should do something like the following:
    @
    $cd /etc/apache2
    $sudo
    insert password:


    $./apache2
    @
    At this point you should know that sudo has more options and try to create a small shell script like the following naming it apachestarter.sh
    @
    #!/bin/bash
    NUMPARMS=1 # Minimum required parameters

    get the current user userId

    ACTUALUSER=$(whoami)

    check for parms

    if [ $# -lt "$NUMPARMS" ]
    then
    echo
    echo "Apache starter"
    echo
    echo "usage: ./apachestarter.sh <password for user $ACTUALUSER>"
    echo "password omitted, so insert manually"
    read PASSWORD
    else
    # read password argument
    PASSWORD=$1
    fi

    The following command will run apache with the sudo password without asking nothing

    echo $PASSWORD | sudo -S /etc/apache2/apache2
    @
    Then save this file in the user home folder or somewhere in the user area. Then remember to change the privileges of this command to be executable, i.e.
    @
    $sudo chmod +x apachestarter.sh
    @
    [Edit: the previous line has been changed as it is now for a correct and secure operation. See the following posts to understand the reasons]
    At this point you can launch your command (that will be part of the package, installed in the installation folder etc.) directly from inside your GUI calling him with the password set by the user.

    [/quote]

    Hi,
    how can I start apache if the sudo has no password(no password is set for user) ?



  • Sorry for hijacking this thread but I'm doing some work along these lines as well. Right now I do a call in one of my functions in my QT application so it's a little like this:

    @
    char cmdLine[1024];
    sprintf(cmdLine, "echo %s | sudo -S somethingthatneedssudo);
    system(cmdLine);
    @

    This is all fine and dandy but the function that I run takes a while and I want to pop open a dialog box that tells the user that it's running with a progressbar. I also want the application to be "responsive" during this time so that there isn't the spinning wheel in the case of Mac OSX. I can run the cmdLine as a background process by adding a "&" to the end of the sudo command which will allow the application to be responsive. However I don't know of a good way of detecting when this process is finished so I can change the dialog to display something that tells the user the process is finished. I tried using QProcess::execute() but that takes the cmdLine string and interprets the command as echo and everything after it as a literal string so it just prints "%s | sudo -S somethingthatneedssudo". Is there a good way to do this that I'm not finding?

    [EDIT: code formatting, please wrap in @-tags, Volker]



  • This code works for me:

    @
    void MainWindow::pushButton1Pressed()
    {
    bool ok;
    QString password = QInputDialog::getText(
    this,
    tr("Password"),
    tr("Password:"),
    QLineEdit::Normal,
    "",
    &ok);
    if(!ok || password.isEmpty())
    return;

    // proc is a QProcess pointer defined in the class 
    if(!proc) {
        proc = new QProcess(this);
        connect(proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
    } else {
        // terminate a probably running process
        proc->kill();
    }
    proc->start("sudo -S id");
    proc->write(password.toLocal8Bit());
    proc->write("\n");
    proc->closeWriteChannel();
    

    }

    void MainWindow::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
    {
    QString finished = QString("exitCode=%1\nstatus=%2\n").arg(exitCode).arg(exitStatus);
    finished += proc->readAllStandardOutput();
    QMessageBox::information(this, "Process Output", finished);
    }
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.