Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] PATCH: run vdr as non-root user
Hi,
Attached patch enables vdr to switch to a different user (and
optionally group) itself, without help of su, sudo etc.
cu
Ludwig
--
(o_ Ludwig Nussel
//\ SUSE LINUX AG, Development
V_/_ http://www.suse.de/
only in patch2:
--- vdr-1.2.6pre2/vdr.c.orig 2003-10-21 19:41:44.000000000 +0200
+++ vdr-1.2.6pre2/vdr.c 2003-10-21 19:42:24.000000000 +0200
@@ -31,6 +31,8 @@
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
#include "audio.h"
#include "channels.h"
#include "config.h"
@@ -77,6 +79,60 @@
exit(1);
}
+// switch user and group id
+// taken from startproc by Werner Fink
+static int su(const char* username, const char* groupname)
+{
+ gid_t ngid = 0;
+ struct group* grp = NULL;
+ struct passwd *user = NULL;
+
+ if(!username) return 0;
+
+ user = getpwnam(username);
+ endpwent();
+ if(!user)
+ {
+ fprintf(stderr,"invalid user %s: %s\n",username,strerror(errno));
+ return 1;
+ }
+ if(groupname)
+ {
+ grp = getgrnam(groupname);
+ endgrent();
+ if(!grp)
+ {
+ fprintf(stderr,"invalid group %s: %s\n",groupname,strerror(errno));
+ return 1;
+ }
+ }
+
+ ngid = user->pw_gid;
+ if (grp)
+ ngid = grp->gr_gid;
+ else if (setgid(ngid) < 0)
+ {
+ fprintf(stderr,"cannot set group id %u: %s\n", (unsigned int)ngid, strerror(errno));
+ return 1;
+ }
+ if (!getuid())
+ {
+ if (initgroups(user->pw_name, ngid) < 0)
+ {
+ fprintf(stderr,"cannot set supplemental group ids for user %s: %s\n",
+ user->pw_name, strerror(errno));
+ return 1;
+ }
+ }
+ if (setuid(user->pw_uid) < 0)
+ {
+ fprintf(stderr,"cannot set user id %u: %s\n",
+ (unsigned int)user->pw_uid, strerror(errno));
+ return 1;
+ }
+ return 0;
+}
+
int main(int argc, char *argv[])
{
// Save terminal settings:
@@ -106,6 +162,8 @@
const char *Terminal = NULL;
const char *Shutdown = NULL;
cPluginManager PluginManager(DEFAULTPLUGINDIR);
+ const char* username = NULL;
+ const char* groupname = NULL;
static struct option long_options[] = {
{ "audio", required_argument, NULL, 'a' },
@@ -125,11 +183,13 @@
{ "version", no_argument, NULL, 'V' },
{ "video", required_argument, NULL, 'v' },
{ "watchdog", required_argument, NULL, 'w' },
+ { "user", required_argument, NULL, 'u' },
+ { "group", required_argument, NULL, 'g' },
{ NULL }
};
int c;
- while ((c = getopt_long(argc, argv, "a:c:dD:E:hl:L:mp:P:r:s:t:v:Vw:", long_options, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "a:c:dD:E:hl:L:mp:P:r:s:t:v:Vw:u:g:", long_options, NULL)) != -1) {
switch (c) {
case 'a': AudioCommand = optarg;
break;
@@ -219,6 +279,10 @@
fprintf(stderr, "vdr: invalid watchdog timeout: %s\n", optarg);
return 2;
break;
+ case 'u': username = optarg;
+ break;
+ case 'g': groupname = optarg;
+ break;
default: return 2;
}
}
@@ -260,6 +324,8 @@
" -V, --version print version information and exit\n"
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
" seconds (default: %d); '0' disables the watchdog\n"
+ " -u USER, --user=USER run as user USER instead of root\n"
+ " -g GROUP, --group=GROUP use group GROUP instead of primary group of user\n"
"\n",
cSIProcessor::GetEpgDataFileName() ? cSIProcessor::GetEpgDataFileName() : "'-'",
DEFAULTPLUGINDIR,
@@ -290,6 +356,9 @@
return 0;
}
+ if (su(username, groupname) != 0)
+ return 2;
+
// Log file:
if (SysLogLevel > 0)
Home |
Main Index |
Thread Index