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,10 +59,12 @@ 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 ) {
@@ -67,44 +73,104 @@ check_pkg_files(struct xbps_handle *xhp, const char *pkgname, void *arg)
6773 return -1 ;
6874
6975 while ((obj = xbps_object_iterator_next (iter ))) {
76+ noexist = mutable = false;
77+
7078 xbps_dictionary_get_cstring_nocopy (obj , "file" , & file );
7179 /* skip noextract files */
7280 if (xhp -> noextract && xbps_patterns_match (xhp -> noextract , file ))
7381 continue ;
7482 path = xbps_xasprintf ("%s/%s" , xhp -> rootdir , file );
75- xbps_dictionary_get_cstring_nocopy (obj ,
76- "sha256" , & sha256 );
83+
84+ xbps_dictionary_get_bool (obj , "mutable" , & mutable );
85+
86+ /* check sha256 */
87+ xbps_dictionary_get_cstring_nocopy (obj , "sha256" , & sha256 );
7788 rv = xbps_file_sha256_check (path , sha256 );
7889 switch (rv ) {
7990 case 0 :
80- free (path );
8191 break ;
8292 case ENOENT :
83- xbps_error_printf ("%s: unexistent file %s.\n" ,
84- pkgname , file );
85- free (path );
86- test_broken = true;
93+ xbps_error_printf ("%s: unexistent file %s.\n" , pkgname , file );
94+ test_broken = noexist = true;
8795 break ;
8896 case ERANGE :
89- mutable = false;
90- xbps_dictionary_get_bool (obj ,
91- "mutable" , & mutable );
9297 if (!mutable ) {
93- xbps_error_printf ("%s: hash mismatch "
94- "for %s.\n" , pkgname , file );
98+ xbps_error_printf ("%s: hash mismatch for %s.\n" , pkgname , file );
9599 test_broken = true;
96100 }
97- free (path );
98101 break ;
99102 default :
100- xbps_error_printf (
101- "%s: can't check `%s' (%s)\n" ,
102- pkgname , file , strerror (rv ));
103- free (path );
103+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (rv ));
104104 break ;
105105 }
106- }
107- xbps_object_iterator_release (iter );
106+
107+ if (noexist ) {
108+ free (path );
109+ continue ;
110+ }
111+
112+ /* check mode */
113+ mode = 0 ;
114+ if (xbps_dictionary_get_uint32 (obj , "mode" , & mode )) {
115+ rv = file_mode_check (path , mode );
116+ switch (rv ) {
117+ case 0 :
118+ break ;
119+ case ERANGE :
120+ if (!mutable ) {
121+ xbps_error_printf ("%s: mode mismatch for %s.\n" , pkgname , file );
122+ test_broken = true;
123+ }
124+ break ;
125+ default :
126+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (- rv ));
127+ break ;
128+ }
129+ }
130+
131+ /* check user */
132+ user = NULL ;
133+ xbps_dictionary_get_cstring_nocopy (obj , "user" , & user );
134+ if (user == NULL )
135+ user = "root" ;
136+ rv = file_user_check (idt , path , user );
137+ switch (rv ) {
138+ case 0 :
139+ break ;
140+ case ERANGE :
141+ if (!mutable ) {
142+ xbps_error_printf ("%s: user mismatch for %s.\n" , pkgname , file );
143+ test_broken = true;
144+ }
145+ break ;
146+ default :
147+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (- rv ));
148+ break ;
149+ }
150+
151+ /* check group */
152+ group = NULL ;
153+ xbps_dictionary_get_cstring_nocopy (obj , "group" , & group );
154+ if (group == NULL )
155+ group = "root" ;
156+ rv = file_group_check (idt , path , group );
157+ switch (rv ) {
158+ case 0 :
159+ break ;
160+ case ERANGE :
161+ if (!mutable ) {
162+ xbps_error_printf ("%s: group mismatch for %s.\n" , pkgname , file );
163+ test_broken = true;
164+ }
165+ break ;
166+ default :
167+ xbps_error_printf ("%s: can't check `%s' (%s)\n" , pkgname , file , strerror (- rv ));
168+ break ;
169+ }
170+
171+ free (path );
172+ }
173+ xbps_object_iterator_release (iter );
108174 }
109175 if (test_broken ) {
110176 xbps_error_printf ("%s: files check FAILED.\n" , pkgname );
0 commit comments