/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

  • Committer: Teddy Hogeborn
  • Date: 2009-11-03 00:12:35 UTC
  • Revision ID: teddy@fukt.bsnet.se-20091103001235-op9jfvtx6xvxch3h
* README (FAQ): Fix typo.
* mandos (main): Try to always do cleanup() before exit, since
                 otherwise the D-Bus bus name gets unregistered first.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <fcntl.h>              /* open(), O_WRONLY, O_RDONLY */
32
32
#include <iso646.h>             /* and, or, not*/
33
33
#include <errno.h>              /* errno, EINTR */
34
 
#include <error.h>
35
34
#include <sys/types.h>          /* size_t, ssize_t, pid_t, DIR, struct
36
35
                                   dirent */
37
36
#include <stddef.h>             /* NULL */
38
37
#include <string.h>             /* strlen(), memcmp() */
39
 
#include <stdio.h>              /* asprintf()*/
 
38
#include <stdio.h>              /* asprintf(), perror() */
40
39
#include <unistd.h>             /* close(), write(), readlink(),
41
40
                                   read(), STDOUT_FILENO, sleep(),
42
41
                                   fork(), setuid(), geteuid(),
43
42
                                   setsid(), chdir(), dup2(),
44
43
                                   STDERR_FILENO, execv() */
45
44
#include <stdlib.h>             /* free(), EXIT_FAILURE, realloc(),
46
 
                                   EXIT_SUCCESS, malloc(), _exit(),
47
 
                                   getenv() */
 
45
                                   EXIT_SUCCESS, malloc(), _exit() */
 
46
#include <stdlib.h>             /* getenv() */
48
47
#include <dirent.h>             /* opendir(), readdir(), closedir() */
49
48
#include <inttypes.h>           /* intmax_t, strtoimax() */
50
49
#include <sys/stat.h>           /* struct stat, lstat(), S_ISLNK */
154
153
  size_t cmdline_len = 0;
155
154
  DIR *proc_dir = opendir("/proc");
156
155
  if(proc_dir == NULL){
157
 
    error(0, errno, "opendir");
 
156
    perror("opendir");
158
157
    return -1;
159
158
  }
160
159
  errno = 0;
182
181
      char *exe_link;
183
182
      ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name);
184
183
      if(ret == -1){
185
 
        error(0, errno, "asprintf");
 
184
        perror("asprintf");
186
185
        goto fail_find_usplash;
187
186
      }
188
187
      
194
193
          free(exe_link);
195
194
          continue;
196
195
        }
197
 
        error(0, errno, "lstat");
 
196
        perror("lstat");
198
197
        free(exe_link);
199
198
        goto fail_find_usplash;
200
199
      }
225
224
        ret = asprintf(&cmdline_filename, "/proc/%s/cmdline",
226
225
                       proc_ent->d_name);
227
226
        if(ret == -1){
228
 
          error(0, errno, "asprintf");
 
227
          perror("asprintf");
229
228
          goto fail_find_usplash;
230
229
        }
231
230
        cl_fd = open(cmdline_filename, O_RDONLY);
232
231
        free(cmdline_filename);
233
232
        if(cl_fd == -1){
234
 
          error(0, errno, "open");
 
233
          perror("open");
235
234
          goto fail_find_usplash;
236
235
        }
237
236
      }
243
242
        if(cmdline_len + blocksize > cmdline_allocated){
244
243
          tmp = realloc(cmdline, cmdline_allocated + blocksize);
245
244
          if(tmp == NULL){
246
 
            error(0, errno, "realloc");
 
245
            perror("realloc");
247
246
            close(cl_fd);
248
247
            goto fail_find_usplash;
249
248
          }
254
253
        sret = read(cl_fd, cmdline + cmdline_len,
255
254
                    cmdline_allocated - cmdline_len);
256
255
        if(sret == -1){
257
 
          error(0, errno, "read");
 
256
          perror("read");
258
257
          close(cl_fd);
259
258
          goto fail_find_usplash;
260
259
        }
262
261
      } while(sret != 0);
263
262
      ret = close(cl_fd);
264
263
      if(ret == -1){
265
 
        error(0, errno, "close");
 
264
        perror("close");
266
265
        goto fail_find_usplash;
267
266
      }
268
267
    }
269
268
    /* Close directory */
270
269
    ret = closedir(proc_dir);
271
270
    if(ret == -1){
272
 
      error(0, errno, "closedir");
 
271
      perror("closedir");
273
272
      goto fail_find_usplash;
274
273
    }
