Group permissions
Posted: Sun Nov 15, 2009 2:52 pm
On my system (Ubuntu 9.10), /dev/video0 belongs to group "video". When you add user accounts, the graphical tools ask if you want to let this user have access to 'video' amongst other options, if so it appends them to the video group in /etc/group
I added my webserver user 'www-data' to the video group as well to give it access to the webcam.
However, it appears zmfix only compares the gid of the process to the gid of the file, not the entire list of groups the process belongs to. As a result, zmfix unnecessarily gives /dev/video0 read/write privileges to everyone.
Here is a patch which compares the gid of the device to the list of groups the process belongs to.
I added my webserver user 'www-data' to the video group as well to give it access to the webcam.
Code: Select all
/etc/group:
video:x:44:jen,josh,www-data
Here is a patch which compares the gid of the device to the list of groups the process belongs to.
Code: Select all
diff -ur orig/ZoneMinder-1.24.2/src/zmfix.cpp ZoneMinder-1.24.2/src/zmfix.cpp
--- orig/ZoneMinder-1.24.2/src/zmfix.cpp 2009-03-20 08:07:00.000000000 -0400
+++ ZoneMinder-1.24.2/src/zmfix.cpp 2009-11-15 09:47:09.900248599 -0500
@@ -31,9 +31,61 @@
#include "zm.h"
#include "zm_db.h"
+// determine if we are a member of the group
+int inGroup(gid_t gid)
+{
+ int n_gids;
+ gid_t *gids;
+ int in_gid;
+ int i;
+
+ // get how many groups we are in
+ n_gids = getgroups(0, NULL);
+ if(n_gids < 0)
+ {
+ Error("getgroups:%s", strerror(errno));
+ return -1;
+ }
+
+ // not in any groups
+ if(!n_gids)
+ {
+ return 0;
+ }
+
+ // allocate space to hold groups
+ gids = (gid_t *)malloc(n_gids * sizeof(gid_t));
+ if(!gids)
+ {
+ Error("malloc:%s", strerror(errno));
+ return -1;
+ }
+
+ // get list of groups
+ if(getgroups(n_gids, gids) != n_gids)
+ {
+ Error("getgroups:%s", strerror(errno));
+ free(gids);
+ return -1;
+ }
+
+ // see if gid in list of groups we belong to
+ in_gid = 0;
+ for(i=0; i<n_gids; i++)
+ {
+ if(gids[i] == gid)
+ {
+ in_gid = 1;
+ }
+ }
+ free(gids);
+ return in_gid;
+}
+
bool fixDevice( const char *device_path )
{
struct stat stat_buf;
+ int in_gid;
if ( stat( device_path, &stat_buf ) < 0 )
{
@@ -44,13 +96,18 @@
uid_t uid = getuid();
gid_t gid = getgid();
+ if((in_gid = inGroup(stat_buf.st_gid)) < 0)
+ {
+ return( false );
+ }
+
mode_t mask = 0;
if ( uid == stat_buf.st_uid )
{
// If we are the owner
mask = 00600;
}
- else if ( gid == stat_buf.st_gid )
+ else if ( gid == stat_buf.st_gid || in_gid)
{
// If we are in the owner group
mask = 00060;