4343 * o Check the hash for all installed files, except
4444 * configuration files (which is expected if they are modified).
4545 *
46- * o Compares stored file modification time.
46+ * o Check the mode for all installed files, except configuration files.
47+ *
48+ * o Check the user for all installed files, except configuration files.
49+ *
50+ * o Check the group for all installed files, except configuration files.
4751 *
4852 * Return 0 if test ran successfully, 1 otherwise and -1 on error.
4953 */
@@ -55,56 +59,120 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
5559 xbps_object_t obj ;
5660 xbps_object_iterator_t iter ;
5761 xbps_dictionary_t pkg_filesd = arg ;
58- const char * file = NULL , * sha256 = NULL ;
62+ const char * file = NULL , * sha256 = NULL , * user = NULL , * group = NULL ;
5963 char * path ;
60- bool mutable , test_broken = false;
64+ bool mutable , test_broken = false, noexist = false ;
6165 int rv = 0 , errors = 0 ;
66+ mode_t mode = 0 ;
67+ struct idtree * idt = NULL ;
6268
6369 array = xbps_dictionary_get (pkg_filesd , "files" );
6470 if (array != NULL && xbps_array_count (array ) > 0 ) {
6571 iter = xbps_array_iter_from_dict (pkg_filesd , "files" );
66- if (iter == NULL )
67- return -1 ;
72+ if (iter == NULL ) {
73+ errors ++ ;
74+ goto out ;
75+ }
6876
6977 while ((obj = xbps_object_iterator_next (iter ))) {
78+ noexist = mutable = false;
79+
7080 xbps_dictionary_get_cstring_nocopy (obj , "file" , & file );
7181 /* skip noextract files */
7282 if (xhp -> noextract && xbps_patterns_match (xhp -> noextract , file ))
7383 continue ;
7484 path = xbps_xasprintf ("%s/%s" , xhp -> rootdir , file );
75- xbps_dictionary_get_cstring_nocopy (obj ,
76- "sha256" , & sha256 );
85+
86+ xbps_dictionary_get_bool (obj , "mutable" , & mutable );
87+
88+ /* check sha256 */
89+ xbps_dictionary_get_cstring_nocopy (obj , "sha256" , & sha256 );
7790 rv = xbps_file_sha256_check (path , sha256 );
7891 switch (rv ) {
7992 case 0 :
80- free (path );
8193 break ;
8294 case ENOENT :
83- xbps_error_printf ("%s: unexistent file %s.\n" ,
84- pkgname , file );
85- free (path );
86- test_broken = true;
95+ xbps_error_printf ("%s: unexistent file %s.\n" , pkgname , file );
96+ test_broken = noexist = true;
8797 break ;
8898 case ERANGE :
89- mutable = false;
90- xbps_dictionary_get_bool (obj ,
91- "mutable" , & mutable );
9299 if (!mutable ) {
93- xbps_error_printf ("%s: hash mismatch "
94- "for %s.\n" , pkgname , file );
100+ xbps_error_printf ("%s: hash mismatch for %s.\n" , pkgname , file );
95101 test_broken = true;
96102 }
97- free (path );
98103 break ;
99104 default :
100- xbps_error_printf (
101- "%s: can't check `%s' (%s)\n" ,
102- pkgname , file , strerror (rv ));
103- free (path );
105+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (rv ));
104106 break ;
105107 }
106- }
107- xbps_object_iterator_release (iter );
108+
109+ if (noexist ) {
110+ free (path );
111+ continue ;
112+ }
113+
114+ /* check mode */
115+ mode = 0 ;
116+ if (xbps_dictionary_get_uint32 (obj , "mode" , & mode )) {
117+ rv = file_mode_check (path , mode );
118+ switch (rv ) {
119+ case 0 :
120+ break ;
121+ case ERANGE :
122+ if (!mutable ) {
123+ xbps_error_printf ("%s: mode mismatch for %s.\n" , pkgname , file );
124+ test_broken = true;
125+ }
126+ break ;
127+ default :
128+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (- rv ));
129+ break ;
130+ }
131+ }
132+
133+ /* check user */
134+ user = NULL ;
135+ xbps_dictionary_get_cstring_nocopy (obj , "user" , & user );
136+ if (user == NULL )
137+ user = "root" ;
138+ rv = file_user_check (idt , path , user );
139+ switch (rv ) {
140+ case 0 :
141+ break ;
142+ case ERANGE :
143+ if (!mutable ) {
144+ xbps_error_printf ("%s: user mismatch for %s.\n" , pkgname , file );
145+ test_broken = true;
146+ }
147+ break ;
148+ default :
149+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (- rv ));
150+ break ;
151+ }
152+
153+ /* check group */
154+ group = NULL ;
155+ xbps_dictionary_get_cstring_nocopy (obj , "group" , & group );
156+ if (group == NULL )
157+ group = "root" ;
158+ rv = file_group_check (idt , path , group );
159+ switch (rv ) {
160+ case 0 :
161+ break ;
162+ case ERANGE :
163+ if (!mutable ) {
164+ xbps_error_printf ("%s: group mismatch for %s.\n" , pkgname , file );
165+ test_broken = true;
166+ }
167+ break ;
168+ default :
169+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (- rv ));
170+ break ;
171+ }
172+
173+ free (path );
174+ }
175+ xbps_object_iterator_release (iter );
108176 }
109177 if (test_broken ) {
110178 xbps_error_printf ("%s: files check FAILED.\n" , pkgname );
@@ -118,8 +186,10 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
118186 array = xbps_dictionary_get (pkg_filesd , "conf_files" );
119187 if (array != NULL && xbps_array_count (array ) > 0 ) {
120188 iter = xbps_array_iter_from_dict (pkg_filesd , "conf_files" );
121- if (iter == NULL )
122- return -1 ;
189+ if (iter == NULL ) {
190+ errors ++ ;
191+ goto out ;
192+ }
123193
124194 while ((obj = xbps_object_iterator_next (iter ))) {
125195 xbps_dictionary_get_cstring_nocopy (obj , "file" , & file );
@@ -148,5 +218,7 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
148218 errors ++ ;
149219 }
150220
221+ out :
222+ idtree_free (idt );
151223 return errors ? -1 : 0 ;
152224}
0 commit comments