Share POSIX message queue between users in the same group - c

I'm trying to open and create a POSIX message queue with one user (named "usuario-prueba") in order to send a message to the queue, and just open and receive the message with another user (named "usuario-prueba2"). Both users belong to the same group, however it seems impossible to open the queue with the second user (I get "permission denied" message).
Here're some outputs:
usuario-prueba#myhost:~$ id
uid=1001(usuario-prueba) gid=1002(usuario-prueba) grupos=1002(usuario-prueba),1001(pruebas-mqueue)
usuario-prueba2#myhost:~$ id
uid=1002(usuario-prueba2) gid=1003(usuario-prueba2) grupos=1003(usuario-prueba2),1001(pruebas-mqueue)
As you can see both users belong to the same group (pruebas-mqueue) as I told before.
I'm creating and opening the queue with:
flags = O_RDWR | O_CREAT
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
What is wrong?

Related

How can I create a POSIX shared message queue without it created as root access only?

I am creating a message queue using the POSIX mqueue API:
mq_open("/myqueue", O_CREAT | O_WRONLY, O_WRONLY, NULL)
I also mount the directory for the message queue objects:
su
mkdir /dev/mqueue
mount -t mqueue none /dev/mqueue
exit
When I run my program, the message queue appears in /dev/mqueue with permissions:
---------x
I cannot interact with this message queue, and it does not show up with the ipcs command.
How can I create a POSIX message queue to be used by a user-level application in Ubuntu 18.04?
Your arguments to the function are wrong. You're passing O_WRONLY as the mode, but it's a flag, just like the other O_*. Instead you should do:
mq_open("/myqueue", O_CREAT | O_WRONLY, 0600, NULL);
or some other file access mode that you want (0600 = rw-------).

lighttpd, fastcgi and application script written in "C" using libfcgi - Weird system error message

