@@ -27,6 +27,30 @@ int _nss_tcb_endspent(void)
2727 return 1 ;
2828}
2929
30+ /* IEEE Std 1003.1-2001 allows only the following characters to appear
31+ in group- and usernames: letters, digits, underscores, periods,
32+ <at>-signs (@), and dashes. The name may not start with a dash or @.
33+ The "$" sign is allowed at the end of usernames to allow typical
34+ Samba machine accounts. */
35+ static int
36+ is_valid_username (const char * un )
37+ {
38+ if (!un || !* un || un [0 ] == '-' || un [0 ] == '@' ||
39+ /* curdir || parentdir */
40+ !strcmp (un , "." ) || !strcmp (un , ".." ))
41+ return 0 ;
42+
43+ do {
44+ char c = * un ++ ;
45+ if (!((c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) ||
46+ (c >= '0' && c <= '9' ) || c == '-' || c == '.' ||
47+ c == '@' || c == '_' || (!* un && c == '$' )))
48+ return 0 ;
49+ } while (* un );
50+
51+ return 1 ;
52+ }
53+
3054static FILE * tcb_safe_open (const char * file , const char * name )
3155{
3256 gid_t grplist [TCB_NGROUPS ];
@@ -64,12 +88,18 @@ int _nss_tcb_getspnam_r(const char *name, struct spwd *__result_buf,
6488 char * file ;
6589 int retval , saved_errno ;
6690
91+ /* Disallow potentially-malicious user names */
92+ if (!is_valid_username (name )) {
93+ errno = ENOENT ;
94+ return NSS_STATUS_NOTFOUND ;
95+ }
96+
6797 if (asprintf (& file , TCB_FMT , name ) < 0 )
6898 return NSS_STATUS_TRYAGAIN ;
6999 f = tcb_safe_open (file , name );
70100 free (file );
71101 if (!f )
72- return NSS_STATUS_UNAVAIL ;
102+ return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL ;
73103
74104 retval = fgetspent_r (f , __result_buf , __buffer , __buflen , __result );
75105 saved_errno = errno ;
0 commit comments