-C Version\s3.7.12
-D 2012-05-14T02:05:15.770
+C Improve\serror\sreporting\sfrom\ssqlite3_file_control,\sSQLITE_FCNTL_REPLACE_DATABASE\sshouldn't\scopy\sfile\ssecurity/ACL\smetadata,\sbad\sbit\smask\sfixed
+D 2012-05-16T22:08:18.407
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 957c9693400fca6cb8b533b589e69ddee7bcb27c
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/legacy.c 015826a958f690302d27e096a68d50b3657e4201
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
-F src/main.c 75cdf5977022fe92a8fc2327934fd2ab4ccd29c0
+F src/main.c 9c3003dc0a5e2c7e1d79cf94a08229dd803fd8df
F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1
F src/os.h 59beba555b65a450bd1d804220532971d4299f60
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
-F src/os_unix.c f8c943a0f9c4e2e7fae9facb3a243cb58cc8ceb5
+F src/os_unix.c a87e927ca7c7d8cab313f8263cd24ea06fc20169
F src/os_win.c 24b57b4aec07ec78ae759244ab6d9759a70fe29b
F src/pager.c 544cc84d50fea0ca921d448037b217ecabba359b
F src/pager.h 42926ac0fe69e9d7e17a54e6b37417e581a429d7
F src/select.c cf2f8f771bab6417e51a0f17b086a87bb74d624c
F src/shell.c 04399b2f9942bd02ed5ffee3b84bcdb39c52a1e6
F src/sqlite.h.in 192eb22f3f217c00ff48a8da356a8a020f6b4a8e
-F src/sqlite3_private.h 97a1e15b3a078bb583622da01a2e9bc96c6edf14
+F src/sqlite3_private.h a81a9c5f97c095cc3e86914a05f8fabe0011f4a1
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h ec90f0d797bbc93dd849629f18513b57bfd9a787
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P bf57f0fb73500f384fc57cbe2501343c97dc433e 8654aa9540fe9fd210899d83d17f3f407096c004
-R 12b92e18e3ce253aa9f29c615d138e39
-U drh
-Z f2b43ef80e7018715193d790be637b9b
+P d9348b2a4e15873756adfd092e8128d9f1cf72b4
+R e2d571d2583903dcbc6ab145be90448d
+U adam
+Z f6b6e32f1d1ba2c99da3b7a6e5f275fb
static int unixInvalidateSupportFiles(unixFile *, int);
+static int findCreateFileMode(const char *, int, mode_t*, uid_t *,gid_t *);
+
+/* opens a read/write connection to a file zName inheriting the appropriate
+ ** user/perms from the database file if running as root. Returns the file
+ ** descriptor by reference */
+static int unixOpenChildFile(const char *zName, int openFlags, int dbOpenFlags, int protFlags, int *pFd) {
+ int fd = -1;
+ mode_t openMode; /* Permissions to create file with */
+ uid_t uid; /* Userid for the file */
+ gid_t gid; /* Groupid for the file */
+ int rc;
+
+ assert(pFd!=NULL);
+ rc = findCreateFileMode(zName, dbOpenFlags, &openMode, &uid, &gid);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ fd = robust_open(zName, openFlags, openMode);
+ OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
+ if( fd<0 ){
+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
+ return rc;
+ }
+ /* if we're opening the wal or journal and running as root, set the journal uid/gid */
+ if( dbOpenFlags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
+ uid_t euid = geteuid();
+ if( euid==0 && (euid!=uid || getegid()!=gid) ){
+ if( fchown(fd, uid, gid) ){
+ rc = SQLITE_CANTOPEN_BKPT;
+ }
+ }
+ }
+ if( rc==SQLITE_OK ){
+ *pFd = fd;
+ } else {
+ *pFd = -1;
+ close(fd);
+ }
+ return rc;
+}
+
static int unixReplaceDatabase(unixFile *pFile, sqlite3 *srcdb) {
sqlite3_file *id = (sqlite3_file *)pFile;
Btree *pSrcBtree = NULL;
if( !(srcWalFD<0) ){
char dstWalPath[MAXPATHLEN+5];
int dstWalFD = -1;
+ int protFlags = 0;
strlcpy(dstWalPath, pFile->zPath, MAXPATHLEN+5);
strlcat(dstWalPath, "-wal", MAXPATHLEN+5);
- dstWalFD = open(dstWalPath, O_RDWR|O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS);
- if( !(dstWalFD<0) ){
+
+ rc = unixOpenChildFile(dstWalPath, O_RDWR|O_CREAT, SQLITE_OPEN_WAL, protFlags, &dstWalFD);
+ if( rc==SQLITE_OK ){
s = copyfile_state_alloc();
lseek(srcWalFD, 0, SEEK_SET);
lseek(dstWalFD, 0, SEEK_SET);
- if( fcopyfile(srcWalFD, dstWalFD, s, COPYFILE_ALL) ){
+ if( fcopyfile(srcWalFD, dstWalFD, s, COPYFILE_DATA) ){
int err=errno;
switch(err) {
case ENOMEM:
s = copyfile_state_alloc();
lseek(pSrcFile->h, 0, SEEK_SET);
lseek(pFile->h, 0, SEEK_SET);
- if( fcopyfile(pSrcFile->h, pFile->h, s, COPYFILE_ALL) ){
+ if( fcopyfile(pSrcFile->h, pFile->h, s, COPYFILE_DATA) ){
int err=errno;
switch(err) {
case ENOMEM:
char walPath[MAXPATHLEN];
int rc = SQLITE_OK;
+#ifdef DEBUG
+ fprintf(stderr, "Force truncating database %s\n", pFile->zPath);
+#endif
strlcpy(journalPath, pFile->zPath, MAXPATHLEN);
strlcat(journalPath, "-journal", MAXPATHLEN);
strlcpy(walPath, pFile->zPath, MAXPATHLEN);
int corruptFileLock = 0;
int isCorrupt = 0;
int force = (bFlags & SQLITE_TRUNCATE_FORCE);
-
+ int safeFailed = 0;
+
#if SQLITE_ENABLE_DATA_PROTECTION
flags |= pFile->protFlags;
#endif
if( rc && !force ){
return rc;
}
+ rc = SQLITE_OK; /* Ignore the locking failure if force is true */
}
if( (bFlags&SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK)!=0 ){
/* initialize a new database in TMPDIR and copy the contents over */
if( tFd==-1 ){
storeLastErrno(pFile, errno);
rc = SQLITE_IOERR;
- if( force ){
- /* attempt the truncation, even if we can't seed the database in a temp directory */
- rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L);
- }
+ safeFailed = 1;
}else{
sqlite3 *tDb = NULL;
copyfile_state_t s;
s = copyfile_state_alloc();
lseek(tFd, 0, SEEK_SET);
lseek(pFile->h, 0, SEEK_SET);
- if( fcopyfile(tFd, pFile->h, s, COPYFILE_ALL) ){
+ if( fcopyfile(tFd, pFile->h, s, COPYFILE_DATA) ){
int err=errno;
switch(err) {
case ENOMEM:
- rc = SQLITE_NOMEM;
+ trc = SQLITE_NOMEM;
break;
default:
storeLastErrno(pFile, err);
- rc = SQLITE_IOERR;
+ trc = SQLITE_IOERR;
}
}
copyfile_state_free(s);
fsync(pFile->h);
close(tFd);
unlink(tDbPath);
+ if( trc!=SQLITE_OK ){
+ safeFailed = 1;
+ rc = trc;
+ }
}
free(tDbPath);
} else {
rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L);
+ if( rc ){
+ safeFailed = 1;
+ }
}
if( rc==SQLITE_OK || force ){
- unixInvalidateSupportFiles(pFile, 0);
+ rc = unixInvalidateSupportFiles(pFile, 0);
+ if( rc ){
+ safeFailed = 1;
+ }
}
pFile->pMethod->xSync(id, SQLITE_SYNC_FULL);
assert(force);
}
- if( rc!=SQLITE_OK && force){
- unixUnsafeTruncateDatabase(pFile);
+ if( force && safeFailed){
+ rc = unixUnsafeTruncateDatabase(pFile);
}
return rc;