Changeset 740 for vendor/current/source4/auth/session.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/auth/session.c
r414 r740 3 3 Authentication utility functions 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 Copyright (C) Andrew Bartlett 2001 5 Copyright (C) Andrew Bartlett 2001-2010 6 6 Copyright (C) Jeremy Allison 2000-2001 7 7 Copyright (C) Rafal Szczesniak 2002 … … 24 24 #include "includes.h" 25 25 #include "auth/auth.h" 26 #include "auth/auth_sam.h" 27 #include "auth/credentials/credentials.h" 28 #include "auth/credentials/credentials_krb5.h" 26 29 #include "libcli/security/security.h" 27 30 #include "libcli/auth/libcli_auth.h" 28 31 #include "dsdb/samdb/samdb.h" 29 #include "auth/credentials/credentials.h"30 #include "param/param.h"31 32 #include "auth/session_proto.h" 33 #include "system/kerberos.h" 34 #include <gssapi/gssapi.h> 32 35 33 36 _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, 34 struct tevent_context *event_ctx, 35 struct loadparm_context *lp_ctx) 37 struct loadparm_context *lp_ctx) 36 38 { 37 39 NTSTATUS nt_status; 38 40 struct auth_session_info *session_info = NULL; 39 nt_status = auth_anonymous_session_info(mem_ctx, event_ctx,lp_ctx, &session_info);41 nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info); 40 42 if (!NT_STATUS_IS_OK(nt_status)) { 41 43 return NULL; … … 44 46 } 45 47 46 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 47 struct tevent_context *event_ctx, 48 struct loadparm_context *lp_ctx, 49 struct auth_session_info **_session_info) 50 { 51 NTSTATUS nt_status; 52 struct auth_serversupplied_info *server_info = NULL; 53 struct auth_session_info *session_info = NULL; 54 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 55 56 nt_status = auth_anonymous_server_info(mem_ctx, 57 lp_netbios_name(lp_ctx), 58 &server_info); 59 if (!NT_STATUS_IS_OK(nt_status)) { 60 talloc_free(mem_ctx); 61 return nt_status; 62 } 63 64 /* references the server_info into the session_info */ 65 nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info); 66 talloc_free(mem_ctx); 67 68 NT_STATUS_NOT_OK_RETURN(nt_status); 69 70 session_info->credentials = cli_credentials_init(session_info); 71 if (!session_info->credentials) { 72 return NT_STATUS_NO_MEMORY; 73 } 74 75 cli_credentials_set_conf(session_info->credentials, lp_ctx); 76 cli_credentials_set_anonymous(session_info->credentials); 77 78 *_session_info = session_info; 79 80 return NT_STATUS_OK; 81 } 82 83 _PUBLIC_ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx, 84 const char *netbios_name, 85 struct auth_serversupplied_info **_server_info) 86 { 87 struct auth_serversupplied_info *server_info; 88 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 89 NT_STATUS_HAVE_NO_MEMORY(server_info); 90 91 server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS); 92 NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); 93 94 /* is this correct? */ 95 server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS); 96 NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); 97 98 server_info->n_domain_groups = 0; 99 server_info->domain_groups = NULL; 100 101 /* annoying, but the Anonymous really does have a session key... */ 102 server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); 103 NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); 104 105 server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); 106 NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); 107 108 /* and it is all zeros! */ 109 data_blob_clear(&server_info->user_session_key); 110 data_blob_clear(&server_info->lm_session_key); 111 112 server_info->account_name = talloc_strdup(server_info, "ANONYMOUS LOGON"); 113 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 114 115 server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY"); 116 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); 117 118 server_info->full_name = talloc_strdup(server_info, "Anonymous Logon"); 119 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); 120 121 server_info->logon_script = talloc_strdup(server_info, ""); 122 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 123 124 server_info->profile_path = talloc_strdup(server_info, ""); 125 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 126 127 server_info->home_directory = talloc_strdup(server_info, ""); 128 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 129 130 server_info->home_drive = talloc_strdup(server_info, ""); 131 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 132 133 server_info->logon_server = talloc_strdup(server_info, netbios_name); 134 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server); 135 136 server_info->last_logon = 0; 137 server_info->last_logoff = 0; 138 server_info->acct_expiry = 0; 139 server_info->last_password_change = 0; 140 server_info->allow_password_change = 0; 141 server_info->force_password_change = 0; 142 143 server_info->logon_count = 0; 144 server_info->bad_password_count = 0; 145 146 server_info->acct_flags = ACB_NORMAL; 147 148 server_info->authenticated = false; 149 150 *_server_info = server_info; 151 152 return NT_STATUS_OK; 153 } 154 155 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 156 struct tevent_context *event_ctx, 157 struct loadparm_context *lp_ctx, 158 struct auth_serversupplied_info *server_info, 159 struct auth_session_info **_session_info) 48 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 49 struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */ 50 struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */ 51 struct auth_user_info_dc *user_info_dc, 52 uint32_t session_info_flags, 53 struct auth_session_info **_session_info) 160 54 { 161 55 struct auth_session_info *session_info; 162 56 NTSTATUS nt_status; 163 164 session_info = talloc(mem_ctx, struct auth_session_info); 165 NT_STATUS_HAVE_NO_MEMORY(session_info); 166 167 session_info->server_info = talloc_reference(session_info, server_info); 57 unsigned int i, num_sids = 0; 58 59 const char *filter; 60 61 struct dom_sid *sids = 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->info = talloc_reference(session_info, user_info_dc->info); 71 72 session_info->torture = talloc_zero(session_info, struct auth_user_info_torture); 73 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx); 74 session_info->torture->num_dc_sids = user_info_dc->num_sids; 75 session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids); 76 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx); 168 77 169 78 /* unless set otherwise, the session key is the user session 170 79 * key from the auth subsystem */ 171 session_info->session_key = server_info->user_session_key; 80 session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length); 81 if (!session_info->session_key.data && session_info->session_key.length) { 82 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx); 83 } 84 85 anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS); 86 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx); 87 88 system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM); 89 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx); 90 91 sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids); 92 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx); 93 if (!sids) { 94 talloc_free(tmp_ctx); 95 return NT_STATUS_NO_MEMORY; 96 } 97 98 num_sids = user_info_dc->num_sids; 99 100 for (i=0; i < user_info_dc->num_sids; i++) { 101 sids[i] = user_info_dc->sids[i]; 102 } 103 104 if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) { 105 /* Don't expand nested groups of system, anonymous etc*/ 106 } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) { 107 /* Don't expand nested groups of system, anonymous etc*/ 108 } else if (sam_ctx) { 109 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))", 110 GROUP_TYPE_BUILTIN_LOCAL_GROUP); 111 112 /* Search for each group in the token */ 113 for (i = 0; i < user_info_dc->num_sids; i++) { 114 char *sid_string; 115 const char *sid_dn; 116 DATA_BLOB sid_blob; 117 118 sid_string = dom_sid_string(tmp_ctx, 119 &user_info_dc->sids[i]); 120 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc); 121 122 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string); 123 talloc_free(sid_string); 124 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc); 125 sid_blob = data_blob_string_const(sid_dn); 126 127 /* This function takes in memberOf values and expands 128 * them, as long as they meet the filter - so only 129 * builtin groups 130 * 131 * We already have the SID in the token, so set 132 * 'only childs' flag to true */ 133 nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter, 134 tmp_ctx, &sids, &num_sids); 135 if (!NT_STATUS_IS_OK(nt_status)) { 136 talloc_free(tmp_ctx); 137 return nt_status; 138 } 139 } 140 } 172 141 173 142 nt_status = security_token_create(session_info, 174 event_ctx,175 143 lp_ctx, 176 server_info->account_sid, 177 server_info->primary_group_sid, 178 server_info->n_domain_groups, 179 server_info->domain_groups, 180 server_info->authenticated, 144 num_sids, 145 sids, 146 session_info_flags, 181 147 &session_info->security_token); 182 NT_STATUS_NOT_OK_RETURN (nt_status);148 NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx); 183 149 184 150 session_info->credentials = NULL; 185 151 152 talloc_steal(mem_ctx, session_info); 186 153 *_session_info = session_info; 154 talloc_free(tmp_ctx); 187 155 return NT_STATUS_OK; 156 } 157 158 /* Create a session_info structure from the 159 * auth_session_info_transport we were forwarded over named pipe 160 * forwarding. 161 * 162 * NOTE: The stucture members of session_info_transport are stolen 163 * with talloc_move() into auth_session_info for long term use 164 */ 165 struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx, 166 struct auth_session_info_transport *session_info_transport, 167 struct loadparm_context *lp_ctx, 168 const char **reason) 169 { 170 struct auth_session_info *session_info; 171 session_info = talloc_zero(mem_ctx, struct auth_session_info); 172 if (!session_info) { 173 *reason = "failed to allocate session_info"; 174 return NULL; 175 } 176 177 session_info->security_token = talloc_move(session_info, &session_info_transport->security_token); 178 session_info->info = talloc_move(session_info, &session_info_transport->info); 179 session_info->session_key = session_info_transport->session_key; 180 session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data); 181 182 if (session_info_transport->exported_gssapi_credentials.length) { 183 struct cli_credentials *creds; 184 OM_uint32 minor_status; 185 gss_buffer_desc cred_token; 186 gss_cred_id_t cred_handle; 187 const char *error_string; 188 int ret; 189 190 DEBUG(10, ("Delegated credentials supplied by client\n")); 191 192 cred_token.value = session_info_transport->exported_gssapi_credentials.data; 193 cred_token.length = session_info_transport->exported_gssapi_credentials.length; 194 195 ret = gss_import_cred(&minor_status, 196 &cred_token, 197 &cred_handle); 198 if (ret != GSS_S_COMPLETE) { 199 *reason = "Internal error in gss_import_cred()"; 200 return NULL; 201 } 202 203 creds = cli_credentials_init(session_info); 204 if (!creds) { 205 *reason = "Out of memory in cli_credentials_init()"; 206 return NULL; 207 } 208 session_info->credentials = creds; 209 210 cli_credentials_set_conf(creds, lp_ctx); 211 /* Just so we don't segfault trying to get at a username */ 212 cli_credentials_set_anonymous(creds); 213 214 ret = cli_credentials_set_client_gss_creds(creds, 215 lp_ctx, 216 cred_handle, 217 CRED_SPECIFIED, 218 &error_string); 219 if (ret) { 220 *reason = talloc_asprintf(mem_ctx, 221 "Failed to set pipe forwarded" 222 "creds: %s\n", error_string); 223 return NULL; 224 } 225 226 /* This credential handle isn't useful for password 227 * authentication, so ensure nobody tries to do that */ 228 cli_credentials_set_kerberos_state(creds, 229 CRED_MUST_USE_KERBEROS); 230 231 } 232 233 return session_info; 234 } 235 236 237 /* Create a auth_session_info_transport from an auth_session_info. 238 * 239 * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned. They are only valid for the lifetime of the struct auth_session_info 240 * 241 * This isn't normally an issue, as the auth_session_info has a very long typical life 242 */ 243 NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx, 244 struct auth_session_info *session_info, 245 struct tevent_context *event_ctx, 246 struct loadparm_context *lp_ctx, 247 struct auth_session_info_transport **transport_out) 248 { 249 250 struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport); 251 session_info_transport->security_token = talloc_reference(session_info, session_info->security_token); 252 NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token); 253 254 session_info_transport->info = talloc_reference(session_info, session_info->info); 255 NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info); 256 257 session_info_transport->session_key = session_info->session_key; 258 session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data); 259 if (!session_info_transport->session_key.data && session_info->session_key.length) { 260 return NT_STATUS_NO_MEMORY; 261 } 262 263 if (session_info->credentials) { 264 struct gssapi_creds_container *gcc; 265 OM_uint32 gret; 266 OM_uint32 minor_status; 267 gss_buffer_desc cred_token; 268 const char *error_string; 269 int ret; 270 271 ret = cli_credentials_get_client_gss_creds(session_info->credentials, 272 event_ctx, 273 lp_ctx, 274 &gcc, &error_string); 275 if (ret != 0) { 276 *transport_out = session_info_transport; 277 return NT_STATUS_OK; 278 } 279 280 gret = gss_export_cred(&minor_status, 281 gcc->creds, 282 &cred_token); 283 if (gret != GSS_S_COMPLETE) { 284 return NT_STATUS_INTERNAL_ERROR; 285 } 286 287 if (cred_token.length) { 288 session_info_transport->exported_gssapi_credentials 289 = data_blob_talloc(session_info_transport, 290 cred_token.value, 291 cred_token.length); 292 gss_release_buffer(&minor_status, &cred_token); 293 NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data); 294 } 295 } 296 *transport_out = session_info_transport; 297 return NT_STATUS_OK; 298 } 299 300 301 /* Produce a session_info for an arbitary DN or principal in the local 302 * DB, assuming the local DB holds all the groups 303 * 304 * Supply either a principal or a DN 305 */ 306 NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx, 307 struct loadparm_context *lp_ctx, 308 struct ldb_context *sam_ctx, 309 const char *principal, 310 struct ldb_dn *user_dn, 311 uint32_t session_info_flags, 312 struct auth_session_info **session_info) 313 { 314 NTSTATUS nt_status; 315 struct auth_user_info_dc *user_info_dc; 316 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 317 if (!tmp_ctx) { 318 return NT_STATUS_NO_MEMORY; 319 } 320 nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx, 321 principal, user_dn, 322 &user_info_dc); 323 if (!NT_STATUS_IS_OK(nt_status)) { 324 talloc_free(tmp_ctx); 325 return nt_status; 326 } 327 328 nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx, 329 user_info_dc, session_info_flags, 330 session_info); 331 332 if (NT_STATUS_IS_OK(nt_status)) { 333 talloc_steal(mem_ctx, *session_info); 334 } 335 talloc_free(tmp_ctx); 336 return nt_status; 188 337 } 189 338 … … 199 348 } 200 349 201 security_token_debug( dbg_lev, session_info->security_token);202 } 203 350 security_token_debug(0, dbg_lev, session_info->security_token); 351 } 352
Note:
See TracChangeset
for help on using the changeset viewer.