Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header.
[metze/samba/wip.git] / source3 / auth / auth_rhosts.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Main SMB reply routines
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /****************************************************************************
25  Read the a hosts.equiv or .rhosts file and check if it
26  allows this user from this machine.
27 ****************************************************************************/
28
29 static BOOL check_user_equiv(const char *user, const char *remote, const char *equiv_file)
30 {
31   int plus_allowed = 1;
32   char *file_host;
33   char *file_user;
34   char **lines = file_lines_load(equiv_file, NULL);
35   int i;
36
37   DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
38   if (! lines) return False;
39   for (i=0; lines[i]; i++) {
40     char *buf = lines[i];
41     trim_string(buf," "," ");
42
43     if (buf[0] != '#' && buf[0] != '\n') 
44     {
45       BOOL is_group = False;
46       int plus = 1;
47       char *bp = buf;
48       if (strcmp(buf, "NO_PLUS\n") == 0)
49       {
50         DEBUG(6, ("check_user_equiv NO_PLUS\n"));
51         plus_allowed = 0;
52       }
53       else {
54         if (buf[0] == '+') 
55         {
56           bp++;
57           if (*bp == '\n' && plus_allowed) 
58           {
59             /* a bare plus means everbody allowed */
60             DEBUG(6, ("check_user_equiv everybody allowed\n"));
61             file_lines_free(lines);
62             return True;
63           }
64         }
65         else if (buf[0] == '-')
66         {
67           bp++;
68           plus = 0;
69         }
70         if (*bp == '@') 
71         {
72           is_group = True;
73           bp++;
74         }
75         file_host = strtok(bp, " \t\n");
76         file_user = strtok(NULL, " \t\n");
77         DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)", 
78                  file_user ? file_user : "(null)" ));
79         if (file_host && *file_host) 
80         {
81           BOOL host_ok = False;
82
83 #if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN)
84           if (is_group)
85             {
86               static char *mydomain = NULL;
87               if (!mydomain)
88                 yp_get_default_domain(&mydomain);
89               if (mydomain && innetgr(file_host,remote,user,mydomain))
90                 host_ok = True;
91             }
92 #else
93           if (is_group)
94             {
95               DEBUG(1,("Netgroups not configured\n"));
96               continue;
97             }
98 #endif
99
100           /* is it this host */
101           /* the fact that remote has come from a call of gethostbyaddr
102            * means that it may have the fully qualified domain name
103            * so we could look up the file version to get it into
104            * a canonical form, but I would rather just type it
105            * in full in the equiv file
106            */
107           if (!host_ok && !is_group && strequal(remote, file_host))
108             host_ok = True;
109
110           if (!host_ok)
111             continue;
112
113           /* is it this user */
114           if (file_user == 0 || strequal(user, file_user)) 
115             {
116               DEBUG(5, ("check_user_equiv matched %s%s %s\n",
117                         (plus ? "+" : "-"), file_host,
118                         (file_user ? file_user : "")));
119               file_lines_free(lines);
120               return (plus ? True : False);
121             }
122         }
123       }
124     }
125   }
126   file_lines_free(lines);
127   return False;
128 }
129
130
131 /****************************************************************************
132 check for a possible hosts equiv or rhosts entry for the user
133 ****************************************************************************/
134 static BOOL check_hosts_equiv(char *user) /* should be const... */
135 {
136   char *fname = NULL;
137   pstring rhostsfile;
138   struct passwd *pass = Get_Pwnam(user,False);
139
140   if (!pass) 
141     return(False);
142
143   fname = lp_hosts_equiv();
144
145   /* note: don't allow hosts.equiv on root */
146   if (fname && *fname && (pass->pw_uid != 0)) {
147           if (check_user_equiv(pass->pw_name,client_name(),fname))
148                   return(True);
149   }
150   
151   if (lp_use_rhosts())
152     {
153       char *home = pass->pw_dir;
154       if (home) {
155               slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
156               if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
157                       return(True);
158       }
159     }
160
161   return(False);
162 }
163
164 /****************************************************************************
165  Check for a valid .rhosts/hosts.equiv entry for this user
166 ****************************************************************************/
167
168 NTSTATUS check_rhosts_security(const auth_usersupplied_info *user_info, 
169                              auth_serversupplied_info *server_info)
170 {
171         NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
172
173         become_root();
174         if (check_hosts_equiv(user_info->unix_username.str)) {
175                 nt_status = NT_STATUS_OK;
176         }
177         unbecome_root();
178
179         return nt_status;
180 }