+Sun May 28 17:24:09 CEST 2000 Wichert Akkerman <wakkerma@debian.org>
+
+ * dpkg-deb/build.c: remove extra closing brace
+ * include/dpkg.h.in: add define for statusoveride file
+ * main/filedb.[ch]: add code to manage the statoverride list
+ * main/archives.c: modify tarobject() to check for statoverrides
+ * TODO: remove integrating suidmanager note, it's partially done now
+
Sun Apr 30 14:19:41 CEST 2000 Wichert Akkerman <wakkerma@debian.org>
* doc/*: remove all references to GNU/Linux and just mention `Debian
* signatures & checksums
* integrate debconf (add new status)
* allow external program to specify how to handle conffiles
-* integrate suidmanager
* log our actions
* try to remove directories again after removing conffiles
* allow versioned provides
dpkg (1.7.0) unstable; urgency=low
+ * Allow the administrator to override file mode and ownership
* Use objdump instead of ldd in dpkg-shlibdeps
* HURD updates, Closes: Bug#57753,#57754,#57755
* dpkg-architecture: -q should not imply -f, Closes: Bug#57761
*start=*end=fi;
else
*end=(*end)->next=fi;
- }
}
/* Free the memory for all entries in a list of _finfo structs
#define POSTRMFILE "postrm"
#define LISTFILE "list"
-#define ADMINDIR "#ADMINDIR#"
-#define STATUSFILE "status"
-#define AVAILFILE "available"
-#define LOCKFILE "lock"
-#define CMETHOPTFILE "cmethopt"
-#define METHLOCKFILE "methlock"
-#define DIVERSIONSFILE "diversions"
-#define UPDATESDIR "updates/"
-#define INFODIR "info/"
-#define PARTSDIR "parts/"
-#define CONTROLDIRTMP "tmp.ci/"
-#define IMPORTANTTMP "tmp.i"
-#define REASSEMBLETMP "reassemble" DEBEXT
-#define IMPORTANTMAXLEN 10
-#define IMPORTANTFMT "%04d" /* change => also change lib/database.c:cleanup_updates */
-#define MAXUPDATES 50
+#define ADMINDIR "#ADMINDIR#"
+#define STATUSFILE "status"
+#define AVAILFILE "available"
+#define LOCKFILE "lock"
+#define CMETHOPTFILE "cmethopt"
+#define METHLOCKFILE "methlock"
+#define DIVERSIONSFILE "diversions"
+#define STATOVERRIDEFILE "statoverride"
+#define UPDATESDIR "updates/"
+#define INFODIR "info/"
+#define PARTSDIR "parts/"
+#define CONTROLDIRTMP "tmp.ci/"
+#define IMPORTANTTMP "tmp.i"
+#define REASSEMBLETMP "reassemble" DEBEXT
+#define IMPORTANTMAXLEN 10
+#define IMPORTANTFMT "%04d" /* change => also change lib/database.c:cleanup_updates */
+#define MAXUPDATES 50
#define LIBDIR "#LIBDIR#"
#define LOCALLIBDIR "/usr/local/lib/dpkg"
struct fileinlist *nifd;
struct pkginfo *divpkg, *otherpkg;
struct filepackages *packageslump;
+ mode_t am;
/* Append to list of files.
* The trailing / put on the end of names in tarfiles has already
if (fwrite(databuf,1,wsz,thefile) != wsz)
ohshite(_("error writing to `%.255s'"),ti->Name);
}
- if (fchown(fd,ti->UserID,ti->GroupID))
+ if (nifd->namenode->statoverride)
+ debug(dbg_eachfile, _("tarobject ... stat override, uid=%d, gid=%d, mode=%04o"),
+ nifd->namenode->statoverride->uid,
+ nifd->namenode->statoverride->gid,
+ nifd->namenode->statoverride->mode);
+ if (fchown(fd,
+ nifd->namenode->statoverride ? nifd->namenode->statoverride->uid : ti->UserID,
+ nifd->namenode->statoverride ? nifd->namenode->statoverride->gid : ti->GroupID))
ohshite(_("error setting ownership of `%.255s'"),ti->Name);
/* We flush the stream here to avoid any future
* writes, which will mask any setuid or setgid
*/
if (fflush(thefile) == EOF)
ohshite(_("error flushing `%.255s'"),ti->Name);
- if (fchmod(fd,ti->Mode & ~S_IFMT))
+ am=(nifd->namenode->statoverride ? nifd->namenode->statoverride->mode : ti->Mode) & ~S_IFMT;
+ if (fchmod(fd,am))
ohshite(_("error setting permissions of `%.255s'"),ti->Name);
pop_cleanup(ehflag_normaltidy); /* thefile= fdopen(fd) */
if (fclose(thefile))
newtarobject_utime(fnamenewvb.buf,ti);
break;
case FIFO:
- if (mkfifo(fnamenewvb.buf,ti->Mode & S_IFMT))
+ if (mkfifo(fnamenewvb.buf,am))
ohshite(_("error creating pipe `%.255s'"),ti->Name);
debug(dbg_eachfiledetail,"tarobject FIFO");
newtarobject_allmodes(fnamenewvb.buf,ti);
break;
case CharacterDevice: case BlockDevice:
- if (mknod(fnamenewvb.buf,ti->Mode & S_IFMT,ti->Device))
+ if (mknod(fnamenewvb.buf,am,ti->Device))
ohshite(_("error creating device `%.255s'"),ti->Name);
debug(dbg_eachfiledetail,"tarobject CharacterDevice|BlockDevice");
newtarobject_allmodes(fnamenewvb.buf,ti);
ohshite(_("error creating symbolic link `%.255s'"),ti->Name);
debug(dbg_eachfiledetail,"tarobject SymbolicLink creating");
#ifdef HAVE_LCHOWN
- if (lchown(fnamenewvb.buf,ti->UserID,ti->GroupID))
+ if (lchown(fnamenewvb.buf,
#else
- if (chown(fnamenewvb.buf,ti->UserID,ti->GroupID))
+ if (chown(fnamenewvb.buf,
#endif
+ nifd->namenode->statoverride ? nifd->namenode->statoverride->uid : ti->UserID,
+ nifd->namenode->statoverride ? nifd->namenode->statoverride->gid : ti->GroupID))
ohshite(_("error setting ownership of symlink `%.255s'"),ti->Name);
break;
case Directory:
/* We've already checked for an existing directory. */
if (mkdir(fnamenewvb.buf,
- ti->Mode & (S_IRUSR|S_IRGRP|S_IROTH | S_IXUSR|S_IXGRP|S_IXOTH)))
+ am & (S_IRUSR|S_IRGRP|S_IROTH | S_IXUSR|S_IXGRP|S_IXOTH)))
ohshite(_("error creating directory `%.255s'"),ti->Name);
debug(dbg_eachfiledetail,"tarobject Directory creating");
newtarobject_allmodes(fnamenewvb.buf,ti);
fnameidlu= fnamevb.used;
ensure_diversions();
+ ensure_statoverrides();
while ((thisarg= *argp++) != 0) {
if (setjmp(ejbuf)) {
}
}
+/* vi: ts=8 sw=2
+ */
#include <errno.h>
#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+
#include <config.h>
#include <dpkg.h>
#include <dpkg-db.h>
static int nfiles= 0;
static struct diversion *diversions= 0;
static FILE *diversionsfile= 0;
+static FILE *statoverridefile= 0;
void note_must_reread_files_inpackage(struct pkginfo *pkg) {
allpackagesdone= 0;
while (reversefilelist_next(iterptr));
}
+void ensure_statoverrides(void) {
+ static struct varbuf vb;
+
+ struct stat stab1, stab2;
+ FILE *file;
+ char *loaded_list, *loaded_list_end, *thisline, *nextline, *ptr;
+ ssize_t bytes, readden;
+ struct filestatoverride *fso;
+ struct filenamenode *fnn;
+
+ varbufreset(&vb);
+ varbufaddstr(&vb,admindir);
+ varbufaddstr(&vb,"/" STATOVERRIDEFILE);
+ varbufaddc(&vb,0);
+
+ onerr_abort++;
+
+ file= fopen(vb.buf,"r");
+ if (!file) {
+ if (errno != ENOENT) ohshite(_("failed to open statoverride file"));
+ if (!statoverridefile) { onerr_abort--; return; }
+ } else if (statoverridefile) {
+ if (fstat(fileno(statoverridefile),&stab1))
+ ohshite(_("failed to fstat previous statoverride file"));
+ if (fstat(fileno(file),&stab2))
+ ohshite(_("failed to fstat statoverride file"));
+ if (stab1.st_dev == stab2.st_dev && stab1.st_ino == stab2.st_ino) {
+ fclose(file); onerr_abort--; return;
+ }
+ }
+ if (statoverridefile) fclose(statoverridefile);
+ statoverridefile= file;
+
+ push_cleanup(cu_closefile,ehflag_bombout, 0,0,1,(void*)file);
+
+ loaded_list = nfmalloc(stab1.st_size);
+ loaded_list_end = loaded_list + stab1.st_size;
+ readden=0;
+ while (readden<stab1.st_size) {
+ bytes = read(fileno(file),
+ loaded_list + readden, stab1.st_size - readden);
+ if (bytes < 0) {
+ if (errno == EINTR) continue;
+ ohshite("unable to read statoverride file `%.250s'",vb.buf);
+ }
+ if (!bytes)
+ ohshit("unexpected end of file in statoverride file `%.250s'",vb.buf);
+ readden += bytes;
+ }
+
+ thisline = loaded_list;
+ while (thisline<loaded_list_end) {
+ char* endptr;
+
+ fso= nfmalloc(sizeof(struct filestatoverride));
+
+ if (!(ptr = memchr(thisline, '\n', loaded_list_end - thisline)))
+ ohshit("statoverride file is missing final newline");
+ /* where to start next time around */
+ nextline = ptr + 1;
+ if (ptr == thisline)
+ ohshit(_("statoverride file contains empty line"));
+ *ptr = 0;
+
+ /* Extract the uid */
+ if (!(ptr=memchr(thisline, ' ', nextline-thisline)))
+ ohshit("syntax error in statusoverride file ");
+ *ptr=0;
+ if (thisline[0]=='#') {
+ fso->uid=strtol(thisline, &endptr, 10);
+ if (*endptr!=0)
+ ohshit("syntax error: invalid uid in statusoverride file ");
+ } else {
+ struct passwd* pw = getpwnam(thisline);
+ if (pw==NULL)
+ ohshit("syntax error: unknown user `%s' in statusoverride file ", thisline);
+ fso->uid=pw->pw_uid;
+ }
+
+ /* Move to the next bit */
+ thisline=ptr+1;
+ if (thisline>=loaded_list_end)
+ ohshit("unexecpted end of line in statusoverride file");
+
+ /* Extract the gid */
+ if (!(ptr=memchr(thisline, ' ', nextline-thisline)))
+ ohshit("syntax error in statusoverride file ");
+ *ptr=0;
+ if (thisline[0]=='#') {
+ fso->gid=strtol(thisline, &endptr, 10);
+ if (*endptr!=0)
+ ohshit("syntax error: invalid gid in statusoverride file ");
+ } else {
+ struct group* gr = getgrnam(thisline);
+ if (gr==NULL)
+ ohshit("syntax error: unknown group `%s' in statusoverride file ", thisline);
+ fso->gid=gr->gr_gid;
+ }
+
+ /* Move to the next bit */
+ thisline=ptr+1;
+ if (thisline>=loaded_list_end)
+ ohshit("unexecpted end of line in statusoverride file");
+
+ /* Extract the mode */
+ if (!(ptr=memchr(thisline, ' ', nextline-thisline)))
+ ohshit("syntax error in statusoverride file ");
+ *ptr=0;
+ fso->mode=strtol(thisline, &endptr, 8);
+ if (*endptr!=0)
+ ohshit("syntax error: invalid mode in statusoverride file ");
+
+ /* Move to the next bit */
+ thisline=ptr+1;
+ if (thisline>=loaded_list_end)
+ ohshit("unexecpted end of line in statusoverride file");
+
+ fnn= findnamenode(thisline, 0);
+ if (fnn->statoverride)
+ ohshit("multiple statusoverides present for file `%.250s'", thisline);
+ fnn->statoverride=fso;
+ /* Moving on.. */
+ thisline=nextline;
+ }
+
+ pop_cleanup(ehflag_normaltidy); /* file= fopen() */
+
+ onerr_abort--;
+}
+
void ensure_diversions(void) {
static struct varbuf vb;
}
if (ferror(file)) ohshite(_("read error in diversions [i]"));
- diversionsfile= file;
onerr_abort--;
}
traverse->here->packages= 0;
traverse->here->flags= 0;
traverse->here->divert= 0;
+ traverse->here->statoverride= 0;
traverse->here->filestat= 0;
if((flags & fnn_nocopy) && name > orig_name && name[-1] == '/') {
newnode->flags= 0;
newnode->next= 0;
newnode->divert= 0;
+ newnode->statoverride= 0;
newnode->filestat= 0;
*pointerp= newnode;
nfiles++;
return newnode;
}
+
+/* vi: ts=8 sw=2
+ */
char *name;
struct filepackages *packages;
struct diversion *divert;
+ struct filestatoverride *statoverride;
/* Fields from here on are used by archives.c &c, and cleared by
* filesdbinit.
*/
struct filenamenode *namenode;
};
+struct filestatoverride {
+ /* We allow the administrator to override the owner, group and mode of
+ * a file. If such an override is present we use that instead of the
+ * stat information stored in the archive.
+ *
+ * This functionality used to be in the suidmanager package.
+ */
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+};
+
struct diversion {
/* When we deal with an `overridden' file, every package except
* the overriding one is considered to contain the other file
void iterfileend(struct fileiterator *i);
void ensure_diversions(void);
+void ensure_statoverrides(void);
void ensure_packagefiles_available(struct pkginfo *pkg);
void ensure_allinstfiles_available(void);