openpkg/openpkg.c

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

michael@428 1 /*
michael@428 2 ** openpkg.c -- OpenPKG Frontend
michael@428 3 ** Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>
michael@428 4 **
michael@428 5 ** This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
michael@428 6 ** All rights reserved. Licenses which grant limited permission to use,
michael@428 7 ** copy, modify and distribute this software are available from the
michael@428 8 ** OpenPKG GmbH.
michael@428 9 **
michael@428 10 ** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
michael@428 11 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
michael@428 12 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
michael@428 13 ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
michael@428 14 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@428 15 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@428 16 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
michael@428 17 ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@428 18 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@428 19 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@428 20 ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@428 21 ** SUCH DAMAGE.
michael@428 22 */
michael@428 23
michael@428 24 /* program information */
michael@428 25 #define LICENSE \
michael@428 26 "Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/>\n" \
michael@428 27 "\n" \
michael@428 28 "This software is property of the OpenPKG GmbH, DE MUC HRB 160208.\n" \
michael@428 29 "All rights reserved. Licenses which grant limited permission to use,\n" \
michael@428 30 "copy, modify and distribute this software are available from the\n" \
michael@428 31 "OpenPKG GmbH.\n" \
michael@428 32 "\n" \
michael@428 33 "THIS SOFTWARE IS PROVIDED \"AS IS\" AND ANY EXPRESSED OR IMPLIED\n" \
michael@428 34 "WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" \
michael@428 35 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n" \
michael@428 36 "IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR\n" \
michael@428 37 "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" \
michael@428 38 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" \
michael@428 39 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n" \
michael@428 40 "USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" \
michael@428 41 "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n" \
michael@428 42 "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\n" \
michael@428 43 "OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n" \
michael@428 44 "SUCH DAMAGE.\n"
michael@428 45
michael@428 46 /* system includes */
michael@428 47 #include <stdio.h>
michael@428 48 #include <stdlib.h>
michael@428 49 #include <stdarg.h>
michael@428 50 #include <string.h>
michael@428 51 #include <sys/types.h>
michael@428 52 #include <sys/param.h>
michael@428 53 #include <sys/stat.h>
michael@428 54 #include <pwd.h>
michael@428 55 #include <grp.h>
michael@428 56 #include <unistd.h>
michael@428 57 #include <errno.h>
michael@428 58
michael@428 59 /* sanity check compilation */
michael@428 60 #ifndef OPENPKG_PREFIX
michael@428 61 #error OpenPKG instance prefix not defined
michael@428 62 #endif
michael@428 63 #ifndef OPENPKG_SUSR
michael@428 64 #error OpenPKG super user not defined
michael@428 65 #endif
michael@428 66 #ifndef OPENPKG_MUSR
michael@428 67 #error OpenPKG management user not defined
michael@428 68 #endif
michael@428 69
michael@428 70 /* platform specifics */
michael@428 71 #if defined(OPENPKG_PLATFORM_FREEBSD) || \
michael@428 72 defined(OPENPKG_PLATFORM_NETBSD) || \
michael@428 73 defined(OPENPKG_PLATFORM_OPENBSD) || \
michael@428 74 defined(OPENPKG_PLATFORM_SUNOS) || \
michael@428 75 defined(OPENPKG_PLATFORM_LINUX) || \
michael@428 76 defined(OPENPKG_PLATFORM_DARWIN) || \
michael@428 77 defined(OPENPKG_PLATFORM_AIX) || \
michael@428 78 defined(OPENPKG_PLATFORM_IRIX) || \
michael@428 79 defined(OPENPKG_PLATFORM_HPUX)
michael@428 80 #define HAVE_INITGROUPS
michael@428 81 #endif
michael@428 82
michael@428 83 /* global debug enable flag */
michael@428 84 static int debug_enable = 0;
michael@428 85
michael@428 86 /* helper function: emulate (still less portable) setenv(3) via (more portable) putenv(3) */
michael@428 87 static int my_setenv(const char *name, const char *value, int overwrite)
michael@428 88 {
michael@428 89 char *pair;
michael@428 90
michael@428 91 if (overwrite == 0 && getenv(name) != NULL)
michael@428 92 return 0;
michael@428 93 if ((pair = malloc(strlen(name) + 1 + strlen(value) + 1)) == NULL)
michael@428 94 return -1;
michael@428 95 strcpy(pair, name);
michael@428 96 strcat(pair, "=");
michael@428 97 strcat(pair, value);
michael@428 98 putenv(pair);
michael@428 99 return 0;
michael@428 100 }
michael@428 101
michael@428 102 /* helper function for printing a warning message */
michael@428 103 static void warn(const char *fmt, ...)
michael@428 104 {
michael@428 105 va_list ap;
michael@428 106
michael@428 107 va_start(ap, fmt);
michael@428 108 fprintf(stderr, "openpkg:WARNING: ");
michael@428 109 vfprintf(stderr, fmt, ap);
michael@428 110 fprintf(stderr, "\n");
michael@428 111 va_end(ap);
michael@428 112 return;
michael@428 113 }
michael@428 114
michael@428 115 /* helper function for printing a debug message */
michael@428 116 static void debug(const char *fmt, ...)
michael@428 117 {
michael@428 118 va_list ap;
michael@428 119
michael@428 120 va_start(ap, fmt);
michael@428 121 if (debug_enable) {
michael@428 122 fprintf(stderr, "openpkg:DEBUG: ");
michael@428 123 vfprintf(stderr, fmt, ap);
michael@428 124 fprintf(stderr, "\n");
michael@428 125 }
michael@428 126 va_end(ap);
michael@428 127 return;
michael@428 128 }
michael@428 129
michael@428 130 /* helper function for printing a fatal message and exit */
michael@428 131 static void fatal(const char *fmt, ...)
michael@428 132 {
michael@428 133 va_list ap;
michael@428 134
michael@428 135 va_start(ap, fmt);
michael@428 136 fprintf(stderr, "openpkg:ERROR: ");
michael@428 137 vfprintf(stderr, fmt, ap);
michael@428 138 fprintf(stderr, "\n");
michael@428 139 va_end(ap);
michael@428 140 exit(1);
michael@428 141 return;
michael@428 142 }
michael@428 143
michael@428 144 /* adjust process privileges */
michael@428 145 static void adjust_privileges(uid_t uid, gid_t gid, int login)
michael@428 146 {
michael@428 147 struct passwd *pw;
michael@428 148 char cwd[MAXPATHLEN];
michael@428 149
michael@428 150 /* optionally emulate a more complete login */
michael@428 151 if (login) {
michael@428 152 /* determine information about user id */
michael@428 153 if ((pw = getpwuid(uid)) == NULL)
michael@428 154 fatal("unable to resolve user id \"%d\": %s", uid, strerror(errno));
michael@428 155
michael@428 156 /* reset some essential environment variables */
michael@428 157 my_setenv("LOGNAME", pw->pw_name, 1);
michael@428 158 my_setenv("USER", pw->pw_name, 1);
michael@428 159 my_setenv("SHELL", pw->pw_shell, 1);
michael@428 160 my_setenv("HOME", pw->pw_dir, 1);
michael@428 161
michael@428 162 #ifdef HAVE_INITGROUPS
michael@428 163 /* initialize complete group access list */
michael@428 164 if (initgroups(pw->pw_name, pw->pw_gid) == -1)
michael@428 165 fatal("failed to initialize access group list via initgroups(3): %s", strerror(errno));
michael@428 166 #endif
michael@428 167 }
michael@428 168
michael@428 169 /* switch to group id (first) */
michael@428 170 if (setgid(gid) == -1)
michael@428 171 fatal("failed to set group id via setgid(2): %s", strerror(errno));
michael@428 172
michael@428 173 /* switch to user id (second) */
michael@428 174 if (setuid(uid) == -1)
michael@428 175 fatal("failed to set user id via setuid(2): %s", strerror(errno));
michael@428 176
michael@428 177 /* in case the current working directory is NO LONGER accessible,
michael@428 178 try to switch to the home directory of the target identity to
michael@428 179 prevent failures in subsequently called programs (e.g. GNU bash) */
michael@428 180 if (login) {
michael@428 181 if (getcwd(cwd, sizeof(cwd)) == NULL) {
michael@428 182 warn("current working directory is no longer accessible -- switching to \"%s\"", pw->pw_dir);
michael@428 183 if (chdir(pw->pw_dir) == -1)
michael@428 184 fatal("unable to chdir(2) to \"%s\": %s", pw->pw_dir, strerror(errno));
michael@428 185 }
michael@428 186 }
michael@428 187
michael@428 188 return;
michael@428 189 }
michael@428 190
michael@428 191 /* check whether caller is an explictly configured management user */
michael@428 192 static int check_whether_is_manager(uid_t my_uid, gid_t my_gid, uid_t m_uid, gid_t m_gid)
michael@428 193 {
michael@428 194 char buf[1024];
michael@428 195 char *username;
michael@428 196 char *groupname;
michael@428 197 char *filename;
michael@428 198 struct stat sb;
michael@428 199 char *cp;
michael@428 200 FILE *fp;
michael@428 201 struct passwd *pw;
michael@428 202 struct group *gr;
michael@428 203 int i;
michael@428 204 int ok_uid;
michael@428 205 int ok_gid;
michael@428 206 int is_manager;
michael@428 207
michael@428 208 is_manager = 0;
michael@428 209
michael@428 210 /* path to the managers configuration file */
michael@428 211 filename = OPENPKG_PREFIX "/etc/openpkg/managers";
michael@428 212
michael@428 213 /* check permissions of file */
michael@428 214 if (stat(filename, &sb) == -1) {
michael@428 215 warn("unable to determine information about configuration"
michael@428 216 " file \"%s\": %s -- ignoring file", filename, strerror(errno));
michael@428 217 return 0;
michael@428 218 }
michael@428 219 if (sb.st_uid != m_uid) {
michael@428 220 warn("invalid owner user id %d (expected %d) on configuration"
michael@428 221 " file \"%s\" -- ignoring file", sb.st_uid, m_uid, filename);
michael@428 222 return 0;
michael@428 223 }
michael@428 224 if (sb.st_gid != m_gid) {
michael@428 225 warn("invalid owner group id %d (expected %d) on configuration"
michael@428 226 " file \"%s\" -- ignoring file", sb.st_gid, m_gid, filename);
michael@428 227 return 0;
michael@428 228 }
michael@428 229 if (sb.st_mode != (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) {
michael@428 230 warn("invalid permissions on configuration"
michael@428 231 " file \"%s\" -- ignoring file", filename);
michael@428 232 return 0;
michael@428 233 }
michael@428 234
michael@428 235 /* parse configuration file */
michael@428 236 if ((fp = fopen(filename, "r")) == NULL) {
michael@428 237 warn("unable to open configuration file \"%s\": %s -- ignoring file", filename, strerror(errno));
michael@428 238 return 0;
michael@428 239 }
michael@428 240 while ((cp = fgets(buf, sizeof(buf), fp)) != NULL) {
michael@428 241 /* parse entry as "<username>[:<groupname>]" where both
michael@428 242 <username> and <groupname> can be set and default to "*"
michael@428 243 to indicate an arbitrary user or group */
michael@428 244 if ((i = strlen(buf)) == 0) {
michael@428 245 warn("unexpected empty buffer during parsing of configuration file \"%\"", filename);
michael@428 246 break;
michael@428 247 }
michael@428 248 if (i >= sizeof(buf)) {
michael@428 249 warn("unexpected buffer overflow during parsing of configuration file \"%\"", filename);
michael@428 250 break;
michael@428 251 }
michael@428 252 if (buf[i-1] != '\r' && buf[i-1] != '\n') {
michael@428 253 warn("unexpected non-newline-terminated line found during parsing of configuration file \"%\"", filename);
michael@428 254 break;
michael@428 255 }
michael@428 256 username = buf + strspn(buf, " \t");
michael@428 257 cp = username + strcspn(username, " \t#\r\n");
michael@428 258 *cp = '\0';
michael@428 259 if (username[0] == '#' || username[0] == '\r' || username[0] == '\n' || username[0] == '\0')
michael@428 260 continue;
michael@428 261 groupname = "*";
michael@428 262 if ((cp = strchr(username, ':')) != NULL) {
michael@428 263 *cp++ = '\0';
michael@428 264 groupname = cp;
michael@428 265 }
michael@428 266 debug("parsing result: username=\"%s\" groupname=\"%s\"", username, groupname);
michael@428 267
michael@428 268 /* check whether UID is ok */
michael@428 269 ok_uid = 0;
michael@428 270 if (strcmp(username, "*") == 0)
michael@428 271 ok_uid = 1;
michael@428 272 else {
michael@428 273 if ((pw = getpwnam(username)) == NULL) {
michael@428 274 warn("invalid username \"%s\" in \"%s\"", username, filename);
michael@428 275 continue;
michael@428 276 }
michael@428 277 if (pw->pw_uid == my_uid)
michael@428 278 ok_uid = 1;
michael@428 279 }
michael@428 280
michael@428 281 /* check whether GID is ok */
michael@428 282 ok_gid = 0;
michael@428 283 if (strcmp(groupname, "*") == 0)
michael@428 284 ok_gid = 1;
michael@428 285 else {
michael@428 286 if ((gr = getgrnam(groupname)) == NULL) {
michael@428 287 warn("invalid groupname \"%s\" in \"%s\"", groupname, filename);
michael@428 288 continue;
michael@428 289 }
michael@428 290 if (gr->gr_gid == my_gid)
michael@428 291 ok_gid = 1;
michael@428 292 }
michael@428 293
michael@428 294 /* if both UID and GID are ok, user is manager */
michael@428 295 debug("matching: username ok = %s, groupname ok = %s", ok_uid ? "yes" : "no", ok_gid ? "yes" : "no");
michael@428 296 if (ok_uid && ok_gid) {
michael@428 297 is_manager = 1;
michael@428 298 break;
michael@428 299 }
michael@428 300 }
michael@428 301 fclose(fp);
michael@428 302 return is_manager;
michael@428 303 }
michael@428 304
michael@428 305 /* check whether command requires super-user privileges */
michael@428 306 static int check_whether_require_superuser(int argc, char *argv[])
michael@428 307 {
michael@428 308 int require_superuser;
michael@428 309 int i, j;
michael@428 310
michael@428 311 require_superuser = 0;
michael@428 312 if (argc > 1 && strcmp(argv[1], "rpm") == 0) {
michael@428 313 for (i = 2; i < argc; i++) {
michael@428 314 if (strcmp(argv[i], "--") == 0)
michael@428 315 break;
michael@428 316 else if ( strcmp(argv[i], "--erase") == 0
michael@428 317 || strcmp(argv[i], "--freshen") == 0
michael@428 318 || strcmp(argv[i], "--install") == 0
michael@428 319 || strcmp(argv[i], "--upgrade") == 0
michael@428 320 || strcmp(argv[i], "--import") == 0
michael@428 321 || strcmp(argv[i], "--initdb") == 0
michael@428 322 || strcmp(argv[i], "--rebuilddb") == 0
michael@428 323 || strcmp(argv[i], "--db-build") == 0
michael@428 324 || strcmp(argv[i], "--db-rebuild") == 0
michael@428 325 || strcmp(argv[i], "--db-cleanup") == 0
michael@428 326 || strcmp(argv[i], "--db-fixate") == 0
michael@428 327 || strcmp(argv[i], "--setperms") == 0
michael@428 328 || strcmp(argv[i], "--setugids") == 0) {
michael@428 329 require_superuser = 1;
michael@428 330 break;
michael@428 331 }
michael@428 332 else if ( argv[i][0] == '-'
michael@428 333 && argv[i][1] != '-'
michael@428 334 && argv[i][1] != 'b'
michael@428 335 && argv[i][1] != 't'
michael@428 336 ) {
michael@428 337 for (j = 1; argv[i][j] != '\0'; j++) {
michael@428 338 if ( ( argv[i][j] == 'q'
michael@428 339 || argv[i][j] == 'K')
michael@428 340 && argv[i][j+1] != '\0') {
michael@428 341 j++;
michael@428 342 continue;
michael@428 343 }
michael@428 344 else if ( argv[i][j] == 'i'
michael@428 345 || argv[i][j] == 'U'
michael@428 346 || argv[i][j] == 'F'
michael@428 347 || argv[i][j] == 'V'
michael@428 348 || argv[i][j] == 'e') {
michael@428 349 require_superuser = 1;
michael@428 350 break;
michael@428 351 }
michael@428 352 }
michael@428 353 if (require_superuser)
michael@428 354 break;
michael@428 355 }
michael@428 356 }
michael@428 357 }
michael@428 358 else if (argc > 1 && strcmp(argv[1], "rc") == 0) {
michael@428 359 require_superuser = 1;
michael@428 360 for (i = 2; i < argc; i++) {
michael@428 361 if (strcmp(argv[i], "--") == 0)
michael@428 362 break;
michael@428 363 else if ( strcmp(argv[i], "-p") == 0
michael@428 364 || strcmp(argv[i], "--print") == 0
michael@428 365 || strcmp(argv[i], "-e") == 0
michael@428 366 || strcmp(argv[i], "--eval") == 0
michael@428 367 || strcmp(argv[i], "-q") == 0
michael@428 368 || strcmp(argv[i], "--query") == 0
michael@428 369 || strcmp(argv[i], "-c") == 0
michael@428 370 || strcmp(argv[i], "--config") == 0) {
michael@428 371 require_superuser = 0;
michael@428 372 break;
michael@428 373 }
michael@428 374 }
michael@428 375 }
michael@428 376 return require_superuser;
michael@428 377 }
michael@428 378
michael@428 379 /* main program */
michael@428 380 int main(int argc, char **argv, char **envp)
michael@428 381 {
michael@428 382 int keep_original_privileges;
michael@428 383 int is_manager;
michael@428 384 int require_superuser;
michael@428 385 uid_t my_uid, my_euid;
michael@428 386 gid_t my_gid, my_egid;
michael@428 387 uid_t m_uid;
michael@428 388 gid_t m_gid;
michael@428 389 uid_t s_uid;
michael@428 390 gid_t s_gid;
michael@428 391 struct passwd *pw;
michael@428 392 struct group *gr;
michael@428 393 int dry_run;
michael@428 394 int license;
michael@428 395
michael@428 396 /* parse command line options */
michael@428 397 license = 0;
michael@428 398 dry_run = 0;
michael@428 399 keep_original_privileges = 0;
michael@428 400 if (argc <= 0)
michael@428 401 abort();
michael@428 402 argv++; argc--;
michael@428 403 while (argc > 0) {
michael@428 404 if (argv[0][0] != '-')
michael@428 405 break;
michael@428 406 else if (strcmp(argv[0], "--") == 0) {
michael@428 407 argv++; argc--;
michael@428 408 break;
michael@428 409 }
michael@428 410 else if (strcmp(argv[0], "--license") == 0) {
michael@428 411 license = 1;
michael@428 412 argv++; argc--;
michael@428 413 continue;
michael@428 414 }
michael@428 415 else if (strcmp(argv[0], "--debug") == 0) {
michael@428 416 debug_enable = 1;
michael@428 417 argv++; argc--;
michael@428 418 continue;
michael@428 419 }
michael@428 420 else if (strcmp(argv[0], "--dry-run") == 0) {
michael@428 421 dry_run = 1;
michael@428 422 argv++; argc--;
michael@428 423 continue;
michael@428 424 }
michael@428 425 else if (strcmp(argv[0], "--keep-privileges") == 0) {
michael@428 426 keep_original_privileges = 1;
michael@428 427 argv++; argc--;
michael@428 428 continue;
michael@428 429 }
michael@428 430 break;
michael@428 431 }
michael@428 432 argv--; argc++;
michael@428 433
michael@428 434 /* display stand-alone license information */
michael@428 435 if (license) {
michael@428 436 fprintf(stdout, "%s", LICENSE);
michael@428 437 exit(0);
michael@428 438 }
michael@428 439
michael@428 440 /* determine our current real and effective user/group ids */
michael@428 441 my_uid = getuid();
michael@428 442 my_gid = getgid();
michael@428 443 my_euid = geteuid();
michael@428 444 my_egid = getegid();
michael@428 445 if ((pw = getpwuid(my_uid)) == NULL)
michael@428 446 fatal("unable to resolve current user id %d: %s", my_uid, strerror(errno));
michael@428 447 if ((gr = getgrgid(my_gid)) == NULL)
michael@428 448 fatal("unable to resolve current group id %d: %s", my_gid, strerror(errno));
michael@428 449 debug("current-user: usr=%s uid=%d euid=%d grp=%s gid=%d egid=%d",
michael@428 450 pw->pw_name, my_uid, my_euid, gr->gr_name, my_gid, my_egid);
michael@428 451
michael@428 452 /* determine super user/group id */
michael@428 453 if ((pw = getpwnam(OPENPKG_SUSR)) == NULL)
michael@428 454 fatal("unable to resolve OpenPKG superuser username \"%s\": %s", OPENPKG_SUSR, strerror(errno));
michael@428 455 s_uid = pw->pw_uid;
michael@428 456 s_gid = pw->pw_gid;
michael@428 457 debug("super-user: s_usr=%s s_uid=%d s_gid=%d", OPENPKG_SUSR, s_uid, s_gid);
michael@428 458
michael@428 459 /* determine management user/group id */
michael@428 460 if ((pw = getpwnam(OPENPKG_MUSR)) == NULL)
michael@428 461 fatal("unable to resolve OpenPKG management username \"%s\": %s", OPENPKG_MUSR, strerror(errno));
michael@428 462 m_uid = pw->pw_uid;
michael@428 463 m_gid = pw->pw_gid;
michael@428 464 debug("management-user: m_grp=%s m_uid=%d m_gid=%d", OPENPKG_MUSR, m_uid, m_gid);
michael@428 465
michael@428 466 /* determine whether caller is explicitly configured as a management user */
michael@428 467 is_manager = 0;
michael@428 468 if (!keep_original_privileges)
michael@428 469 is_manager = check_whether_is_manager(my_uid, my_gid, m_uid, m_gid);
michael@428 470 debug("current user is manager: %s", is_manager ? "yes" : "no");
michael@428 471
michael@428 472 /* determine whether command requires super-user privileges */
michael@428 473 require_superuser = check_whether_require_superuser(argc, argv);
michael@428 474 debug("current command requires super user privileges: %s", require_superuser ? "yes" : "no");
michael@428 475
michael@428 476 /* adjust privileges according to determined information */
michael@428 477 if (!keep_original_privileges && require_superuser && is_manager && my_euid == 0) {
michael@428 478 /* increase privileges to super user */
michael@428 479 debug("increase privileges to super user");
michael@428 480 adjust_privileges(s_uid, s_gid, 1);
michael@428 481 }
michael@428 482 else if (!keep_original_privileges && !require_superuser && is_manager && my_euid == 0) {
michael@428 483 /* decrease privileges to management user */
michael@428 484 debug("decrease privileges to management user");
michael@428 485 adjust_privileges(m_uid, m_gid, 1);
michael@428 486 }
michael@428 487 else /* keep_original_privileges || !is_manager */ {
michael@428 488 /* drop effective privileges for current user*/
michael@428 489 debug("drop effective privileges for current user");
michael@428 490 adjust_privileges(my_uid, my_gid, 0);
michael@428 491 }
michael@428 492
michael@428 493 /* pass-through control to real Execution Frontend (shell script) */
michael@428 494 argv[0] = OPENPKG_PREFIX "/lib/openpkg/openpkg";
michael@428 495 debug("execute \"%s\"", argv[0]);
michael@428 496 if (!dry_run) {
michael@428 497 if (execve(argv[0], argv, envp) == -1)
michael@428 498 fatal("failed to execute \"%s\": %s", argv[0], strerror(errno));
michael@428 499 /* NOT REACHED */
michael@428 500 fatal("INTERNAL ERROR");
michael@428 501 }
michael@428 502 return 0;
michael@428 503 }
michael@428 504

mercurial