Line data Source code
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 : #include "passdb.h"
26 :
27 : #undef DBGC_CLASS
28 : #define DBGC_CLASS DBGC_AUTH
29 :
30 10803 : static NTSTATUS auth_sam_ignoredomain_auth(const struct auth_context *auth_context,
31 : void *my_private_data,
32 : TALLOC_CTX *mem_ctx,
33 : const struct auth_usersupplied_info *user_info,
34 : struct auth_serversupplied_info **server_info)
35 : {
36 10803 : if (!user_info || !auth_context) {
37 0 : return NT_STATUS_UNSUCCESSFUL;
38 : }
39 :
40 21588 : if (user_info->mapped.account_name == NULL ||
41 10803 : user_info->mapped.account_name[0] == '\0')
42 : {
43 9 : return NT_STATUS_NOT_IMPLEMENTED;
44 : }
45 :
46 10794 : DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
47 : user_info->mapped.domain_name,
48 : user_info->mapped.account_name);
49 :
50 10794 : return check_sam_security(&auth_context->challenge, mem_ctx,
51 : user_info, server_info);
52 : }
53 :
54 : /* module initialisation */
55 58385 : static NTSTATUS auth_init_sam_ignoredomain(
56 : struct auth_context *auth_context,
57 : const char *param,
58 : struct auth_methods **auth_method)
59 : {
60 : struct auth_methods *result;
61 :
62 58385 : result = talloc_zero(auth_context, struct auth_methods);
63 58385 : if (result == NULL) {
64 0 : return NT_STATUS_NO_MEMORY;
65 : }
66 58385 : result->auth = auth_sam_ignoredomain_auth;
67 58385 : result->name = "sam_ignoredomain";
68 :
69 58385 : *auth_method = result;
70 58385 : return NT_STATUS_OK;
71 : }
72 :
73 :
74 : /****************************************************************************
75 : Check SAM security (above) but with a few extra checks.
76 : ****************************************************************************/
77 :
78 9969 : static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
79 : void *my_private_data,
80 : TALLOC_CTX *mem_ctx,
81 : const struct auth_usersupplied_info *user_info,
82 : struct auth_serversupplied_info **server_info)
83 : {
84 9969 : const char *effective_domain = NULL;
85 : bool is_local_name, is_my_domain;
86 :
87 9969 : if (!user_info || !auth_context) {
88 0 : return NT_STATUS_LOGON_FAILURE;
89 : }
90 9969 : effective_domain = user_info->mapped.domain_name;
91 :
92 19701 : if (user_info->mapped.account_name == NULL ||
93 9969 : user_info->mapped.account_name[0] == '\0')
94 : {
95 8 : return NT_STATUS_NOT_IMPLEMENTED;
96 : }
97 :
98 9961 : if (lp_server_role() == ROLE_DOMAIN_MEMBER) {
99 971 : const char *p = NULL;
100 :
101 971 : p = strchr_m(user_info->mapped.account_name, '@');
102 971 : if (p != NULL) {
103 : /*
104 : * This needs to go to the DC,
105 : * even if @ is the last character
106 : */
107 60 : return NT_STATUS_NOT_IMPLEMENTED;
108 : }
109 : }
110 :
111 9901 : if (effective_domain == NULL) {
112 0 : effective_domain = "";
113 : }
114 :
115 9901 : DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
116 : effective_domain,
117 : user_info->mapped.account_name);
118 :
119 :
120 9901 : if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
121 : /*
122 : * An empty domain name or '.' should be handled
123 : * as the local SAM name.
124 : */
125 130 : effective_domain = lp_netbios_name();
126 : }
127 :
128 9901 : is_local_name = is_myname(effective_domain);
129 9901 : is_my_domain = strequal(effective_domain, lp_workgroup());
130 :
131 : /* check whether or not we service this domain/workgroup name */
132 :
133 9901 : switch ( lp_server_role() ) {
134 911 : case ROLE_STANDALONE:
135 : case ROLE_DOMAIN_MEMBER:
136 911 : if ( !is_local_name ) {
137 174 : DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n",
138 : effective_domain, (lp_server_role() == ROLE_DOMAIN_MEMBER
139 : ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
140 174 : return NT_STATUS_NOT_IMPLEMENTED;
141 : }
142 :
143 737 : break;
144 8990 : case ROLE_DOMAIN_PDC:
145 : case ROLE_DOMAIN_BDC:
146 8990 : if (!is_local_name && !is_my_domain) {
147 : /* If we are running on a DC that has PASSDB module with domain
148 : * information, check if DNS forest name is matching the domain
149 : * name. This is the case of FreeIPA domain controller when
150 : * trusted AD DCs attempt to authenticate FreeIPA users using
151 : * the forest root domain (which is the only domain in FreeIPA).
152 : */
153 1529 : struct pdb_domain_info *dom_info = NULL;
154 :
155 1529 : dom_info = pdb_get_domain_info(mem_ctx);
156 1529 : if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
157 0 : is_my_domain = strequal(user_info->mapped.domain_name,
158 0 : dom_info->dns_forest);
159 : }
160 :
161 1529 : TALLOC_FREE(dom_info);
162 1529 : if (!is_my_domain) {
163 1529 : DEBUG(6,("check_samstrict_security: %s is not one "
164 : "of my local names or domain name (DC)\n",
165 : effective_domain));
166 1529 : return NT_STATUS_NOT_IMPLEMENTED;
167 : }
168 : }
169 :
170 7461 : break;
171 0 : default: /* name is ok */
172 0 : break;
173 : }
174 :
175 8198 : return check_sam_security(&auth_context->challenge, mem_ctx,
176 : user_info, server_info);
177 : }
178 :
179 : /* module initialisation */
180 25872 : static NTSTATUS auth_init_sam(
181 : struct auth_context *auth_context,
182 : const char *param,
183 : struct auth_methods **auth_method)
184 : {
185 : struct auth_methods *result;
186 :
187 25872 : if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
188 0 : && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
189 0 : DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the auth_sam module. \n"));
190 0 : DEBUGADD(0, ("You should not set 'auth methods' when running the AD DC.\n"));
191 0 : exit(1);
192 : }
193 :
194 25872 : result = talloc_zero(auth_context, struct auth_methods);
195 25872 : if (result == NULL) {
196 0 : return NT_STATUS_NO_MEMORY;
197 : }
198 25872 : result->auth = auth_samstrict_auth;
199 25872 : result->name = "sam";
200 25872 : *auth_method = result;
201 25872 : return NT_STATUS_OK;
202 : }
203 :
204 558 : static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
205 : void *my_private_data,
206 : TALLOC_CTX *mem_ctx,
207 : const struct auth_usersupplied_info *user_info,
208 : struct auth_serversupplied_info **server_info)
209 : {
210 558 : const char *effective_domain = NULL;
211 : bool is_my_domain;
212 :
213 558 : if (!user_info || !auth_context) {
214 0 : return NT_STATUS_LOGON_FAILURE;
215 : }
216 558 : effective_domain = user_info->mapped.domain_name;
217 :
218 1116 : if (user_info->mapped.account_name == NULL ||
219 558 : user_info->mapped.account_name[0] == '\0')
220 : {
221 0 : return NT_STATUS_NOT_IMPLEMENTED;
222 : }
223 :
224 558 : if (effective_domain == NULL) {
225 0 : effective_domain = "";
226 : }
227 :
228 558 : DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
229 : effective_domain,
230 : user_info->mapped.account_name);
231 :
232 : /* check whether or not we service this domain/workgroup name */
233 :
234 558 : switch (lp_server_role()) {
235 558 : case ROLE_DOMAIN_PDC:
236 : case ROLE_DOMAIN_BDC:
237 558 : break;
238 0 : default:
239 0 : DBG_ERR("Invalid server role\n");
240 0 : return NT_STATUS_INVALID_SERVER_STATE;
241 : }
242 :
243 558 : if (strequal(effective_domain, "") || strequal(effective_domain, ".")) {
244 : /*
245 : * An empty domain name or '.' should be handled
246 : * as the local SAM name.
247 : */
248 0 : effective_domain = lp_workgroup();
249 : }
250 :
251 558 : is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
252 558 : if (!is_my_domain) {
253 : /* If we are running on a DC that has PASSDB module with domain
254 : * information, check if DNS forest name is matching the domain
255 : * name. This is the case of FreeIPA domain controller when
256 : * trusted AD DCs attempt to authenticate FreeIPA users using
257 : * the forest root domain (which is the only domain in FreeIPA).
258 : */
259 0 : struct pdb_domain_info *dom_info = NULL;
260 0 : dom_info = pdb_get_domain_info(mem_ctx);
261 :
262 0 : if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
263 0 : is_my_domain = strequal(user_info->mapped.domain_name,
264 0 : dom_info->dns_forest);
265 : }
266 :
267 0 : TALLOC_FREE(dom_info);
268 : }
269 :
270 558 : if (!is_my_domain) {
271 0 : DBG_INFO("%s is not our domain name (DC for %s)\n",
272 : effective_domain, lp_workgroup());
273 0 : return NT_STATUS_NOT_IMPLEMENTED;
274 : }
275 :
276 558 : return check_sam_security(&auth_context->challenge, mem_ctx,
277 : user_info, server_info);
278 : }
279 :
280 : /* module initialisation */
281 558 : static NTSTATUS auth_init_sam_netlogon3(
282 : struct auth_context *auth_context,
283 : const char *param,
284 : struct auth_methods **auth_method)
285 : {
286 : struct auth_methods *result;
287 :
288 558 : if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
289 0 : && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
290 0 : DEBUG(0, ("server role = 'active directory domain controller' "
291 : "not compatible with running the auth_sam module.\n"));
292 0 : DEBUGADD(0, ("You should not set 'auth methods' when "
293 : "running the AD DC.\n"));
294 0 : exit(1);
295 : }
296 :
297 558 : result = talloc_zero(auth_context, struct auth_methods);
298 558 : if (result == NULL) {
299 0 : return NT_STATUS_NO_MEMORY;
300 : }
301 558 : result->auth = auth_sam_netlogon3_auth;
302 558 : result->name = "sam_netlogon3";
303 558 : *auth_method = result;
304 558 : return NT_STATUS_OK;
305 : }
306 :
307 26751 : NTSTATUS auth_sam_init(TALLOC_CTX *mem_ctx)
308 : {
309 26751 : smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
310 26751 : smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
311 26751 : smb_register_auth(AUTH_INTERFACE_VERSION, "sam_netlogon3", auth_init_sam_netlogon3);
312 26751 : return NT_STATUS_OK;
313 : }
|