aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/profile.c')
-rw-r--r--src/firejail/profile.c130
1 files changed, 67 insertions, 63 deletions
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 9ae2aa5b4..11258892e 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -28,8 +28,8 @@ int profile_find(const char *name, const char *dir) {
28 EUID_ASSERT(); 28 EUID_ASSERT();
29 assert(name); 29 assert(name);
30 assert(dir); 30 assert(dir);
31 31
32 int rv = 0; 32 int rv = 0;
33 DIR *dp; 33 DIR *dp;
34 char *pname; 34 char *pname;
35 if (asprintf(&pname, "%s.profile", name) == -1) 35 if (asprintf(&pname, "%s.profile", name) == -1)
@@ -74,17 +74,17 @@ static void warning_feature_disabled(const char *feature) {
74// return 0 if the command was already executed inside the function 74// return 0 if the command was already executed inside the function
75int profile_check_line(char *ptr, int lineno, const char *fname) { 75int profile_check_line(char *ptr, int lineno, const char *fname) {
76 EUID_ASSERT(); 76 EUID_ASSERT();
77 77
78 // check ignore list 78 // check ignore list
79 int i; 79 int i;
80 for (i = 0; i < MAX_PROFILE_IGNORE; i++) { 80 for (i = 0; i < MAX_PROFILE_IGNORE; i++) {
81 if (cfg.profile_ignore[i] == NULL) 81 if (cfg.profile_ignore[i] == NULL)
82 break; 82 break;
83 83
84 if (strncmp(ptr, cfg.profile_ignore[i], strlen(cfg.profile_ignore[i])) == 0) 84 if (strncmp(ptr, cfg.profile_ignore[i], strlen(cfg.profile_ignore[i])) == 0)
85 return 0; // ignore line 85 return 0; // ignore line
86 } 86 }
87 87
88 if (strncmp(ptr, "ignore ", 7) == 0) { 88 if (strncmp(ptr, "ignore ", 7) == 0) {
89 char *str = strdup(ptr + 7); 89 char *str = strdup(ptr + 7);
90 if (*str == '\0') { 90 if (*str == '\0') {
@@ -94,7 +94,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
94 // find an empty entry in profile_ignore array 94 // find an empty entry in profile_ignore array
95 int j; 95 int j;
96 for (j = 0; j < MAX_PROFILE_IGNORE; j++) { 96 for (j = 0; j < MAX_PROFILE_IGNORE; j++) {
97 if (cfg.profile_ignore[j] == NULL) 97 if (cfg.profile_ignore[j] == NULL)
98 break; 98 break;
99 } 99 }
100 if (j >= MAX_PROFILE_IGNORE) { 100 if (j >= MAX_PROFILE_IGNORE) {
@@ -102,18 +102,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
102 exit(1); 102 exit(1);
103 } 103 }
104 // ... and configure it 104 // ... and configure it
105 else 105 else
106 cfg.profile_ignore[j] = str; 106 cfg.profile_ignore[j] = str;
107 107
108 return 0; 108 return 0;
109 } 109 }
110 110
111 // mkdir 111 // mkdir
112 if (strncmp(ptr, "mkdir ", 6) == 0) { 112 if (strncmp(ptr, "mkdir ", 6) == 0) {
113 fs_mkdir(ptr + 6); 113 fs_mkdir(ptr + 6);
114 return 1; // process mkdir again while applying blacklists 114 return 1; // process mkdir again while applying blacklists
115 } 115 }
116 // mkfile 116 // mkfile
117 if (strncmp(ptr, "mkfile ", 7) == 0) { 117 if (strncmp(ptr, "mkfile ", 7) == 0) {
118 fs_mkfile(ptr + 7); 118 fs_mkfile(ptr + 7);
119 return 1; // process mkfile again while applying blacklists 119 return 1; // process mkfile again while applying blacklists
@@ -166,7 +166,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
166 else if (strcmp(ptr, "shell none") == 0) { 166 else if (strcmp(ptr, "shell none") == 0) {
167 arg_shell_none = 1; 167 arg_shell_none = 1;
168 return 0; 168 return 0;
169 } 169 }
170 else if (strcmp(ptr, "tracelog") == 0) { 170 else if (strcmp(ptr, "tracelog") == 0) {
171 arg_tracelog = 1; 171 arg_tracelog = 1;
172 return 0; 172 return 0;
@@ -210,6 +210,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
210 arg_nosound = 1; 210 arg_nosound = 1;
211 return 0; 211 return 0;
212 } 212 }
213 else if (strcmp(ptr, "novideo") == 0) {
214 arg_novideo = 1;
215 return 0;
216 }
213 else if (strcmp(ptr, "no3d") == 0) { 217 else if (strcmp(ptr, "no3d") == 0) {
214 arg_no3d = 1; 218 arg_no3d = 1;
215 return 0; 219 return 0;
@@ -217,7 +221,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
217 else if (strcmp(ptr, "allow-private-blacklist") == 0) { 221 else if (strcmp(ptr, "allow-private-blacklist") == 0) {
218 arg_allow_private_blacklist = 1; 222 arg_allow_private_blacklist = 1;
219 return 0; 223 return 0;
220 } 224 }
221 else if (strcmp(ptr, "netfilter") == 0) { 225 else if (strcmp(ptr, "netfilter") == 0) {
222#ifdef HAVE_NETWORK 226#ifdef HAVE_NETWORK
223 if (checkcfg(CFG_NETWORK)) 227 if (checkcfg(CFG_NETWORK))
@@ -288,7 +292,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
288 fprintf(stderr, "Error: only \"net none\" is allowed to non-root users\n"); 292 fprintf(stderr, "Error: only \"net none\" is allowed to non-root users\n");
289 exit(1); 293 exit(1);
290 } 294 }
291 295
292 if (strcmp(ptr + 4, "lo") == 0) { 296 if (strcmp(ptr + 4, "lo") == 0) {
293 fprintf(stderr, "Error: cannot attach to lo device\n"); 297 fprintf(stderr, "Error: cannot attach to lo device\n");
294 exit(1); 298 exit(1);
@@ -314,7 +318,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
314#endif 318#endif
315 return 0; 319 return 0;
316 } 320 }
317 321
318 else if (strncmp(ptr, "veth-name ", 10) == 0) { 322 else if (strncmp(ptr, "veth-name ", 10) == 0) {
319#ifdef HAVE_NETWORK 323#ifdef HAVE_NETWORK
320 if (checkcfg(CFG_NETWORK)) { 324 if (checkcfg(CFG_NETWORK)) {
@@ -365,7 +369,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
365 } 369 }
366 *secondip = '\0'; 370 *secondip = '\0';
367 secondip++; 371 secondip++;
368 372
369 // check addresses 373 // check addresses
370 if (atoip(firstip, &br->iprange_start) || atoip(secondip, &br->iprange_end) || 374 if (atoip(firstip, &br->iprange_start) || atoip(secondip, &br->iprange_end) ||
371 br->iprange_start >= br->iprange_end) { 375 br->iprange_start >= br->iprange_end) {
@@ -392,7 +396,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
392 fprintf(stderr, "Error: no network device configured\n"); 396 fprintf(stderr, "Error: no network device configured\n");
393 exit(1); 397 exit(1);
394 } 398 }
395 399
396 if (mac_not_zero(br->macsandbox)) { 400 if (mac_not_zero(br->macsandbox)) {
397 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n"); 401 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
398 exit(1); 402 exit(1);
@@ -418,7 +422,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
418 fprintf(stderr, "Error: no network device configured\n"); 422 fprintf(stderr, "Error: no network device configured\n");
419 exit(1); 423 exit(1);
420 } 424 }
421 425
422 if (sscanf(ptr + 4, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) { 426 if (sscanf(ptr + 4, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
423 fprintf(stderr, "Error: invalid mtu value\n"); 427 fprintf(stderr, "Error: invalid mtu value\n");
424 exit(1); 428 exit(1);
@@ -479,7 +483,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
479// fprintf(stderr, "Error: invalid IP address\n"); 483// fprintf(stderr, "Error: invalid IP address\n");
480// exit(1); 484// exit(1);
481// } 485// }
482 486
483 } 487 }
484 else 488 else
485 warning_feature_disabled("networking"); 489 warning_feature_disabled("networking");
@@ -502,7 +506,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
502 } 506 }
503 507
504 if (strcmp(ptr, "apparmor") == 0) { 508 if (strcmp(ptr, "apparmor") == 0) {
505#ifdef HAVE_APPARMOR 509#ifdef HAVE_APPARMOR
506 arg_apparmor = 1; 510 arg_apparmor = 1;
507#endif 511#endif
508 return 0; 512 return 0;
@@ -515,7 +519,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
515 fwarning("a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9); 519 fwarning("a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9);
516 return 0; 520 return 0;
517 } 521 }
518 522
519 // store list 523 // store list
520 cfg.protocol = strdup(ptr + 9); 524 cfg.protocol = strdup(ptr + 9);
521 if (!cfg.protocol) 525 if (!cfg.protocol)
@@ -526,7 +530,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
526#endif 530#endif
527 return 0; 531 return 0;
528 } 532 }
529 533
530 if (strncmp(ptr, "env ", 4) == 0) { 534 if (strncmp(ptr, "env ", 4) == 0) {
531 env_store(ptr + 4, SETENV); 535 env_store(ptr + 4, SETENV);
532 return 0; 536 return 0;
@@ -535,7 +539,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
535 env_store(ptr + 6, RMENV); 539 env_store(ptr + 6, RMENV);
536 return 0; 540 return 0;
537 } 541 }
538 542
539 // seccomp drop list on top of default list 543 // seccomp drop list on top of default list
540 if (strncmp(ptr, "seccomp ", 8) == 0) { 544 if (strncmp(ptr, "seccomp ", 8) == 0) {
541#ifdef HAVE_SECCOMP 545#ifdef HAVE_SECCOMP
@@ -549,7 +553,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
549 553
550 return 0; 554 return 0;
551 } 555 }
552 556
553 // seccomp drop list without default list 557 // seccomp drop list without default list
554 if (strncmp(ptr, "seccomp.drop ", 13) == 0) { 558 if (strncmp(ptr, "seccomp.drop ", 13) == 0) {
555#ifdef HAVE_SECCOMP 559#ifdef HAVE_SECCOMP
@@ -559,7 +563,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
559 } 563 }
560 else 564 else
561 warning_feature_disabled("seccomp"); 565 warning_feature_disabled("seccomp");
562#endif 566#endif
563 return 0; 567 return 0;
564 } 568 }
565 569
@@ -572,10 +576,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
572 } 576 }
573 else 577 else
574 warning_feature_disabled("seccomp"); 578 warning_feature_disabled("seccomp");
575#endif 579#endif
576 return 0; 580 return 0;
577 } 581 }
578 582
579 // caps drop list 583 // caps drop list
580 if (strncmp(ptr, "caps.drop ", 10) == 0) { 584 if (strncmp(ptr, "caps.drop ", 10) == 0) {
581 arg_caps_drop = 1; 585 arg_caps_drop = 1;
@@ -586,7 +590,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
586 caps_check_list(arg_caps_list, NULL); 590 caps_check_list(arg_caps_list, NULL);
587 return 0; 591 return 0;
588 } 592 }
589 593
590 // caps keep list 594 // caps keep list
591 if (strncmp(ptr, "caps.keep ", 10) == 0) { 595 if (strncmp(ptr, "caps.keep ", 10) == 0) {
592 arg_caps_keep = 1; 596 arg_caps_keep = 1;
@@ -603,13 +607,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
603 cfg.hostname = ptr + 9; 607 cfg.hostname = ptr + 9;
604 return 0; 608 return 0;
605 } 609 }
606 610
607 // hosts-file 611 // hosts-file
608 if (strncmp(ptr, "hosts-file ", 11) == 0) { 612 if (strncmp(ptr, "hosts-file ", 11) == 0) {
609 cfg.hosts_file = fs_check_hosts_file(ptr + 11); 613 cfg.hosts_file = fs_check_hosts_file(ptr + 11);
610 return 0; 614 return 0;
611 } 615 }
612 616
613 // dns 617 // dns
614 if (strncmp(ptr, "dns ", 4) == 0) { 618 if (strncmp(ptr, "dns ", 4) == 0) {
615 uint32_t dns; 619 uint32_t dns;
@@ -617,7 +621,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
617 fprintf(stderr, "Error: invalid DNS server IP address\n"); 621 fprintf(stderr, "Error: invalid DNS server IP address\n");
618 return 1; 622 return 1;
619 } 623 }
620 624
621 if (cfg.dns1 == 0) 625 if (cfg.dns1 == 0)
622 cfg.dns1 = dns; 626 cfg.dns1 = dns;
623 else if (cfg.dns2 == 0) 627 else if (cfg.dns2 == 0)
@@ -630,13 +634,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
630 } 634 }
631 return 0; 635 return 0;
632 } 636 }
633 637
634 // cpu affinity 638 // cpu affinity
635 if (strncmp(ptr, "cpu ", 4) == 0) { 639 if (strncmp(ptr, "cpu ", 4) == 0) {
636 read_cpu_list(ptr + 4); 640 read_cpu_list(ptr + 4);
637 return 0; 641 return 0;
638 } 642 }
639 643
640 // nice value 644 // nice value
641 if (strncmp(ptr, "nice ", 4) == 0) { 645 if (strncmp(ptr, "nice ", 4) == 0) {
642 cfg.nice = atoi(ptr + 5); 646 cfg.nice = atoi(ptr + 5);
@@ -651,7 +655,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
651 set_cgroup(ptr + 7); 655 set_cgroup(ptr + 7);
652 return 0; 656 return 0;
653 } 657 }
654 658
655 // writable-etc 659 // writable-etc
656 if (strcmp(ptr, "writable-etc") == 0) { 660 if (strcmp(ptr, "writable-etc") == 0) {
657 if (cfg.etc_private_keep) { 661 if (cfg.etc_private_keep) {
@@ -661,7 +665,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
661 arg_writable_etc = 1; 665 arg_writable_etc = 1;
662 return 0; 666 return 0;
663 } 667 }
664 668
665 if (strcmp(ptr, "machine-id") == 0) { 669 if (strcmp(ptr, "machine-id") == 0) {
666 arg_machineid = 1; 670 arg_machineid = 1;
667 return 0; 671 return 0;
@@ -675,7 +679,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
675 arg_writable_var_log = 1; 679 arg_writable_var_log = 1;
676 return 0; 680 return 0;
677 } 681 }
678 682
679 // private directory 683 // private directory
680 if (strncmp(ptr, "private ", 8) == 0) { 684 if (strncmp(ptr, "private ", 8) == 0) {
681 cfg.home_private = ptr + 8; 685 cfg.home_private = ptr + 8;
@@ -717,7 +721,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
717#endif 721#endif
718 return 0; 722 return 0;
719 } 723 }
720 724
721 if (strcmp(ptr, "x11 xpra") == 0) { 725 if (strcmp(ptr, "x11 xpra") == 0) {
722#ifdef HAVE_X11 726#ifdef HAVE_X11
723 if (checkcfg(CFG_X11)) { 727 if (checkcfg(CFG_X11)) {
@@ -736,7 +740,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
736#endif 740#endif
737 return 0; 741 return 0;
738 } 742 }
739 743
740 if (strcmp(ptr, "x11 xvfb") == 0) { 744 if (strcmp(ptr, "x11 xvfb") == 0) {
741#ifdef HAVE_X11 745#ifdef HAVE_X11
742 if (checkcfg(CFG_X11)) { 746 if (checkcfg(CFG_X11)) {
@@ -766,15 +770,15 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
766 else { 770 else {
767 // start x11 771 // start x11
768 x11_start(cfg.original_argc, cfg.original_argv); 772 x11_start(cfg.original_argc, cfg.original_argv);
769 exit(0); 773 exit(0);
770 } 774 }
771 } 775 }
772 else 776 else
773 warning_feature_disabled("x11"); 777 warning_feature_disabled("x11");
774#endif 778#endif
775 return 0; 779 return 0;
776 } 780 }
777 781
778 // private /etc list of files and directories 782 // private /etc list of files and directories
779 if (strncmp(ptr, "private-etc ", 12) == 0) { 783 if (strncmp(ptr, "private-etc ", 12) == 0) {
780 if (arg_writable_etc) { 784 if (arg_writable_etc) {
@@ -788,7 +792,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
788 cfg.etc_private_keep = ptr + 12; 792 cfg.etc_private_keep = ptr + 12;
789 } 793 }
790 arg_private_etc = 1; 794 arg_private_etc = 1;
791 795
792 return 0; 796 return 0;
793 } 797 }
794 798
@@ -801,7 +805,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
801 cfg.opt_private_keep = ptr + 12; 805 cfg.opt_private_keep = ptr + 12;
802 } 806 }
803 arg_private_opt = 1; 807 arg_private_opt = 1;
804 808
805 return 0; 809 return 0;
806 } 810 }
807 811
@@ -814,7 +818,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
814 cfg.srv_private_keep = ptr + 12; 818 cfg.srv_private_keep = ptr + 12;
815 } 819 }
816 arg_private_srv = 1; 820 arg_private_srv = 1;
817 821
818 return 0; 822 return 0;
819 } 823 }
820 824
@@ -906,13 +910,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
906 910
907 // filesystem bind 911 // filesystem bind
908 if (strncmp(ptr, "bind ", 5) == 0) { 912 if (strncmp(ptr, "bind ", 5) == 0) {
909#ifdef HAVE_BIND 913#ifdef HAVE_BIND
910 if (checkcfg(CFG_BIND)) { 914 if (checkcfg(CFG_BIND)) {
911 if (getuid() != 0) { 915 if (getuid() != 0) {
912 fprintf(stderr, "Error: --bind option is available only if running as root\n"); 916 fprintf(stderr, "Error: --bind option is available only if running as root\n");
913 exit(1); 917 exit(1);
914 } 918 }
915 919
916 // extract two directories 920 // extract two directories
917 char *dname1 = ptr + 5; 921 char *dname1 = ptr + 5;
918 char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories 922 char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories
@@ -920,7 +924,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
920 fprintf(stderr, "Error: missing second directory for bind\n"); 924 fprintf(stderr, "Error: missing second directory for bind\n");
921 exit(1); 925 exit(1);
922 } 926 }
923 927
924 // check directories 928 // check directories
925 invalid_filename(dname1); 929 invalid_filename(dname1);
926 invalid_filename(dname2); 930 invalid_filename(dname2);
@@ -932,14 +936,14 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
932 fprintf(stderr, "Symbolic links are not allowed for bind command\n"); 936 fprintf(stderr, "Symbolic links are not allowed for bind command\n");
933 exit(1); 937 exit(1);
934 } 938 }
935 939
936 // insert comma back 940 // insert comma back
937 *(dname2 - 1) = ','; 941 *(dname2 - 1) = ',';
938 return 1; 942 return 1;
939 } 943 }
940 else 944 else
941 warning_feature_disabled("bind"); 945 warning_feature_disabled("bind");
942#endif 946#endif
943 return 0; 947 return 0;
944 } 948 }
945 949
@@ -969,8 +973,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
969 fprintf(stderr, "Invalid rlimit option on line %d\n", lineno); 973 fprintf(stderr, "Invalid rlimit option on line %d\n", lineno);
970 exit(1); 974 exit(1);
971 } 975 }
972 976
973 return 0; 977 return 0;
974 } 978 }
975 979
976 if (strncmp(ptr, "join-or-start ", 14) == 0) { 980 if (strncmp(ptr, "join-or-start ", 14) == 0) {
@@ -1005,14 +1009,14 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
1005 else if (strncmp(ptr, "noblacklist ", 12) == 0) 1009 else if (strncmp(ptr, "noblacklist ", 12) == 0)
1006 ptr += 12; 1010 ptr += 12;
1007 else if (strncmp(ptr, "whitelist ", 10) == 0) { 1011 else if (strncmp(ptr, "whitelist ", 10) == 0) {
1008#ifdef HAVE_WHITELIST 1012#ifdef HAVE_WHITELIST
1009 if (checkcfg(CFG_WHITELIST)) { 1013 if (checkcfg(CFG_WHITELIST)) {
1010 arg_whitelist = 1; 1014 arg_whitelist = 1;
1011 ptr += 10; 1015 ptr += 10;
1012 } 1016 }
1013 else 1017 else
1014 return 0; 1018 return 0;
1015#else 1019#else
1016 return 0; 1020 return 0;
1017#endif 1021#endif
1018 } 1022 }
@@ -1058,13 +1062,13 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
1058// add a profile entry in cfg.profile list; use str to populate the list 1062// add a profile entry in cfg.profile list; use str to populate the list
1059void profile_add(char *str) { 1063void profile_add(char *str) {
1060 EUID_ASSERT(); 1064 EUID_ASSERT();
1061 1065
1062 ProfileEntry *prf = malloc(sizeof(ProfileEntry)); 1066 ProfileEntry *prf = malloc(sizeof(ProfileEntry));
1063 if (!prf) 1067 if (!prf)
1064 errExit("malloc"); 1068 errExit("malloc");
1065 memset(prf, 0, sizeof(ProfileEntry)); 1069 memset(prf, 0, sizeof(ProfileEntry));
1066 prf->next = NULL; 1070 prf->next = NULL;
1067 prf->data = str; 1071 prf->data = str;
1068 1072
1069 // add prf to the list 1073 // add prf to the list
1070 if (cfg.profile == NULL) { 1074 if (cfg.profile == NULL) {
@@ -1081,11 +1085,11 @@ void profile_add(char *str) {
1081static int include_level = 0; 1085static int include_level = 0;
1082void profile_read(const char *fname) { 1086void profile_read(const char *fname) {
1083 EUID_ASSERT(); 1087 EUID_ASSERT();
1084 1088
1085 // exit program if maximum include level was reached 1089 // exit program if maximum include level was reached
1086 if (include_level > MAX_INCLUDE_LEVEL) { 1090 if (include_level > MAX_INCLUDE_LEVEL) {
1087 fprintf(stderr, "Error: maximum profile include level was reached\n"); 1091 fprintf(stderr, "Error: maximum profile include level was reached\n");
1088 exit(1); 1092 exit(1);
1089 } 1093 }
1090 1094
1091 // check file 1095 // check file
@@ -1100,7 +1104,7 @@ void profile_read(const char *fname) {
1100 char *ptr = strstr(base, ".local"); 1104 char *ptr = strstr(base, ".local");
1101 if (ptr && strlen(ptr) == 6) 1105 if (ptr && strlen(ptr) == 6)
1102 return; 1106 return;
1103 1107
1104 fprintf(stderr, "Error: cannot access profile file\n"); 1108 fprintf(stderr, "Error: cannot access profile file\n");
1105 exit(1); 1109 exit(1);
1106 } 1110 }
@@ -1114,7 +1118,7 @@ void profile_read(const char *fname) {
1114 return; 1118 return;
1115 } 1119 }
1116 } 1120 }
1117 1121
1118 // open profile file: 1122 // open profile file:
1119 FILE *fp = fopen(fname, "r"); 1123 FILE *fp = fopen(fname, "r");
1120 if (fp == NULL) { 1124 if (fp == NULL) {
@@ -1133,13 +1137,13 @@ void profile_read(const char *fname) {
1133 char *ptr = line_remove_spaces(buf); 1137 char *ptr = line_remove_spaces(buf);
1134 if (ptr == NULL) 1138 if (ptr == NULL)
1135 continue; 1139 continue;
1136 1140
1137 // comments 1141 // comments
1138 if (*ptr == '#' || *ptr == '\0') { 1142 if (*ptr == '#' || *ptr == '\0') {
1139 free(ptr); 1143 free(ptr);
1140 continue; 1144 continue;
1141 } 1145 }
1142 1146
1143 // process quiet 1147 // process quiet
1144 if (strcmp(ptr, "quiet") == 0) { 1148 if (strcmp(ptr, "quiet") == 0) {
1145 arg_quiet = 1; 1149 arg_quiet = 1;
@@ -1155,13 +1159,13 @@ void profile_read(const char *fname) {
1155 // process include 1159 // process include
1156 if (strncmp(ptr, "include ", 8) == 0) { 1160 if (strncmp(ptr, "include ", 8) == 0) {
1157 include_level++; 1161 include_level++;
1158 1162
1159 // extract profile filename and new skip params 1163 // extract profile filename and new skip params
1160 char *newprofile = ptr + 8; // profile name 1164 char *newprofile = ptr + 8; // profile name
1161 1165
1162 // expand ${HOME}/ in front of the new profile file 1166 // expand ${HOME}/ in front of the new profile file
1163 char *newprofile2 = expand_home(newprofile, cfg.homedir); 1167 char *newprofile2 = expand_home(newprofile, cfg.homedir);
1164 1168
1165 // recursivity 1169 // recursivity
1166 profile_read((newprofile2)? newprofile2:newprofile); 1170 profile_read((newprofile2)? newprofile2:newprofile);
1167 include_level--; 1171 include_level--;
@@ -1170,7 +1174,7 @@ void profile_read(const char *fname) {
1170 free(ptr); 1174 free(ptr);
1171 continue; 1175 continue;
1172 } 1176 }
1173 1177
1174 // verify syntax, exit in case of error 1178 // verify syntax, exit in case of error
1175 if (profile_check_line(ptr, lineno, fname)) 1179 if (profile_check_line(ptr, lineno, fname))
1176 profile_add(ptr); 1180 profile_add(ptr);