mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-10 00:58:20 +03:00
[PATCH] add $local user spport for permissions
This commit is contained in:
parent
311e9ae681
commit
534c853df5
@ -25,6 +25,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "klibc_fixups.h"
|
||||
@ -32,6 +33,8 @@
|
||||
|
||||
#define PW_FILE "/etc/passwd"
|
||||
#define GR_FILE "/etc/group"
|
||||
#define UTMP_FILE "/var/run/utmp"
|
||||
|
||||
|
||||
/* return the id of a passwd style line, selected by the users name */
|
||||
static unsigned long get_id_by_name(const char *uname, const char *dbfile)
|
||||
@ -107,4 +110,38 @@ struct group *getgrnam(const char *name)
|
||||
return &gr;
|
||||
}
|
||||
|
||||
|
||||
int ufd = -1;
|
||||
|
||||
void setutent()
|
||||
{
|
||||
if (ufd < 0)
|
||||
ufd = open(UTMP_FILE, O_RDONLY);
|
||||
fcntl(ufd, F_SETFD, FD_CLOEXEC);
|
||||
lseek(ufd, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
void endutent() {
|
||||
if (ufd < 0)
|
||||
return;
|
||||
close(ufd);
|
||||
ufd = -1;
|
||||
}
|
||||
|
||||
struct utmp *getutent(void)
|
||||
{
|
||||
static struct utmp utmp;
|
||||
int retval;
|
||||
|
||||
if (ufd < 0) {
|
||||
setutent();
|
||||
if (ufd < 0)
|
||||
return NULL;
|
||||
}
|
||||
retval = read(ufd, &utmp, sizeof(struct utmp));
|
||||
if (retval < 1)
|
||||
return NULL;
|
||||
return &utmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifdef __KLIBC__
|
||||
|
||||
#ifndef KLIBC_FIXUPS_H
|
||||
#define KLIBC_FIXUPS_H
|
||||
#define KLIBC_FIXUPS_H
|
||||
|
||||
struct passwd {
|
||||
char *pw_name; /* user name */
|
||||
@ -23,6 +23,49 @@ struct group {
|
||||
struct passwd *getpwnam(const char *name);
|
||||
struct group *getgrnam(const char *name);
|
||||
|
||||
#endif
|
||||
|
||||
#define UT_LINESIZE 32
|
||||
#define UT_NAMESIZE 32
|
||||
#define UT_HOSTSIZE 256
|
||||
#define USER_PROCESS 7 /* normal process */
|
||||
#define ut_time ut_tv.tv_sec
|
||||
|
||||
|
||||
extern int ufd;
|
||||
|
||||
struct exit_status {
|
||||
short int e_termination; /* process termination status */
|
||||
short int e_exit; /* process exit status */
|
||||
};
|
||||
|
||||
struct utmp
|
||||
{
|
||||
short int ut_type; /* type of login */
|
||||
pid_t ut_pid; /* pid of login process */
|
||||
char ut_line[UT_LINESIZE]; /* devicename */
|
||||
char ut_id[4]; /* Inittab id */
|
||||
char ut_user[UT_NAMESIZE]; /* username */
|
||||
char ut_host[UT_HOSTSIZE]; /* hostname for remote login */
|
||||
struct exit_status ut_exit; /* exit status of a process marked as DEAD_PROCESS */
|
||||
/* The ut_session and ut_tv fields must be the same size for 32 and 64-bit */
|
||||
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
|
||||
int32_t ut_session; /* sid used for windowing */
|
||||
struct {
|
||||
int32_t tv_sec; /* seconds */
|
||||
int32_t tv_usec; /* microseconds */
|
||||
} ut_tv;
|
||||
#else
|
||||
long int ut_session;
|
||||
struct timeval ut_tv;
|
||||
#endif
|
||||
int32_t ut_addr_v6[4]; /* internet address of remote host */
|
||||
char __unused[20]; /* reserved for future use */
|
||||
};
|
||||
|
||||
struct utmp *getutent(void);
|
||||
void setutent(void);
|
||||
void endutent(void);
|
||||
|
||||
|
||||
#endif /* KLIBC_FIXUPS_H */
|
||||
#endif /* __KLIBC__ */
|
||||
|
37
udev-add.c
37
udev-add.c
@ -32,6 +32,7 @@
|
||||
#include <grp.h>
|
||||
#ifndef __KLIBC__
|
||||
#include <pwd.h>
|
||||
#include <utmp.h>
|
||||
#endif
|
||||
|
||||
#include "libsysfs/sysfs/libsysfs.h"
|
||||
@ -44,6 +45,8 @@
|
||||
#include "udevdb.h"
|
||||
#include "klibc_fixups.h"
|
||||
|
||||
#define LOCAL_USER "$local"
|
||||
|
||||
/*
|
||||
* Right now the major/minor of a device is stored in a file called
|
||||
* "dev" in sysfs.
|
||||
@ -132,6 +135,37 @@ static int make_node(char *filename, int major, int minor, unsigned int mode, ui
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the local logged in user */
|
||||
static void set_to_local_user(char *user)
|
||||
{
|
||||
struct utmp *u;
|
||||
time_t recent = 0;
|
||||
|
||||
strnfieldcpy(user, default_owner_str, OWNER_SIZE);
|
||||
setutent();
|
||||
while (1) {
|
||||
u = getutent();
|
||||
if (u == NULL)
|
||||
break;
|
||||
|
||||
/* is this a user login ? */
|
||||
if (u->ut_type != USER_PROCESS)
|
||||
continue;
|
||||
|
||||
/* is this a local login ? */
|
||||
if (strcmp(u->ut_host, ""))
|
||||
continue;
|
||||
|
||||
if (u->ut_time > recent) {
|
||||
recent = u->ut_time;
|
||||
strfieldcpy(user, u->ut_user);
|
||||
dbg("local user is '%s'", user);
|
||||
break;
|
||||
}
|
||||
}
|
||||
endutent();
|
||||
}
|
||||
|
||||
static int create_node(struct udevice *dev, int fake)
|
||||
{
|
||||
struct stat stats;
|
||||
@ -175,6 +209,9 @@ static int create_node(struct udevice *dev, int fake)
|
||||
if (endptr[0] == '\0')
|
||||
uid = (uid_t) id;
|
||||
else {
|
||||
if (strncmp(dev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0)
|
||||
set_to_local_user(dev->owner);
|
||||
|
||||
struct passwd *pw = getpwnam(dev->owner);
|
||||
if (pw == NULL)
|
||||
dbg("specified user unknown '%s'", dev->owner);
|
||||
|
Loading…
x
Reference in New Issue
Block a user