s4-auth Remove event context from privilage database handling
[amitay/samba.git] / source4 / auth / session.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001-2010
6    Copyright (C) Jeremy Allison 2000-2001
7    Copyright (C) Rafal Szczesniak 2002
8    Copyright (C) Stefan Metzmacher 2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "auth/auth.h"
26 #include "libcli/security/security.h"
27 #include "libcli/auth/libcli_auth.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "auth/session_proto.h"
30
31 _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, 
32                                             struct loadparm_context *lp_ctx)
33 {
34         NTSTATUS nt_status;
35         struct auth_session_info *session_info = NULL;
36         nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info);
37         if (!NT_STATUS_IS_OK(nt_status)) {
38                 return NULL;
39         }
40         return session_info;
41 }
42
43 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
44                                              struct auth_context *auth_context, /* Optional if the domain SID is in the NT AUTHORITY domain */
45                                              struct auth_serversupplied_info *server_info,
46                                              uint32_t session_info_flags,
47                                              struct auth_session_info **_session_info)
48 {
49         struct auth_session_info *session_info;
50         NTSTATUS nt_status;
51         unsigned int i, num_groupSIDs = 0;
52         const char *account_sid_string;
53         const char *account_sid_dn;
54         DATA_BLOB account_sid_blob;
55         const char *primary_group_string;
56         const char *primary_group_dn;
57         DATA_BLOB primary_group_blob;
58
59         const char *filter;
60
61         struct dom_sid **groupSIDs = NULL;
62         const struct dom_sid *anonymous_sid, *system_sid;
63
64         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
65         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
66
67         session_info = talloc(tmp_ctx, struct auth_session_info);
68         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx);
69
70         session_info->server_info = talloc_reference(session_info, server_info);
71
72         /* unless set otherwise, the session key is the user session
73          * key from the auth subsystem */ 
74         session_info->session_key = server_info->user_session_key;
75
76         anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS);
77         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx);
78
79         system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM);
80         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx);
81
82         if (dom_sid_equal(anonymous_sid, server_info->account_sid)) {
83                 /* Don't expand nested groups of system, anonymous etc*/
84         } else if (dom_sid_equal(system_sid, server_info->account_sid)) {
85                 /* Don't expand nested groups of system, anonymous etc*/
86         } else if (auth_context) {
87                 groupSIDs = talloc_array(tmp_ctx, struct dom_sid *, server_info->n_domain_groups);
88                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs, tmp_ctx);
89                 if (!groupSIDs) {
90                         talloc_free(tmp_ctx);
91                         return NT_STATUS_NO_MEMORY;
92                 }
93                 
94                 num_groupSIDs = server_info->n_domain_groups;
95                 
96                 for (i=0; i < server_info->n_domain_groups; i++) {
97                         groupSIDs[i] = server_info->domain_groups[i];
98                 }
99                 
100                 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
101                                          GROUP_TYPE_BUILTIN_LOCAL_GROUP);
102
103                 /* Search for each group in the token */
104
105                 /* Expands the account SID - this function takes in
106                  * memberOf-like values, so we fake one up with the
107                  * <SID=S-...> format of DN and then let it expand
108                  * them, as long as they meet the filter - so only
109                  * builtin groups
110                  *
111                  * We already have the primary group in the token, so set
112                  * 'only childs' flag to true
113                  */
114                 account_sid_string = dom_sid_string(tmp_ctx, server_info->account_sid);
115                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid_string, server_info);
116                 
117                 account_sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", account_sid_string);
118                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid_dn, server_info);
119                 
120                 account_sid_blob = data_blob_string_const(account_sid_dn);
121                 
122                 nt_status = authsam_expand_nested_groups(auth_context->sam_ctx, &account_sid_blob, true, filter,
123                                                          tmp_ctx, &groupSIDs, &num_groupSIDs);
124                 if (!NT_STATUS_IS_OK(nt_status)) {
125                         talloc_free(tmp_ctx);
126                         return nt_status;
127                 }
128
129                 /* Expands the primary group - this function takes in
130                  * memberOf-like values, so we fake one up with the
131                  * <SID=S-...> format of DN and then let it expand
132                  * them, as long as they meet the filter - so only
133                  * builtin groups
134                  *
135                  * We already have the primary group in the token, so set
136                  * 'only childs' flag to true
137                  */
138                 primary_group_string = dom_sid_string(tmp_ctx, server_info->primary_group_sid);
139                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, server_info);
140                 
141                 primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
142                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, server_info);
143                 
144                 primary_group_blob = data_blob_string_const(primary_group_dn);
145                 
146                 nt_status = authsam_expand_nested_groups(auth_context->sam_ctx, &primary_group_blob, true, filter,
147                                                          tmp_ctx, &groupSIDs, &num_groupSIDs);
148                 if (!NT_STATUS_IS_OK(nt_status)) {
149                         talloc_free(tmp_ctx);
150                         return nt_status;
151                 }
152                 
153                 for (i = 0; i < server_info->n_domain_groups; i++) {
154                         char *group_string;
155                         const char *group_dn;
156                         DATA_BLOB group_blob;
157                         
158                         group_string = dom_sid_string(tmp_ctx,
159                                                       server_info->domain_groups[i]);
160                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(group_string, server_info);
161                         
162                         group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", group_string);
163                         talloc_free(group_string);
164                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(group_dn, server_info);
165                         group_blob = data_blob_string_const(group_dn);
166                         
167                         /* This function takes in memberOf values and expands
168                          * them, as long as they meet the filter - so only
169                          * builtin groups */
170                         nt_status = authsam_expand_nested_groups(auth_context->sam_ctx, &group_blob, true, filter,
171                                                                  tmp_ctx, &groupSIDs, &num_groupSIDs);
172                         if (!NT_STATUS_IS_OK(nt_status)) {
173                                 talloc_free(tmp_ctx);
174                                 return nt_status;
175                         }
176                 }
177         }
178
179         nt_status = security_token_create(session_info,
180                                           auth_context ? auth_context->lp_ctx : NULL,
181                                           server_info->account_sid,
182                                           server_info->primary_group_sid,
183                                           num_groupSIDs,
184                                           groupSIDs,
185                                           session_info_flags,
186                                           &session_info->security_token);
187         NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
188
189         session_info->credentials = NULL;
190
191         talloc_steal(mem_ctx, session_info);
192         *_session_info = session_info;
193         talloc_free(tmp_ctx);
194         return NT_STATUS_OK;
195 }
196
197 /**
198  * prints a struct auth_session_info security token to debug output.
199  */
200 void auth_session_info_debug(int dbg_lev, 
201                              const struct auth_session_info *session_info)
202 {
203         if (!session_info) {
204                 DEBUG(dbg_lev, ("Session Info: (NULL)\n"));
205                 return; 
206         }
207
208         security_token_debug(0, dbg_lev, session_info->security_token);
209 }
210