2 Unix SMB/CIFS implementation.
3 Main SMB reply routines
4 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
24 #define DBGC_CLASS DBGC_AUTH
26 /****************************************************************************
27 Create a struct samu - either by looking in the pdb, or by faking it up from
29 ****************************************************************************/
31 static NTSTATUS
auth_get_sam_account(const char *user
, struct samu
**account
)
34 NTSTATUS nt_status
= NT_STATUS_NO_SUCH_USER
;
36 if ( !(*account
= samu_new( NULL
)) ) {
37 return NT_STATUS_NO_MEMORY
;
41 pdb_ret
= pdb_getsampwnam(*account
, user
);
48 if ( !(pass
= Get_Pwnam( user
)) ) {
49 return NT_STATUS_NO_SUCH_USER
;
52 nt_status
= samu_set_unix( *account
, pass
);
58 /****************************************************************************
59 Read the a hosts.equiv or .rhosts file and check if it
60 allows this user from this machine.
61 ****************************************************************************/
63 static BOOL
check_user_equiv(const char *user
, const char *remote
, const char *equiv_file
)
68 char **lines
= file_lines_load(equiv_file
, NULL
,0);
71 DEBUG(5, ("check_user_equiv %s %s %s\n", user
, remote
, equiv_file
));
75 for (i
=0; lines
[i
]; i
++) {
77 trim_char(buf
,' ',' ');
79 if (buf
[0] != '#' && buf
[0] != '\n') {
80 BOOL is_group
= False
;
84 if (strcmp(buf
, "NO_PLUS\n") == 0) {
85 DEBUG(6, ("check_user_equiv NO_PLUS\n"));
90 if (*bp
== '\n' && plus_allowed
) {
91 /* a bare plus means everbody allowed */
92 DEBUG(6, ("check_user_equiv everybody allowed\n"));
93 file_lines_free(lines
);
96 } else if (buf
[0] == '-') {
104 file_host
= strtok(bp
, " \t\n");
105 file_user
= strtok(NULL
, " \t\n");
106 DEBUG(7, ("check_user_equiv %s %s\n", file_host
? file_host
: "(null)",
107 file_user
? file_user
: "(null)" ));
109 if (file_host
&& *file_host
) {
110 BOOL host_ok
= False
;
112 #if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN)
114 static char *mydomain
= NULL
;
116 yp_get_default_domain(&mydomain
);
118 if (mydomain
&& innetgr(file_host
,remote
,user
,mydomain
)) {
124 DEBUG(1,("Netgroups not configured\n"));
129 /* is it this host */
130 /* the fact that remote has come from a call of gethostbyaddr
131 * means that it may have the fully qualified domain name
132 * so we could look up the file version to get it into
133 * a canonical form, but I would rather just type it
134 * in full in the equiv file
137 if (!host_ok
&& !is_group
&& strequal(remote
, file_host
)) {
145 /* is it this user */
146 if (file_user
== 0 || strequal(user
, file_user
)) {
147 DEBUG(5, ("check_user_equiv matched %s%s %s\n",
148 (plus
? "+" : "-"), file_host
,
149 (file_user
? file_user
: "")));
150 file_lines_free(lines
);
151 return (plus
? True
: False
);
158 file_lines_free(lines
);
162 /****************************************************************************
163 check for a possible hosts equiv or rhosts entry for the user
164 ****************************************************************************/
166 static BOOL
check_hosts_equiv(struct samu
*account
)
171 fname
= lp_hosts_equiv();
172 if (!sid_to_uid(pdb_get_user_sid(account
), &uid
))
175 /* note: don't allow hosts.equiv on root */
176 if (fname
&& *fname
&& uid
!= 0) {
177 if (check_user_equiv(pdb_get_username(account
),client_name(),fname
))
185 /****************************************************************************
186 Check for a valid .rhosts/hosts.equiv entry for this user
187 ****************************************************************************/
189 static NTSTATUS
check_hostsequiv_security(const struct auth_context
*auth_context
,
190 void *my_private_data
,
192 const auth_usersupplied_info
*user_info
,
193 auth_serversupplied_info
**server_info
)
196 struct samu
*account
= NULL
;
197 if (!NT_STATUS_IS_OK(nt_status
=
198 auth_get_sam_account(user_info
->internal_username
,
200 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_SUCH_USER
))
201 nt_status
= NT_STATUS_NOT_IMPLEMENTED
;
205 if (check_hosts_equiv(account
)) {
206 nt_status
= make_server_info_sam(server_info
, account
);
207 if (!NT_STATUS_IS_OK(nt_status
)) {
208 TALLOC_FREE(account
);
211 TALLOC_FREE(account
);
212 nt_status
= NT_STATUS_NOT_IMPLEMENTED
;
218 /* module initialisation */
219 static NTSTATUS
auth_init_hostsequiv(struct auth_context
*auth_context
, const char* param
, auth_methods
**auth_method
)
221 if (!make_auth_methods(auth_context
, auth_method
)) {
222 return NT_STATUS_NO_MEMORY
;
225 (*auth_method
)->auth
= check_hostsequiv_security
;
226 (*auth_method
)->name
= "hostsequiv";
231 /****************************************************************************
232 Check for a valid .rhosts/hosts.equiv entry for this user
233 ****************************************************************************/
235 static NTSTATUS
check_rhosts_security(const struct auth_context
*auth_context
,
236 void *my_private_data
,
238 const auth_usersupplied_info
*user_info
,
239 auth_serversupplied_info
**server_info
)
242 struct samu
*account
= NULL
;
246 if (!NT_STATUS_IS_OK(nt_status
=
247 auth_get_sam_account(user_info
->internal_username
,
249 if (NT_STATUS_EQUAL(nt_status
, NT_STATUS_NO_SUCH_USER
))
250 nt_status
= NT_STATUS_NOT_IMPLEMENTED
;
254 home
= pdb_get_unix_homedir(account
);
257 slprintf(rhostsfile
, sizeof(rhostsfile
)-1, "%s/.rhosts", home
);
259 if (check_user_equiv(pdb_get_username(account
),client_name(),rhostsfile
)) {
260 nt_status
= make_server_info_sam(server_info
, account
);
261 if (!NT_STATUS_IS_OK(nt_status
)) {
262 TALLOC_FREE(account
);
265 TALLOC_FREE(account
);
269 TALLOC_FREE(account
);
270 nt_status
= NT_STATUS_NOT_IMPLEMENTED
;
276 /* module initialisation */
277 static NTSTATUS
auth_init_rhosts(struct auth_context
*auth_context
, const char *param
, auth_methods
**auth_method
)
279 if (!make_auth_methods(auth_context
, auth_method
)) {
280 return NT_STATUS_NO_MEMORY
;
283 (*auth_method
)->auth
= check_rhosts_security
;
284 (*auth_method
)->name
= "rhosts";
288 NTSTATUS
auth_rhosts_init(void)
290 smb_register_auth(AUTH_INTERFACE_VERSION
, "rhosts", auth_init_rhosts
);
291 smb_register_auth(AUTH_INTERFACE_VERSION
, "hostsequiv", auth_init_hostsequiv
);