File indexing completed on 2024-05-05 12:17:40

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #include <config-kdeinit.h>
0009 
0010 #include <stdio.h>
0011 #include <string.h>
0012 #include <unistd.h>
0013 
0014 #define EXECUTE KDE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit"
0015 
0016 #if KDEINIT_OOM_PROTECT
0017 
0018 /*
0019  The start_kdeinit wrapper is setuid, which means some shell variables like LD_LIBRARY_PATH
0020  get unset before it's launched. However kdeinit is used to launch most of KDE, so such variables
0021  should not be dropped. Therefore this wrapper for the setuid wrapper read the environment
0022  and writes it to start_kdeinit's stdin, which after dropping privileges reads it and uses it
0023  for launching the real kdeinit.
0024 */
0025 int main(int argc, char **argv)
0026 {
0027     int pipes[ 2 ];
0028     if (argc == 0) {
0029         return 1;
0030     }
0031     if (pipe(pipes) < 0) {
0032         perror("pipe()");
0033         return 1;
0034     }
0035     switch (fork()) {
0036     case -1:
0037         perror("fork()");
0038         return 1;
0039     default: /* parent, exec */
0040         close(pipes[ 1 ]);
0041         close(0);   /* stdin */
0042         dup2(pipes[ 0 ], 0);
0043         close(pipes[ 0 ]);
0044         argv[ 0 ] = (char *)EXECUTE;
0045         execvp(EXECUTE, argv);
0046         perror("start_kdeinit");
0047         return 1;
0048     case 0: { /* child, pass env and exit */
0049         extern char **environ;
0050         int i;
0051         close(pipes[ 0 ]);
0052         write(pipes[ 1 ], "environ", 7);   /* header, just in case */
0053         for (i = 0;
0054                 environ[ i ] != NULL;
0055                 ++i) {
0056         }
0057         write(pipes[ 1 ], &i, sizeof(int));    /* write count */
0058         for (i = 0;
0059                 environ[ i ] != NULL;
0060                 ++i) {
0061             int len = strlen(environ[ i ]);
0062             write(pipes[ 1 ], &len, sizeof(int));    /* write length */
0063             write(pipes[ 1 ], environ[ i ], strlen(environ[ i ]));
0064         }
0065         close(pipes[ 1 ]);
0066     }
0067     }
0068     return 0;
0069 }
0070 
0071 #else /* not Linux, the simple non-setuid case */
0072 
0073 int main(int argc, char **argv)
0074 {
0075     if (argc == 0) {
0076         return 1;
0077     }
0078     argv[0] = (char *)EXECUTE;
0079     execvp(EXECUTE, argv);
0080     perror("start_kdeinit");
0081     return 1;
0082 }
0083 #endif