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 varbuf_end_str(&args
);
140 debug(dbg_scripts
, "fork/exec %s (%s )", cmd
->filename
,
142 varbuf_destroy(&args
);
144 if (instdirlen
== 0 || in_force(FORCE_SCRIPT_CHROOTLESS
))
145 return cmd
->filename
;
147 if (strlen(cmd
->filename
) < instdirlen
)
148 internerr("maintscript name '%s' length < instdir length %zd",
149 cmd
->filename
, instdirlen
);
151 return cmd
->filename
+ instdirlen
;
155 * Set a new security execution context for the maintainer script.
157 * Try to create a new execution context based on the current one and the
158 * specific maintainer script filename. If it's the same as the current
159 * one, use the given fallback.
162 maintscript_set_exec_context(struct command
*cmd
)
164 #ifdef WITH_LIBSELINUX
165 return setexecfilecon(cmd
->filename
, "dpkg_script_t");
172 maintscript_exec(struct pkginfo
*pkg
, struct pkgbin
*pkgbin
,
173 struct command
*cmd
, struct stat
*stab
, int warn
)
178 setexecute(cmd
->filename
, stab
);
180 push_cleanup(cu_post_script_tasks
, ehflag_bombout
, 0);
182 pid
= subproc_fork();
185 const char *maintscript_debug
;
187 pkg_count
= str_fmt("%d", pkgset_installed_instances(pkg
->set
));
189 maintscript_debug
= debug_has_flag(dbg_scripts
) ? "1" : "0";
191 if (setenv("DPKG_MAINTSCRIPT_PACKAGE", pkg
->set
->name
, 1) ||
192 setenv("DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT", pkg_count
, 1) ||
193 setenv("DPKG_MAINTSCRIPT_ARCH", pkgbin
->arch
->name
, 1) ||
194 setenv("DPKG_MAINTSCRIPT_NAME", cmd
->argv
[0], 1) ||
195 setenv("DPKG_MAINTSCRIPT_DEBUG", maintscript_debug
, 1) ||
196 setenv("DPKG_RUNNING_VERSION", PACKAGE_VERSION
, 1))
197 ohshite(_("unable to setenv for maintainer script"));
199 cmd
->filename
= cmd
->argv
[0] = maintscript_pre_exec(cmd
);
201 if (maintscript_set_exec_context(cmd
) < 0)
202 ohshite(_("cannot set security execution context for "
203 "maintainer script"));
207 subproc_signals_ignore(cmd
->name
);
208 rc
= subproc_reap(pid
, cmd
->name
, warn
);
209 subproc_signals_restore();
211 pop_cleanup(ehflag_normaltidy
);
217 vmaintscript_installed(struct pkginfo
*pkg
, const char *scriptname
,
218 const char *desc
, va_list args
)
221 const char *scriptpath
;
225 scriptpath
= pkg_infodb_get_file(pkg
, &pkg
->installed
, scriptname
);
226 m_asprintf(&buf
, _("installed %s package %s script"),
227 pkg_name(pkg
, pnaw_nonambig
), desc
);
229 command_init(&cmd
, scriptpath
, buf
);
230 command_add_arg(&cmd
, scriptname
);
231 command_add_argv(&cmd
, args
);
233 if (stat(scriptpath
, &stab
)) {
234 command_destroy(&cmd
);
236 if (errno
== ENOENT
) {
238 "vmaintscript_installed nonexistent %s",
243 ohshite(_("unable to stat %s '%.250s'"), buf
, scriptpath
);
245 maintscript_exec(pkg
, &pkg
->installed
, &cmd
, &stab
, 0);
247 command_destroy(&cmd
);
254 * All ...'s in maintscript_* are const char *'s.
258 maintscript_installed(struct pkginfo
*pkg
, const char *scriptname
,
259 const char *desc
, ...)
264 va_start(args
, desc
);
265 rc
= vmaintscript_installed(pkg
, scriptname
, desc
, args
);
275 maintscript_postinst(struct pkginfo
*pkg
, ...)
281 rc
= vmaintscript_installed(pkg
, POSTINSTFILE
, "post-installation", args
);
291 maintscript_new(struct pkginfo
*pkg
, const char *scriptname
,
292 const char *desc
, const char *cidir
, char *cidirrest
, ...)
299 strcpy(cidirrest
, scriptname
);
300 m_asprintf(&buf
, _("new %s package %s script"),
301 pkg_name(pkg
, pnaw_nonambig
), desc
);
303 va_start(args
, cidirrest
);
304 command_init(&cmd
, cidir
, buf
);
305 command_add_arg(&cmd
, scriptname
);
306 command_add_argv(&cmd
, args
);
309 if (stat(cidir
, &stab
)) {
310 command_destroy(&cmd
);
312 if (errno
== ENOENT
) {
314 "maintscript_new nonexistent %s '%s'",
319 ohshite(_("unable to stat %s '%.250s'"), buf
, cidir
);
321 maintscript_exec(pkg
, &pkg
->available
, &cmd
, &stab
, 0);
323 command_destroy(&cmd
);
331 maintscript_fallback(struct pkginfo
*pkg
,
332 const char *scriptname
, const char *desc
,
333 const char *cidir
, char *cidirrest
,
334 const char *ifok
, const char *iffallback
)
337 const char *oldscriptpath
;
341 oldscriptpath
= pkg_infodb_get_file(pkg
, &pkg
->installed
, scriptname
);
342 m_asprintf(&buf
, _("old %s package %s script"),
343 pkg_name(pkg
, pnaw_nonambig
), desc
);
345 command_init(&cmd
, oldscriptpath
, buf
);
346 command_add_args(&cmd
, scriptname
, ifok
,
347 versiondescribe(&pkg
->available
.version
, vdew_nonambig
),
350 if (stat(oldscriptpath
, &stab
)) {
351 if (errno
== ENOENT
) {
353 "maintscript_fallback nonexistent %s '%s'",
354 scriptname
, oldscriptpath
);
355 command_destroy(&cmd
);
359 warning(_("unable to stat %s '%.250s': %s"),
360 cmd
.name
, oldscriptpath
, strerror(errno
));
362 if (!maintscript_exec(pkg
, &pkg
->installed
, &cmd
, &stab
, SUBPROC_WARN
)) {
363 command_destroy(&cmd
);
369 notice(_("trying script from the new package instead ..."));
371 strcpy(cidirrest
, scriptname
);
372 m_asprintf(&buf
, _("new %s package %s script"),
373 pkg_name(pkg
, pnaw_nonambig
), desc
);
375 command_destroy(&cmd
);
376 command_init(&cmd
, cidir
, buf
);
377 command_add_args(&cmd
, scriptname
, iffallback
,
378 versiondescribe(&pkg
->installed
.version
, vdew_nonambig
),
379 versiondescribe(&pkg
->available
.version
, vdew_nonambig
),
382 if (stat(cidir
, &stab
)) {
383 command_destroy(&cmd
);
386 ohshit(_("there is no script in the new version of the package - giving up"));
388 ohshite(_("unable to stat %s '%.250s'"), buf
, cidir
);
391 maintscript_exec(pkg
, &pkg
->available
, &cmd
, &stab
, 0);
392 notice(_("... it looks like that went OK"));
394 command_destroy(&cmd
);