简体   繁体   English

如何在C中读取linux etc / passwd文件并比较用户输入名称以进行身份​​验证

[英]how to read a linux etc/passwd file and compare the user input name for authentication in C

This is the program i have written can anyone tell what is wrong with it, because whatever input i give, it shows valid user. 这是我编写的程序,任何人都可以说出它出了什么问题,因为无论我提供什么输入,它都会显示有效的用户。

#include<stdio.h>
#include<string.h>
#define max_size 20
void main()
{
 File *Fptr;
 char username[max_size];
 char line[20];
 if((fptr=fopen("/etc/passwd","r"))==NULL)
 { 
   printf("cannot open file");
 }
 else
  {
      fptr=fopen("/etc/passwd","r");
      fputs("enter the username",stdout);
      fflush(stdout);
      fgets(username,sizeof username,stdin);
      while((fgets(line,sizeof(line),fptr))!=NULL)
      { 
          if(strcmp(line,username))
          {
             printf("%s valid user",username);
             break; 
          }
          else
            {
              printf("%s not valid user",username);
            }    
      } 
   fclose(fptr);
  }
}

strcmp is a three-way comparator. strcmp是三向比较器。 It tells you if the strings are equal or if the first string is lexicographically less or greater than second. 它告诉您字符串是否相等,或者在字典上第一个字符串小于或大于第二个字符串。

Because of this, its results are a bit unintuitive when used as booelan values. 因此,将其结果用作booelan值时有点不直观。 It returns 0 when the strings match, which evaluates to false in an if statement. 当字符串匹配时,它返回0 ,在if语句中计算为false。 It returns nonzero values, usually -1 or 1, (all of which evaluate to true) when the strings are different. 当字符串不同时,它将返回非零值,通常为-1或1(所有值都为true)。

If you want to test if two strings are the same, you should change 如果要测试两个字符串是否相同,则应更改

if(strcmp(line,username))

to

if(strcmp(line,username) == 0)

Also take note of Starkey's answer about the extra contents of lines in /etc/passwd . 还要注意Starkey关于/etc/passwd额外内容的回答。 If you make only the change above, your program will always return "not a valid user". 如果仅进行上述更改,则程序将始终返回“不是有效用户”。

与其尝试手动解析/etc/passwdgetpwnam使用getpwnam

strcmp returns 0 (which is false) if the two strings are exactly equivalent, or a non-zero number (which is true) if the strings differ at all. 如果两个字符串完全相等,则strcmp返回0(为假),如果两个字符串完全不同,则返回非零数字(为true)。

So firstly, you appear to have your if-test the wrong way around. 因此,首先,您似乎经历了错误的if-test测试。 Secondly, you need to test just the leading n characters, where n is the length of the username. 其次,您只需要测试前n字符,其中n是用户名的长度。 Off the top of my head, I suggest you try replacing your if-test with: 建议,我建议您尝试将if-test替换为:

if (!strncmp(line, username, strlen(username))

strcmp compares the whole line in the passwd file with what you have entered. strcmp会将passwd文件中的整个行与您输入的内容进行比较。 The passwd file contains more than just the user name on each line (look at a passwd file to see what I'm talking about). passwd文件在每一行中不仅包含用户名(查看passwd文件以了解我在说什么)。

Aside from the fact that your strcmp test condition is wrong as others have already pointed out, lines in the passwd file contain more than just the username. 除了其他人已经指出的,您的strcmp测试条件错误之外,passwd文件中的行还包含不仅用户名。 You could use strstr to see if the name is present in a particular line. 您可以使用strstr查看该名称是否出现在特定行中。

if(strstr(line, username) == line)
{
    /* valid user */
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM