@@ -308,14 +308,52 @@ static int fcontext_matches(const semanage_fcontext_t *fcontext, void *varg)
308308 return retval ;
309309}
310310
311+ /*
312+ * Parses `file` for `key` seperated by `sep` into `out`.
313+ * Returns:
314+ * true on success.
315+ * false on failure.
316+ * `out` is guaranteed to be initalised.
317+ * `fallback_set` is initalised to false, and set to true if a fallback was used.
318+ */
319+ static bool parse_uid_config (const char * file , const char * key , const char * sep ,
320+ uid_t fallback , uid_t * out , bool * fallback_set )
321+ {
322+ assert (out );
323+ assert (fallback_set );
324+
325+ * fallback_set = false;
326+
327+ char * uid_str = semanage_findval (file , key , sep );
328+ if (!uid_str || !* uid_str ) {
329+ free (uid_str );
330+ * fallback_set = true;
331+ * out = fallback ;
332+ return true;
333+ }
334+
335+ char * endptr ;
336+ errno = 0 ;
337+ const unsigned long val = strtoul (uid_str , & endptr , 0 );
338+
339+ if (endptr != uid_str && * endptr == '\0' && errno != ERANGE ) {
340+ * out = (uid_t )val ;
341+ free (uid_str );
342+ return true;
343+ }
344+
345+ free (uid_str );
346+ * fallback_set = true;
347+ * out = fallback ;
348+ return false;
349+ }
350+
311351static semanage_list_t * get_home_dirs (genhomedircon_settings_t * s )
312352{
313353 semanage_list_t * homedir_list = NULL ;
314354 semanage_list_t * shells = NULL ;
315355 fc_match_handle_t hand ;
316356 char * path = NULL ;
317- uid_t temp , minuid = 500 , maxuid = 60000 ;
318- int minuid_set = 0 ;
319357 struct passwd * pwbuf ;
320358 struct stat buf ;
321359
@@ -362,56 +400,25 @@ static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s)
362400 "Conversion failed for key " key ", is its value a number?" \
363401 " Falling back to default value of `%s`.", #val);
364402
365- path = semanage_findval (PATH_ETC_LOGIN_DEFS , "UID_MIN" , NULL );
366- if (path && * path ) {
367- char * endptr ;
368- const unsigned long val = strtoul (path , & endptr , 0 );
369- if (endptr != path && * endptr == '\0' ) {
370- minuid = (uid_t )val ;
371- minuid_set = 1 ;
372- } else {
373- /* we were provided an invalid value, use defaults. */
374- genhomedircon_warn_conv_fail ("UID_MIN" , FALLBACK_MINUID );
375- minuid = FALLBACK_MINUID ;
376- minuid_set = 1 ;
377- }
378- }
379- free (path );
380- path = NULL ;
403+ uid_t minuid ;
404+ bool fallback_set ;
405+ if (!parse_uid_config (PATH_ETC_LOGIN_DEFS , "UID_MIN" , NULL , FALLBACK_MINUID , & minuid , & fallback_set ))
406+ genhomedircon_warn_conv_fail ("UID_MIN" , FALLBACK_MINUID );
381407
382- path = semanage_findval (PATH_ETC_LOGIN_DEFS , "UID_MAX" , NULL );
383- if (path && * path ) {
384- char * endptr ;
385- const unsigned long val = strtoul (path , & endptr , 0 );
386- if (endptr != path && * endptr == '\0' ) {
387- maxuid = (uid_t )val ;
388- } else {
389- /* we were provided an invalid value, use defaults. */
390- genhomedircon_warn_conv_fail ("UID_MAX" , FALLBACK_MAXUID );
391- maxuid = FALLBACK_MAXUID ;
392- }
393- }
394- free (path );
395- path = NULL ;
408+ const bool logindefs_minuid_fallback_set = fallback_set ;
396409
397- path = semanage_findval (PATH_ETC_LIBUSER , "LU_UIDNUMBER" , "=" );
398- if (path && * path ) {
399- char * endptr ;
400- const unsigned long val = strtoul (path , & endptr , 0 );
401- if (endptr != path && * endptr == '\0' ) {
402- temp = (uid_t )val ;
403- } else {
404- /* we were provided an invalid value, use defaults. */
405- genhomedircon_warn_conv_fail ("LU_UIDNUMBER" , FALLBACK_LU_UIDNUMBER );
406- temp = FALLBACK_LU_UIDNUMBER ;
407- }
408- if (!minuid_set || temp < minuid ) {
409- minuid = temp ;
410- minuid_set = 1 ;
411- }
412- }
413- free (path );
414- path = NULL ;
410+ uid_t temp ;
411+ if (!parse_uid_config (PATH_ETC_LIBUSER , "LU_UIDNUMBER" , "=" , FALLBACK_LU_UIDNUMBER , & temp , & fallback_set ))
412+ genhomedircon_warn_conv_fail ("LU_UIDNUMBER" , FALLBACK_LU_UIDNUMBER );
413+
414+ if (logindefs_minuid_fallback_set )
415+ minuid = temp ;
416+
417+ uid_t maxuid ;
418+ /* We don't actually check fallback_set here, PATH_ETC_LOGIN_DEFS is the one source of
419+ truth for UID_MAX. */
420+ if (!parse_uid_config (PATH_ETC_LOGIN_DEFS , "UID_MAX" , NULL , FALLBACK_MAXUID , & maxuid , & fallback_set ))
421+ genhomedircon_warn_conv_fail ("UID_MAX" , FALLBACK_MAXUID );
415422
416423#undef genhomedircon_warn_conv_fail
417424
0 commit comments