2 * dpkg - main program for package management
3 * script.c - maintainer script routines
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2007-2014 Guillem Jover <guillem@debian.org>
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 #include <sys/types.h>
33 #ifdef WITH_LIBSELINUX
34 #include <selinux/selinux.h>
37 #include <dpkg/i18n.h>
38 #include <dpkg/debug.h>
39 #include <dpkg/dpkg.h>
40 #include <dpkg/dpkg-db.h>
42 #include <dpkg/subproc.h>
43 #include <dpkg/command.h>
44 #include <dpkg/triglib.h>
45 #include <dpkg/db-ctrl.h>
46 #include <dpkg/db-fsys.h>
51 post_postinst_tasks(struct pkginfo
*pkg
, enum pkgstatus new_status
)
53 if (new_status
< PKG_STAT_TRIGGERSAWAITED
)
54 pkg_set_status(pkg
, new_status
);
55 else if (pkg
->trigaw
.head
)
56 pkg_set_status(pkg
, PKG_STAT_TRIGGERSAWAITED
);
57 else if (pkg
->trigpend_head
)
58 pkg_set_status(pkg
, PKG_STAT_TRIGGERSPENDING
);
60 pkg_set_status(pkg
, PKG_STAT_INSTALLED
);
63 debug(dbg_triggersdetail
, "post_postinst_tasks - trig_incorporate");
64 trig_incorporate(modstatdb_get_status());
68 post_script_tasks(void)
70 debug(dbg_triggersdetail
, "post_script_tasks - ensure_diversions");
73 debug(dbg_triggersdetail
, "post_script_tasks - trig_incorporate");
74 trig_incorporate(modstatdb_get_status());
78 cu_post_script_tasks(int argc
, void **argv
)
84 setexecute(const char *path
, struct stat
*stab
)
86 if ((stab
->st_mode
& 0555) == 0555)
88 if (!chmod(path
, 0755))
90 ohshite(_("unable to set execute permissions on '%.250s'"), path
);
94 * Returns the path to the script inside the chroot.
97 maintscript_pre_exec(struct command
*cmd
)
99 const char *instdir
= dpkg_fsys_get_dir();
100 const char *admindir
= dpkg_db_get_dir();
101 const char *changedir
;
102 size_t instdirlen
= strlen(instdir
);
104 if (instdirlen
> 0 && in_force(FORCE_SCRIPT_CHROOTLESS
))
109 if (instdirlen
> 0 && !in_force(FORCE_SCRIPT_CHROOTLESS
)) {
112 if (strncmp(admindir
, instdir
, instdirlen
) != 0)
113 ohshit(_("admindir must be inside instdir for dpkg to work properly"));
114 if (setenv("DPKG_ADMINDIR", admindir
+ instdirlen
, 1) < 0)
115 ohshite(_("unable to setenv for subprocesses"));
116 if (setenv("DPKG_ROOT", "", 1) < 0)
117 ohshite(_("unable to setenv for subprocesses"));
119 rc
= chroot(instdir
);
120 if (rc
&& in_force(FORCE_NON_ROOT
) && errno
== EPERM
)
121 ohshit(_("not enough privileges to change root "
122 "directory with --force-not-root, consider "
123 "using --force-script-chrootless?"));
125 ohshite(_("failed to chroot to '%.250s'"), instdir
);
127 /* Switch to a known good directory to give the maintainer script
128 * a saner environment, also needed after the chroot(). */
129 if (chdir(changedir
))
130 ohshite(_("failed to chdir to '%.255s'"), changedir
);
131 if (debug_has_flag(dbg_scripts
)) {
132 struct varbuf args
= VARBUF_INIT
;
133 const char **argv
= cmd
->argv
;
136 varbuf_add_char(&args
, ' ');
137 varbuf_add_str(&args
, *argv
);
139 debug(dbg_scripts
, "fork/exec %s (%s )", cmd
->filename
,
141 varbuf_destroy(&args
);
143 if (instdirlen
== 0 || in_force(FORCE_SCRIPT_CHROOTLESS
))
144 return cmd
->filename
;
146 if (strlen(cmd
->filename
) < instdirlen
)
147 internerr("maintscript name '%s' length < instdir length %zd",
148 cmd
->filename
, instdirlen
);
150 return cmd
->filename
+ instdirlen
;
154 * Set a new security execution context for the maintainer script.
156 * Try to create a new execution context based on the current one and the
157 * specific maintainer script filename. If it's the same as the current
158 * one, use the given fallback.
161 maintscript_set_exec_context(struct command
*cmd
)
163 #ifdef WITH_LIBSELINUX
164 return setexecfilecon(cmd
->filename
, "dpkg_script_t");
171 maintscript_exec(struct pkginfo
*pkg
, struct pkgbin
*pkgbin
,
172 struct command
*cmd
, struct stat
*stab
, int warn
)
177 setexecute(cmd
->filename
, stab
);
179 push_cleanup(cu_post_script_tasks
, ehflag_bombout
, 0);
181 pid
= subproc_fork();
184 const char *maintscript_debug
;
186 pkg_count
= str_fmt("%d", pkgset_installed_instances(pkg
->set
));
188 maintscript_debug
= debug_has_flag(dbg_scripts
) ? "1" : "0";
190 if (setenv("DPKG_MAINTSCRIPT_PACKAGE", pkg
->set
->name
, 1) ||
191 setenv("DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT", pkg_count
, 1) ||
192 setenv("DPKG_MAINTSCRIPT_ARCH", pkgbin
->arch
->name
, 1) ||
193 setenv("DPKG_MAINTSCRIPT_NAME", cmd
->argv
[0], 1) ||
194 setenv("DPKG_MAINTSCRIPT_DEBUG", maintscript_debug
, 1) ||
195 setenv("DPKG_RUNNING_VERSION", PACKAGE_VERSION
, 1))
196 ohshite(_("unable to setenv for maintainer script"));
198 cmd
->filename
= cmd
->argv
[0] = maintscript_pre_exec(cmd
);
200 if (maintscript_set_exec_context(cmd
) < 0)
201 ohshite(_("cannot set security execution context for "
202 "maintainer script"));
206 subproc_signals_ignore(cmd
->name
);
207 rc
= subproc_reap(pid
, cmd
->name
, warn
);
208 subproc_signals_restore();
210 pop_cleanup(ehflag_normaltidy
);
216 vmaintscript_installed(struct pkginfo
*pkg
, const char *scriptname
,
217 const char *desc
, va_list args
)
220 const char *scriptpath
;
224 scriptpath
= pkg_infodb_get_file(pkg
, &pkg
->installed
, scriptname
);
225 m_asprintf(&buf
, _("installed %s package %s script"),
226 pkg_name(pkg
, pnaw_nonambig
), desc
);
228 command_init(&cmd
, scriptpath
, buf
);
229 command_add_arg(&cmd
, scriptname
);
230 command_add_argv(&cmd
, args
);
232 if (stat(scriptpath
, &stab
)) {
233 command_destroy(&cmd
);
235 if (errno
== ENOENT
) {
237 "vmaintscript_installed nonexistent %s",
242 ohshite(_("unable to stat %s '%.250s'"), buf
, scriptpath
);
244 maintscript_exec(pkg
, &pkg
->installed
, &cmd
, &stab
, 0);
246 command_destroy(&cmd
);
253 * All ...'s in maintscript_* are const char *'s.
257 maintscript_installed(struct pkginfo
*pkg
, const char *scriptname
,
258 const char *desc
, ...)
263 va_start(args
, desc
);
264 rc
= vmaintscript_installed(pkg
, scriptname
, desc
, args
);
274 maintscript_postinst(struct pkginfo
*pkg
, ...)
280 rc
= vmaintscript_installed(pkg
, POSTINSTFILE
, "post-installation", args
);
290 maintscript_new(struct pkginfo
*pkg
, const char *scriptname
,
291 const char *desc
, const char *cidir
, char *cidirrest
, ...)
298 strcpy(cidirrest
, scriptname
);
299 m_asprintf(&buf
, _("new %s package %s script"),
300 pkg_name(pkg
, pnaw_nonambig
), desc
);
302 va_start(args
, cidirrest
);
303 command_init(&cmd
, cidir
, buf
);
304 command_add_arg(&cmd
, scriptname
);
305 command_add_argv(&cmd
, args
);
308 if (stat(cidir
, &stab
)) {
309 command_destroy(&cmd
);
311 if (errno
== ENOENT
) {
313 "maintscript_new nonexistent %s '%s'",
318 ohshite(_("unable to stat %s '%.250s'"), buf
, cidir
);
320 maintscript_exec(pkg
, &pkg
->available
, &cmd
, &stab
, 0);
322 command_destroy(&cmd
);
330 maintscript_fallback(struct pkginfo
*pkg
,
331 const char *scriptname
, const char *desc
,
332 const char *cidir
, char *cidirrest
,
333 const char *ifok
, const char *iffallback
)
336 const char *oldscriptpath
;
340 oldscriptpath
= pkg_infodb_get_file(pkg
, &pkg
->installed
, scriptname
);
341 m_asprintf(&buf
, _("old %s package %s script"),
342 pkg_name(pkg
, pnaw_nonambig
), desc
);
344 command_init(&cmd
, oldscriptpath
, buf
);
345 command_add_args(&cmd
, scriptname
, ifok
,
346 versiondescribe(&pkg
->available
.version
, vdew_nonambig
),
349 if (stat(oldscriptpath
, &stab
)) {
350 if (errno
== ENOENT
) {
352 "maintscript_fallback nonexistent %s '%s'",
353 scriptname
, oldscriptpath
);
354 command_destroy(&cmd
);
358 warning(_("unable to stat %s '%.250s': %s"),
359 cmd
.name
, oldscriptpath
, strerror(errno
));
360 } else if (!maintscript_exec(pkg
, &pkg
->installed
, &cmd
, &stab
, SUBPROC_WARN
)) {
361 command_destroy(&cmd
);
366 notice(_("trying script from the new package instead ..."));
368 strcpy(cidirrest
, scriptname
);
369 m_asprintf(&buf
, _("new %s package %s script"),
370 pkg_name(pkg
, pnaw_nonambig
), desc
);
372 command_destroy(&cmd
);
373 command_init(&cmd
, cidir
, buf
);
374 command_add_args(&cmd
, scriptname
, iffallback
,
375 versiondescribe(&pkg
->installed
.version
, vdew_nonambig
),
376 versiondescribe(&pkg
->available
.version
, vdew_nonambig
),
379 if (stat(cidir
, &stab
)) {
380 command_destroy(&cmd
);
383 ohshit(_("there is no script in the new version of the package - giving up"));
385 ohshite(_("unable to stat %s '%.250s'"), buf
, cidir
);
388 maintscript_exec(pkg
, &pkg
->available
, &cmd
, &stab
, 0);
389 notice(_("... it looks like that went OK"));
391 command_destroy(&cmd
);