/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/usplash.c

merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
                                   SIG_IGN, kill(), SIGKILL */
6
6
#include <stdbool.h>            /* bool, false, true */
7
7
#include <fcntl.h>              /* open(), O_WRONLY, O_RDONLY */
8
 
#include <iso646.h>             /* and, or, not*/
9
8
#include <errno.h>              /* errno, EINTR */
10
 
#include <sys/types.h>          /* size_t, ssize_t, pid_t, DIR, struct
11
 
                                   dirent */
 
9
#include <sys/types.h>          /* size_t, ssize_t, pid_t, DIR,
 
10
                                   struct dirent */
12
11
#include <stddef.h>             /* NULL */
13
12
#include <string.h>             /* strlen(), memcmp() */
14
13
#include <stdio.h>              /* asprintf(), perror() */
22
21
                                   _exit() */
23
22
#include <stdlib.h>             /* getenv() */
24
23
#include <dirent.h>             /* opendir(), readdir(), closedir() */
25
 
#include <sys/stat.h>           /* struct stat, lstat(), S_ISLNK */
 
24
 
 
25
 
 
26
 
 
27
#include <iso646.h>             /* and */
 
28
#include <sys/wait.h>           /* waitpid(), WIFEXITED(),
 
29
                                   WEXITSTATUS() */
26
30
 
27
31
sig_atomic_t interrupted_by_signal = 0;
28
32
 
32
36
 
33
37
static bool usplash_write(const char *cmd, const char *arg){
34
38
  /* 
35
 
   * usplash_write("TIMEOUT", "15") will write "TIMEOUT 15\0"
36
 
   * usplash_write("PULSATE", NULL) will write "PULSATE\0"
 
39
   * usplash_write("TIMEOUT", "15"); -> "TIMEOUT 15\0"
 
40
   * usplash_write("PULSATE", NULL); -> "PULSATE\0"
37
41
   * SEE ALSO
38
42
   *         usplash_write(8)
39
43
   */
153
157
         /proc/<pid>/exe link */
154
158
      char exe_target[sizeof(usplash_name)];
155
159
      {
156
 
        /* create file name string */
157
160
        char *exe_link;
158
161
        ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name);
159
162
        if(ret == -1){
162
165
          closedir(proc_dir);
163
166
          return EXIT_FAILURE;
164
167
        }
165
 
        
166
 
        /* Check that it refers to a symlink owned by root:root */
167
 
        struct stat exe_stat;
168
 
        ret = lstat(exe_link, &exe_stat);
169
 
        if(ret == -1){
170
 
          perror("lstat");
171
 
          free(exe_link);
172
 
          free(prompt);
173
 
          closedir(proc_dir);
174
 
          return EXIT_FAILURE;
175
 
        }
176
 
        if(not S_ISLNK(exe_stat.st_mode)
177
 
           or exe_stat.st_uid != 0
178
 
           or exe_stat.st_gid != 0){
179
 
          free(exe_link);
180
 
          continue;
181
 
        }
182
 
        
183
168
        sret = readlink(exe_link, exe_target, sizeof(exe_target));
184
169
        free(exe_link);
185
170
        if(sret == -1){
268
253
      free(prompt);
269
254
      return EXIT_FAILURE;
270
255
    }
271
 
    if(old_action.sa_handler != SIG_IGN){
 
256
    if (old_action.sa_handler != SIG_IGN){
272
257
      ret = sigaction(SIGINT, &new_action, NULL);
273
258
      if(ret == -1){
274
259
        perror("sigaction");
282
267
      free(prompt);
283
268
      return EXIT_FAILURE;
284
269
    }
285
 
    if(old_action.sa_handler != SIG_IGN){
 
270
    if (old_action.sa_handler != SIG_IGN){
286
271
      ret = sigaction(SIGHUP, &new_action, NULL);
287
272
      if(ret == -1){
288
273
        perror("sigaction");
296
281
      free(prompt);
297
282
      return EXIT_FAILURE;
298
283
    }
299
 
    if(old_action.sa_handler != SIG_IGN){
 
284
    if (old_action.sa_handler != SIG_IGN){
300
285
      ret = sigaction(SIGTERM, &new_action, NULL);
301
286
      if(ret == -1){
302
287
        perror("sigaction");
422
407
      return EXIT_SUCCESS;
423
408
    }
424
409
    break;                      /* Big */
425
 
  }                             /* end of non-loop while() */
 
410
  }
426
411
  
427
412
  /* If we got here, an error or interrupt must have happened */
428
413
  
429
 
  /* Create argc and argv for new usplash*/
430
414
  int cmdline_argc = 0;
431
415
  char **cmdline_argv = malloc(sizeof(char *));
 
416
  /* Create argv and argc for new usplash*/
432
417
  {
433
418
    size_t position = 0;
434
419
    while(position < cmdline_len){
448
433
    cmdline_argv[cmdline_argc] = NULL;
449
434
  }
450
435
  /* Kill old usplash */
451
 
  kill(usplash_pid, SIGTERM);
452
 
  sleep(2);
 
436
    kill(usplash_pid, SIGTERM);
 
437
    sleep(2);
453
438
  while(kill(usplash_pid, 0) == 0){
454
439
    kill(usplash_pid, SIGKILL);
455
440
    sleep(1);
461
446
    /* Make the effective user ID (root) the only user ID instead of
462
447
       the real user ID (mandos) */
463
448
    ret = setuid(geteuid());
464
 
    if(ret == -1){
 
449
    if (ret == -1){
465
450
      perror("setuid");
466
451
    }
467
452
    
477
462
    }
478
463
    
479
464
    execv(usplash_name, cmdline_argv);
480
 
    if(not interrupted_by_signal){
481
 
      perror("execv");
482
 
    }
 
465
    perror("execv");
483
466
    free(cmdline);
484
467
    free(cmdline_argv);
485
468
    _exit(EXIT_FAILURE);