275
274
    /* Success */
324
323
    sigemptyset(&new_action.sa_mask);
325
324
    ret = sigaddset(&new_action.sa_mask, SIGINT);
326
325
    if(ret == -1){
327
 
      error(0, errno, "sigaddset");
 
326
      perror("sigaddset");
328
327
      status = EX_OSERR;
329
328
      goto failure;
330
329
    }
331
330
    ret = sigaddset(&new_action.sa_mask, SIGHUP);
332
331
    if(ret == -1){
333
 
      error(0, errno, "sigaddset");
 
332
      perror("sigaddset");
334
333
      status = EX_OSERR;
335
334
      goto failure;
336
335
    }
337
336
    ret = sigaddset(&new_action.sa_mask, SIGTERM);
338
337
    if(ret == -1){
339
 
      error(0, errno, "sigaddset");
 
338
      perror("sigaddset");
340
339
      status = EX_OSERR;
341
340
      goto failure;
342
341
    }
343
342
    ret = sigaction(SIGINT, NULL, &old_action);
344
343
    if(ret == -1){
345
344
      if(errno != EINTR){
346
 
        error(0, errno, "sigaction");
 
345
        perror("sigaction");
347
346
        status = EX_OSERR;
348
347
      }
349
348
      goto failure;
352
351
      ret = sigaction(SIGINT, &new_action, NULL);
353
352
      if(ret == -1){
354
353
        if(errno != EINTR){
355
 
          error(0, errno, "sigaction");
 
354
          perror("sigaction");
356
355
          status = EX_OSERR;
357
356
        }
358
357
        goto failure;
361
360
    ret = sigaction(SIGHUP, NULL, &old_action);
362
361
    if(ret == -1){
363
362
      if(errno != EINTR){
364
 
        error(0, errno, "sigaction");
 
363
        perror("sigaction");
365
364
        status = EX_OSERR;
366
365
      }
367
366
      goto failure;
370
369
      ret = sigaction(SIGHUP, &new_action, NULL);
371
370
      if(ret == -1){
372
371
        if(errno != EINTR){
373
 
          error(0, errno, "sigaction");
 
372
          perror("sigaction");
374
373
          status = EX_OSERR;
375
374
        }
376
375
        goto failure;
379
378
    ret = sigaction(SIGTERM, NULL, &old_action);
380
379
    if(ret == -1){
381
380
      if(errno != EINTR){
382
 
        error(0, errno, "sigaction");
 
381
        perror("sigaction");
383
382
        status = EX_OSERR;
384
383
      }
385
384
      goto failure;
388
387
      ret = sigaction(SIGTERM, &new_action, NULL);
389
388
      if(ret == -1){
390
389
        if(errno != EINTR){
391
 
          error(0, errno, "sigaction");
 
390
          perror("sigaction");
392
391
          status = EX_OSERR;
393
392
        }
394
393
        goto failure;
400
399
  /* Write command to FIFO */
401
400
  if(not usplash_write(&fifo_fd, "TIMEOUT", "0")){
402
401
    if(errno != EINTR){
403
 
      error(0, errno, "usplash_write");
 
402
      perror("usplash_write");
404
403
      status = EX_OSERR;
405
404
    }
406
405
    goto failure;
412
411
  
413
412
  if(not usplash_write(&fifo_fd, "INPUTQUIET", prompt)){
414
413
    if(errno != EINTR){
415
 
      error(0, errno, "usplash_write");
 
414
      perror("usplash_write");
416
415
      status = EX_OSERR;
417
416
    }
418
417
    goto failure;
430
429
  outfifo_fd = open("/dev/.initramfs/usplash_outfifo", O_RDONLY);
431
430
  if(outfifo_fd == -1){
432
431
    if(errno != EINTR){
433
 
      error(0, errno, "open");
 
432
      perror("open");
434
433
      status = EX_OSERR;
435
434
    }
436
435
    goto failure;
449
448
      char *tmp = realloc(buf, buf_allocated + blocksize);
450
449
      if(tmp == NULL){
451
450
        if(errno != EINTR){
452
 
          error(0, errno, "realloc");
 
451
          perror("realloc");
453
452
          status = EX_OSERR;
454
453
        }
455
454
        goto failure;
461
460
                buf_allocated - buf_len);
462
461
    if(sret == -1){
463
462
      if(errno != EINTR){
464
 
        error(0, errno, "read");
 
463
        perror("read");
465
464
        status = EX_OSERR;
466
465
      }
467
466
      TEMP_FAILURE_RETRY(close(outfifo_fd));
476
475
  ret = close(outfifo_fd);
477
476
  if(ret == -1){
478
477
    if(errno != EINTR){
479
 
      error(0, errno, "close");
 
478
      perror("close");
480
479
      status = EX_OSERR;
481
480
    }
482
481
    goto failure;
489
488
  
490
489
  if(not usplash_write(&fifo_fd, "TIMEOUT", "15")){
491
490
    if(errno != EINTR){
492
 
      error(0, errno, "usplash_write");
 
491
      perror("usplash_write");
493
492
      status = EX_OSERR;
494
493
    }
495
494
    goto failure;
502
501
  ret = close(fifo_fd);
503
502
  if(ret == -1){
504
503
    if(errno != EINTR){
505
 
      error(0, errno, "close");
 
504
      perror("close");
506
505
      status = EX_OSERR;
507
506
    }
508
507
    goto failure;
516
515
      sret = write(STDOUT_FILENO, buf + written, buf_len - written);
517
516
      if(sret == -1){
518
517
        if(errno != EINTR){
519
 
          error(0, errno, "write");
 
518
          perror("write");
520
519
          status = EX_OSERR;
521
520
        }
522
521
        goto failure;
553
552
  if(fifo_fd != -1){
554
553
    ret = (int)TEMP_FAILURE_RETRY(close(fifo_fd));
555
554
    if(ret == -1 and errno != EINTR){
556
 
      error(0, errno, "close");
 
555
      perror("close");
557
556
    }
558
557
    fifo_fd = -1;
559
558
  }
562
561
  if(outfifo_fd != -1){
563
562
    ret = (int)TEMP_FAILURE_RETRY(close(outfifo_fd));
564
563
    if(ret == -1){
565
 
      error(0, errno, "close");
 
564
      perror("close");
566
565
    }
567
566
  }
568
567
  
576
575
                           (sizeof(char *)
577
576
                            * (size_t)(cmdline_argc + 2)));
578
577
      if(tmp == NULL){
579
 
        error(0, errno, "realloc");
 
578
        perror("realloc");
580
579
        free(cmdline_argv);
581
580
        return status;
582
581
      }
603
602
       the real user ID (_mandos) */
604
603
    ret = setuid(geteuid());
605
604
    if(ret == -1){
606
 
      error(0, errno, "setuid");
 
605
      perror("setuid");
607
606
    }
608
607
    
609
608
    setsid();
610
609
    ret = chdir("/");
611
 
    if(ret == -1){
612
 
      error(0, errno, "chdir");
613
 
      _exit(EX_OSERR);
614
 
    }
615
610
/*     if(fork() != 0){ */
616
611
/*       _exit(EXIT_SUCCESS); */
617
612
/*     } */
618
613
    ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */
619
614
    if(ret == -1){
620
 
      error(0, errno, "dup2");
 
615
      perror("dup2");
621
616
      _exit(EX_OSERR);
622
617
    }
623
618
    
624
619
    execv(usplash_name, cmdline_argv);
625
620
    if(not interrupted_by_signal){
626
 
      error(0, errno, "execv");
 
621
      perror("execv");
627
622
    }
628
623
    free(cmdline);
629
624
    free(cmdline_argv);
634
629
  sleep(2);
635
630
  if(not usplash_write(&fifo_fd, "PULSATE", NULL)){
636
631
    if(errno != EINTR){
637
 
      error(0, errno, "usplash_write");
 
632
      perror("usplash_write");
638
633
    }
639
634
  }
640
635
  
642
637
  if(fifo_fd != -1){
643
638
    ret = (int)TEMP_FAILURE_RETRY(close(fifo_fd));
644
639
    if(ret == -1 and errno != EINTR){
645
 
      error(0, errno, "close");
 
640
      perror("close");
646
641
    }
647
642
    fifo_fd = -1;
648
643
  }
653
648
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
654
649
                                            &signal_action, NULL));
655
650
    if(ret == -1){
656
 
      error(0, errno, "sigaction");
 
651
      perror("sigaction");
657
652
    }
658
653
    do {
659
654
      ret = raise(signal_received);
660
655
    } while(ret != 0 and errno == EINTR);
661
656
    if(ret != 0){
662
 
      error(0, errno, "raise");
 
657
      perror("raise");
663
658
      abort();
664
659
    }
665
660
    TEMP_FAILURE_RETRY(pause());