Hello Adolf,

> On 9 May 2025, at 13:15, Adolf Belka <[email protected]> wrote:
> 
> Hi Michael,
> 
> On 08/05/2025 15:11, Michael Tremer wrote:
>> Hello Adolf,
>> I just gave this a try:
>> ipfire build chroot (x86_64) root:~$ htpasswd -vb /var/ipfire/auth/users 
>> admin ipfire; echo $?
>> User admin not found
>> 6
>> ipfire build chroot (x86_64) root:~$ htpasswd -b /var/ipfire/auth/users 
>> admin ipfire
>> Adding password for user admin
>> ipfire build chroot (x86_64) root:~$ htpasswd -vb /var/ipfire/auth/users 
>> admin ipfire; echo $?
>> Password for user admin correct.
>> 0
>> ipfire build chroot (x86_64) root:~$ htpasswd -vb /var/ipfire/auth/users 
>> admin ipfire2; echo $?
>> password verification failed
>> 3
>> ipfire build chroot (x86_64) root:~$ htpasswd -vb /var/ipfire/auth/users 
>> admin2 ipfire2; echo $?
>> User admin2 not found
>> 6
>> This is in the dev system, so the password file was empty to start with.
>> Basically if the username and password match the return code is zero. If 
>> something else happened it isn’t. And this is exactly what I would check 
>> for: Okay on zero, not okay on anything else. I would not even case why 
>> htpasswd was upset because it does not matter in our use-case.
> 
> Okay, so the $? contains the status of the bash command htpasswd but how do I 
> access that via the perl system_output command. I have tried making the 
> result of the system_output command be fed to a $variable but I just get a 1 
> for all the different conditions you tried.
> I also tried making the system_output command be fed to an array variable and 
> then printing all the elements of that array variable out but there was no 
> status value.

You don’t use the system_output() function, you should use the 
&General::system() function. On there, we fetch the return code and return it:

  
https://git.ipfire.org/?p=ipfire-2.x.git;a=blob;f=config/cfgroot/general-functions.pl;h=8ba6e3f79f0a9660ba8f8630ad0c7f1a3f6c988d;hb=HEAD#l32

Perl stores the value in $? like bash, but weirdly shifts it by 8 bits, so we 
have to shift it back.

So your code should read a bit like:

  if (&General::system(“htpasswd”, “-B”, …) == 0) {
    // success
  } else {
    // fail
  }

> It will probably turn out to be very simple but I am afraid I am not having 
> any luck figuring out how to do it.

Not a problem :)

The &General::system_output() function does not return the return code because 
it is already returning the output of the command. If the command fails there 
won't be any output - and that is not a very good way to check things normally.

-Michael

> All feedback gladly welcomed.
> 
> Regards,
> Adolf.
> 
>> -Michael
>>> On 7 May 2025, at 15:02, Adolf Belka <[email protected]> wrote:
>>> 
>>> Hi Michael,
>>> 
>>> On 07/05/2025 15:52, Adolf Belka wrote:
>>>> Hi Michael,
>>>> On 07/05/2025 14:44, Michael Tremer wrote:
>>>>> Hello Adolf,
>>>>> 
>>>>> Thanks for the patch. Is there no return code that we get from htpasswd 
>>>>> instead of parsing the output?
>>>> It gives a return code for everything, with numbers of 0 to 7, except for 
>>>> the use of the -v option to verify the password.
>>> There might be a status code returned. The man page says
>>> 
>>> 3 if the password was entered interactively and the verification entry 
>>> didn't match
>>> 
>>> but elsewhere it does suggest that interactively is not via the -bv option 
>>> but where you just use -v and manually type the password when requested on 
>>> the command line.
>>> 
>>> If the status 3 is a valid status code, how can I access that from the 
>>> output of the &General::system_output subroutine?
>>> 
>>> I could give it a try out and if it does work then I could do a v3 patch.
>>> 
>>> Regards,
>>> 
>>> Adolf.
>>> 
>>>> This gives
>>>> password verification failed
>>>> if the existing password for the specified user is not correct and
>>>> Password for user fred correct.
>>>> if the user specified was fred and the specified password was correct.
>>>> It does the above for both the interactive -v and the batch mode using the 
>>>> command line of -bv
>>>> I had to use the check for if the string was found in the return variable 
>>>> because if I checked if the string matched the contents of the variable it 
>>>> always failed so I think there is a hidden Carriage Return or something in 
>>>> the output from htpasswd for the verification test.
>>>> Regards,
>>>> Adolf.
>>>>> 
>>>>> -Michael
>>>>> 
>>>>>> On 7 May 2025, at 13:42, Adolf Belka <[email protected]> wrote:
>>>>>> 
>>>>>> - Realised that I had not tested the old password beinhg correct or not. 
>>>>>> Previous check
>>>>>>    gave the same answer irrespective of the output coming from the 
>>>>>> htpasswd verification.
>>>>>> - This changes the variable used for the system_output result to an 
>>>>>> array and then
>>>>>>    checks if the first element contains the failure message that 
>>>>>> htpasswd gives if
>>>>>>    password verification fails.
>>>>>> - Tested out with correct and incorrect old passwords and gave the 
>>>>>> correct answer in
>>>>>>    both cases. Confirmed also that the check for the user being present 
>>>>>> works correctly
>>>>>>    for both an existing and new user name, which it did.
>>>>>> 
>>>>>> Fixes: bug12755
>>>>>> Tested-by: Adolf Belka <[email protected]>
>>>>>> Signed-off-by: Adolf Belka <[email protected]>
>>>>>> ---
>>>>>> html/cgi-bin/chpasswd.cgi | 4 ++--
>>>>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>> 
>>>>>> diff --git a/html/cgi-bin/chpasswd.cgi b/html/cgi-bin/chpasswd.cgi
>>>>>> index c00caca20..46c3e02f6 100644
>>>>>> --- a/html/cgi-bin/chpasswd.cgi
>>>>>> +++ b/html/cgi-bin/chpasswd.cgi
>>>>>> @@ -77,11 +77,11 @@ if ($cgiparams{'SUBMIT'} eq $tr{'advproxy chgwebpwd 
>>>>>> change password'})
>>>>>>         # Check if a user with this name and password exists in the 
>>>>>> userdb file
>>>>>>         # and if it does then change the password to the new one
>>>>>>         my $user = &General::system_output("grep", 
>>>>>> "$cgiparams{'USERNAME'}", "$userdb");
>>>>>> -       my $old_password = &General::system_output("/usr/bin/htpasswd", 
>>>>>> "-bv", "$userdb", "$cgiparams{'USERNAME'}", 
>>>>>> "$cgiparams{'OLD_PASSWORD'}");
>>>>>> +       my @old_password = &General::system_output("/usr/bin/htpasswd", 
>>>>>> "-bv", "$userdb", "$cgiparams{'USERNAME'}", 
>>>>>> "$cgiparams{'OLD_PASSWORD'}");
>>>>>>         if (!$user) {
>>>>>>                 $errormessage = $tr{'advproxy errmsg invalid user'};
>>>>>>                 goto ERROR;
>>>>>> -       } elsif (!$old_password) {
>>>>>> +       } elsif (@old_password[0] =~ /password verification failed/) {
>>>>>>                  $errormessage = $tr{'advproxy errmsg password 
>>>>>> incorrect'};
>>>>>>                  goto ERROR;
>>>>>>         } else {
>>>>>> -- 
>>>>>> 2.49.0



Reply via email to