1 /*
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Andrew Tridgell              1992-2000
5    Copyright (C) Luke Kenneth Casson Leighton 1996-2000
6    Copyright (C) Andrew Bartlett              2001-2003
7    Copyright (C) Gerald Carter                2003
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #include "includes.h"
24 #include "auth.h"
25 
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_AUTH
28 
auth_sam_ignoredomain_auth(const struct auth_context * auth_context,void * my_private_data,TALLOC_CTX * mem_ctx,const struct auth_usersupplied_info * user_info,struct auth_serversupplied_info ** server_info)29 static NTSTATUS auth_sam_ignoredomain_auth(const struct auth_context *auth_context,
30 					   void *my_private_data,
31 					   TALLOC_CTX *mem_ctx,
32 					   const struct auth_usersupplied_info *user_info,
33 					   struct auth_serversupplied_info **server_info)
34 {
35 	if (!user_info || !auth_context) {
36 		return NT_STATUS_UNSUCCESSFUL;
37 	}
38 
39 	if (user_info->mapped.account_name == NULL ||
40 	    user_info->mapped.account_name[0] == '\0')
41 	{
42 		return NT_STATUS_NOT_IMPLEMENTED;
43 	}
44 
45 	DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
46 		  user_info->mapped.domain_name,
47 		  user_info->mapped.account_name);
48 
49 	return check_sam_security(&auth_context->challenge, mem_ctx,
50 				  user_info, server_info);
51 }
52 
53 /* module initialisation */
auth_init_sam_ignoredomain(struct auth_context * auth_context,const char * param,struct auth_methods ** auth_method)54 static NTSTATUS auth_init_sam_ignoredomain(
55 	struct auth_context *auth_context,
56 	const char *param,
57 	struct auth_methods **auth_method)
58 {
59 	struct auth_methods *result;
60 
61 	result = talloc_zero(auth_context, struct auth_methods);
62 	if (result == NULL) {
63 		return NT_STATUS_NO_MEMORY;
64 	}
65 	result->auth = auth_sam_ignoredomain_auth;
66 	result->name = "sam_ignoredomain";
67 
68         *auth_method = result;
69 	return NT_STATUS_OK;
70 }
71 
72 
73 /****************************************************************************
74 Check SAM security (above) but with a few extra checks.
75 ****************************************************************************/
76 
auth_samstrict_auth(const struct auth_context * auth_context,void * my_private_data,TALLOC_CTX * mem_ctx,const struct auth_usersupplied_info * user_info,struct auth_serversupplied_info ** server_info)77 static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
78 				    void *my_private_data,
79 				    TALLOC_CTX *mem_ctx,
80 				    const struct auth_usersupplied_info *user_info,
81 				    struct auth_serversupplied_info **server_info)
82 {
83 	const char *effective_domain = NULL;
84 	bool is_local_name, is_my_domain;
85 
86 	if (!user_info || !auth_context) {
87 		return NT_STATUS_LOGON_FAILURE;
88 	}
89 	effective_domain = user_info->mapped.domain_name;
90 
91 	if (user_info->mapped.account_name == NULL ||
92 	    user_info->mapped.account_name[0] == '\0')
93 	{
94 		return NT_STATUS_NOT_IMPLEMENTED;
95 	}
96 
97 	if (lp_server_role() == ROLE_DOMAIN_MEMBER) {
98 		const char *p = NULL;
99 
100 		p = strchr_m(user_info->mapped.account_name, '@');
101 		if (p != NULL) {
102 			/*
103 			 * This needs to go to the DC,
104 			 * even if @ is the last character
105 			 */
106 			return NT_STATUS_NOT_IMPLEMENTED;
107 		}
108 	}
109 
110 	if (effective_domain == NULL) {
111 		effective_domain = "";
112 	}
113 
114 	DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
115 		  effective_domain,
116 		  user_info->mapped.account_name);
117 
118 
119 	if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
120 		/*
121 		 * An empty domain name or '.' should be handled
122 		 * as the local SAM name.
123 		 */
124 		effective_domain = lp_netbios_name();
125 	}
126 
127 	is_local_name = is_myname(effective_domain);
128 	is_my_domain  = strequal(effective_domain, lp_workgroup());
129 
130 	/* check whether or not we service this domain/workgroup name */
131 
132 	switch ( lp_server_role() ) {
133 		case ROLE_STANDALONE:
134 		case ROLE_DOMAIN_MEMBER:
135 			if ( !is_local_name ) {
136 				DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n",
137 					effective_domain, (lp_server_role() == ROLE_DOMAIN_MEMBER
138 					? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
139 				return NT_STATUS_NOT_IMPLEMENTED;
140 			}
141 
142 			break;
143 		case ROLE_DOMAIN_PDC:
144 		case ROLE_DOMAIN_BDC:
145 			if ( !is_local_name && !is_my_domain ) {
146 				DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
147 					effective_domain));
148 				return NT_STATUS_NOT_IMPLEMENTED;
149 			}
150 
151 			break;
152 		default: /* name is ok */
153 			break;
154 	}
155 
156 	return check_sam_security(&auth_context->challenge, mem_ctx,
157 				  user_info, server_info);
158 }
159 
160 /* module initialisation */
auth_init_sam(struct auth_context * auth_context,const char * param,struct auth_methods ** auth_method)161 static NTSTATUS auth_init_sam(
162 	struct auth_context *auth_context,
163 	const char *param,
164 	struct auth_methods **auth_method)
165 {
166 	struct auth_methods *result;
167 
168 	if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
169 	    && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
170 		DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the auth_sam module. \n"));
171 		DEBUGADD(0, ("You should not set 'auth methods' when running the AD DC.\n"));
172 		exit(1);
173 	}
174 
175 	result = talloc_zero(auth_context, struct auth_methods);
176 	if (result == NULL) {
177 		return NT_STATUS_NO_MEMORY;
178 	}
179 	result->auth = auth_samstrict_auth;
180 	result->name = "sam";
181 	*auth_method = result;
182 	return NT_STATUS_OK;
183 }
184 
auth_sam_netlogon3_auth(const struct auth_context * auth_context,void * my_private_data,TALLOC_CTX * mem_ctx,const struct auth_usersupplied_info * user_info,struct auth_serversupplied_info ** server_info)185 static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
186 					void *my_private_data,
187 					TALLOC_CTX *mem_ctx,
188 					const struct auth_usersupplied_info *user_info,
189 					struct auth_serversupplied_info **server_info)
190 {
191 	const char *effective_domain = NULL;
192 	bool is_my_domain;
193 
194 	if (!user_info || !auth_context) {
195 		return NT_STATUS_LOGON_FAILURE;
196 	}
197 	effective_domain = user_info->mapped.domain_name;
198 
199 	if (user_info->mapped.account_name == NULL ||
200 	    user_info->mapped.account_name[0] == '\0')
201 	{
202 		return NT_STATUS_NOT_IMPLEMENTED;
203 	}
204 
205 	if (effective_domain == NULL) {
206 		effective_domain = "";
207 	}
208 
209 	DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
210 		  effective_domain,
211 		  user_info->mapped.account_name);
212 
213 	/* check whether or not we service this domain/workgroup name */
214 
215 	switch (lp_server_role()) {
216 	case ROLE_DOMAIN_PDC:
217 	case ROLE_DOMAIN_BDC:
218 		break;
219 	default:
220 		DBG_ERR("Invalid server role\n");
221 		return NT_STATUS_INVALID_SERVER_STATE;
222 	}
223 
224 	if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
225 		/*
226 		 * An empty domain name or '.' should be handled
227 		 * as the local SAM name.
228 		 */
229 		effective_domain = lp_workgroup();
230 	}
231 
232 	is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
233 	if (!is_my_domain) {
234 		DBG_INFO("%s is not our domain name (DC for %s)\n",
235 			 effective_domain, lp_workgroup());
236 		return NT_STATUS_NOT_IMPLEMENTED;
237 	}
238 
239 	return check_sam_security(&auth_context->challenge, mem_ctx,
240 				  user_info, server_info);
241 }
242 
243 /* module initialisation */
auth_init_sam_netlogon3(struct auth_context * auth_context,const char * param,struct auth_methods ** auth_method)244 static NTSTATUS auth_init_sam_netlogon3(
245 	struct auth_context *auth_context,
246 	const char *param,
247 	struct auth_methods **auth_method)
248 {
249 	struct auth_methods *result;
250 
251 	if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
252 	    && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
253 		DEBUG(0, ("server role = 'active directory domain controller' "
254 			  "not compatible with running the auth_sam module.\n"));
255 		DEBUGADD(0, ("You should not set 'auth methods' when "
256 			     "running the AD DC.\n"));
257 		exit(1);
258 	}
259 
260 	result = talloc_zero(auth_context, struct auth_methods);
261 	if (result == NULL) {
262 		return NT_STATUS_NO_MEMORY;
263 	}
264 	result->auth = auth_sam_netlogon3_auth;
265 	result->name = "sam_netlogon3";
266 	*auth_method = result;
267 	return NT_STATUS_OK;
268 }
269 
auth_sam_init(TALLOC_CTX * mem_ctx)270 NTSTATUS auth_sam_init(TALLOC_CTX *mem_ctx)
271 {
272 	smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
273 	smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
274 	smb_register_auth(AUTH_INTERFACE_VERSION, "sam_netlogon3", auth_init_sam_netlogon3);
275 	return NT_STATUS_OK;
276 }
277