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