login bug? Fix?

walter harms wharms at bfs.de
Fri Nov 7 08:52:35 UTC 2008


i am sorry for my stupid question but ...
according to sources in the internet login should test for /etc/nologin
and die if exists and you are not root.
so i do not understand why someone may want to read it content.

IMHO the line
 puts("\r\nSystem closed for routine maintenance\r");
could be printed always. Not only will it save an if()
but also remind root that /etc/nologin is still present.

just my to cents,
wh

Denys Vlasenko schrieb:
> On Friday 07 November 2008 01:39, Cathey, Jim wrote:
>> The /etc/nologin logic of BB 10&11 seems a bit odd, and
>> had problems echoing newlines in our system.  Also,
>> as I understand it, if nologin has contents those
>> are all that's echoed, whereas if there but empty
>> a system default message is supplied. 
>>
>> $ diff -c loginutils/login.c~ loginutils/login.c 
>> *** loginutils/login.c~      2008-10-15 11:01:16.000000000 -0700
>> --- loginutils/login.c       2008-11-06 15:19:18.000000000 -0800
>> ***************
>> *** 117,123 ****
>>   static void die_if_nologin(void)
>>   {
>>         FILE *fp;
>> !       int c;
>>   
>>         if (access("/etc/nologin", F_OK))
>>                 return;
>> --- 117,123 ----
>>   static void die_if_nologin(void)
>>   {
>>         FILE *fp;
>> !       int c, ii = 0;
>>   
>>         if (access("/etc/nologin", F_OK))
>>                 return;
>> ***************
>> *** 125,135 ****
>>         fp = fopen("/etc/nologin", "r");
>>         if (fp) {
>>                 while ((c = getc(fp)) != EOF)
>> !                       bb_putchar((c=='\n') ? '\r' : c);
>>                 fflush(stdout);
>>                 fclose(fp);
>> !       } else
>>                 puts("\r\nSystem closed for routine maintenance\r");
>>         exit(EXIT_FAILURE);
>>   }
>>   #else
>> --- 125,139 ----
>>         fp = fopen("/etc/nologin", "r");
>>         if (fp) {
>>                 while ((c = getc(fp)) != EOF)
>> !                  ++ii,bb_putchar((c=='\n') ? (bb_putchar('\r'),c) :
>> c);
> 
> (1) Linewrapep patch
> (2) Do you hate poor souls who read your code or just try
>     to win code obfuscation contest?
> 
>>                 fflush(stdout);
>>                 fclose(fp);
>> !       }
>> !       if (!ii) {
>>                 puts("\r\nSystem closed for routine maintenance\r");
>> +               fflush(stdout);
>> +       }
>> +       tcdrain(fileno(stdout));
> 
> fflush() can be done once, after if() - smaller code.
> fileno(stdout) is a known constant, it's STDOUT_FILENO.
> Use it directly - smaller code.
> 
>> The above change makes for a recursive \r-adder on \n's, and counts
>> emitted characters.  The original code wouldn't emit any \n's that were
>> in a standard unix text file, converting them to \r's instead, resulting
>> in lines that overwrote themselves on display.  I thought the purpose of
>> this was to be able to deal with output paths that didn't have a tty
>> device driver that could do CRNL mapping itself.  In which case you
>> need both, not a conversion.
>>
>> If any characters are emitted due to the nologin file contents, the
>> default message is suppressed.  (This was how I understood the original
>> login [big] to work, and allows for supporting non-English
>> installations.)
>>
>> We also had problems with the emitted file contents being truncated
>> due to the exit(), and the race of the close and the write.  The
>> tcdrain()
>> call fixed that.  (I don't remember if it was telnet or console that
>> exhibited this problem.)
> 
> Thanks.
> 
> Applying this patch:
> 
> diff -d -urpN busybox.8/loginutils/login.c busybox.9/loginutils/login.c
> --- busybox.8/loginutils/login.c	2008-10-30 08:41:37.000000000 +0100
> +++ busybox.9/loginutils/login.c	2008-11-07 02:07:13.000000000 +0100
> @@ -118,18 +118,25 @@ static void die_if_nologin(void)
>  {
>  	FILE *fp;
>  	int c;
> +	int empty = 1;
>  
> -	if (access("/etc/nologin", F_OK))
> +	fp = fopen_for_read("/etc/nologin");
> +	if (!fp) /* assuming it does not exist */
>  		return;
>  
> -	fp = fopen_for_read("/etc/nologin");
> -	if (fp) {
> -		while ((c = getc(fp)) != EOF)
> -			bb_putchar((c=='\n') ? '\r' : c);
> -		fflush(stdout);
> -		fclose(fp);
> -	} else
> +	while ((c = getc(fp)) != EOF) {
> +		if (c == '\n')
> +			bb_putchar('\r');
> +		bb_putchar(c);
> +		empty = 0;
> +	}
> +	if (empty)
>  		puts("\r\nSystem closed for routine maintenance\r");
> +
> +	fclose(fp);
> +	fflush(NULL);
> +	/* Users say that they do need this prior exit: */
> +	tcdrain(STDOUT_FILENO);
>  	exit(EXIT_FAILURE);
>  }
>  #else
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://busybox.net/cgi-bin/mailman/listinfo/busybox
> 
> 
> 



More information about the busybox mailing list