LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 765|回复: 1

Password and Shadow - Unix User Accounts Information( Notes by baif )

[复制链接]
发表于 2004-1-20 01:04:29 | 显示全部楼层 |阅读模式
  1. Password and Shadow - Unix User Accounts Information
  2.         Reading Notes by baif, 2004, Jan 18th.
  3. 1. Database files
  4.         1.1 Format of the Password File
  5.         1.2 Format of the Shadow File
  6.         1.3 Function crpyt()
  7. 2. What Can We do...
  8.         2.1  Shell
  9.         2.2  Getting Accounts Infourmantion with C
  10.        
  11.         To get more, refer to: 1.Linux Shadow Password HOWTO, 2.Unix Programming
  12.                        
  13.        
  14.        
  15. 1. Database files
  16.         Unix/Linux's user accounts information were stored
  17.         in the following files:
  18.        /etc/passwd - user account information
  19.        /etc/shadow - secure user account information
  20.        
  21.         drped from
  22.         Linux Shadow Password HOWTO
  23.         [url]http://www.linux.org/docs/ldp/howto/Shadow-Password-HOWTO.html[/url]
  24. 1.1 Format of the Password File
  25. A non-shadowed /etc/passwd file has the following format:
  26.        
  27.         username:passwd:UID:GID:full_name:directory:shell
  28. Where:
  29. username    The user (login) name
  30. passwd      The encoded password
  31. UID         Numerical user ID
  32. GID         Numerical default group ID
  33. full_name   The user's full name - Actually this field is called the GECOS
  34.                 (General Electric Comprehensive Operating System) field and
  35.                 can store information other than just the full name.
  36.                 The Shadow commands and manual pages refer to this field as the comment field.
  37. directory   User's home directory (Full pathname)
  38. shell       User's login shell (Full Pathname)
  39. For example:
  40. username:Npge08pfz4wuk:503:100:Full Name:/home/username:/bin/sh
  41. Where Np is the salt and ge08pfz4wuk is the encoded password. The encoded salt/password could just
  42. as easily have been kbeMVnZM0oL7I and the two are exactly the same password. There are 4096 possible
  43. encodings for the same password.
  44.   (The example password in this case is 'password', a really bad password).
  45. Once the shadow suite is installed, the /etc/passwd file would instead contain:
  46.         username:x:503:100:Full Name:/home/username:/bin/sh
  47. The x in the second field in this case is now just a place holder. The format of the /etc/passwd file
  48. really didn't change, it just no longer contains the encoded password. This means that any program
  49. that reads the /etc/passwd file but does not actually need to verify passwords will still operate
  50. correctly.
  51. The passwords are now relocated to the shadow file (usually /etc/shadow file).
  52. 1.2 Format of the Shadow File
  53. The /etc/shadow file contains the following information:
  54.        
  55.         username:passwd:last:may:must:warn:expire:disable:reserved
  56. Where:
  57. username    The User Name
  58. passwd      The Encoded password
  59. last        Days since Jan 1, 1970 that password was last changed
  60. may         Days before password may be changed
  61. must        Days after which password must be changed
  62. warn        Days before password is to expire that user is warned
  63. expire      Days after password expires that account is disabled
  64. disable     Days since Jan 1, 1970 that account is disabled
  65. reserved    A reserved field
  66. The previous example might then be:
  67.        
  68.         username:Npge08pfz4wuk:9479:0:10000::::
  69. 1.3 Function crpyt()
  70. From the crypt(3) manual page:
  71. "crypt is the password encryption function. It is based on the Data Encryption Standard algorithm
  72. with variations intended (among other things) to discourage use of hardware implementations of a
  73. key search. "
  74. [The] key is a user's typed password. [The encoded string is all NULLs]
  75. [The] salt is a two-character string chosen from the set [a-zA-Z0-9./].
  76. This string is used to perturb the algorithm in one of 4096 different ways.
  77. By taking the lowest 7 bit[s] of each character of the key, a 56-bit key is obtained. This 56-bit
  78. key is used to encrypt repeatedly a constant string (usually a string consisting of all zeros).
  79. The returned value points to the encrypted password, a series of 13 printable ASCII characters
  80. (the first two characters represent the salt itself). The return value points to static data whose
  81. content is overwritten by each call.
  82. 2. What Can We do...
  83. 2.1  Shell
  84. Some commands about accounts' operations
  85. User account operating:
  86. adduser: Creating new Users without option -D.
  87. userdel: Modifies the system account files, deleting all entries that refer to login. The named user must exist.
  88. Modifies the system account files in manual way:
  89. vipw: invork the command with -s option Modify the file /etc/shadow,
  90.       invork without -s will modify /etc/passwd.
  91. chfn: Change the "finger name"(GECOS domain).
  92. chsh: Change the default Shell for specified account.
  93. passwd: Change the passwords of specified account.
  94. 2.2 Getting Accounts Infourmantion with C
  95. So, C provides some functions to read Unix accounts informantion. The information were stroed in files: passwd and shadow.
  96. First
  97.     We should know about the definition of struct passwd in the <pwd.h> header, which includes at least the following members:
  98. struct passwd
  99. {
  100.     char    *pw_name   /* user's login name */
  101.     uid_t    pw_uid    /* numerical user ID */
  102.     gid_t    pw_gid    /* numerical group ID */
  103.     char    *pw_dir    /* initial working directory */
  104.     char    *pw_shell  /* program to use as shell */
  105.     /* The gid_t and uid_t types are defined as described in <sys/types.h> */
  106. }
  107. Seconed
  108.     We can get the structure by the following two funtions for request entry:
  109.     struct passwd * getpwnam(const char *); /* IT'S getpwnam(), NOT getpwname() */
  110.     struct passwd * getpwuid(uid_t);
  111.   The getpwnam() function searches the user database for an entry with a matching UserName, WHILE the getpwuid() funtion searches
  112.     with maching UID.
  113.   Those functions return pointers to a struct passwd with a matching entry if FOUND. A null pointer is returned if the requested
  114.     entry is NOT found, or an ERORR occurs. On error, errno is set to indicate the error.
  115.   Applications wishing to check for error situations should set errno to 0 before calling. To get more about error checking ,please
  116.     turn to Manual.
  117.     Example:
  118. __________________________________________________________________
  119. #include <stdio.h>
  120. #include <pwd.h>
  121. #include <limits.h>
  122. #include <sys/types.h>
  123. /* WITHOUT ERORR CHECKING */
  124. char * getuserhomedir_byun (char *user)
  125. {
  126.     static char homedir[_POSIX_PATH_MAX]; /* defined in limits.h */
  127.     struct passwd *pws;
  128.     pws = getpwnam (user);
  129.     if (!pws)
  130.         return;
  131.     strcpy (homedir, pws->pw_dir);
  132.         return homedir;
  133. }
  134. char * getuserhomedir_byuid(uid_t uid) /* uid_t is defined in sys/types.h */
  135. {   
  136.     static char homedir[_POSIX_PATH_MAX];
  137.     struct passwd * pws;
  138.             
  139.     pws = getpwuid(uid);
  140.     if(!pws)
  141.         return;
  142.     strcpy(homedir, pws->pw_dir);
  143.         return homedir;
  144.     }
  145. int main (void)
  146. {
  147.     printf("The user baif's home directory: %s\n", getuserhomedir_byun ("baif"));
  148.     printf("Currnet process' UID is %d .The related home directory is %s\n", getuid(), getuserhomedir_byuid(getuid()) );
  149. }
  150. ____________________________________________________________________
  151. Third
  152.     We can scan the user database by:
  153.     struct passwd *getpwent(void);
  154.     void           endpwent(void);
  155.     void           setpwent(void);
  156.   The getpwent() function returns a pointer to a structure containing the broken-out fields of an entry in the user database.
  157.   
  158.     Each entry in the user database contains a passwd structure. When first called, getpwent() returns a pointer to a passwd
  159.     structure containing the first entry in the user database. Thereafter, it returns a pointer to a passwd structure
  160.     containing the next entry in the user database. Successive calls can be used to search the entire user database.
  161.     If an end-of-file or an error is encountered on reading, getpwent() returns a null pointer.
  162.     The setpwent() function effectively rewinds the user database to allow repeated searches.
  163.     The endpwent() function may be called to close the user database when processing is complete.
  164.   In aother words, they are working just like files operations function, fgets(), fclose(),reset(). Can you follow me :P ?
  165.   
  166.     Successive callings of the getpent() will get a entry one by one(line by line in the user database file). The endpwent() will
  167.     call the system function to close the database file in crrect way, while the setpwent() will re-open the database file.
  168.     These interfaces need not be reentrant.
  169.     Example:
  170. __________________________________________________________________
  171. #include <stdio.h>
  172. #include <pwd.h>
  173. #include <limits.h>
  174. #include <sys/types.h>
  175. /* WITHOUT ERORR CHECKING */
  176. /* Finds the hightest uid in passwd file and sets the nextued global variable to the next number. */
  177. void inituid(void)
  178. {
  179.     struct passwd * entry;
  180.     uid_t netxtuid = 0; /* uid_t is deifned in sys/types.h */
  181.     printf("Scanning for next available uid... \r");
  182.     fflush(stdout);
  183.     while ( (entry = getpwent()) )
  184.         if ( (entry->pw_uid > nextuid) &&
  185.                 (entry->pw_uid < 32767) )   /* Compensate for broken systems */
  186.         nextuid = entry->pw_uid;
  187.         endpwent();
  188.         nextuid++;
  189.         printf("The next uid will be %d%-20c.\n", nextuid, '.');
  190.         
  191. }
  192. int main(void)
  193. {
  194.     inituid();
  195. }
  196. __________________________________________________________________
  197.     Others:
  198.     int getpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **);
  199.     int getpwuid_r(uid_t, struct passwd *, char *,size_t, struct passwd **);
  200.     To get more, please refer to Manual.
复制代码
 楼主| 发表于 2004-1-20 01:06:17 | 显示全部楼层

对不起大家了,没有贴过这么长的贴子。。。。

不太熟练, sorry~

还是麻烦一下版主了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表