/ Check-in [1254dffe]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When creating journal files (including -wal and -shm files) try to set the ownership to be the same as the original database. This will prevent root from locking out the original owner of the file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1254dffe4071656a783cd000b1dd40c975ac18cb
User & Date: drh 2012-02-11 19:23:48
Context
2012-02-11
19:53
Another attempt to fix warnings in the randomFunc() function. check-in: 768df4e1 user: drh tags: trunk
19:23
When creating journal files (including -wal and -shm files) try to set the ownership to be the same as the original database. This will prevent root from locking out the original owner of the file. check-in: 1254dffe user: drh tags: trunk
18:51
Remove a redundant test from the shared-memory logic in os_unix.c. check-in: 31142ca7 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  3900   3900           pShmNode->isReadonly = 1;
  3901   3901         }
  3902   3902         pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
  3903   3903         if( pShmNode->h<0 ){
  3904   3904           rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
  3905   3905           goto shm_open_err;
  3906   3906         }
         3907  +
         3908  +      /* If this process is running as root, make sure that the SHM file
         3909  +      ** is owned by the same user that owns the original database.  Otherwise,
         3910  +      ** the original owner will not be able to connect. If this process is
         3911  +      ** not root, the following fchown() will fail, but we don't care.
         3912  +      */
         3913  +      fchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
  3907   3914     
  3908   3915         /* Check to see if another process is holding the dead-man switch.
  3909   3916         ** If not, truncate the file to zero length. 
  3910   3917         */
  3911   3918         rc = SQLITE_OK;
  3912   3919         if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
  3913   3920           if( robust_ftruncate(pShmNode->h, 0) ){
................................................................................
  4892   4899   ** original filename is unavailable.  But 8_3_NAMES is only used for
  4893   4900   ** FAT filesystems and permissions do not matter there, so just use
  4894   4901   ** the default permissions.
  4895   4902   */
  4896   4903   static int findCreateFileMode(
  4897   4904     const char *zPath,              /* Path of file (possibly) being created */
  4898   4905     int flags,                      /* Flags passed as 4th argument to xOpen() */
  4899         -  mode_t *pMode                   /* OUT: Permissions to open file with */
         4906  +  mode_t *pMode,                  /* OUT: Permissions to open file with */
         4907  +  uid_t *pUid,                    /* OUT: uid to set on the file */
         4908  +  gid_t *pGid                     /* OUT: gid to set on the file */
  4900   4909   ){
  4901   4910     int rc = SQLITE_OK;             /* Return Code */
  4902   4911     *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS;
         4912  +  *pUid = 0;
         4913  +  *pGid = 0;
  4903   4914     if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
  4904   4915       char zDb[MAX_PATHNAME+1];     /* Database file path */
  4905   4916       int nDb;                      /* Number of valid bytes in zDb */
  4906   4917       struct stat sStat;            /* Output of stat() on database file */
  4907   4918   
  4908   4919       /* zPath is a path to a WAL or journal file. The following block derives
  4909   4920       ** the path to the associated database file from zPath. This block handles
................................................................................
  4929   4940       }
  4930   4941   #endif
  4931   4942       memcpy(zDb, zPath, nDb);
  4932   4943       zDb[nDb] = '\0';
  4933   4944   
  4934   4945       if( 0==osStat(zDb, &sStat) ){
  4935   4946         *pMode = sStat.st_mode & 0777;
         4947  +      *pUid = sStat.st_uid;
         4948  +      *pGid = sStat.st_gid;
  4936   4949       }else{
  4937   4950         rc = SQLITE_IOERR_FSTAT;
  4938   4951       }
  4939   4952     }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
  4940   4953       *pMode = 0600;
  4941   4954     }
  4942   4955     return rc;
................................................................................
  5075   5088     if( isReadWrite ) openFlags |= O_RDWR;
  5076   5089     if( isCreate )    openFlags |= O_CREAT;
  5077   5090     if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
  5078   5091     openFlags |= (O_LARGEFILE|O_BINARY);
  5079   5092   
  5080   5093     if( fd<0 ){
  5081   5094       mode_t openMode;              /* Permissions to create file with */
  5082         -    rc = findCreateFileMode(zName, flags, &openMode);
         5095  +    uid_t uid;                    /* Userid for the file */
         5096  +    gid_t gid;                    /* Groupid for the file */
         5097  +    rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
  5083   5098       if( rc!=SQLITE_OK ){
  5084   5099         assert( !p->pUnused );
  5085   5100         assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
  5086   5101         return rc;
  5087   5102       }
  5088   5103       fd = robust_open(zName, openFlags, openMode);
  5089   5104       OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
................................................................................
  5096   5111         isReadonly = 1;
  5097   5112         fd = robust_open(zName, openFlags, openMode);
  5098   5113       }
  5099   5114       if( fd<0 ){
  5100   5115         rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
  5101   5116         goto open_finished;
  5102   5117       }
         5118  +
         5119  +    /* If this process is running as root and if creating a new rollback
         5120  +    ** journal or WAL file, set the ownership of the journal or WAL to be
         5121  +    ** the same as the original database.  If we are not running as root,
         5122  +    ** then the fchown() call will fail, but that's ok - there is nothing
         5123  +    ** we can do about it so just ignore the error.
         5124  +    */
         5125  +    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
         5126  +      fchown(fd, uid, gid);
         5127  +    }
  5103   5128     }
  5104   5129     assert( fd>=0 );
  5105   5130     if( pOutFlags ){
  5106   5131       *pOutFlags = flags;
  5107   5132     }
  5108   5133   
  5109   5134     if( p->pUnused ){