r4339: - rename auth_guest to auth_anonymous
[samba.git] / source4 / auth / auth_builtin.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Generic authentication types
4    Copyright (C) Andrew Bartlett         2001-2002
5    Copyright (C) Jelmer Vernooij              2002
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 #include "auth/auth.h"
24 #include "librpc/gen_ndr/ndr_samr.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
29
30 /***************************************************************************
31  Make (and fill) a user_info struct for a anonymous login.
32 ***************************************************************************/
33 static NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx, struct auth_serversupplied_info **server_info)
34 {
35         *server_info = talloc_p(mem_ctx, struct auth_serversupplied_info);
36         if (!*server_info) {
37                 return NT_STATUS_NO_MEMORY;
38         }
39
40         (*server_info)->guest = True;
41
42         (*server_info)->user_sid = dom_sid_parse_talloc((*server_info), SID_NT_ANONYMOUS);
43
44         /* is this correct? */
45         (*server_info)->primary_group_sid = dom_sid_parse_talloc((*server_info), SID_BUILTIN_GUESTS);
46
47         (*server_info)->n_domain_groups = 0;
48         (*server_info)->domain_groups = NULL;
49
50         /* annoying, but the Guest really does have a session key, 
51            and it is all zeros! */
52         (*server_info)->user_session_key = data_blob_talloc(*server_info, NULL, 16);
53         (*server_info)->lm_session_key = data_blob_talloc(*server_info, NULL, 16);
54
55         data_blob_clear(&(*server_info)->user_session_key);
56         data_blob_clear(&(*server_info)->lm_session_key);
57
58         (*server_info)->account_name = talloc_strdup((*server_info), "ANONYMOUS LOGON");
59         (*server_info)->domain = talloc_strdup((*server_info), "NT AUTHORITY");
60         (*server_info)->full_name = talloc_strdup((*server_info), "Anonymous Logon");
61         (*server_info)->logon_script = talloc_strdup((*server_info), "");
62         (*server_info)->profile_path = talloc_strdup((*server_info), "");
63         (*server_info)->home_directory = talloc_strdup((*server_info), "");
64         (*server_info)->home_drive = talloc_strdup((*server_info), "");
65
66         (*server_info)->last_logon = 0;
67         (*server_info)->last_logoff = 0;
68         (*server_info)->acct_expiry = 0;
69         (*server_info)->last_password_change = 0;
70         (*server_info)->allow_password_change = 0;
71         (*server_info)->force_password_change = 0;
72
73         (*server_info)->logon_count = 0;
74         (*server_info)->bad_password_count = 0;
75
76         (*server_info)->acct_flags = ACB_NORMAL;
77
78         return NT_STATUS_OK;
79 }
80
81 /**
82  * Return a anonymous logon for anonymous users (username = "")
83  *
84  * Typically used as the first module in the auth chain, this allows
85  * guest logons to be dealt with in one place.  Non-guest logons 'fail'
86  * and pass onto the next module.
87  **/
88
89 static NTSTATUS check_anonymous_security(const struct auth_context *auth_context,
90                                      void *my_private_data, 
91                                      TALLOC_CTX *mem_ctx,
92                                      const struct auth_usersupplied_info *user_info, 
93                                      struct auth_serversupplied_info **server_info)
94 {
95         /* mark this as 'not for me' */
96         NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
97
98         if (!(user_info->internal_username.str 
99               && *user_info->internal_username.str)) {
100                 nt_status = make_server_info_anonymous(discard_const(auth_context), 
101                                                         server_info);
102         }
103
104         return nt_status;
105 }
106
107 /* Guest modules initialisation */
108
109 static NTSTATUS auth_init_anonymous(struct auth_context *auth_context, 
110                                 const char *options, 
111                                 struct auth_methods **auth_method) 
112 {
113         if (!make_auth_methods(auth_context, auth_method))
114                 return NT_STATUS_NO_MEMORY;
115
116         (*auth_method)->auth = check_anonymous_security;
117         (*auth_method)->name = "anonymous";
118         return NT_STATUS_OK;
119 }
120
121 #ifdef DEVELOPER
122 /** 
123  * Return an error based on username
124  *
125  * This function allows the testing of obsure errors, as well as the generation
126  * of NT_STATUS -> DOS error mapping tables.
127  *
128  * This module is of no value to end-users.
129  *
130  * The password is ignored.
131  *
132  * @return An NTSTATUS value based on the username
133  **/
134
135 static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
136                                                 void *my_private_data, 
137                                                 TALLOC_CTX *mem_ctx,
138                                                 const struct auth_usersupplied_info *user_info, 
139                                                 struct auth_serversupplied_info **server_info)
140 {
141         NTSTATUS nt_status;
142         fstring user;
143         long error_num;
144         fstrcpy(user, user_info->smb_name.str);
145         
146         if (strncasecmp("NT_STATUS", user, strlen("NT_STATUS")) == 0) {
147                 return nt_status_string_to_code(user);
148         }
149
150         error_num = strtoul(user, NULL, 16);
151         
152         DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was 0x%lx\n", user, error_num));
153
154         nt_status = NT_STATUS(error_num);
155         
156         return nt_status;
157 }
158
159 /** Module initialisation function */
160
161 static NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, 
162                                            const char *param, 
163                                            struct auth_methods **auth_method) 
164 {
165         if (!make_auth_methods(auth_context, auth_method))
166                 return NT_STATUS_NO_MEMORY;
167
168         (*auth_method)->auth = check_name_to_ntstatus_security;
169         (*auth_method)->name = "name_to_ntstatus";
170         return NT_STATUS_OK;
171 }
172
173 /** 
174  * Return a 'fixed' challenge instead of a variable one.
175  *
176  * The idea of this function is to make packet snifs consistant
177  * with a fixed challenge, so as to aid debugging.
178  *
179  * This module is of no value to end-users.
180  *
181  * This module does not actually authenticate the user, but
182  * just pretenteds to need a specified challenge.  
183  * This module removes *all* security from the challenge-response system
184  *
185  * @return NT_STATUS_UNSUCCESSFUL
186  **/
187
188 static NTSTATUS check_fixed_challenge_security(const struct auth_context *auth_context,
189                                                void *my_private_data, 
190                                                TALLOC_CTX *mem_ctx,
191                                                const struct auth_usersupplied_info *user_info, 
192                                                struct auth_serversupplied_info **server_info)
193 {
194         return NT_STATUS_NOT_IMPLEMENTED;
195 }
196
197 /****************************************************************************
198  Get the challenge out of a password server.
199 ****************************************************************************/
200
201 static DATA_BLOB auth_get_fixed_challenge(const struct auth_context *auth_context,
202                                           void **my_private_data, 
203                                           TALLOC_CTX *mem_ctx)
204 {
205         const char *challenge = "I am a teapot";   
206         return data_blob(challenge, 8);
207 }
208
209
210 /** Module initailisation function */
211
212 static NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, 
213                                           const char *param, 
214                                           struct auth_methods **auth_method) 
215 {
216         if (!make_auth_methods(auth_context, auth_method))
217                 return NT_STATUS_NO_MEMORY;
218
219         (*auth_method)->auth = check_fixed_challenge_security;
220         (*auth_method)->get_chal = auth_get_fixed_challenge;
221         (*auth_method)->name = "fixed_challenge";
222         return NT_STATUS_OK;
223 }
224 #endif /* DEVELOPER */
225
226 NTSTATUS auth_builtin_init(void)
227 {
228         NTSTATUS ret;
229         struct auth_operations ops;
230
231         ops.name = "anonymous";
232         ops.init = auth_init_anonymous;
233         ret = auth_register(&ops);
234         if (!NT_STATUS_IS_OK(ret)) {
235                 DEBUG(0,("Failed to register '%s' auth backend!\n",
236                         ops.name));
237                 return ret;
238         }
239
240 #ifdef DEVELOPER
241         ops.name = "name_to_ntstatus";
242         ops.init = auth_init_name_to_ntstatus;
243         ret = auth_register(&ops);
244         if (!NT_STATUS_IS_OK(ret)) {
245                 DEBUG(0,("Failed to register '%s' auth backend!\n",
246                         ops.name));
247                 return ret;
248         }
249
250         ops.name = "fixed_challenge";
251         ops.init = auth_init_fixed_challenge;
252         ret = auth_register(&ops);
253         if (!NT_STATUS_IS_OK(ret)) {
254                 DEBUG(0,("Failed to register '%s' auth backend!\n",
255                         ops.name));
256                 return ret;
257         }
258 #endif /* DEVELOPER */
259         return ret;
260 }