Page 1 of 1
[Solved]How to reboot/poweroff as normal User
Posted: 14 May 2014, 20:40
by sabir
Hi all!
How to restart Linux from inside a C program without qt/gtk/sudo/python/java script/bash script/pressing poweroff button manually/etc?
I mean using only real system/kernel calls and pure C libs, for example:
#include <unistd.h>
#include <sys/reboot.h>
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc
sync();
reboot(RB_POWER_OFF); / reboot(LINUX_REBOOT_CMD_POWER_OFF);
or
#include <stdio.h>
int main()
{
setuid (0);
system("shutdown -P now");
return 0;
}
It works under root user only, but it is wrong way (security). User is in power group (/etc/group/power
84:guest).
Please don't tell me about:
just press lxde panel->menu->Logout
cairo-dock->Logout->Shutdown/Restart
su->root password->reboot/poweroff
execl("/usr/bin/sudo", "/sbin/shutdown", "-h", "1:30", (char*)NULL);
Thanks
Re: How to reboot/poweroff as normal User
Posted: 15 May 2014, 04:02
by tome
Re: How to reboot/poweroff as normal User
Posted: 15 May 2014, 17:53
by sabir
Thanks, man
As I understood there is no way to do it as normal user, unless run any prog with root privileges.
Re: How to reboot/poweroff as normal User
Posted: 15 May 2014, 18:49
by tome
root privileges are unneeded
Re: How to reboot/poweroff as normal User
Posted: 17 May 2014, 05:42
by sabir
tome wrote:root privileges are unneeded
To run "/usr/bin/dbus-send" the root privileges are unneeded, but "dbus" itself has root privileges (/usr/bin/dbus-send owner:root, group:root). A normal user just asks dbus-send to send his message to the ConsoleKit/UPower. The /usr/bin/upower and the /usr/bin/ck-* have root privileges too. Am I wrong?
Re: How to reboot/poweroff as normal User
Posted: 17 May 2014, 10:14
by tome
I don't know but you don't need root password.
Re: How to reboot/poweroff as normal User
Posted: 18 May 2014, 01:26
by brokenman
No you are not wrong. This is the process when guest hits the shutdown button. You should be able to accomplish this from within a script like so:
Code: Select all
/usr/bin/dbus-send --system --print-reply \
--dest="org.freedesktop.ConsoleKit" \
/org/freedesktop/ConsoleKit/Manager \
org.freedesktop.ConsoleKit.Manager.Stop
This is what tome says in his thread.
Re: How to reboot/poweroff as normal User
Posted: 19 May 2014, 07:33
by sabir
brokenman wrote:This is what tome says in his thread.
Yeah, I understood. But I'd like to reboot my own computer directly as a normal user, without any root privileged progs. I mean, I'd like to call reboot(RB_POWER_OFF) directly as a non-privileged user
Re: How to reboot/poweroff as normal User
Posted: 19 May 2014, 19:28
by fanthom
linux is designed to prevent this
Code: Select all
guest@porteus:~$ /sbin/reboot
reboot: must be superuser.
Re: [Solved]How to reboot/poweroff as normal User
Posted: 21 May 2014, 01:50
by brokenman
OK i understood you were writing a script that would run on other systems too. If this is just for your box then perhaps change ownership/access rights of the binaries and put them in /usr/bin. Havn't tried it since the shutdown button works as guest fo rme. If you're in terminal then just su to root and shutdown.
Another option is to create a script as suggested above, put it in /usr/bin and call it as guest. I tested this and it works fine.
Re: [Solved]How to reboot/poweroff as normal User
Posted: 30 May 2014, 03:41
by sabir
brokenman wrote:If this is just for your box then perhaps change ownership/access rights of the binaries and put them in /usr/bin.
Make our reboot binary file:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/reboot.h>
#include <sys/reboot.h>
#include <grp.h>
#include <pwd.h>
#include <error.h>
#include <errno.h>
static gid_t * read_groups(void)
{
int n;
gid_t *groups;
n = getgroups(0, NULL);
if(n < 0)
{
fprintf(stderr, "Unable to retrieve groups: %m\n");
return NULL;
}
groups = malloc(n * sizeof(gid_t));
if(!groups) return NULL;
if(getgroups(n, groups) < 0)
{
fprintf(stderr, "Unable to retrieve groups: %m\n");
free(groups);
return NULL;
}
return groups;
}
static int reboot_allowed()
{
struct group *gr;
gid_t *groups;
int i;
gr = getgrnam("power");
if(gr)
{
groups = read_groups();
if (groups)
{
for (i = 0; groups[i]; ++i)
{
if (groups[i] == gr->gr_gid)
{
free(groups);
return 1;
}
}
free(groups);
}
}
return 0;
}
int main()
{
struct passwd *pw;
pw = getpwuid(getuid());
if(pw == NULL) error(1, errno, "failed to get username\n");
if(!reboot_allowed()) error(1, 0, "Permission denied\n");
sync();
reboot(LINUX_REBOOT_CMD_RESTART);
return 0;
}
Then change ownership/access rights of the binary and put it in /usr/bin:
Run it as root of course
Code: Select all
cp re-boot /usr/bin/
chown root /usr/bin/re-boot
chmod +s /usr/bin/re-boot
And now you can reboot you're computer as normal user. Just run re-boot (where re-boot is the binary name), but be carefull it's unsecure way to do it