@@ -278,6 +278,8 @@ enum filter {
278278 * Combine fonts.dir and fonts.aliases files.
279279 */
280280 FILTER_FONT ,
281+
282+ FILTER_SERVICE ,
281283 /*
282284 * Pass file through unaltered.
283285 */
@@ -289,6 +291,7 @@ const char *const filter_str[] = {
289291 "bin-restrict" ,
290292 "ini" ,
291293 "font" ,
294+ "service" ,
292295 "pass" ,
293296};
294297
@@ -1715,6 +1718,60 @@ static inline int set_local_stratum(void)
17151718 return 0 ;
17161719}
17171720
1721+ static inline void getattr_ini (struct cfg_entry * cfg , const char * ipath , size_t ipath_len , struct stat * stbuf , int * rv ) {
1722+ if (!S_ISREG (stbuf -> st_mode )) {
1723+ return ;
1724+ }
1725+
1726+ struct back_entry * back ;
1727+ char bpath [PATH_MAX ];
1728+ * rv = loc_first_bpath (cfg , ipath , ipath_len , & back , bpath );
1729+ if (rv < 0 ) {
1730+ * rv = - errno ;
1731+
1732+ return ;
1733+ }
1734+
1735+ FILE * fp = fchroot_fopen_rdonly (deref (back )-> root_fd , bpath );
1736+ if (fp == NULL ) {
1737+ * rv = - errno ;
1738+
1739+ return ;
1740+ }
1741+
1742+ char line [PATH_MAX ];
1743+ while (fgets (line , sizeof (line ), fp ) != NULL ) {
1744+ for (size_t i = 0 ; i < ARRAY_LEN (ini_inject_strat_str );
1745+ i ++ ) {
1746+ /*
1747+ * No ini_inject_strat_len will exceed line's PATH_MAX,
1748+ * this should be safe.
1749+ */
1750+ if (strncmp (line , ini_inject_strat_str [i ],
1751+ ini_inject_strat_len [i ]) != 0 ) {
1752+ continue ;
1753+ }
1754+ stbuf -> st_size += STRAT_PATH_LEN ;
1755+ stbuf -> st_size += strlen (" " );
1756+ stbuf -> st_size += deref (back )-> name_len ;
1757+ stbuf -> st_size += strlen (" " );
1758+ break ;
1759+ }
1760+ for (size_t i = 0 ; i < ARRAY_LEN (ini_expand_path_str );
1761+ i ++ ) {
1762+ if (strncmp (line , ini_expand_path_str [i ],
1763+ ini_expand_path_len [i ]) != 0
1764+ || line [ini_expand_path_len [i ]] !=
1765+ '/' ) {
1766+ continue ;
1767+ }
1768+ stbuf -> st_size += STRATA_ROOT_LEN ;
1769+ stbuf -> st_size += deref (back )-> name_len ;
1770+ }
1771+ }
1772+ fclose (fp );
1773+ }
1774+
17181775static inline int getattr_back (struct cfg_entry * cfg , const char * ipath ,
17191776 size_t ipath_len , struct stat * stbuf )
17201777{
@@ -1741,58 +1798,25 @@ static inline int getattr_back(struct cfg_entry *cfg, const char *ipath,
17411798 }
17421799 break ;
17431800
1744- case FILTER_INI :
1745- if (!S_ISREG (stbuf -> st_mode )) {
1746- break ;
1747- }
1748-
1749- struct back_entry * back ;
1801+ case FILTER_SERVICE :
1802+ ;
1803+ struct back_entry * back ;
17501804 char bpath [PATH_MAX ];
17511805 rv = loc_first_bpath (cfg , ipath , ipath_len , & back , bpath );
17521806 if (rv < 0 ) {
17531807 rv = - errno ;
17541808 break ;
17551809 }
17561810
1757- FILE * fp = fchroot_fopen_rdonly (deref (back )-> root_fd , bpath );
1758- if (fp == NULL ) {
1759- rv = - errno ;
1760- break ;
1761- }
1811+ if (strstr (bpath , "systemd" )) {
1812+ getattr_ini (cfg , ipath , ipath_len , stbuf , & rv );
1813+ }
17621814
1763- char line [PATH_MAX ];
1764- while (fgets (line , sizeof (line ), fp ) != NULL ) {
1765- for (size_t i = 0 ; i < ARRAY_LEN (ini_inject_strat_str );
1766- i ++ ) {
1767- /*
1768- * No ini_inject_strat_len will exceed line's PATH_MAX,
1769- * this should be safe.
1770- */
1771- if (strncmp (line , ini_inject_strat_str [i ],
1772- ini_inject_strat_len [i ]) != 0 ) {
1773- continue ;
1774- }
1775- stbuf -> st_size += STRAT_PATH_LEN ;
1776- stbuf -> st_size += strlen (" " );
1777- stbuf -> st_size += deref (back )-> name_len ;
1778- stbuf -> st_size += strlen (" " );
1779- break ;
1780- }
1781- for (size_t i = 0 ; i < ARRAY_LEN (ini_expand_path_str );
1782- i ++ ) {
1783- if (strncmp (line , ini_expand_path_str [i ],
1784- ini_expand_path_len [i ]) != 0
1785- || line [ini_expand_path_len [i ]] !=
1786- '/' ) {
1787- continue ;
1788- }
1789- stbuf -> st_size += STRATA_ROOT_LEN ;
1790- stbuf -> st_size += deref (back )-> name_len ;
1791- }
1792- }
1793- fclose (fp );
1794- break ;
1815+ break ;
1816+ case FILTER_INI :
1817+ getattr_ini (cfg , ipath , ipath_len , stbuf , & rv );
17951818
1819+ break ;
17961820 case FILTER_FONT :
17971821 ;
17981822 /*
@@ -2078,6 +2102,89 @@ static inline int read_pass(struct cfg_entry *cfg, const char *const ipath,
20782102 return rv ;
20792103}
20802104
2105+ static inline int inject_ini (struct cfg_entry * cfg , const char * ipath , size_t ipath_len , char * buf , size_t size , off_t offset ) {
2106+ struct back_entry * back ;
2107+ char bpath [PATH_MAX ];
2108+ int rv = loc_first_bpath (cfg , ipath , ipath_len , & back , bpath );
2109+ if (rv < 0 ) {
2110+ return - errno ;
2111+ }
2112+
2113+ FILE * fp = fchroot_fopen_rdonly (deref (back )-> root_fd , bpath );
2114+ if (fp == NULL ) {
2115+ return - errno ;
2116+ }
2117+
2118+ size_t wrote = 0 ;
2119+ char line [PATH_MAX ];
2120+ if (offset < 0 ) {
2121+ return - EINVAL ;
2122+ }
2123+
2124+ size_t off = offset ;
2125+ while (fgets (line , sizeof (line ), fp ) != NULL ) {
2126+ int found = 0 ;
2127+ for (size_t i = 0 ; i < ARRAY_LEN (ini_inject_strat_str );
2128+ i ++ ) {
2129+ if (strncmp (line , ini_inject_strat_str [i ],
2130+ ini_inject_strat_len [i ]) != 0 ) {
2131+ continue ;
2132+ }
2133+ strcatoff (buf , ini_inject_strat_str [i ],
2134+ ini_inject_strat_len [i ], & off , & wrote ,
2135+ size );
2136+ strcatoff (buf , STRAT_PATH , STRAT_PATH_LEN , & off ,
2137+ & wrote , size );
2138+ strcatoff (buf , " " , 1 , & off , & wrote , size );
2139+ strcatoff (buf , deref (back )-> name ,
2140+ deref (back )-> name_len , & off , & wrote ,
2141+ size );
2142+ strcatoff (buf , " " , 1 , & off , & wrote , size );
2143+ strcatoff (buf , line + ini_inject_strat_len [i ],
2144+ strlen (line + ini_inject_strat_len [i ]),
2145+ & off , & wrote , size );
2146+ found = 1 ;
2147+ break ;
2148+ }
2149+ for (size_t i = 0 ; i < ARRAY_LEN (ini_expand_path_str );
2150+ i ++ ) {
2151+ if (strncmp (line , ini_expand_path_str [i ],
2152+ ini_expand_path_len [i ]) != 0
2153+ || line [ini_expand_path_len [i ]] !=
2154+ '/' ) {
2155+ continue ;
2156+ }
2157+ strcatoff (buf , ini_expand_path_str [i ],
2158+ ini_expand_path_len [i ], & off , & wrote ,
2159+ size );
2160+ strcatoff (buf , STRATA_ROOT , STRATA_ROOT_LEN ,
2161+ & off , & wrote , size );
2162+ strcatoff (buf , deref (back )-> name ,
2163+ deref (back )-> name_len , & off , & wrote ,
2164+ size );
2165+ strcatoff (buf , line + ini_expand_path_len [i ],
2166+ strlen (line + ini_expand_path_len [i ]),
2167+ & off , & wrote , size );
2168+ found = 1 ;
2169+ }
2170+ if (!found ) {
2171+ strcatoff (buf , line , strlen (line ), & off ,
2172+ & wrote , size );
2173+ }
2174+ if (wrote >= size ) {
2175+ break ;
2176+ }
2177+ }
2178+ rv = wrote ;
2179+ fclose (fp );
2180+
2181+ return rv ;
2182+ }
2183+
2184+ static inline int read_systemd_service (struct cfg_entry * cfg , const char * const ipath , size_t ipath_len , char * buf , size_t size , off_t offset ) {
2185+ return inject_ini (cfg , ipath , ipath_len , buf , size , offset );
2186+ }
2187+
20812188static inline int read_back (struct cfg_entry * cfg , const char * ipath , size_t
20822189 ipath_len , char * buf , size_t size , off_t offset )
20832190{
@@ -2089,84 +2196,26 @@ static inline int read_back(struct cfg_entry *cfg, const char *ipath, size_t
20892196 rv = pread (bouncer_fd , buf , size , offset );
20902197 break ;
20912198
2092- case FILTER_INI :
2093- ;
2094- struct back_entry * back ;
2199+ case FILTER_SERVICE :
2200+ ;
2201+ struct back_entry * back ;
20952202 char bpath [PATH_MAX ];
20962203 rv = loc_first_bpath (cfg , ipath , ipath_len , & back , bpath );
20972204 if (rv < 0 ) {
20982205 rv = - errno ;
20992206 break ;
21002207 }
21012208
2102- FILE * fp = fchroot_fopen_rdonly ( deref ( back ) -> root_fd , bpath );
2103- if ( fp == NULL ) {
2104- rv = - errno ;
2105- break ;
2106- }
2209+ if ( strstr ( bpath , "systemd" )) {
2210+ rv = read_systemd_service ( cfg , ipath , ipath_len , buf , size , offset );
2211+ } else {
2212+ rv = read_pass ( cfg , ipath , ipath_len , buf , size , offset ) ;
2213+ }
21072214
2108- size_t wrote = 0 ;
2109- char line [PATH_MAX ];
2110- if (offset < 0 ) {
2111- rv = - EINVAL ;
2112- break ;
2113- }
2114- size_t off = offset ;
2115- while (fgets (line , sizeof (line ), fp ) != NULL ) {
2116- int found = 0 ;
2117- for (size_t i = 0 ; i < ARRAY_LEN (ini_inject_strat_str );
2118- i ++ ) {
2119- if (strncmp (line , ini_inject_strat_str [i ],
2120- ini_inject_strat_len [i ]) != 0 ) {
2121- continue ;
2122- }
2123- strcatoff (buf , ini_inject_strat_str [i ],
2124- ini_inject_strat_len [i ], & off , & wrote ,
2125- size );
2126- strcatoff (buf , STRAT_PATH , STRAT_PATH_LEN , & off ,
2127- & wrote , size );
2128- strcatoff (buf , " " , 1 , & off , & wrote , size );
2129- strcatoff (buf , deref (back )-> name ,
2130- deref (back )-> name_len , & off , & wrote ,
2131- size );
2132- strcatoff (buf , " " , 1 , & off , & wrote , size );
2133- strcatoff (buf , line + ini_inject_strat_len [i ],
2134- strlen (line + ini_inject_strat_len [i ]),
2135- & off , & wrote , size );
2136- found = 1 ;
2137- break ;
2138- }
2139- for (size_t i = 0 ; i < ARRAY_LEN (ini_expand_path_str );
2140- i ++ ) {
2141- if (strncmp (line , ini_expand_path_str [i ],
2142- ini_expand_path_len [i ]) != 0
2143- || line [ini_expand_path_len [i ]] !=
2144- '/' ) {
2145- continue ;
2146- }
2147- strcatoff (buf , ini_expand_path_str [i ],
2148- ini_expand_path_len [i ], & off , & wrote ,
2149- size );
2150- strcatoff (buf , STRATA_ROOT , STRATA_ROOT_LEN ,
2151- & off , & wrote , size );
2152- strcatoff (buf , deref (back )-> name ,
2153- deref (back )-> name_len , & off , & wrote ,
2154- size );
2155- strcatoff (buf , line + ini_expand_path_len [i ],
2156- strlen (line + ini_expand_path_len [i ]),
2157- & off , & wrote , size );
2158- found = 1 ;
2159- }
2160- if (!found ) {
2161- strcatoff (buf , line , strlen (line ), & off ,
2162- & wrote , size );
2163- }
2164- if (wrote >= size ) {
2165- break ;
2166- }
2167- }
2168- rv = wrote ;
2169- fclose (fp );
2215+ break ;
2216+
2217+ case FILTER_INI :
2218+ rv = inject_ini (cfg , ipath , ipath_len , buf , size , offset );
21702219 break ;
21712220
21722221 case FILTER_FONT :
@@ -2199,8 +2248,8 @@ static inline int read_back(struct cfg_entry *cfg, const char *ipath, size_t
21992248 break ;
22002249 }
22012250
2202- wrote = 0 ;
2203- off = offset ;
2251+ size_t wrote = 0 ;
2252+ size_t off = offset ;
22042253
22052254 /*
22062255 * Handle line count line
0 commit comments