openpkg/openpkg.c

changeset 428
f880f219c566
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/openpkg/openpkg.c	Tue Jul 31 12:23:42 2012 +0200
     1.3 @@ -0,0 +1,504 @@
     1.4 +/*
     1.5 +**  openpkg.c -- OpenPKG Frontend
     1.6 +**  Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>
     1.7 +**
     1.8 +**  This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
     1.9 +**  All rights reserved. Licenses which grant limited permission to use,
    1.10 +**  copy, modify and distribute this software are available from the
    1.11 +**  OpenPKG GmbH.
    1.12 +**
    1.13 +**  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
    1.14 +**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    1.15 +**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    1.16 +**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
    1.17 +**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.18 +**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.19 +**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    1.20 +**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    1.21 +**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    1.22 +**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    1.23 +**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.24 +**  SUCH DAMAGE.
    1.25 +*/
    1.26 +
    1.27 +/* program information */
    1.28 +#define LICENSE \
    1.29 +    "Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>\n" \
    1.30 +    "\n" \
    1.31 +    "This software is property of the OpenPKG GmbH, DE MUC HRB 160208.\n" \
    1.32 +    "All rights reserved. Licenses which grant limited permission to use,\n" \
    1.33 +    "copy, modify and distribute this software are available from the\n" \
    1.34 +    "OpenPKG GmbH.\n" \
    1.35 +    "\n" \
    1.36 +    "THIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\n" \
    1.37 +    "WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" \
    1.38 +    "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n" \
    1.39 +    "IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR\n" \
    1.40 +    "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" \
    1.41 +    "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" \
    1.42 +    "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n" \
    1.43 +    "USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" \
    1.44 +    "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n" \
    1.45 +    "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n" \
    1.46 +    "OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n" \
    1.47 +    "SUCH DAMAGE.\n"
    1.48 +
    1.49 +/* system includes */
    1.50 +#include <stdio.h>
    1.51 +#include <stdlib.h>
    1.52 +#include <stdarg.h>
    1.53 +#include <string.h>
    1.54 +#include <sys/types.h>
    1.55 +#include <sys/param.h>
    1.56 +#include <sys/stat.h>
    1.57 +#include <pwd.h>
    1.58 +#include <grp.h>
    1.59 +#include <unistd.h>
    1.60 +#include <errno.h>
    1.61 +
    1.62 +/* sanity check compilation */
    1.63 +#ifndef OPENPKG_PREFIX
    1.64 +#error OpenPKG instance prefix not defined
    1.65 +#endif
    1.66 +#ifndef OPENPKG_SUSR
    1.67 +#error OpenPKG super user not defined
    1.68 +#endif
    1.69 +#ifndef OPENPKG_MUSR
    1.70 +#error OpenPKG management user not defined
    1.71 +#endif
    1.72 +
    1.73 +/* platform specifics */
    1.74 +#if defined(OPENPKG_PLATFORM_FREEBSD) || \
    1.75 +    defined(OPENPKG_PLATFORM_NETBSD)  || \
    1.76 +    defined(OPENPKG_PLATFORM_OPENBSD) || \
    1.77 +    defined(OPENPKG_PLATFORM_SUNOS)   || \
    1.78 +    defined(OPENPKG_PLATFORM_LINUX)   || \
    1.79 +    defined(OPENPKG_PLATFORM_DARWIN)  || \
    1.80 +    defined(OPENPKG_PLATFORM_AIX)     || \
    1.81 +    defined(OPENPKG_PLATFORM_IRIX)    || \
    1.82 +    defined(OPENPKG_PLATFORM_HPUX)
    1.83 +#define HAVE_INITGROUPS
    1.84 +#endif
    1.85 +
    1.86 +/* global debug enable flag */
    1.87 +static int debug_enable = 0;
    1.88 +
    1.89 +/* helper function: emulate (still less portable) setenv(3) via (more portable) putenv(3) */
    1.90 +static int my_setenv(const char *name, const char *value, int overwrite)
    1.91 +{
    1.92 +    char *pair;
    1.93 +
    1.94 +    if (overwrite == 0 && getenv(name) != NULL)
    1.95 +        return 0;
    1.96 +    if ((pair = malloc(strlen(name) + 1 + strlen(value) + 1)) == NULL)
    1.97 +        return -1;
    1.98 +    strcpy(pair, name);
    1.99 +    strcat(pair, "=");
   1.100 +    strcat(pair, value);
   1.101 +    putenv(pair);
   1.102 +    return 0;
   1.103 +}
   1.104 +
   1.105 +/* helper function for printing a warning message */
   1.106 +static void warn(const char *fmt, ...)
   1.107 +{
   1.108 +    va_list ap;
   1.109 +
   1.110 +    va_start(ap, fmt);
   1.111 +    fprintf(stderr, "openpkg:WARNING: ");
   1.112 +    vfprintf(stderr, fmt, ap);
   1.113 +    fprintf(stderr, "\n");
   1.114 +    va_end(ap);
   1.115 +    return;
   1.116 +}
   1.117 +
   1.118 +/* helper function for printing a debug message */
   1.119 +static void debug(const char *fmt, ...)
   1.120 +{
   1.121 +    va_list ap;
   1.122 +
   1.123 +    va_start(ap, fmt);
   1.124 +    if (debug_enable) {
   1.125 +        fprintf(stderr, "openpkg:DEBUG: ");
   1.126 +        vfprintf(stderr, fmt, ap);
   1.127 +        fprintf(stderr, "\n");
   1.128 +    }
   1.129 +    va_end(ap);
   1.130 +    return;
   1.131 +}
   1.132 +
   1.133 +/* helper function for printing a fatal message and exit */
   1.134 +static void fatal(const char *fmt, ...)
   1.135 +{
   1.136 +    va_list ap;
   1.137 +
   1.138 +    va_start(ap, fmt);
   1.139 +    fprintf(stderr, "openpkg:ERROR: ");
   1.140 +    vfprintf(stderr, fmt, ap);
   1.141 +    fprintf(stderr, "\n");
   1.142 +    va_end(ap);
   1.143 +    exit(1);
   1.144 +    return;
   1.145 +}
   1.146 +
   1.147 +/* adjust process privileges */
   1.148 +static void adjust_privileges(uid_t uid, gid_t gid, int login)
   1.149 +{
   1.150 +    struct passwd *pw;
   1.151 +    char cwd[MAXPATHLEN];
   1.152 +
   1.153 +    /* optionally emulate a more complete login */
   1.154 +    if (login) {
   1.155 +        /* determine information about user id */
   1.156 +        if ((pw = getpwuid(uid)) == NULL)
   1.157 +            fatal("unable to resolve user id \"%d\": %s", uid, strerror(errno));
   1.158 +
   1.159 +        /* reset some essential environment variables */
   1.160 +        my_setenv("LOGNAME", pw->pw_name,   1);
   1.161 +        my_setenv("USER",    pw->pw_name,   1);
   1.162 +        my_setenv("SHELL",   pw->pw_shell,  1);
   1.163 +        my_setenv("HOME",    pw->pw_dir,    1);
   1.164 +
   1.165 +#ifdef HAVE_INITGROUPS
   1.166 +        /* initialize complete group access list */
   1.167 +        if (initgroups(pw->pw_name, pw->pw_gid) == -1)
   1.168 +            fatal("failed to initialize access group list via initgroups(3): %s", strerror(errno));
   1.169 +#endif
   1.170 +    }
   1.171 +
   1.172 +    /* switch to group id (first) */
   1.173 +    if (setgid(gid) == -1)
   1.174 +        fatal("failed to set group id via setgid(2): %s", strerror(errno));
   1.175 +
   1.176 +    /* switch to user id (second) */
   1.177 +    if (setuid(uid) == -1)
   1.178 +        fatal("failed to set user id via setuid(2): %s", strerror(errno));
   1.179 +
   1.180 +    /* in case the current working directory is NO LONGER accessible,
   1.181 +       try to switch to the home directory of the target identity to
   1.182 +       prevent failures in subsequently called programs (e.g. GNU bash) */
   1.183 +    if (login) {
   1.184 +        if (getcwd(cwd, sizeof(cwd)) == NULL) {
   1.185 +            warn("current working directory is no longer accessible -- switching to \"%s\"", pw->pw_dir);
   1.186 +            if (chdir(pw->pw_dir) == -1)
   1.187 +                fatal("unable to chdir(2) to \"%s\": %s", pw->pw_dir, strerror(errno));
   1.188 +        }
   1.189 +    }
   1.190 +
   1.191 +    return;
   1.192 +}
   1.193 +
   1.194 +/* check whether caller is an explictly configured management user */
   1.195 +static int check_whether_is_manager(uid_t my_uid, gid_t my_gid, uid_t m_uid, gid_t m_gid)
   1.196 +{
   1.197 +    char buf[1024];
   1.198 +    char *username;
   1.199 +    char *groupname;
   1.200 +    char *filename;
   1.201 +    struct stat sb;
   1.202 +    char *cp;
   1.203 +    FILE *fp;
   1.204 +    struct passwd *pw;
   1.205 +    struct group *gr;
   1.206 +    int i;
   1.207 +    int ok_uid;
   1.208 +    int ok_gid;
   1.209 +    int is_manager;
   1.210 +
   1.211 +    is_manager = 0;
   1.212 +
   1.213 +    /* path to the managers configuration file */
   1.214 +    filename = OPENPKG_PREFIX "/etc/openpkg/managers";
   1.215 +
   1.216 +    /* check permissions of file */
   1.217 +    if (stat(filename, &sb) == -1) {
   1.218 +        warn("unable to determine information about configuration"
   1.219 +             " file \"%s\": %s -- ignoring file", filename, strerror(errno));
   1.220 +        return 0;
   1.221 +    }
   1.222 +    if (sb.st_uid != m_uid) {
   1.223 +        warn("invalid owner user id %d (expected %d) on configuration"
   1.224 +             " file \"%s\" -- ignoring file", sb.st_uid, m_uid, filename);
   1.225 +        return 0;
   1.226 +    }
   1.227 +    if (sb.st_gid != m_gid) {
   1.228 +        warn("invalid owner group id %d (expected %d) on configuration"
   1.229 +             " file \"%s\" -- ignoring file", sb.st_gid, m_gid, filename);
   1.230 +        return 0;
   1.231 +    }
   1.232 +    if (sb.st_mode != (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) {
   1.233 +        warn("invalid permissions on configuration"
   1.234 +             " file \"%s\" -- ignoring file", filename);
   1.235 +        return 0;
   1.236 +    }
   1.237 +
   1.238 +    /* parse configuration file */
   1.239 +    if ((fp = fopen(filename, "r")) == NULL) {
   1.240 +        warn("unable to open configuration file \"%s\": %s -- ignoring file", filename, strerror(errno));
   1.241 +        return 0;
   1.242 +    }
   1.243 +    while ((cp = fgets(buf, sizeof(buf), fp)) != NULL) {
   1.244 +        /* parse entry as "<username>[:<groupname>]" where both
   1.245 +           <username> and <groupname> can be set and default to "*"
   1.246 +           to indicate an arbitrary user or group */
   1.247 +        if ((i = strlen(buf)) == 0) {
   1.248 +            warn("unexpected empty buffer during parsing of configuration file \"%\"", filename);
   1.249 +            break;
   1.250 +        }
   1.251 +        if (i >= sizeof(buf)) {
   1.252 +            warn("unexpected buffer overflow during parsing of configuration file \"%\"", filename);
   1.253 +            break;
   1.254 +        }
   1.255 +        if (buf[i-1] != '\r' && buf[i-1] != '\n') {
   1.256 +            warn("unexpected non-newline-terminated line found during parsing of configuration file \"%\"", filename);
   1.257 +            break;
   1.258 +        }
   1.259 +        username = buf + strspn(buf, " \t");
   1.260 +        cp = username + strcspn(username, " \t#\r\n");
   1.261 +        *cp = '\0';
   1.262 +        if (username[0] == '#' || username[0] == '\r' || username[0] == '\n' || username[0] == '\0')
   1.263 +            continue;
   1.264 +        groupname = "*";
   1.265 +        if ((cp = strchr(username, ':')) != NULL) {
   1.266 +            *cp++ = '\0';
   1.267 +            groupname = cp;
   1.268 +        }
   1.269 +        debug("parsing result: username=\"%s\" groupname=\"%s\"", username, groupname);
   1.270 +
   1.271 +        /* check whether UID is ok */
   1.272 +        ok_uid = 0;
   1.273 +        if (strcmp(username, "*") == 0)
   1.274 +            ok_uid = 1;
   1.275 +        else {
   1.276 +            if ((pw = getpwnam(username)) == NULL) {
   1.277 +                warn("invalid username \"%s\" in \"%s\"", username, filename);
   1.278 +                continue;
   1.279 +            }
   1.280 +            if (pw->pw_uid == my_uid)
   1.281 +                ok_uid = 1;
   1.282 +        }
   1.283 +
   1.284 +        /* check whether GID is ok */
   1.285 +        ok_gid = 0;
   1.286 +        if (strcmp(groupname, "*") == 0)
   1.287 +            ok_gid = 1;
   1.288 +        else {
   1.289 +            if ((gr = getgrnam(groupname)) == NULL) {
   1.290 +                warn("invalid groupname \"%s\" in \"%s\"", groupname, filename);
   1.291 +                continue;
   1.292 +            }
   1.293 +            if (gr->gr_gid == my_gid)
   1.294 +                ok_gid = 1;
   1.295 +        }
   1.296 +
   1.297 +        /* if both UID and GID are ok, user is manager */
   1.298 +        debug("matching: username ok = %s, groupname ok = %s", ok_uid ? "yes" : "no", ok_gid ? "yes" : "no");
   1.299 +        if (ok_uid && ok_gid) {
   1.300 +            is_manager = 1;
   1.301 +            break;
   1.302 +        }
   1.303 +    }
   1.304 +    fclose(fp);
   1.305 +    return is_manager;
   1.306 +}
   1.307 +
   1.308 +/* check whether command requires super-user privileges */
   1.309 +static int check_whether_require_superuser(int argc, char *argv[])
   1.310 +{
   1.311 +    int require_superuser;
   1.312 +    int i, j;
   1.313 +
   1.314 +    require_superuser = 0;
   1.315 +    if (argc > 1 && strcmp(argv[1], "rpm") == 0) {
   1.316 +        for (i = 2; i < argc; i++) {
   1.317 +            if (strcmp(argv[i], "--") == 0)
   1.318 +                break;
   1.319 +            else if (   strcmp(argv[i], "--erase")      == 0
   1.320 +                     || strcmp(argv[i], "--freshen")    == 0
   1.321 +                     || strcmp(argv[i], "--install")    == 0
   1.322 +                     || strcmp(argv[i], "--upgrade")    == 0
   1.323 +                     || strcmp(argv[i], "--import")     == 0
   1.324 +                     || strcmp(argv[i], "--initdb")     == 0
   1.325 +                     || strcmp(argv[i], "--rebuilddb")  == 0
   1.326 +                     || strcmp(argv[i], "--db-build")   == 0
   1.327 +                     || strcmp(argv[i], "--db-rebuild") == 0
   1.328 +                     || strcmp(argv[i], "--db-cleanup") == 0
   1.329 +                     || strcmp(argv[i], "--db-fixate")  == 0
   1.330 +                     || strcmp(argv[i], "--setperms")   == 0
   1.331 +                     || strcmp(argv[i], "--setugids")   == 0) {
   1.332 +                require_superuser = 1;
   1.333 +                break;
   1.334 +            }
   1.335 +            else if (   argv[i][0] == '-'
   1.336 +                     && argv[i][1] != '-'
   1.337 +                     && argv[i][1] != 'b'
   1.338 +                     && argv[i][1] != 't'
   1.339 +                ) {
   1.340 +                for (j = 1; argv[i][j] != '\0'; j++) {
   1.341 +                    if (    (   argv[i][j] == 'q'
   1.342 +                             || argv[i][j] == 'K')
   1.343 +                         && argv[i][j+1] != '\0') {
   1.344 +                        j++;
   1.345 +                        continue;
   1.346 +                    }
   1.347 +                    else if (   argv[i][j] == 'i'
   1.348 +                        || argv[i][j] == 'U'
   1.349 +                        || argv[i][j] == 'F'
   1.350 +                        || argv[i][j] == 'V'
   1.351 +                        || argv[i][j] == 'e') {
   1.352 +                        require_superuser = 1;
   1.353 +                        break;
   1.354 +                    }
   1.355 +                }
   1.356 +                if (require_superuser)
   1.357 +                    break;
   1.358 +            }
   1.359 +        }
   1.360 +    }
   1.361 +    else if (argc > 1 && strcmp(argv[1], "rc") == 0) {
   1.362 +        require_superuser = 1;
   1.363 +        for (i = 2; i < argc; i++) {
   1.364 +            if (strcmp(argv[i], "--") == 0)
   1.365 +                break;
   1.366 +            else if (   strcmp(argv[i], "-p")       == 0
   1.367 +                     || strcmp(argv[i], "--print")  == 0
   1.368 +                     || strcmp(argv[i], "-e")       == 0
   1.369 +                     || strcmp(argv[i], "--eval")   == 0
   1.370 +                     || strcmp(argv[i], "-q")       == 0
   1.371 +                     || strcmp(argv[i], "--query")  == 0
   1.372 +                     || strcmp(argv[i], "-c")       == 0
   1.373 +                     || strcmp(argv[i], "--config") == 0) {
   1.374 +                require_superuser = 0;
   1.375 +                break;
   1.376 +            }
   1.377 +        }
   1.378 +    }
   1.379 +    return require_superuser;
   1.380 +}
   1.381 +
   1.382 +/* main program */
   1.383 +int main(int argc, char **argv, char **envp)
   1.384 +{
   1.385 +    int keep_original_privileges;
   1.386 +    int is_manager;
   1.387 +    int require_superuser;
   1.388 +    uid_t my_uid, my_euid;
   1.389 +    gid_t my_gid, my_egid;
   1.390 +    uid_t m_uid;
   1.391 +    gid_t m_gid;
   1.392 +    uid_t s_uid;
   1.393 +    gid_t s_gid;
   1.394 +    struct passwd *pw;
   1.395 +    struct group *gr;
   1.396 +    int dry_run;
   1.397 +    int license;
   1.398 +
   1.399 +    /* parse command line options */
   1.400 +    license = 0;
   1.401 +    dry_run = 0;
   1.402 +    keep_original_privileges = 0;
   1.403 +    if (argc <= 0)
   1.404 +        abort();
   1.405 +    argv++; argc--;
   1.406 +    while (argc > 0) {
   1.407 +        if (argv[0][0] != '-')
   1.408 +            break;
   1.409 +        else if (strcmp(argv[0], "--") == 0) {
   1.410 +            argv++; argc--;
   1.411 +            break;
   1.412 +        }
   1.413 +        else if (strcmp(argv[0], "--license") == 0) {
   1.414 +            license = 1;
   1.415 +            argv++; argc--;
   1.416 +            continue;
   1.417 +        }
   1.418 +        else if (strcmp(argv[0], "--debug") == 0) {
   1.419 +            debug_enable = 1;
   1.420 +            argv++; argc--;
   1.421 +            continue;
   1.422 +        }
   1.423 +        else if (strcmp(argv[0], "--dry-run") == 0) {
   1.424 +            dry_run = 1;
   1.425 +            argv++; argc--;
   1.426 +            continue;
   1.427 +        }
   1.428 +        else if (strcmp(argv[0], "--keep-privileges") == 0) {
   1.429 +            keep_original_privileges = 1;
   1.430 +            argv++; argc--;
   1.431 +            continue;
   1.432 +        }
   1.433 +        break;
   1.434 +    }
   1.435 +    argv--; argc++;
   1.436 +
   1.437 +    /* display stand-alone license information */
   1.438 +    if (license) {
   1.439 +        fprintf(stdout, "%s", LICENSE);
   1.440 +        exit(0);
   1.441 +    }
   1.442 +
   1.443 +    /* determine our current real and effective user/group ids */
   1.444 +    my_uid  = getuid();
   1.445 +    my_gid  = getgid();
   1.446 +    my_euid = geteuid();
   1.447 +    my_egid = getegid();
   1.448 +    if ((pw = getpwuid(my_uid)) == NULL)
   1.449 +        fatal("unable to resolve current user id %d: %s", my_uid, strerror(errno));
   1.450 +    if ((gr = getgrgid(my_gid)) == NULL)
   1.451 +        fatal("unable to resolve current group id %d: %s", my_gid, strerror(errno));
   1.452 +    debug("current-user: usr=%s uid=%d euid=%d grp=%s gid=%d egid=%d",
   1.453 +          pw->pw_name, my_uid, my_euid, gr->gr_name, my_gid, my_egid);
   1.454 +
   1.455 +    /* determine super user/group id */
   1.456 +    if ((pw = getpwnam(OPENPKG_SUSR)) == NULL)
   1.457 +        fatal("unable to resolve OpenPKG superuser username \"%s\": %s", OPENPKG_SUSR, strerror(errno));
   1.458 +    s_uid = pw->pw_uid;
   1.459 +    s_gid = pw->pw_gid;
   1.460 +    debug("super-user: s_usr=%s s_uid=%d s_gid=%d", OPENPKG_SUSR, s_uid, s_gid);
   1.461 +
   1.462 +    /* determine management user/group id */
   1.463 +    if ((pw = getpwnam(OPENPKG_MUSR)) == NULL)
   1.464 +        fatal("unable to resolve OpenPKG management username \"%s\": %s", OPENPKG_MUSR, strerror(errno));
   1.465 +    m_uid = pw->pw_uid;
   1.466 +    m_gid = pw->pw_gid;
   1.467 +    debug("management-user: m_grp=%s m_uid=%d m_gid=%d", OPENPKG_MUSR, m_uid, m_gid);
   1.468 +
   1.469 +    /* determine whether caller is explicitly configured as a management user */
   1.470 +    is_manager = 0;
   1.471 +    if (!keep_original_privileges)
   1.472 +        is_manager = check_whether_is_manager(my_uid, my_gid, m_uid, m_gid);
   1.473 +    debug("current user is manager: %s", is_manager ? "yes" : "no");
   1.474 +
   1.475 +    /* determine whether command requires super-user privileges */
   1.476 +    require_superuser = check_whether_require_superuser(argc, argv);
   1.477 +    debug("current command requires super user privileges: %s", require_superuser ? "yes" : "no");
   1.478 +
   1.479 +    /* adjust privileges according to determined information */
   1.480 +    if (!keep_original_privileges && require_superuser && is_manager && my_euid == 0) {
   1.481 +        /* increase privileges to super user */
   1.482 +        debug("increase privileges to super user");
   1.483 +        adjust_privileges(s_uid, s_gid, 1);
   1.484 +    }
   1.485 +    else if (!keep_original_privileges && !require_superuser && is_manager && my_euid == 0) {
   1.486 +        /* decrease privileges to management user */
   1.487 +        debug("decrease privileges to management user");
   1.488 +        adjust_privileges(m_uid, m_gid, 1);
   1.489 +    }
   1.490 +    else /* keep_original_privileges || !is_manager */ {
   1.491 +        /* drop effective privileges for current user*/
   1.492 +        debug("drop effective privileges for current user");
   1.493 +        adjust_privileges(my_uid, my_gid, 0);
   1.494 +    }
   1.495 +
   1.496 +    /* pass-through control to real Execution Frontend (shell script) */
   1.497 +    argv[0] = OPENPKG_PREFIX "/lib/openpkg/openpkg";
   1.498 +    debug("execute \"%s\"", argv[0]);
   1.499 +    if (!dry_run) {
   1.500 +        if (execve(argv[0], argv, envp) == -1)
   1.501 +            fatal("failed to execute \"%s\": %s", argv[0], strerror(errno));
   1.502 +        /* NOT REACHED */
   1.503 +        fatal("INTERNAL ERROR");
   1.504 +    }
   1.505 +    return 0;
   1.506 +}
   1.507 +

mercurial