openpkg/openpkg.c

Thu, 04 Oct 2012 20:30:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 04 Oct 2012 20:30:05 +0200
changeset 715
c10fb90893b9
permissions
-rw-r--r--

Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.

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