Page 1 of 1

Group permissions

Posted: Sun Nov 15, 2009 2:52 pm
by joshuanekl
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.

Code: Select all

/etc/group:
video:x:44:jen,josh,www-data
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.

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;