home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / contrib / samba / samba-1.8 / samba-1 / samba-1.8.05 / password.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-27  |  19.9 KB  |  787 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.8.
  4.    Copyright (C) Andrew Tridgell 1992,1993,1994
  5.    
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.    
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.    
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #include "includes.h"
  22. #include "loadparm.h"
  23.  
  24. extern int DEBUGLEVEL;
  25.  
  26. /* users from session setup */
  27. pstring session_users="";
  28.  
  29.  
  30. /* this holds info on user ids that are already validated for this VC */
  31. user_struct *validated_users = NULL;
  32. int num_validated_users = 0;
  33.  
  34. /****************************************************************************
  35. check if a uid has been validated, and return an index if it has. -1 if not
  36. ****************************************************************************/
  37. int valid_uid(int uid)
  38. {
  39.   int i;
  40.   for (i=0;i<num_validated_users;i++)
  41.     if (validated_users[i].uid == uid)
  42.       {
  43.     DEBUG(3,("valid uid %d mapped to vuid %d\n",uid,i));
  44.     return(i);
  45.       }
  46.   return(-1);
  47. }
  48.  
  49. /****************************************************************************
  50. return a validated username
  51. ****************************************************************************/
  52. char *validated_username(int vuid)
  53. {
  54.   return(validated_users[vuid].name);
  55. }
  56.  
  57. /****************************************************************************
  58. register a uid/name pair as being valid and that a valid password
  59. has been given.
  60. ****************************************************************************/
  61. void register_uid(int uid,char *name,BOOL guest)
  62. {
  63.   if (valid_uid(uid) >= 0)
  64.     return;
  65.   if (!validated_users)
  66.     validated_users = (user_struct *)malloc(sizeof(user_struct));
  67.   else
  68.     validated_users = (user_struct *)realloc(validated_users,
  69.                          sizeof(user_struct)*
  70.                          (num_validated_users+1));
  71.  
  72.   if (!validated_users)
  73.     {
  74.       DEBUG(0,("Failed to realloc users struct!\n"));
  75.       return;
  76.     }
  77.  
  78.   validated_users[num_validated_users].uid = uid;
  79.   validated_users[num_validated_users].guest = guest;
  80.   validated_users[num_validated_users].name = strdup(name);    
  81.  
  82.   DEBUG(3,("uid %d registered to name %s\n",uid,name));
  83.   
  84.   num_validated_users++;
  85. }
  86.  
  87.  
  88. /****************************************************************************
  89. add a name to the session users list
  90. ****************************************************************************/
  91. void add_session_user(char *user)
  92. {
  93.   if (user && *user && !in_list(user,session_users,False))
  94.     {
  95.       if (strlen(user) + strlen(session_users) + 2 >= sizeof(pstring))
  96.     DEBUG(1,("Too many session users??\n"));
  97.       else
  98.     {
  99.       strcat(session_users," ");
  100.       strcat(session_users,user);
  101.     }
  102.     }
  103. }
  104.  
  105.  
  106. #ifdef NO_GETSPNAM
  107. /* a fake shadow password routine which just fills a fake spwd struct
  108.  * with the sp_pwdp field. (sreiz@aie.nl)
  109.  */
  110. struct spwd *getspnam(char *username) /* fake shadow password routine */
  111. {
  112.        FILE *f;
  113.        char line[1024];
  114.        static char pw[20];
  115.        static struct spwd static_spwd;
  116.  
  117.        static_spwd.sp_pwdp=0;
  118.        if (!(f=fopen("/etc/master.passwd", "r")))
  119.                return 0;
  120.        while (fgets(line, 1024, f)) {
  121.                if (!strncmp(line, username, strlen(username)) &&
  122.                 line[strlen(username)]==':') { /* found entry */
  123.                        char *p, *q;
  124.  
  125.                        p=line+strlen(username)+1;
  126.                        if (q=strchr(p, ':')) {
  127.                                *q=0;
  128.                                if (q-p+1>20)
  129.                                        break;
  130.                                strcpy(pw, p);
  131.                                static_spwd.sp_pwdp=pw;
  132.                        }
  133.                        break;
  134.                }
  135.        }
  136.        fclose(f);
  137.        if (static_spwd.sp_pwdp)
  138.                return &static_spwd;
  139.        return 0;
  140. }
  141. #endif
  142.  
  143.  
  144. #ifdef OSF1_ENH_SEC
  145. /****************************************************************************
  146. an enhanced crypt for OSF1
  147. ****************************************************************************/
  148. char *osf1_bigcrypt(char *password,char *salt1)
  149. {
  150.   static char result[AUTH_MAX_PASSWD_LENGTH] = "";
  151.   char *p1;
  152.   char *p2=password;
  153.   char salt[3];
  154.   int i;
  155.   int parts = strlen(password) / AUTH_CLEARTEXT_SEG_CHARS;
  156.   if (strlen(password)%AUTH_CLEARTEXT_SEG_CHARS)
  157.     parts++;
  158.  
  159.   strcpy(salt,salt1);
  160.   strcpy(result,salt1);
  161.  
  162.   for (i=0; i<parts;i++)
  163.     {
  164.       p1 = crypt(p2,salt);
  165.       strcat(result,p1+2);
  166.       StrnCpy(salt,&result[2+i*AUTH_CIPHERTEXT_SEG_CHARS],2);
  167.       p2 += AUTH_CLEARTEXT_SEG_CHARS;
  168.     }
  169.  
  170.   return(result);
  171. }
  172. #endif
  173.  
  174.  
  175. /****************************************************************************
  176. update the enhanced security database. Only relevant for OSF1 at the moment.
  177. ****************************************************************************/
  178. void update_protected_database( char *user, BOOL result)
  179. {
  180. #ifdef OSF1_ENH_SEC
  181.   struct pr_passwd *mypasswd;
  182.   time_t starttime;
  183.   long tz;
  184.  
  185.   mypasswd = getprpwnam (user);
  186.   starttime = time (NULL);
  187.   tz = mktime ( localtime ( &starttime ) );
  188.  
  189.   if (result)
  190.     {
  191.       mypasswd->ufld.fd_slogin = tz;
  192.       mypasswd->ufld.fd_nlogins = 0;
  193.       
  194.       putprpwnam(user,mypasswd);
  195.       
  196.       DEBUG(3,("Update protected database for Account %s after succesful connection\n",user));
  197.     }
  198.   else
  199.     {
  200.       mypasswd->ufld.fd_ulogin = tz;
  201.       mypasswd->ufld.fd_nlogins = mypasswd->ufld.fd_nlogins + 1;
  202.       if ( mypasswd->ufld.fd_max_tries != 0 && mypasswd->ufld.fd_nlogins > mypasswd->ufld.fd_max_tries )
  203.     {
  204.       mypasswd->uflg.fg_lock = 0;
  205.       DEBUG(3,("Account is disabled -- see Account Administrator.\n"));
  206.     }
  207.       putprpwnam ( user , mypasswd );
  208.       DEBUG(3,("Update protected database for Account %s after refusing connection\n",user));
  209.     }
  210. #else
  211.   DEBUG(6,("Updated database with %s %s\n",user,BOOLSTR(result)));
  212. #endif
  213. }
  214.  
  215.  
  216.  
  217. /* these are kept here to keep the string_combinations function simple */
  218. char this_user[100]="";
  219. char this_salt[10]="";
  220. char this_crypted[100]="";
  221.  
  222.  
  223. /****************************************************************************
  224. core of password checking routine
  225. ****************************************************************************/
  226. BOOL password_check(char *password)
  227. {
  228.   DEBUG(4,("Checking password for user %s\n", this_user));
  229. #ifdef PWDAUTH
  230.   if (pwdauth(this_user,password) == 0)
  231.     return(True);
  232. #endif
  233. #ifdef OSF1_ENH_SEC
  234.   return(strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0);
  235. #endif
  236. #ifdef ULTRIX_AUTH
  237.   return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
  238. #endif
  239.   return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
  240. }
  241.  
  242. /****************************************************************************
  243. check if a username/password is OK
  244. ****************************************************************************/
  245. BOOL password_ok(char *user,char *password, struct passwd *pwd)
  246. {
  247.   int level = lp_passwordlevel();
  248.   struct passwd *pass;
  249.  
  250.   if (!password || !*password)
  251.     return(False);
  252.  
  253.   if (pwd && !user) 
  254.     {
  255.       pass = (struct passwd *) pwd;
  256.       user = pass->pw_name;
  257.     } 
  258.   else 
  259.     pass = Get_Pwnam(user);
  260.  
  261.   DEBUG(4,("Checking password for user %s\n",user));
  262.  
  263.   if (!pass) 
  264.     {
  265.       DEBUG(3,("Couldn't find user %s\n",user));
  266.       return(False);
  267.     }
  268.  
  269. #ifdef SHADOW_PWD
  270.   {
  271.     struct spwd *spass = getspnam(pass->pw_name);
  272.     if (spass && spass->sp_pwdp)
  273.       pass->pw_passwd = spass->sp_pwdp;
  274.   }
  275. #endif
  276.  
  277. #ifdef SecureWare
  278.   {
  279.     struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
  280.     if (pr_pw && pr_pw->ufld.fd_encrypt)
  281.       pass->pw_passwd = pr_pw->ufld.fd_encrypt;
  282.   }
  283. #endif
  284.  
  285. #ifdef OSF1_ENH_SEC
  286.   {
  287.     struct pr_passwd *mypasswd;
  288.     DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",user));
  289.     mypasswd = getprpwnam (user);
  290.     if ( mypasswd )
  291.       { 
  292.       strcpy(pass->pw_name,mypasswd->ufld.fd_name);
  293.       strcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
  294.       }
  295.     else
  296.       {
  297.     DEBUG(5,("No entry for user %s in protected database !\n",user));
  298.     return(False);
  299.       }
  300.   }
  301. #endif
  302.  
  303. #ifdef ULTRIX_AUTH
  304.   {
  305.     AUTHORIZATION *ap = getauthuid( pass->pw_uid );
  306.     if (ap)
  307.       {
  308.     strcpy( pass->pw_passwd, ap->a_password );
  309.     endauthent();
  310.       }
  311.   }
  312. #endif
  313.  
  314.   /* extract relevant info */
  315.   strcpy(this_user,pass->pw_name);  
  316.   StrnCpy(this_salt,pass->pw_passwd,2); this_salt[2] = 0;
  317.   strcpy(this_crypted,pass->pw_passwd);
  318.  
  319.   if (*this_crypted == 0 && !lp_null_passwords())
  320.     {
  321.       DEBUG(2,("Disallowing access to %s due to null password\n",this_user));
  322.       return(False);
  323.     }
  324.  
  325.  
  326.   /* try it as it came to us */
  327.   if (password_check(password))
  328.     {
  329.       update_protected_database(user,True);
  330.       return(True);
  331.     }
  332.  
  333.   /* try all lowercase */
  334.   strlower(password);
  335.   if (password_check(password))
  336.     {
  337.       update_protected_database(user,True);
  338.       return(True);
  339.     }
  340.  
  341.   /* give up? */
  342.   if(level < 1)
  343.     {
  344.       update_protected_database(user,False);
  345.       return(False);
  346.     }
  347.  
  348.   /* last chance - all combinations of up to level chars upper! */
  349.   strlower(password);
  350.  
  351.   if (string_combinations(password,0,password_check,level))
  352.     {
  353.       update_protected_database(user,True);
  354.       return(True);
  355.     }
  356.  
  357.   update_protected_database(user,False);
  358.   return(False);
  359. }
  360.  
  361.  
  362. /****************************************************************************
  363. check if a user is in a user list
  364. ****************************************************************************/
  365. BOOL user_in_list(char *user,char *list)
  366. {
  367.   pstring list2;
  368.   char *p;
  369.  
  370.   strcpy(list2,list);
  371.  
  372.   
  373.  
  374.   for (p = strtok(list2,LIST_SEP); p; p = strtok(NULL,LIST_SEP))
  375.     {
  376.       if (strequal(user,p))
  377.     return(True);
  378. #if HAVE_GETGRNAM 
  379.       if (*p == '@')
  380.     {
  381.       struct group *gptr = (struct group *)getgrnam(p+1);
  382.       char **member;
  383.       if (gptr)
  384.         {
  385.           member = gptr->gr_mem;
  386.           while (member && *member)
  387.         {
  388.           if (strequal(*member,user))
  389.             return(True);
  390.           member++;
  391.         }
  392.         }
  393.     }          
  394. #endif
  395.     }
  396.   return(False);
  397. }
  398.  
  399.  
  400.  
  401. /****************************************************************************
  402. check if a username is valid
  403. ****************************************************************************/
  404. BOOL user_ok(char *user,int snum)
  405. {
  406.   char *valid = lp_valid_users(snum);
  407.   char *invalid = lp_invalid_users(snum);
  408.   BOOL ret = !user_in_list(user,invalid);
  409.   if (ret && valid && *valid)
  410.     ret = user_in_list(user,valid);
  411.   return(ret);
  412. }
  413.  
  414.  
  415.  
  416.  
  417. /****************************************************************************
  418. validate a group username entry. Return the username or NULL
  419. ****************************************************************************/
  420. char *validate_group(char *group,char *password,int snum)
  421. {
  422. #if HAVE_GETGRNAM 
  423.   struct group *gptr = (struct group *)getgrnam(group);
  424.   char **member;
  425.   if (gptr)
  426.     {
  427.       member = gptr->gr_mem;
  428.       while (member && *member)
  429.     {
  430.       if (user_ok(*member,snum) &&
  431.           password_ok(*member,password,NULL))
  432.         return(*member);
  433.       member++;
  434.     }
  435. #ifdef GROUP_CHECK_PWENT
  436.       {
  437.       struct passwd *pwd;
  438.       static char tm[200];
  439.  
  440.       setpwent ();
  441.       while (pwd = getpwent ()) {
  442.           if (*(pwd->pw_passwd) && *password && pwd->pw_gid == gptr->gr_gid) {
  443.           /* This Entry have PASSWORD and same GID then check pwd */
  444.           if (password_ok (0, password, pwd)) {
  445.               strcpy (tm, pwd->pw_name);
  446.               endpwent ();
  447.               return tm;
  448.           }
  449.           }
  450.       }
  451.       endpwent ();
  452.       }
  453. #endif /* GROUP_CHECK_PWENT */
  454.     }              
  455. #endif
  456.   return(NULL);
  457. }
  458.  
  459.  
  460.  
  461. /****************************************************************************
  462. check for authority to login to a service with a given username/password
  463. ****************************************************************************/
  464. BOOL authorise_login(int snum,char *user,char *password,BOOL *guest,int vuid)
  465. {
  466.   BOOL ok = False;
  467.   pstring user_list;
  468.   char *auser;
  469.  
  470.   *guest = False;
  471.  
  472.   /* there are several possabilities:
  473.      1) login as the given user with given password
  474.      2) login as a previously registered username with the given password
  475.      3) login as a session list username with the given password
  476.      4) login as a previously validated user/password pair
  477.      5) login as the "user =" user with given password
  478.      6) login as the "user =" user with no password (guest connection)
  479.      7) login as guest user with no password
  480.  
  481.      if the service is guest_only then steps 1 to 5 are skipped
  482.   */
  483.  
  484.   if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
  485.     {
  486.  
  487.   if (!lp_onlyuser(snum))
  488.     {
  489.  
  490.       /* check the given username and password */
  491.       if (!ok && (*password) && (*user) && user_ok(user,snum))
  492.     {
  493.       ok = password_ok(user,password, NULL);
  494.       if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
  495.     }
  496.  
  497.       /* check for a previous registered username */
  498.       if (!ok && *password && (vuid >= 0) && validated_users[vuid].guest)
  499.      {
  500.  
  501.        if (user_ok(validated_users[vuid].name,snum) &&
  502.           password_ok(validated_users[vuid].name, password, NULL))
  503.          {
  504.            strcpy(user, validated_users[vuid].name);
  505.            validated_users[vuid].guest = False;
  506.            DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
  507.            ok = True;
  508.          }
  509.      }
  510.  
  511.  
  512.       /* now check the list of session users */
  513.       if (!ok && *password && !lp_onlyuser(snum))
  514.     {
  515.       strcpy(user_list,session_users);
  516.       
  517.       for (auser=strtok(user_list,LIST_SEP); 
  518.            !ok && auser; 
  519.            auser = strtok(NULL,LIST_SEP))
  520.         {
  521.           if (!user_ok(auser,snum)) continue;
  522.  
  523.           if (password_ok(auser,password, NULL))
  524.         {
  525.           ok = True;
  526.           strcpy(user,auser);
  527.           DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
  528.         }
  529.         }
  530.     }
  531.  
  532.       /* check for a previously validated username/password pair */
  533.       if (!ok && !lp_onlyuser(snum) && 
  534.       (vuid >= 0) && !validated_users[vuid].guest &&
  535.       user_ok(validated_users[vuid].name,snum))
  536.     {
  537.       strcpy(user,validated_users[vuid].name);
  538.       *guest = False;
  539.       DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
  540.       ok = True;
  541.     }
  542.  
  543.       /* check for a rhosts entry */
  544.       if (!ok && user_ok(user,snum) && check_hosts_equiv(user))
  545.     {
  546.       ok = True;
  547.       DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
  548.     }
  549.     }
  550.  
  551.       /* check the user= fields and the given password */
  552.       if (!ok && *password && USER(snum))
  553.     {
  554.       strcpy(user_list,USER(snum));
  555.  
  556.       for (auser=strtok(user_list,LIST_SEP);
  557.            auser && !ok;
  558.            auser = strtok(NULL,LIST_SEP))
  559.         {
  560.           if (*auser == '@')
  561.         {
  562.           auser = validate_group(auser+1,password,snum);
  563.           if (auser)
  564.             {
  565.               ok = True;
  566.               strcpy(user,auser);
  567.               DEBUG(3,("ACCEPTED: group username and given password ok\n"));
  568.             }
  569.         }
  570.           else
  571.         {
  572.           if (user_ok(auser,snum) && password_ok(auser,password,NULL))
  573.             {
  574.               ok = True;
  575.               strcpy(user,auser);
  576.               DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
  577.             }
  578.         }
  579.         }
  580.     }
  581.       
  582.     } /* not guest only */
  583.  
  584.   /* check for a user= with no password (guest connection) */
  585.   if (!ok && USER(snum) && (*USER(snum)) && GUEST_OK(snum))
  586.     {
  587.       strcpy(user_list,USER(snum));
  588.       auser = strtok(user_list,LIST_SEP);
  589.       if (*auser == '@')
  590.     DEBUG(2,("can't use group as guest user\n"));
  591.       else
  592.     {
  593.       if (auser && Get_Pwnam(auser))
  594.         {
  595.           ok = True;
  596.           strcpy(user,auser);
  597.           DEBUG(3,("ACCEPTED: user list username and guest ok\n"));
  598.         }
  599.       else
  600.         DEBUG(0,("Invalid user account %s??\n",auser?auser:"NULL"));
  601.     }
  602.       *guest = True;
  603.     }
  604.  
  605.   /* check for a normal guest connection */
  606.   if (!ok && GUEST && (*GUEST) && GUEST_OK(snum))
  607.     {
  608.       if (Get_Pwnam(GUEST))
  609.     {
  610.       strcpy(user,GUEST);
  611.       ok = True;
  612.       DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
  613.     }
  614.       else
  615.     DEBUG(0,("Invalid guest account %s??\n",GUEST?GUEST:"NULL"));
  616.       *guest = True;
  617.     }
  618.  
  619.   if (ok && !user_ok(user,snum))
  620.     {
  621.       DEBUG(0,("rejected invalid user %s\n",user));
  622.       ok = False;
  623.     }
  624.  
  625.   return(ok);
  626. }
  627.  
  628. /****************************************************************************
  629. read the a hosts.equiv or .rhosts file and check if it
  630. allows this user from this machine
  631. ****************************************************************************/
  632. BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
  633. {
  634.   pstring buf;
  635.   int plus_allowed = 1;
  636.   char *file_host;
  637.   char *file_user;
  638.   FILE *fp = fopen(equiv_file, "r");
  639.   DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
  640.   if (! fp) return False;
  641.   while(fgets(buf, sizeof(buf), fp)) 
  642.   {
  643.     trim_string(buf," "," ");
  644.  
  645.     if (buf[0] != '#' && buf[0] != '\n') 
  646.     {
  647.       BOOL is_group = False;
  648.       int plus = 1;
  649.       char *bp = buf;
  650.       if (strcmp(buf, "NO_PLUS\n") == 0)
  651.       {
  652.     DEBUG(6, ("check_user_equiv NO_PLUS\n"));
  653.     plus_allowed = 0;
  654.       }
  655.       else {
  656.     if (buf[0] == '+') 
  657.     {
  658.       bp++;
  659.       if (*bp == '\n' && plus_allowed) 
  660.       {
  661.         /* a bare plus means everbody allowed */
  662.         DEBUG(6, ("check_user_equiv everybody allowed\n"));
  663.         fclose(fp);
  664.         return True;
  665.       }
  666.     }
  667.     else if (buf[0] == '-')
  668.     {
  669.       bp++;
  670.       plus = 0;
  671.     }
  672.     if (*bp == '@') 
  673.     {
  674.       is_group = True;
  675.       bp++;
  676.     }
  677.     file_host = strtok(bp, " \t\n");
  678.     file_user = strtok(NULL, " \t\n");
  679.     DEBUG(7, ("check_user_equiv %s %s\n", file_host, file_user));
  680.     if (file_host && *file_host) 
  681.     {
  682.       BOOL host_ok = False;
  683.  
  684. #ifdef NETGROUP      
  685.       /* THIS IS UNTESTED!! */
  686.       if (is_group)
  687.         {
  688.           static char *mydomain = NULL;
  689.           if (!mydomain)
  690.         yp_get_default_domain(&mydomain);
  691.           if (mydomain && innetgr(remote,file_host,user,mydomain))
  692.         host_ok = True;
  693.         }
  694. #else
  695.       if (is_group)
  696.         {
  697.           DEBUG(1,("Netgroups not configured - add -DNETGROUP and recompile\n"));
  698.           continue;
  699.         }
  700. #endif
  701.  
  702.       /* is it this host */
  703.       /* the fact that remote has come from a call of gethostbyaddr
  704.        * means that it may have the fully qualified domain name
  705.        * so we could look up the file version to get it into
  706.        * a canonical form, but I would rather just type it
  707.        * in full in the equiv file
  708.        */
  709.       if (!host_ok && !is_group && strequal(remote, file_host))
  710.         host_ok = True;
  711.  
  712.       if (!host_ok)
  713.         continue;
  714.  
  715.       /* is it this user */
  716.       if (file_user == 0 || strequal(user, file_user)) 
  717.         {
  718.           fclose(fp);
  719.           DEBUG(5, ("check_user_equiv matched %s%s %s\n",
  720.             (plus ? "+" : "-"), file_host,
  721.             (file_user ? file_user : "")));
  722.           return (plus ? True : False);
  723.         }
  724.     }
  725.       }
  726.     }
  727.   }
  728.   fclose(fp);
  729.   return False;
  730. }
  731.  
  732.  
  733. /****************************************************************************
  734. check for a possible hosts equiv or rhosts entry for the user
  735. ****************************************************************************/
  736. BOOL check_hosts_equiv(char *user)
  737. {
  738.   char *fname = NULL;
  739.   pstring rhostsfile;
  740.   struct passwd *pass = Get_Pwnam(user);
  741.  
  742.   extern struct from_host Client_info;
  743.   extern int Client;
  744.  
  745.   if (!pass) 
  746.     return(False);
  747.  
  748.   fromhost(Client,&Client_info);
  749.  
  750.   fname = lp_hosts_equiv();
  751.  
  752.   /* note: don't allow hosts.equiv on root */
  753.   if (fname && *fname && (pass->pw_uid != 0))
  754.     {
  755.       if (check_user_equiv(user,Client_info.name,fname))
  756.     return(True);
  757.     }
  758.   
  759.   if (lp_use_rhosts())
  760.     {
  761.       char *home = get_home_dir(user);
  762.       if (home)
  763.     {
  764.       sprintf(rhostsfile, "%s/.rhosts", home);
  765.       if (check_user_equiv(user,Client_info.name,rhostsfile))
  766.         return(True);
  767.     }
  768.     }
  769.  
  770.   return(False);
  771. }
  772.  
  773.  
  774. /*******************************************************************
  775. set a user password. Assumes the oldpass is already validated.
  776. ********************************************************************/
  777. BOOL set_user_password(char *user,char *oldpass,char *newpass)
  778. {
  779. #ifdef ALLOW_CHANGE_PASSWORD
  780.   DEBUG(1,("Setting user password for: %s\n",user));
  781.   return (chgpasswd(user,oldpass,newpass));
  782. #else
  783.   DEBUG(3,("Change password is not supported: %s\n",user));
  784.   return (False);
  785. #endif
  786. }
  787.