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;