I get a wierd Linux system message "Transport Endpoint is not connected" in response to a write call immediately after a successful open call. All this happens immediately after a Slackware Linux 2.6.33.4 reboot.
I'm writing a forms-handler in C and it runs under lighttpd and fastcgi (and before some smart alec pipes up and asks 'why am I not using his/her favourite language, it's because I like C --- OK? OK!).
I've got the major facilities of the application running - it displays index.htm (which is a form) and when the form is 'Submit'ted, finds the program I've written which correctly processes the contents returned and displays the next form. It's got complex enough that now I need to print some debugging statements somewhere, to give me some feedback from program additions. Thus arises the problem.
Research indicates that this message usually means that the endpoint of the file path is not or has become not mounted but /tmp/debug.log (which is the file I'm trying to create/append-to lives on the root partition. But then why is the open() successful but the write() is not?
The program fragment below is the bit which is giving trouble. The printf() statements send output to the web interface (for those unfamiliar with libfcgi) to give me some idea what's happening.
I can't get my (properly indented) code through this forum's demented code filter and I can't attach it in a zip file, so you'll just have to take my word that the syntax is correct.
Any clues?
This line
if(fd = open(DEBUG_FILE_NAME, (O_CREAT | O_APPEND | O_RDWR), (S_IWUSR | S_IRGRP | S_IROTH | S_IRUSR)) < 0)
results in fd being set to the result of open(DEBUG_FILE_NAME, (O_CREAT | O_APPEND | O_RDWR), (S_IWUSR | S_IRGRP | S_IROTH | S_IRUSR)) < 0 which most likely is 0.
So the write(fd, ... tries to write to stdin, which is weird, so you get a weird error ... ;-)
To fix this fix the parenthesis.
You could do this for example in save manner by using Yoda-Conditions:
if (0 > (fd = open(DEBUG_FILE_NAME, (O_CREAT | O_APPEND | O_RDWR), (S_IWUSR | S_IRGRP | S_IROTH | S_IRUSR))))
("save" in terms that everything important is at the left in one place: if (0 > (fd = open(...)

c - tcp - netmap : could tun/tap interface neglict the use of netmap?

I just asked a question here : previous question
Would a Tun/tap device avoid a netmap/pf_ring/dpdk installation ?
If tun/tap allow to bypass kernel, isn't it the same thing ?
Or those codes bring so many optimizations that they overclass tun os bypass strategy ?
I don't quite understand here.
Thanks
TUN/TAP interfaces are virtual network interfaces in which instead of sending and receiving packets from physical media, sends and receives them from user space program. They don't by pass kernel but it's common to set TAP interface as the default interface in order to have a user space program to intercept applications traffic.
Consider below diagram a typical interaction of an userspace program with network interface and network stack.
+--------------------------+
| Network Interface Driver |
+------------+-------------+
|
+------------+-------------+
| Network Stack |
+--------+---+---+---------+
| | | Kernel Space
+----------------------------------------+
| | | User Space
|Sockets|
| | |
+--------+---+---+---------+
| User Space Applications |
+--------------------------+
There’s no way to entirely bypass network stack in case of TAP interface. Userspace applications can still connect to physical interface. Only if a frame specifically is directed to the TAP interface the interceptor application can intercept frames.
+--------------------------+ +--------------------------+
| Network Interface Driver | | TAP Interface |
+------------+-------------+ +--------+----+------------+
| | |
+------------+-------------+ | |
| Network Stack +--------------+ |
+---+------------------+---+ |
| | | Kernel Space
+-------------------------------------------------------------------------+
| | | User Space
Sockets to NIC Sockets to TAP TAP File Descriptor
| | |
+---+------------------+---+ +-------------+------------+
| Normal Applications | | Interceptor Application |
+--------------------------+ +--------------------------+
In case of Netmap once userspace application exclusively acquired the NIC it is up to userspace application to decide which frames (if any) can be injected to the network stack. Therefore we can have the performance of direct packet capturing and take advantage of network stack services when we need them. The exclusive access to NIC is not a good feature always, consider the simple scenario when the NIC has to reply to ARP request.
+-----------------------------------------------------------+
| Netmap Enabled Network Interface Driver |
+-----+-----------------------------------------------------+
|
+-----+-----+ +-----------+ +--------------------------+
| NIC Rings | | Host Ring +------+ Network Stack |
+-----+-----+ +-----+-----+ +--------+---+---+---------+
| | | | | Kernel Space
+-------------------------------------------------------------------------+
| | | | | User Space
MMAP Access MMAP Access |Sockets|
| | | | |
+-----+-------------+------+ +--------+---+---+---------+
| Interceptor Application | | Normal Applications |
+--------------------------+ +--------------------------+
Unfortunatly DPDK doesn’t support “host rings” according to http://dpdk.org/doc/guides/sample_app_ug/netmap_compatibility.html
I’m not certain about PF_RING
Also note in order to utilize NETMAP/PF_RING/DPDK you must modify, recompile or even redesign your application to match to the frameworks.

How to detect a user logged in through GUI in Linux

I would like to capture the user name logged in through GUI in my program. My program is running as a daemon from root login. If a non root user logs in through GUI my program should be notified.
I am pasting my current program which calls a perl script making use of system call to check who is the current user logged in. I am pasting my perl script too for reference.
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
int main()
{
char *user;
char buf[1024];
int fd, ret;
fd = open("/tmp/log", O_TRUNC|O_RDWR|O_CREAT);
if (!fd) {
printf("Error opening file\n");
exit(1);
}
chmod("/tmp/log", S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP
| S_IROTH | S_IWOTH | S_IXOTH);
daemon(0, 0);
while (1) {
system("perl /home/curr-usr.pl");
sleep(5);
}
return 0;
}
The perl script which is used to get the current user logged in.
#!/usr/bin/perl
my $result;
$result = `whoami`;
open FH, "+>>", "/tmp/log" or die $!;
print FH "$result ";
close (FH);
In the c program above I am calling the perl script in a while loop every 5 seconds. The perl script makes use of the command "whoami" to get the current user logged in & dumps it into the /tmp/log file.
What I want to achieve is if user1 logs in the perl script should give me the current user to be user1. Instead the perl script gives me root as the current user irrespective of the user I am logged in through GUI as I am running the C program & perl script with root user.
Could anyone please advise me with a mechanism by which the C program could get to know the current user logged in through GUI ?
Any help is greatly appreciated.
You can detect the user using the main display like this:
#!/bin/bash
#Detect the name of the display in use
display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
#Detect the user using such display
user=$(who | grep '('$display')' | awk '{print $1}')
#Detect the id of the user
uid=$(id -u $user)
I am using XFCE4 and LXDM. "who" and "users" report only users that are logged on a terminal. GUI logon is not reported as Nominal Animal pointed out (Thanks!). I use "pgrep xfce" to check if XFCE4 is running. Following prints out current xfce-user:
#!/usr/bin/perl
# Get all processes
my #xfce_processes = `pgrep xfce`;
# If processes exist, get user of first process in list.
if(scalar #xfce_processes) {
print `ps -o user h $xfce_processes[0]`;
}
else
{
# No xfce processes.
;
}
As you mentioned your program runs as a daemon. Consequently any process it spawns would be run as the same user as one that started that daemon. The user that logs in via UI (or any other method) would never be the user you can get by calling whoami from your daemon.
Instead what you should do is explicitly notify your daemon of a login event or, if that is not an option, keep a list of all the logged-in sessions currently running on the box and see if new sessions appear - that would be a session of a newly logged-in user.
The programms who and users get their information from the file /var/run/utmp.
The file contains N entries of the size of "struct utmp", defined in <utmp.h>
You are interested in the USER_PROCESS type entries. The host field contains the display.
Note that there are multiple entries for the same display if the user opened some terminal emulations (xterm, konsole...).
You could monitor this file or /var/log/wtmp for a history
struct utmp ut_entry;
FILE *fp = fopen(UTMP_FILE, "r");
if( !fp )
{
printf("Could not open utmp file!");
return;
}
while(fread(&ut_entry, sizeof(struct utmp), 1, fp) == 1)
{
if(ut_entry.ut_type != USER_PROCESS)
continue;
// string entries are not 0 terminated if too long...
// copy user name to make sure it is 0 terminated
char tmpUser[UT_NAMESIZE+1] = {0};
strncpy(tmpUser, ut_entry.ut_user, UT_NAMESIZE);
// do more stuff... read the display from ut_entry.host
}
For more information see the utmp manual page
You probably want to investigate either ConsoleKit or its newer incarnation loginctl.
These tools are specifically designed for managing seats and sessions, while maintaining distinction between local text console, GUI and remote sessions. They are not guaranteed to be present on every X11 machine, but if yours is relatively recent, chances are it uses either one or the other tool.
For anyone else coming here for xfce4, what I had to do was run ps -aux | grep xfce4 then there was a line:
root 2497 0.0 0.3 323052 13408 ? Sl 01:24 0:00 xfce4-session
I run kill -9 2497 and that got rid of it. For me this was a hung instance I wanted to kill from SSH.

mkfifo file permissions not being executed correctly

The following line in my C program should provided All/Group/Owner read and write permissions
mkfifo("/tmp/dumbPipe", 0666)
But once I execute the code and check out the permission non of the write bits were set, I end up with
prw-r--r--
The owners are the same, Is it a problem since I'm creating the pipe in the tmp directory? When I run chmod 666 from the cmd line all the permissions get set correctly.
This is a no-comments post, just quoting manuals. Brievity etc.
Quote from man 3 mkfifo:
It is modified by the process's umask in the usual way: the permissions of the created file are (mode & ~umask).
Quote from man 2 umask
The typical default value for the process umask is S_IWGRP | S_IWOTH (octal 022). In the usual case where the mode argument to
open(2) is specified as:
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
(octal 0666) when creating a new file, the permissions on the resulting file will be:
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
(because 0666 & ~022 = 0644; i.e., rw-r--r--).
Salam,
I know it is to late but for other users I choose to write this comment
Even if you precise 0666 as permission, you should know that there is an another factor that is called " process's file mode creation ", so the question is :
how to change current process file mode creation ?
Answer : use umask(permission) at beginning of your program - and give 0000 as permission
http://www.cyberciti.biz/tips/understanding-linux-unix-umask-value-usage.html
this should help .

Resources