Changeset 988 for vendor/current/source4/auth
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/auth
- Files:
-
- 4 added
- 17 deleted
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/auth/auth.h
r740 r988 44 44 /* version 4 - subsequent samba4 version - metze */ 45 45 /* version 0 - till samba4 is stable - metze */ 46 #define AUTH_INTERFACE_VERSION 0 47 48 #define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */ 49 #define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */ 50 #define AUTH_SESSION_INFO_SIMPLE_PRIVILEGES 0x04 /* Use a trivial map between users and privilages, rather than a DB */ 46 #define AUTH4_INTERFACE_VERSION 0 51 47 52 48 struct auth_method_context; 53 49 struct auth_check_password_request; 54 struct auth _context;50 struct auth4_context; 55 51 struct auth_session_info; 56 52 struct ldb_dn; 53 struct smb_krb5_context; 57 54 58 55 struct auth_operations { 59 56 const char *name; 60 61 /* If you are using this interface, then you are probably62 * getting something wrong. This interface is only for63 * security=server, and makes a number of compromises to allow64 * that. It is not compatible with being a PDC. */65 66 NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]);67 57 68 58 /* Given the user supplied info, check if this backend want to handle the password checking */ … … 79 69 /* Lookup a 'session info interim' return based only on the principal or DN */ 80 70 NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, 81 struct auth _context *auth_context,71 struct auth4_context *auth_context, 82 72 const char *principal, 83 73 struct ldb_dn *user_dn, 84 74 struct auth_user_info_dc **interim_info); 75 uint32_t flags; 85 76 }; 86 77 87 78 struct auth_method_context { 88 79 struct auth_method_context *prev, *next; 89 struct auth _context *auth_ctx;80 struct auth4_context *auth_ctx; 90 81 const struct auth_operations *ops; 91 82 int depth; 92 83 void *private_data; 93 };94 95 struct auth_context {96 struct {97 /* Who set this up in the first place? */98 const char *set_by;99 100 bool may_be_modified;101 102 DATA_BLOB data;103 } challenge;104 105 /* methods, in the order they should be called */106 struct auth_method_context *methods;107 108 /* the event context to use for calls that can block */109 struct tevent_context *event_ctx;110 111 /* the messaging context which can be used by backends */112 struct messaging_context *msg_ctx;113 114 /* loadparm context */115 struct loadparm_context *lp_ctx;116 117 /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */118 struct ldb_context *sam_ctx;119 120 NTSTATUS (*check_password)(struct auth_context *auth_ctx,121 TALLOC_CTX *mem_ctx,122 const struct auth_usersupplied_info *user_info,123 struct auth_user_info_dc **user_info_dc);124 125 NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]);126 127 bool (*challenge_may_be_modified)(struct auth_context *auth_ctx);128 129 NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by);130 131 NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,132 struct auth_context *auth_ctx,133 const char *principal,134 struct ldb_dn *user_dn,135 struct auth_user_info_dc **user_info_dc);136 137 NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx,138 struct auth_context *auth_context,139 struct auth_user_info_dc *user_info_dc,140 uint32_t session_info_flags,141 struct auth_session_info **session_info);142 84 }; 143 85 … … 152 94 }; 153 95 154 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth _context *auth_context,96 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, 155 97 enum auth_password_state to_state, 156 98 const struct auth_usersupplied_info *user_info_in, … … 158 100 159 101 #include "auth/session.h" 102 #include "auth/unix_token_proto.h" 160 103 #include "auth/system_session_proto.h" 161 104 #include "libcli/security/security.h" … … 166 109 struct cli_credentials; 167 110 168 NTSTATUS auth_get_challenge(struct auth _context *auth_ctx, uint8_t chal[8]);111 NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]); 169 112 NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, 170 113 struct ldb_context *sam_ctx, … … 176 119 bool allow_domain_trust, 177 120 bool password_change); 178 NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx, 179 struct ldb_val *dn_val, const bool only_childs, const char *filter, 180 TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids, 181 unsigned int *num_res_sids); 121 182 122 struct auth_session_info *system_session(struct loadparm_context *lp_ctx); 183 123 NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, … … 192 132 struct auth_session_info **_session_info) ; 193 133 194 NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * *methods,134 NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods, 195 135 struct tevent_context *ev, 196 struct messaging_context *msg,136 struct imessaging_context *msg, 197 137 struct loadparm_context *lp_ctx, 198 138 struct ldb_context *sam_ctx, 199 struct auth _context **auth_ctx);139 struct auth4_context **auth_ctx); 200 140 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); 201 141 202 142 NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 203 143 struct tevent_context *ev, 204 struct messaging_context *msg,144 struct imessaging_context *msg, 205 145 struct loadparm_context *lp_ctx, 206 struct auth_context **auth_ctx); 207 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx); 146 struct auth4_context **auth_ctx); 208 147 209 NTSTATUS auth_check_password (struct auth_context *auth_ctx,148 NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx, 210 149 TALLOC_CTX *mem_ctx, 211 const struct auth_usersupplied_info *user_info, 150 const struct auth_usersupplied_info *user_info, 151 void **server_returned_info, 152 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key); 153 154 NTSTATUS auth_check_password(struct auth4_context *auth_ctx, 155 TALLOC_CTX *mem_ctx, 156 const struct auth_usersupplied_info *user_info, 212 157 struct auth_user_info_dc **user_info_dc); 213 158 NTSTATUS auth4_init(void); … … 216 161 NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, 217 162 struct tevent_context *ev, 218 struct messaging_context *msg,163 struct imessaging_context *msg, 219 164 struct loadparm_context *lp_ctx, 220 165 const char *nt4_domain, … … 226 171 struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, 227 172 struct tevent_context *ev, 228 struct auth _context *auth_ctx,173 struct auth4_context *auth_ctx, 229 174 const struct auth_usersupplied_info *user_info); 230 175 NTSTATUS auth_check_password_recv(struct tevent_req *req, … … 232 177 struct auth_user_info_dc **user_info_dc); 233 178 234 bool auth_challenge_may_be_modified(struct auth _context *auth_ctx);235 NTSTATUS auth_context_set_challenge(struct auth _context *auth_ctx, const uint8_t chal[8], const char *set_by);179 bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx); 180 NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); 236 181 237 182 NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, 238 struct auth _context *auth_ctx,183 struct auth4_context *auth_ctx, 239 184 const char *principal, 240 185 struct ldb_dn *user_dn, … … 243 188 NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, 244 189 struct tevent_context *event_ctx, 245 struct messaging_context *msg_ctx,190 struct imessaging_context *msg_ctx, 246 191 struct loadparm_context *lp_ctx, 247 192 struct cli_credentials *server_credentials, -
vendor/current/source4/auth/gensec/gensec_gssapi.c
r740 r988 25 25 #include "lib/events/events.h" 26 26 #include "system/kerberos.h" 27 #include "system/gssapi.h" 27 28 #include "auth/kerberos/kerberos.h" 28 29 #include "librpc/gen_ndr/krb5pac.h" … … 30 31 #include <ldb.h> 31 32 #include "auth/auth_sam.h" 32 #include "librpc/ rpc/dcerpc.h"33 #include "librpc/gen_ndr/dcerpc.h" 33 34 #include "auth/credentials/credentials.h" 34 35 #include "auth/credentials/credentials_krb5.h" 35 36 #include "auth/gensec/gensec.h" 37 #include "auth/gensec/gensec_internal.h" 36 38 #include "auth/gensec/gensec_proto.h" 39 #include "auth/gensec/gensec_toplevel_proto.h" 37 40 #include "param/param.h" 38 41 #include "auth/session_proto.h" 39 #include <gssapi/gssapi.h> 40 #include <gssapi/gssapi_krb5.h> 41 #include <gssapi/gssapi_spnego.h> 42 #include "auth/gensec/gensec_gssapi.h" 42 #include "gensec_gssapi.h" 43 43 #include "lib/util/util_net.h" 44 #include "auth/kerberos/pac_utils.h" 45 #include "auth/kerberos/gssapi_helper.h" 46 47 #ifndef gss_mech_spnego 48 gss_OID_desc spnego_mech_oid_desc = 49 { 6, discard_const_p(void, "\x2b\x06\x01\x05\x05\x02") }; 50 #define gss_mech_spnego (&spnego_mech_oid_desc) 51 #endif 52 53 _PUBLIC_ NTSTATUS gensec_gssapi_init(void); 44 54 45 55 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); 46 56 static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); 47 48 static char *gssapi_error_string(TALLOC_CTX *mem_ctx, 49 OM_uint32 maj_stat, OM_uint32 min_stat, 50 const gss_OID mech) 51 { 52 OM_uint32 disp_min_stat, disp_maj_stat; 53 gss_buffer_desc maj_error_message; 54 gss_buffer_desc min_error_message; 55 char *maj_error_string, *min_error_string; 56 OM_uint32 msg_ctx = 0; 57 58 char *ret; 59 60 maj_error_message.value = NULL; 61 min_error_message.value = NULL; 62 maj_error_message.length = 0; 63 min_error_message.length = 0; 64 65 disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, 66 mech, &msg_ctx, &maj_error_message); 67 disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, 68 mech, &msg_ctx, &min_error_message); 69 70 maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length); 71 72 min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length); 73 74 ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string); 75 76 talloc_free(maj_error_string); 77 talloc_free(min_error_string); 78 79 gss_release_buffer(&disp_min_stat, &maj_error_message); 80 gss_release_buffer(&disp_min_stat, &min_error_message); 81 82 return ret; 83 } 84 57 static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size); 85 58 86 59 static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) 87 60 { 88 OM_uint32 m aj_stat, min_stat;89 61 OM_uint32 min_stat; 62 90 63 if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { 91 maj_stat = gss_release_cred(&min_stat,92 64 gss_release_cred(&min_stat, 65 &gensec_gssapi_state->delegated_cred_handle); 93 66 } 94 67 95 68 if (gensec_gssapi_state->gssapi_context != GSS_C_NO_CONTEXT) { 96 maj_stat = gss_delete_sec_context(&min_stat,97 98 69 gss_delete_sec_context(&min_stat, 70 &gensec_gssapi_state->gssapi_context, 71 GSS_C_NO_BUFFER); 99 72 } 100 73 101 74 if (gensec_gssapi_state->server_name != GSS_C_NO_NAME) { 102 maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->server_name); 75 gss_release_name(&min_stat, 76 &gensec_gssapi_state->server_name); 103 77 } 104 78 if (gensec_gssapi_state->client_name != GSS_C_NO_NAME) { 105 maj_stat = gss_release_name(&min_stat, &gensec_gssapi_state->client_name); 106 } 107 108 if (gensec_gssapi_state->lucid) { 109 gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid); 79 gss_release_name(&min_stat, 80 &gensec_gssapi_state->client_name); 110 81 } 111 82 112 83 return 0; 113 }114 115 static NTSTATUS gensec_gssapi_init_lucid(struct gensec_gssapi_state *gensec_gssapi_state)116 {117 OM_uint32 maj_stat, min_stat;118 119 if (gensec_gssapi_state->lucid) {120 return NT_STATUS_OK;121 }122 123 maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,124 &gensec_gssapi_state->gssapi_context,125 1,126 (void **)&gensec_gssapi_state->lucid);127 if (maj_stat != GSS_S_COMPLETE) {128 DEBUG(0,("gensec_gssapi_init_lucid: %s\n",129 gssapi_error_string(gensec_gssapi_state,130 maj_stat, min_stat,131 gensec_gssapi_state->gss_oid)));132 return NT_STATUS_INTERNAL_ERROR;133 }134 135 if (gensec_gssapi_state->lucid->version != 1) {136 DEBUG(0,("gensec_gssapi_init_lucid: lucid version[%d] != 1\n",137 gensec_gssapi_state->lucid->version));138 gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid);139 gensec_gssapi_state->lucid = NULL;140 return NT_STATUS_INTERNAL_ERROR;141 }142 143 return NT_STATUS_OK;144 84 } 145 85 … … 148 88 struct gensec_gssapi_state *gensec_gssapi_state; 149 89 krb5_error_code ret; 90 #ifdef SAMBA4_USES_HEIMDAL 150 91 const char *realm; 92 #endif 151 93 152 94 gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state); … … 165 107 gensec_gssapi_state->client_name = GSS_C_NO_NAME; 166 108 167 gensec_gssapi_state->want_flags = 0; 109 gensec_gssapi_state->gss_want_flags = 0; 110 gensec_gssapi_state->expire_time = GENSEC_EXPIRE_TIME_INFINITY; 168 111 169 112 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) { 170 gensec_gssapi_state-> want_flags |= GSS_C_DELEG_POLICY_FLAG;113 gensec_gssapi_state->gss_want_flags |= GSS_C_DELEG_POLICY_FLAG; 171 114 } 172 115 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) { 173 gensec_gssapi_state-> want_flags |= GSS_C_MUTUAL_FLAG;116 gensec_gssapi_state->gss_want_flags |= GSS_C_MUTUAL_FLAG; 174 117 } 175 118 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation", true)) { 176 gensec_gssapi_state-> want_flags |= GSS_C_DELEG_FLAG;119 gensec_gssapi_state->gss_want_flags |= GSS_C_DELEG_FLAG; 177 120 } 178 121 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "replay", true)) { 179 gensec_gssapi_state-> want_flags |= GSS_C_REPLAY_FLAG;122 gensec_gssapi_state->gss_want_flags |= GSS_C_REPLAY_FLAG; 180 123 } 181 124 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "sequence", true)) { 182 gensec_gssapi_state-> want_flags |= GSS_C_SEQUENCE_FLAG;125 gensec_gssapi_state->gss_want_flags |= GSS_C_SEQUENCE_FLAG; 183 126 } 184 127 185 128 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 186 gensec_gssapi_state-> want_flags |= GSS_C_INTEG_FLAG;129 gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG; 187 130 } 188 131 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 189 gensec_gssapi_state->want_flags |= GSS_C_CONF_FLAG; 132 gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG; 133 gensec_gssapi_state->gss_want_flags |= GSS_C_CONF_FLAG; 190 134 } 191 135 if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) { 192 gensec_gssapi_state-> want_flags |= GSS_C_DCE_STYLE;193 } 194 195 gensec_gssapi_state->g ot_flags = 0;136 gensec_gssapi_state->gss_want_flags |= GSS_C_DCE_STYLE; 137 } 138 139 gensec_gssapi_state->gss_got_flags = 0; 196 140 197 141 switch (gensec_security->ops->auth_type) { … … 201 145 case DCERPC_AUTH_TYPE_KRB5: 202 146 default: 203 gensec_gssapi_state->gss_oid = gss_mech_krb5; 147 gensec_gssapi_state->gss_oid = 148 discard_const_p(void, gss_mech_krb5); 204 149 break; 205 150 } 206 151 207 gensec_gssapi_state->session_key = data_blob(NULL, 0);208 gensec_gssapi_state->pac = data_blob(NULL, 0);209 210 152 ret = smb_krb5_init_context(gensec_gssapi_state, 211 NULL,212 153 gensec_security->settings->lp_ctx, 213 154 &gensec_gssapi_state->smb_krb5_context); 214 155 if (ret) { 215 DEBUG(1,("gensec_ krb5_start:krb5_init_context failed (%s)\n",156 DEBUG(1,("gensec_gssapi_start: smb_krb5_init_context failed (%s)\n", 216 157 error_message(ret))); 217 158 talloc_free(gensec_gssapi_state); … … 221 162 gensec_gssapi_state->client_cred = NULL; 222 163 gensec_gssapi_state->server_cred = NULL; 223 224 gensec_gssapi_state->lucid = NULL;225 164 226 165 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; … … 237 176 talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor); 238 177 178 #ifdef SAMBA4_USES_HEIMDAL 239 179 realm = lpcfg_realm(gensec_security->settings->lp_ctx); 240 180 if (realm != NULL) { 241 181 ret = gsskrb5_set_default_realm(realm); 242 182 if (ret) { 243 DEBUG(1,("gensec_ krb5_start: gsskrb5_set_default_realm failed\n"));183 DEBUG(1,("gensec_gssapi_start: gsskrb5_set_default_realm failed\n")); 244 184 talloc_free(gensec_gssapi_state); 245 185 return NT_STATUS_INTERNAL_ERROR; … … 250 190 ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); 251 191 if (ret) { 252 DEBUG(1,("gensec_ krb5_start: gsskrb5_set_dns_canonicalize failed\n"));192 DEBUG(1,("gensec_gssapi_start: gsskrb5_set_dns_canonicalize failed\n")); 253 193 talloc_free(gensec_gssapi_state); 254 194 return NT_STATUS_INTERNAL_ERROR; 255 195 } 256 196 #endif 257 197 return NT_STATUS_OK; 258 198 } … … 306 246 } 307 247 308 static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) 248 static NTSTATUS gensec_gssapi_client_creds(struct gensec_security *gensec_security, 249 struct tevent_context *ev) 309 250 { 310 251 struct gensec_gssapi_state *gensec_gssapi_state; 252 struct gssapi_creds_container *gcc; 311 253 struct cli_credentials *creds = gensec_get_credentials(gensec_security); 312 krb5_error_code ret;313 NTSTATUS nt_status;314 gss_buffer_desc name_token;315 gss_OID name_type;316 OM_uint32 maj_stat, min_stat;317 const char *hostname = gensec_get_target_hostname(gensec_security);318 struct gssapi_creds_container *gcc;319 254 const char *error_string; 320 321 if (!hostname) { 322 DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n")); 323 return NT_STATUS_INVALID_PARAMETER; 324 } 325 if (is_ipaddress(hostname)) { 326 DEBUG(2, ("Cannot do GSSAPI to an IP address\n")); 327 return NT_STATUS_INVALID_PARAMETER; 328 } 329 if (strcmp(hostname, "localhost") == 0) { 330 DEBUG(2, ("GSSAPI to 'localhost' does not make sense\n")); 331 return NT_STATUS_INVALID_PARAMETER; 332 } 333 334 nt_status = gensec_gssapi_start(gensec_security); 335 if (!NT_STATUS_IS_OK(nt_status)) { 336 return nt_status; 337 } 255 int ret; 338 256 339 257 gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 340 258 341 gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); 342 if (gensec_gssapi_state->target_principal) { 343 name_type = GSS_C_NULL_OID; 344 } else { 345 gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s", 346 gensec_get_target_service(gensec_security), 347 hostname, lpcfg_realm(gensec_security->settings->lp_ctx)); 348 349 name_type = GSS_C_NT_USER_NAME; 350 } 351 name_token.value = discard_const_p(uint8_t, gensec_gssapi_state->target_principal); 352 name_token.length = strlen(gensec_gssapi_state->target_principal); 353 354 355 maj_stat = gss_import_name (&min_stat, 356 &name_token, 357 name_type, 358 &gensec_gssapi_state->server_name); 359 if (maj_stat) { 360 DEBUG(2, ("GSS Import name of %s failed: %s\n", 361 (char *)name_token.value, 362 gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 363 return NT_STATUS_INVALID_PARAMETER; 364 } 365 366 ret = cli_credentials_get_client_gss_creds(creds, 367 gensec_security->event_ctx, 259 /* Only run this the first time the update() call is made */ 260 if (gensec_gssapi_state->client_cred) { 261 return NT_STATUS_OK; 262 } 263 264 ret = cli_credentials_get_client_gss_creds(creds, 265 ev, 368 266 gensec_security->settings->lp_ctx, &gcc, &error_string); 369 267 switch (ret) { 370 268 case 0: 371 269 break; 270 case EINVAL: 271 DEBUG(3, ("Cannot obtain client GSS credentials we need to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string)); 272 return NT_STATUS_INVALID_PARAMETER; 372 273 case KRB5KDC_ERR_PREAUTH_FAILED: 373 274 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 275 case KRB5KRB_AP_ERR_BAD_INTEGRITY: 374 276 DEBUG(1, ("Wrong username or password: %s\n", error_string)); 375 277 return NT_STATUS_LOGON_FAILURE; 278 case KRB5KDC_ERR_CLIENT_REVOKED: 279 DEBUG(1, ("Account locked out: %s\n", error_string)); 280 return NT_STATUS_ACCOUNT_LOCKED_OUT; 281 case KRB5_REALM_UNKNOWN: 376 282 case KRB5_KDC_UNREACH: 377 283 DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string)); … … 390 296 return NT_STATUS_NO_MEMORY; 391 297 } 392 298 299 return NT_STATUS_OK; 300 } 301 302 static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security) 303 { 304 struct gensec_gssapi_state *gensec_gssapi_state; 305 struct cli_credentials *creds = gensec_get_credentials(gensec_security); 306 NTSTATUS nt_status; 307 gss_buffer_desc name_token; 308 gss_OID name_type; 309 OM_uint32 maj_stat, min_stat; 310 const char *hostname = gensec_get_target_hostname(gensec_security); 311 312 if (!hostname) { 313 DEBUG(3, ("No hostname for target computer passed in, cannot use kerberos for this connection\n")); 314 return NT_STATUS_INVALID_PARAMETER; 315 } 316 if (is_ipaddress(hostname)) { 317 DEBUG(2, ("Cannot do GSSAPI to an IP address\n")); 318 return NT_STATUS_INVALID_PARAMETER; 319 } 320 if (strcmp(hostname, "localhost") == 0) { 321 DEBUG(2, ("GSSAPI to 'localhost' does not make sense\n")); 322 return NT_STATUS_INVALID_PARAMETER; 323 } 324 325 nt_status = gensec_gssapi_start(gensec_security); 326 if (!NT_STATUS_IS_OK(nt_status)) { 327 return nt_status; 328 } 329 330 gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 331 332 if (cli_credentials_get_impersonate_principal(creds)) { 333 gensec_gssapi_state->gss_want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG); 334 } 335 336 gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); 337 if (gensec_gssapi_state->target_principal) { 338 name_type = GSS_C_NULL_OID; 339 } else { 340 gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s", 341 gensec_get_target_service(gensec_security), 342 hostname, lpcfg_realm(gensec_security->settings->lp_ctx)); 343 344 name_type = GSS_C_NT_USER_NAME; 345 } 346 name_token.value = discard_const_p(uint8_t, gensec_gssapi_state->target_principal); 347 name_token.length = strlen(gensec_gssapi_state->target_principal); 348 349 350 maj_stat = gss_import_name (&min_stat, 351 &name_token, 352 name_type, 353 &gensec_gssapi_state->server_name); 354 if (maj_stat) { 355 DEBUG(2, ("GSS Import name of %s failed: %s\n", 356 (char *)name_token.value, 357 gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 358 return NT_STATUS_INVALID_PARAMETER; 359 } 360 393 361 return NT_STATUS_OK; 394 362 } … … 405 373 } 406 374 return nt_status; 407 }408 409 410 /**411 * Check if the packet is one for this mechansim412 *413 * @param gensec_security GENSEC state414 * @param in The request, as a DATA_BLOB415 * @return Error, INVALID_PARAMETER if it's not a packet for us416 * or NT_STATUS_OK if the packet is ok.417 */418 419 static NTSTATUS gensec_gssapi_magic(struct gensec_security *gensec_security,420 const DATA_BLOB *in)421 {422 if (gensec_gssapi_check_oid(in, GENSEC_OID_KERBEROS5)) {423 return NT_STATUS_OK;424 } else {425 return NT_STATUS_INVALID_PARAMETER;426 }427 375 } 428 376 … … 440 388 441 389 static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, 442 TALLOC_CTX *out_mem_ctx, 443 const DATA_BLOB in, DATA_BLOB *out) 390 TALLOC_CTX *out_mem_ctx, 391 struct tevent_context *ev, 392 const DATA_BLOB in, DATA_BLOB *out) 444 393 { 445 394 struct gensec_gssapi_state *gensec_gssapi_state … … 448 397 OM_uint32 maj_stat, min_stat; 449 398 OM_uint32 min_stat2; 450 gss_buffer_desc input_token, output_token; 399 gss_buffer_desc input_token = { 0, NULL }; 400 gss_buffer_desc output_token = { 0, NULL }; 401 451 402 gss_OID gss_oid_p = NULL; 403 OM_uint32 time_req = 0; 404 OM_uint32 time_rec = 0; 405 struct timeval tv; 406 407 time_req = gensec_setting_int(gensec_security->settings, 408 "gensec_gssapi", "requested_life_time", 409 time_req); 410 452 411 input_token.length = in.length; 453 412 input_token.value = in.data; … … 459 418 case GENSEC_CLIENT: 460 419 { 420 #ifdef SAMBA4_USES_HEIMDAL 461 421 struct gsskrb5_send_to_kdc send_to_kdc; 462 422 krb5_error_code ret; 423 #endif 424 425 nt_status = gensec_gssapi_client_creds(gensec_security, ev); 426 if (!NT_STATUS_IS_OK(nt_status)) { 427 return nt_status; 428 } 429 430 #ifdef SAMBA4_USES_HEIMDAL 463 431 send_to_kdc.func = smb_krb5_send_and_recv_func; 464 send_to_kdc.ptr = gensec_security->event_ctx;432 send_to_kdc.ptr = ev; 465 433 466 434 min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc); 467 435 if (min_stat) { 468 DEBUG(1,("gensec_ krb5_start: gsskrb5_set_send_to_kdc failed\n"));436 DEBUG(1,("gensec_gssapi_update: gsskrb5_set_send_to_kdc failed\n")); 469 437 return NT_STATUS_INTERNAL_ERROR; 470 438 } 471 439 #endif 472 440 maj_stat = gss_init_sec_context(&min_stat, 473 441 gensec_gssapi_state->client_cred->creds, … … 475 443 gensec_gssapi_state->server_name, 476 444 gensec_gssapi_state->gss_oid, 477 gensec_gssapi_state-> want_flags,478 0,445 gensec_gssapi_state->gss_want_flags, 446 time_req, 479 447 gensec_gssapi_state->input_chan_bindings, 480 448 &input_token, 481 449 &gss_oid_p, 482 450 &output_token, 483 &gensec_gssapi_state->g ot_flags, /* ret flags */484 NULL);451 &gensec_gssapi_state->gss_got_flags, /* ret flags */ 452 &time_rec); 485 453 if (gss_oid_p) { 486 454 gensec_gssapi_state->gss_oid = gss_oid_p; 487 455 } 488 456 457 #ifdef SAMBA4_USES_HEIMDAL 489 458 send_to_kdc.func = smb_krb5_send_and_recv_func; 490 459 send_to_kdc.ptr = NULL; … … 492 461 ret = gsskrb5_set_send_to_kdc(&send_to_kdc); 493 462 if (ret) { 494 DEBUG(1,("gensec_ krb5_start: gsskrb5_set_send_to_kdc failed\n"));463 DEBUG(1,("gensec_gssapi_update: gsskrb5_set_send_to_kdc failed\n")); 495 464 return NT_STATUS_INTERNAL_ERROR; 496 465 } 497 466 #endif 498 467 break; 499 468 } … … 508 477 &gss_oid_p, 509 478 &output_token, 510 &gensec_gssapi_state->g ot_flags,511 NULL,479 &gensec_gssapi_state->gss_got_flags, 480 &time_rec, 512 481 &gensec_gssapi_state->delegated_cred_handle); 513 482 if (gss_oid_p) { … … 527 496 gss_release_buffer(&min_stat2, &output_token); 528 497 529 if (gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG) { 498 if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG && 499 gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { 530 500 DEBUG(5, ("gensec_gssapi: credentials were delegated\n")); 531 501 } else { 532 502 DEBUG(5, ("gensec_gssapi: NO credentials were delegated\n")); 533 503 } 504 505 tv = timeval_current_ofs(time_rec, 0); 506 gensec_gssapi_state->expire_time = timeval_to_nttime(&tv); 534 507 535 508 /* We may have been invoked as SASL, so there … … 556 529 557 530 return NT_STATUS_MORE_PROCESSING_REQUIRED; 558 } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { 531 } else if (maj_stat == GSS_S_CONTEXT_EXPIRED) { 532 gss_cred_id_t creds = NULL; 533 gss_name_t name; 534 gss_buffer_desc buffer; 535 OM_uint32 lifetime = 0; 536 gss_cred_usage_t usage; 537 const char *role = NULL; 538 DEBUG(0, ("GSS %s Update(krb5)(%d) Update failed, credentials expired during GSSAPI handshake!\n", 539 role, 540 gensec_gssapi_state->gss_exchange_count)); 541 542 543 switch (gensec_security->gensec_role) { 544 case GENSEC_CLIENT: 545 creds = gensec_gssapi_state->client_cred->creds; 546 role = "client"; 547 break; 548 case GENSEC_SERVER: 549 creds = gensec_gssapi_state->server_cred->creds; 550 role = "server"; 551 break; 552 } 553 554 maj_stat = gss_inquire_cred(&min_stat, 555 creds, 556 &name, &lifetime, &usage, NULL); 557 558 if (maj_stat == GSS_S_COMPLETE) { 559 const char *usage_string = NULL; 560 switch (usage) { 561 case GSS_C_BOTH: 562 usage_string = "GSS_C_BOTH"; 563 break; 564 case GSS_C_ACCEPT: 565 usage_string = "GSS_C_ACCEPT"; 566 break; 567 case GSS_C_INITIATE: 568 usage_string = "GSS_C_INITIATE"; 569 break; 570 } 571 maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); 572 if (maj_stat) { 573 buffer.value = NULL; 574 buffer.length = 0; 575 } 576 if (lifetime > 0) { 577 DEBUG(0, ("GSSAPI gss_inquire_cred indicates expiry of %*.*s in %u sec for %s\n", 578 (int)buffer.length, (int)buffer.length, (char *)buffer.value, 579 lifetime, usage_string)); 580 } else { 581 DEBUG(0, ("GSSAPI gss_inquire_cred indicates %*.*s has already expired for %s\n", 582 (int)buffer.length, (int)buffer.length, (char *)buffer.value, 583 usage_string)); 584 } 585 gss_release_buffer(&min_stat, &buffer); 586 gss_release_name(&min_stat, &name); 587 } else if (maj_stat != GSS_S_COMPLETE) { 588 DEBUG(0, ("inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", 589 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 590 } 591 return NT_STATUS_INVALID_PARAMETER; 592 } else if (smb_gss_oid_equal(gensec_gssapi_state->gss_oid, 593 gss_mech_krb5)) { 559 594 switch (min_stat) { 560 595 case KRB5KRB_AP_ERR_TKT_NYV: … … 569 604 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 570 605 case KRB5_KDC_UNREACH: 571 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a tic etkto %s: %s\n",606 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticket to %s: %s\n", 572 607 gensec_gssapi_state->target_principal, 573 608 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); … … 586 621 gensec_gssapi_state->gss_exchange_count, 587 622 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 588 return nt_status;623 return NT_STATUS_LOGON_FAILURE; 589 624 } 590 625 } else { … … 593 628 gensec_gssapi_state->gss_exchange_count, 594 629 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 595 return nt_status;630 return NT_STATUS_LOGON_FAILURE; 596 631 } 597 632 break; … … 942 977 if (GSS_ERROR(maj_stat)) { 943 978 TALLOC_CTX *mem_ctx = talloc_new(NULL); 944 DEBUG(1, ("gensec_gssapi_max_input_size: determin aing signature size with gss_wrap_size_limit failed: %s\n",979 DEBUG(1, ("gensec_gssapi_max_input_size: determining signature size with gss_wrap_size_limit failed: %s\n", 945 980 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 946 981 talloc_free(mem_ctx); … … 966 1001 struct gensec_gssapi_state *gensec_gssapi_state 967 1002 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 968 OM_uint32 maj_stat, min_stat; 969 gss_buffer_desc input_token, output_token; 970 int conf_state; 971 ssize_t sig_length; 972 973 input_token.length = length; 974 input_token.value = data; 975 976 maj_stat = gss_wrap(&min_stat, 977 gensec_gssapi_state->gssapi_context, 978 gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), 979 GSS_C_QOP_DEFAULT, 980 &input_token, 981 &conf_state, 982 &output_token); 983 if (GSS_ERROR(maj_stat)) { 984 DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n", 985 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 986 return NT_STATUS_ACCESS_DENIED; 987 } 988 989 if (output_token.length < input_token.length) { 990 DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", 991 (long)output_token.length, (long)length)); 992 return NT_STATUS_INTERNAL_ERROR; 993 } 994 sig_length = output_token.length - input_token.length; 995 996 memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); 997 *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); 998 999 dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); 1000 dump_data_pw("gensec_gssapi_seal_packet: clear\n", data, length); 1001 dump_data_pw("gensec_gssapi_seal_packet: sealed\n", ((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); 1002 1003 gss_release_buffer(&min_stat, &output_token); 1004 1005 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) 1006 && !conf_state) { 1007 return NT_STATUS_ACCESS_DENIED; 1008 } 1003 bool hdr_signing = false; 1004 size_t sig_size = 0; 1005 NTSTATUS status; 1006 1007 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 1008 hdr_signing = true; 1009 } 1010 1011 sig_size = gensec_gssapi_sig_size(gensec_security, length); 1012 1013 status = gssapi_seal_packet(gensec_gssapi_state->gssapi_context, 1014 gensec_gssapi_state->gss_oid, 1015 hdr_signing, sig_size, 1016 data, length, 1017 whole_pdu, pdu_length, 1018 mem_ctx, sig); 1019 if (!NT_STATUS_IS_OK(status)) { 1020 DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%zu," 1021 "data=%zu,pdu=%zu) failed: %s\n", 1022 hdr_signing, sig_size, length, pdu_length, 1023 nt_errstr(status))); 1024 return status; 1025 } 1026 1009 1027 return NT_STATUS_OK; 1010 1028 } 1011 1029 1012 1030 static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_security, 1013 TALLOC_CTX *mem_ctx,1014 1031 uint8_t *data, size_t length, 1015 1032 const uint8_t *whole_pdu, size_t pdu_length, … … 1018 1035 struct gensec_gssapi_state *gensec_gssapi_state 1019 1036 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1020 OM_uint32 maj_stat, min_stat; 1021 gss_buffer_desc input_token, output_token; 1022 int conf_state; 1023 gss_qop_t qop_state; 1024 DATA_BLOB in; 1025 1026 dump_data_pw("gensec_gssapi_unseal_packet: sig\n", sig->data, sig->length); 1027 1028 in = data_blob_talloc(mem_ctx, NULL, sig->length + length); 1029 1030 memcpy(in.data, sig->data, sig->length); 1031 memcpy(in.data + sig->length, data, length); 1032 1033 input_token.length = in.length; 1034 input_token.value = in.data; 1035 1036 maj_stat = gss_unwrap(&min_stat, 1037 gensec_gssapi_state->gssapi_context, 1038 &input_token, 1039 &output_token, 1040 &conf_state, 1041 &qop_state); 1042 if (GSS_ERROR(maj_stat)) { 1043 DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n", 1044 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1045 return NT_STATUS_ACCESS_DENIED; 1046 } 1047 1048 if (output_token.length != length) { 1049 return NT_STATUS_INTERNAL_ERROR; 1050 } 1051 1052 memcpy(data, output_token.value, length); 1053 1054 gss_release_buffer(&min_stat, &output_token); 1055 1056 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) 1057 && !conf_state) { 1058 return NT_STATUS_ACCESS_DENIED; 1059 } 1037 bool hdr_signing = false; 1038 NTSTATUS status; 1039 1040 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 1041 hdr_signing = true; 1042 } 1043 1044 status = gssapi_unseal_packet(gensec_gssapi_state->gssapi_context, 1045 gensec_gssapi_state->gss_oid, 1046 hdr_signing, 1047 data, length, 1048 whole_pdu, pdu_length, 1049 sig); 1050 if (!NT_STATUS_IS_OK(status)) { 1051 DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%zu," 1052 "data=%zu,pdu=%zu) failed: %s\n", 1053 hdr_signing, sig->length, length, pdu_length, 1054 nt_errstr(status))); 1055 return status; 1056 } 1057 1060 1058 return NT_STATUS_OK; 1061 1059 } … … 1069 1067 struct gensec_gssapi_state *gensec_gssapi_state 1070 1068 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1071 OM_uint32 maj_stat, min_stat;1072 gss_buffer_desc input_token, output_token;1069 bool hdr_signing = false; 1070 NTSTATUS status; 1073 1071 1074 1072 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 1075 input_token.length = pdu_length; 1076 input_token.value = discard_const_p(uint8_t *, whole_pdu); 1077 } else { 1078 input_token.length = length; 1079 input_token.value = discard_const_p(uint8_t *, data); 1080 } 1081 1082 maj_stat = gss_get_mic(&min_stat, 1083 gensec_gssapi_state->gssapi_context, 1084 GSS_C_QOP_DEFAULT, 1085 &input_token, 1086 &output_token); 1087 if (GSS_ERROR(maj_stat)) { 1088 DEBUG(1, ("GSS GetMic failed: %s\n", 1089 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1090 return NT_STATUS_ACCESS_DENIED; 1091 } 1092 1093 *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length); 1094 1095 dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); 1096 1097 gss_release_buffer(&min_stat, &output_token); 1073 hdr_signing = true; 1074 } 1075 1076 status = gssapi_sign_packet(gensec_gssapi_state->gssapi_context, 1077 gensec_gssapi_state->gss_oid, 1078 hdr_signing, 1079 data, length, 1080 whole_pdu, pdu_length, 1081 mem_ctx, sig); 1082 if (!NT_STATUS_IS_OK(status)) { 1083 DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u," 1084 "data=%zu,pdu=%zu) failed: %s\n", 1085 hdr_signing, length, pdu_length, 1086 nt_errstr(status))); 1087 return status; 1088 } 1098 1089 1099 1090 return NT_STATUS_OK; … … 1101 1092 1102 1093 static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_security, 1103 TALLOC_CTX *mem_ctx,1104 1094 const uint8_t *data, size_t length, 1105 1095 const uint8_t *whole_pdu, size_t pdu_length, … … 1108 1098 struct gensec_gssapi_state *gensec_gssapi_state 1109 1099 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1110 OM_uint32 maj_stat, min_stat; 1111 gss_buffer_desc input_token; 1112 gss_buffer_desc input_message; 1113 gss_qop_t qop_state; 1114 1115 dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); 1100 bool hdr_signing = false; 1101 NTSTATUS status; 1116 1102 1117 1103 if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { 1118 input_message.length = pdu_length; 1119 input_message.value = discard_const(whole_pdu); 1120 } else { 1121 input_message.length = length; 1122 input_message.value = discard_const(data); 1123 } 1124 1125 input_token.length = sig->length; 1126 input_token.value = sig->data; 1127 1128 maj_stat = gss_verify_mic(&min_stat, 1129 gensec_gssapi_state->gssapi_context, 1130 &input_message, 1131 &input_token, 1132 &qop_state); 1133 if (GSS_ERROR(maj_stat)) { 1134 DEBUG(1, ("GSS VerifyMic failed: %s\n", 1135 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1136 return NT_STATUS_ACCESS_DENIED; 1104 hdr_signing = true; 1105 } 1106 1107 status = gssapi_check_packet(gensec_gssapi_state->gssapi_context, 1108 gensec_gssapi_state->gss_oid, 1109 hdr_signing, 1110 data, length, 1111 whole_pdu, pdu_length, 1112 sig); 1113 if (!NT_STATUS_IS_OK(status)) { 1114 DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%zu," 1115 "data=%zu,pdu=%zu) failed: %s\n", 1116 hdr_signing, sig->length, length, pdu_length, 1117 nt_errstr(status))); 1118 return status; 1137 1119 } 1138 1120 … … 1151 1133 && gensec_gssapi_state->sasl_state == STAGE_DONE) { 1152 1134 return ((gensec_gssapi_state->sasl_protection & NEG_SIGN) 1153 && (gensec_gssapi_state->g ot_flags & GSS_C_INTEG_FLAG));1154 } 1155 return gensec_gssapi_state->g ot_flags & GSS_C_INTEG_FLAG;1135 && (gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG)); 1136 } 1137 return gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG; 1156 1138 } 1157 1139 if (feature & GENSEC_FEATURE_SEAL) { … … 1160 1142 && gensec_gssapi_state->sasl_state == STAGE_DONE) { 1161 1143 return ((gensec_gssapi_state->sasl_protection & NEG_SEAL) 1162 && (gensec_gssapi_state->g ot_flags & GSS_C_CONF_FLAG));1163 } 1164 return gensec_gssapi_state->g ot_flags & GSS_C_CONF_FLAG;1144 && (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG)); 1145 } 1146 return gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG; 1165 1147 } 1166 1148 if (feature & GENSEC_FEATURE_SESSION_KEY) { 1167 1149 /* Only for GSSAPI/Krb5 */ 1168 if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { 1150 if (smb_gss_oid_equal(gensec_gssapi_state->gss_oid, 1151 gss_mech_krb5)) { 1169 1152 return true; 1170 1153 } 1171 1154 } 1172 1155 if (feature & GENSEC_FEATURE_DCE_STYLE) { 1173 return gensec_gssapi_state->g ot_flags & GSS_C_DCE_STYLE;1156 return gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE; 1174 1157 } 1175 1158 if (feature & GENSEC_FEATURE_NEW_SPNEGO) { 1176 1159 NTSTATUS status; 1177 1178 if (!(gensec_gssapi_state->got_flags & GSS_C_INTEG_FLAG)) { 1160 uint32_t keytype; 1161 1162 if (!(gensec_gssapi_state->gss_got_flags & GSS_C_INTEG_FLAG)) { 1179 1163 return false; 1180 1164 } … … 1187 1171 } 1188 1172 1189 status = gensec_gssapi_init_lucid(gensec_gssapi_state); 1190 if (!NT_STATUS_IS_OK(status)) { 1191 return false; 1192 } 1193 1194 if (gensec_gssapi_state->lucid->protocol == 1) { 1195 return true; 1196 } 1197 1198 return false; 1173 status = gssapi_get_session_key(gensec_gssapi_state, 1174 gensec_gssapi_state->gssapi_context, NULL, &keytype); 1175 /* 1176 * We should do a proper sig on the mechListMic unless 1177 * we know we have to be backwards compatible with 1178 * earlier windows versions. 1179 * 1180 * Negotiating a non-krb5 1181 * mech for example should be regarded as having 1182 * NEW_SPNEGO 1183 */ 1184 if (NT_STATUS_IS_OK(status)) { 1185 switch (keytype) { 1186 case ENCTYPE_DES_CBC_CRC: 1187 case ENCTYPE_DES_CBC_MD5: 1188 case ENCTYPE_ARCFOUR_HMAC: 1189 case ENCTYPE_DES3_CBC_SHA1: 1190 return false; 1191 } 1192 } 1193 return true; 1199 1194 } 1200 1195 /* We can always do async (rather than strict request/reply) packets. */ … … 1202 1197 return true; 1203 1198 } 1199 if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { 1200 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 1201 return true; 1202 } 1203 1204 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 1205 return true; 1206 } 1207 1208 return false; 1209 } 1204 1210 return false; 1211 } 1212 1213 static NTTIME gensec_gssapi_expire_time(struct gensec_security *gensec_security) 1214 { 1215 struct gensec_gssapi_state *gensec_gssapi_state = 1216 talloc_get_type_abort(gensec_security->private_data, 1217 struct gensec_gssapi_state); 1218 1219 return gensec_gssapi_state->expire_time; 1205 1220 } 1206 1221 … … 1212 1227 */ 1213 1228 static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security, 1229 TALLOC_CTX *mem_ctx, 1214 1230 DATA_BLOB *session_key) 1215 1231 { 1216 1232 struct gensec_gssapi_state *gensec_gssapi_state 1217 1233 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1218 OM_uint32 maj_stat, min_stat; 1219 krb5_keyblock *subkey; 1220 1221 if (gensec_gssapi_state->sasl_state != STAGE_DONE) { 1222 return NT_STATUS_NO_USER_SESSION_KEY; 1223 } 1224 1225 if (gensec_gssapi_state->session_key.data) { 1226 *session_key = gensec_gssapi_state->session_key; 1227 return NT_STATUS_OK; 1228 } 1229 1230 maj_stat = gsskrb5_get_subkey(&min_stat, 1231 gensec_gssapi_state->gssapi_context, 1232 &subkey); 1233 if (maj_stat != 0) { 1234 DEBUG(1, ("NO session key for this mech\n")); 1235 return NT_STATUS_NO_USER_SESSION_KEY; 1236 } 1237 1238 DEBUG(10, ("Got KRB5 session key of length %d%s\n", 1239 (int)KRB5_KEY_LENGTH(subkey), 1240 (gensec_gssapi_state->sasl_state == STAGE_DONE)?" (done)":"")); 1241 *session_key = data_blob_talloc(gensec_gssapi_state, 1242 KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey)); 1243 krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey); 1244 gensec_gssapi_state->session_key = *session_key; 1245 dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); 1246 1247 return NT_STATUS_OK; 1234 return gssapi_get_session_key(mem_ctx, gensec_gssapi_state->gssapi_context, session_key, NULL); 1248 1235 } 1249 1236 … … 1252 1239 * database lookup */ 1253 1240 static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security, 1241 TALLOC_CTX *mem_ctx, 1254 1242 struct auth_session_info **_session_info) 1255 1243 { 1256 1244 NTSTATUS nt_status; 1257 TALLOC_CTX * mem_ctx;1245 TALLOC_CTX *tmp_ctx; 1258 1246 struct gensec_gssapi_state *gensec_gssapi_state 1259 1247 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1260 struct auth_user_info_dc *user_info_dc = NULL;1261 1248 struct auth_session_info *session_info = NULL; 1262 1249 OM_uint32 maj_stat, min_stat; 1263 gss_buffer_desc pac;1264 DATA_BLOB pac_blob; 1265 struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL;1266 struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL;1250 DATA_BLOB pac_blob, *pac_blob_ptr = NULL; 1251 1252 gss_buffer_desc name_token; 1253 char *principal_string; 1267 1254 1268 if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length) 1269 || (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements, 1270 gensec_gssapi_state->gss_oid->length) != 0)) { 1271 DEBUG(1, ("NO session info available for this mech\n")); 1272 return NT_STATUS_INVALID_PARAMETER; 1273 } 1274 1275 mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); 1276 NT_STATUS_HAVE_NO_MEMORY(mem_ctx); 1277 1278 maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, 1279 gensec_gssapi_state->gssapi_context, 1280 KRB5_AUTHDATA_WIN2K_PAC, 1281 &pac); 1282 1283 1284 if (maj_stat == 0) { 1285 pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); 1286 gss_release_buffer(&min_stat, &pac); 1287 1288 } else { 1289 pac_blob = data_blob(NULL, 0); 1290 } 1255 tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); 1256 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 1257 1258 maj_stat = gss_display_name (&min_stat, 1259 gensec_gssapi_state->client_name, 1260 &name_token, 1261 NULL); 1262 if (GSS_ERROR(maj_stat)) { 1263 DEBUG(1, ("GSS display_name failed: %s\n", 1264 gssapi_error_string(tmp_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1265 talloc_free(tmp_ctx); 1266 return NT_STATUS_FOOBAR; 1267 } 1268 1269 principal_string = talloc_strndup(tmp_ctx, 1270 (const char *)name_token.value, 1271 name_token.length); 1272 1273 gss_release_buffer(&min_stat, &name_token); 1274 1275 if (!principal_string) { 1276 talloc_free(tmp_ctx); 1277 return NT_STATUS_NO_MEMORY; 1278 } 1279 1280 nt_status = gssapi_obtain_pac_blob(tmp_ctx, gensec_gssapi_state->gssapi_context, 1281 gensec_gssapi_state->client_name, 1282 &pac_blob); 1291 1283 1292 1284 /* IF we have the PAC - otherwise we need to get this … … 1294 1286 * kind... 1295 1287 */ 1296 if (pac_blob.length) { 1297 pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); 1298 if (!pac_srv_sig) { 1299 talloc_free(mem_ctx); 1300 return NT_STATUS_NO_MEMORY; 1301 } 1302 pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); 1303 if (!pac_kdc_sig) { 1304 talloc_free(mem_ctx); 1305 return NT_STATUS_NO_MEMORY; 1306 } 1307 1308 nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx, 1309 pac_blob, 1310 gensec_gssapi_state->smb_krb5_context->krb5_context, 1311 &user_info_dc, 1312 pac_srv_sig, 1313 pac_kdc_sig); 1314 if (!NT_STATUS_IS_OK(nt_status)) { 1315 talloc_free(mem_ctx); 1316 return nt_status; 1317 } 1318 } else { 1319 gss_buffer_desc name_token; 1320 char *principal_string; 1321 1322 maj_stat = gss_display_name (&min_stat, 1323 gensec_gssapi_state->client_name, 1324 &name_token, 1325 NULL); 1326 if (GSS_ERROR(maj_stat)) { 1327 DEBUG(1, ("GSS display_name failed: %s\n", 1328 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1329 talloc_free(mem_ctx); 1330 return NT_STATUS_FOOBAR; 1331 } 1332 1333 principal_string = talloc_strndup(mem_ctx, 1334 (const char *)name_token.value, 1335 name_token.length); 1336 1337 gss_release_buffer(&min_stat, &name_token); 1338 1339 if (!principal_string) { 1340 talloc_free(mem_ctx); 1341 return NT_STATUS_NO_MEMORY; 1342 } 1343 1344 if (gensec_security->auth_context && 1345 !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { 1346 DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", 1347 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1348 nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx, 1349 gensec_security->auth_context, 1350 principal_string, 1351 NULL, 1352 &user_info_dc); 1353 1354 if (!NT_STATUS_IS_OK(nt_status)) { 1355 talloc_free(mem_ctx); 1356 return nt_status; 1357 } 1358 } else { 1359 DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s\n", 1360 principal_string, 1361 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1362 return NT_STATUS_ACCESS_DENIED; 1363 } 1364 } 1365 1366 /* references the user_info_dc into the session_info */ 1367 nt_status = gensec_generate_session_info(mem_ctx, gensec_security, 1368 user_info_dc, &session_info); 1288 if (NT_STATUS_IS_OK(nt_status)) { 1289 pac_blob_ptr = &pac_blob; 1290 } 1291 nt_status = gensec_generate_session_info_pac(tmp_ctx, 1292 gensec_security, 1293 gensec_gssapi_state->smb_krb5_context, 1294 pac_blob_ptr, principal_string, 1295 gensec_get_remote_address(gensec_security), 1296 &session_info); 1369 1297 if (!NT_STATUS_IS_OK(nt_status)) { 1370 talloc_free( mem_ctx);1298 talloc_free(tmp_ctx); 1371 1299 return nt_status; 1372 1300 } 1373 1301 1374 nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key);1302 nt_status = gensec_gssapi_session_key(gensec_security, session_info, &session_info->session_key); 1375 1303 if (!NT_STATUS_IS_OK(nt_status)) { 1376 talloc_free( mem_ctx);1304 talloc_free(tmp_ctx); 1377 1305 return nt_status; 1378 1306 } 1379 1307 1380 /* Allow torture tests to check the PAC signatures */ 1381 if (session_info->torture) { 1382 session_info->torture->pac_srv_sig = talloc_steal(session_info->torture, pac_srv_sig); 1383 session_info->torture->pac_kdc_sig = talloc_steal(session_info->torture, pac_kdc_sig); 1384 } 1385 1386 if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) { 1387 DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); 1388 } else { 1308 if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG && 1309 gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { 1389 1310 krb5_error_code ret; 1390 1311 const char *error_string; … … 1393 1314 session_info->credentials = cli_credentials_init(session_info); 1394 1315 if (!session_info->credentials) { 1395 talloc_free( mem_ctx);1316 talloc_free(tmp_ctx); 1396 1317 return NT_STATUS_NO_MEMORY; 1397 1318 } … … 1406 1327 CRED_SPECIFIED, &error_string); 1407 1328 if (ret) { 1408 talloc_free( mem_ctx);1329 talloc_free(tmp_ctx); 1409 1330 DEBUG(2,("Failed to get gss creds: %s\n", error_string)); 1410 1331 return NT_STATUS_NO_MEMORY; … … 1416 1337 /* It has been taken from this place... */ 1417 1338 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; 1418 } 1419 talloc_steal(gensec_gssapi_state, session_info); 1420 talloc_free(mem_ctx); 1421 *_session_info = session_info; 1339 } else { 1340 DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); 1341 } 1342 1343 *_session_info = talloc_steal(mem_ctx, session_info); 1344 talloc_free(tmp_ctx); 1422 1345 1423 1346 return NT_STATUS_OK; … … 1428 1351 struct gensec_gssapi_state *gensec_gssapi_state 1429 1352 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1430 NTSTATUS status;1431 1432 if (gensec_gssapi_state->sig_size ) {1353 size_t sig_size; 1354 1355 if (gensec_gssapi_state->sig_size > 0) { 1433 1356 return gensec_gssapi_state->sig_size; 1434 1357 } 1435 1358 1436 if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { 1437 gensec_gssapi_state->sig_size = 45; 1438 } else { 1439 gensec_gssapi_state->sig_size = 37; 1440 } 1441 1442 status = gensec_gssapi_init_lucid(gensec_gssapi_state); 1443 if (!NT_STATUS_IS_OK(status)) { 1444 return gensec_gssapi_state->sig_size; 1445 } 1446 1447 if (gensec_gssapi_state->lucid->protocol == 1) { 1448 if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { 1449 /* 1450 * TODO: windows uses 76 here, but we don't know 1451 * gss_wrap works with aes keys yet 1452 */ 1453 gensec_gssapi_state->sig_size = 76; 1454 } else { 1455 gensec_gssapi_state->sig_size = 28; 1456 } 1457 } else if (gensec_gssapi_state->lucid->protocol == 0) { 1458 switch (gensec_gssapi_state->lucid->rfc1964_kd.ctx_key.type) { 1459 case KEYTYPE_DES: 1460 case KEYTYPE_ARCFOUR: 1461 case KEYTYPE_ARCFOUR_56: 1462 if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { 1463 gensec_gssapi_state->sig_size = 45; 1464 } else { 1465 gensec_gssapi_state->sig_size = 37; 1466 } 1467 break; 1468 case KEYTYPE_DES3: 1469 if (gensec_gssapi_state->got_flags & GSS_C_CONF_FLAG) { 1470 gensec_gssapi_state->sig_size = 57; 1471 } else { 1472 gensec_gssapi_state->sig_size = 49; 1473 } 1474 break; 1475 } 1476 } 1477 1359 sig_size = gssapi_get_sig_size(gensec_gssapi_state->gssapi_context, 1360 gensec_gssapi_state->gss_oid, 1361 gensec_gssapi_state->gss_want_flags, 1362 data_size); 1363 1364 gensec_gssapi_state->sig_size = sig_size; 1478 1365 return gensec_gssapi_state->sig_size; 1479 1366 } … … 1498 1385 .client_start = gensec_gssapi_client_start, 1499 1386 .server_start = gensec_gssapi_server_start, 1500 .magic = gensec_ gssapi_magic,1387 .magic = gensec_magic_check_krb5_oid, 1501 1388 .update = gensec_gssapi_update, 1502 1389 .session_key = gensec_gssapi_session_key, … … 1506 1393 .seal_packet = gensec_gssapi_seal_packet, 1507 1394 .unseal_packet = gensec_gssapi_unseal_packet, 1395 .max_input_size = gensec_gssapi_max_input_size, 1396 .max_wrapped_size = gensec_gssapi_max_wrapped_size, 1508 1397 .wrap = gensec_gssapi_wrap, 1509 1398 .unwrap = gensec_gssapi_unwrap, 1510 1399 .have_feature = gensec_gssapi_have_feature, 1400 .expire_time = gensec_gssapi_expire_time, 1511 1401 .enabled = false, 1512 1402 .kerberos = true, … … 1521 1411 .client_start = gensec_gssapi_client_start, 1522 1412 .server_start = gensec_gssapi_server_start, 1523 .magic = gensec_ gssapi_magic,1413 .magic = gensec_magic_check_krb5_oid, 1524 1414 .update = gensec_gssapi_update, 1525 1415 .session_key = gensec_gssapi_session_key, … … 1530 1420 .seal_packet = gensec_gssapi_seal_packet, 1531 1421 .unseal_packet = gensec_gssapi_unseal_packet, 1422 .max_input_size = gensec_gssapi_max_input_size, 1423 .max_wrapped_size = gensec_gssapi_max_wrapped_size, 1532 1424 .wrap = gensec_gssapi_wrap, 1533 1425 .unwrap = gensec_gssapi_unwrap, 1534 1426 .have_feature = gensec_gssapi_have_feature, 1427 .expire_time = gensec_gssapi_expire_time, 1535 1428 .enabled = true, 1536 1429 .kerberos = true, … … 1552 1445 .unwrap = gensec_gssapi_unwrap, 1553 1446 .have_feature = gensec_gssapi_have_feature, 1447 .expire_time = gensec_gssapi_expire_time, 1554 1448 .enabled = true, 1555 1449 .kerberos = true, -
vendor/current/source4/auth/gensec/gensec_gssapi.h
r740 r988 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 4 4 Kerberos backend for GENSEC 5 5 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 7 7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2004-2005 … … 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of … … 17 17 GNU General Public License for more details. 18 18 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 /* This structure described here, so the RPC-PAC test can get at the PAC provided */ 25 25 26 enum gensec_gssapi_sasl_state 26 enum gensec_gssapi_sasl_state 27 27 { 28 28 STAGE_GSS_NEG, … … 38 38 struct gensec_gssapi_state { 39 39 gss_ctx_id_t gssapi_context; 40 struct gss_channel_bindings_struct *input_chan_bindings;41 40 gss_name_t server_name; 42 41 gss_name_t client_name; 43 OM_uint32 want_flags, got_flags; 42 OM_uint32 gss_want_flags, gss_got_flags; 43 44 gss_cred_id_t delegated_cred_handle; 45 46 NTTIME expire_time; 47 48 /* gensec_gssapi only */ 44 49 gss_OID gss_oid; 45 50 46 DATA_BLOB session_key; 47 DATA_BLOB pac; 48 51 struct gss_channel_bindings_struct *input_chan_bindings; 49 52 struct smb_krb5_context *smb_krb5_context; 50 53 struct gssapi_creds_container *client_cred; 51 54 struct gssapi_creds_container *server_cred; 52 gss_krb5_lucid_context_v1_t *lucid;53 54 gss_cred_id_t delegated_cred_handle;55 55 56 56 bool sasl; /* We have two different mechs in this file: One … … 68 68 const char *target_principal; 69 69 }; 70 -
vendor/current/source4/auth/gensec/gensec_krb5.c
r740 r988 28 28 #include "auth/kerberos/kerberos.h" 29 29 #include "auth/auth.h" 30 #include "lib/socket/socket.h"31 30 #include "lib/tsocket/tsocket.h" 32 #include "librpc/ rpc/dcerpc.h"31 #include "librpc/gen_ndr/dcerpc.h" 33 32 #include "auth/credentials/credentials.h" 34 33 #include "auth/credentials/credentials_krb5.h" 35 34 #include "auth/kerberos/kerberos_credentials.h" 36 35 #include "auth/gensec/gensec.h" 36 #include "auth/gensec/gensec_internal.h" 37 37 #include "auth/gensec/gensec_proto.h" 38 #include "auth/gensec/gensec_toplevel_proto.h" 38 39 #include "param/param.h" 39 40 #include "auth/auth_sam_reply.h" 40 41 #include "lib/util/util_net.h" 42 #include "../lib/util/asn1.h" 43 #include "auth/kerberos/pac_utils.h" 44 #include "gensec_krb5_util.h" 45 46 _PUBLIC_ NTSTATUS gensec_krb5_init(void); 41 47 42 48 enum GENSEC_KRB5_STATE { … … 48 54 49 55 struct gensec_krb5_state { 50 DATA_BLOB session_key;51 DATA_BLOB pac;52 56 enum GENSEC_KRB5_STATE state_position; 53 57 struct smb_krb5_context *smb_krb5_context; … … 113 117 ZERO_STRUCT(gensec_krb5_state->enc_ticket); 114 118 gensec_krb5_state->keyblock = NULL; 115 gensec_krb5_state->session_key = data_blob(NULL, 0);116 gensec_krb5_state->pac = data_blob(NULL, 0);117 119 gensec_krb5_state->gssapi = gssapi; 118 120 … … 234 236 static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi) 235 237 { 238 const char *hostname; 236 239 struct gensec_krb5_state *gensec_krb5_state; 237 krb5_error_code ret;238 240 NTSTATUS nt_status; 239 struct ccache_container *ccache_container;240 const char *hostname;241 const char *error_string;242 const char *principal;243 krb5_data in_data;244 struct tevent_context *previous_ev;245 246 241 hostname = gensec_get_target_hostname(gensec_security); 247 242 if (!hostname) { 248 DEBUG( 1, ("Could not determine hostname for target computer, cannot use kerberos\n"));243 DEBUG(3, ("No hostname for target computer passed in, cannot use kerberos for this connection\n")); 249 244 return NT_STATUS_INVALID_PARAMETER; 250 245 } … … 268 263 269 264 if (gensec_krb5_state->gssapi) { 270 /* The Fake GSSAPI mod al emulates Samba3, which does not do mutual authentication */265 /* The Fake GSSAPI model emulates Samba3, which does not do mutual authentication */ 271 266 if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) { 272 267 gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED; … … 278 273 } 279 274 } 275 return NT_STATUS_OK; 276 } 277 278 static NTSTATUS gensec_krb5_common_client_creds(struct gensec_security *gensec_security, 279 struct tevent_context *ev, 280 bool gssapi) 281 { 282 struct gensec_krb5_state *gensec_krb5_state; 283 krb5_error_code ret; 284 struct ccache_container *ccache_container; 285 const char *error_string; 286 const char *principal; 287 const char *hostname; 288 krb5_data in_data = { .length = 0 }; 289 krb5_data *in_data_p = NULL; 290 struct tevent_context *previous_ev; 291 292 if (lpcfg_parm_bool(gensec_security->settings->lp_ctx, 293 NULL, "gensec_krb5", "send_authenticator_checksum", true)) { 294 in_data_p = &in_data; 295 } 296 297 gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; 280 298 281 299 principal = gensec_get_target_principal(gensec_security); 300 hostname = gensec_get_target_hostname(gensec_security); 282 301 283 302 ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security), 284 gensec_security->event_ctx,303 ev, 285 304 gensec_security->settings->lp_ctx, &ccache_container, &error_string); 286 305 switch (ret) { … … 301 320 return NT_STATUS_UNSUCCESSFUL; 302 321 } 303 in_data.length = 0;304 322 305 323 /* Do this every time, in case we have weird recursive issues here */ 306 ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, gensec_security->event_ctx, &previous_ev);324 ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, ev, &previous_ev); 307 325 if (ret != 0) { 308 326 DEBUG(1, ("gensec_krb5_start: Setting event context failed\n")); … … 318 336 gensec_krb5_state->ap_req_options, 319 337 target_principal, 320 &in_data, ccache_container->ccache,338 in_data_p, ccache_container->ccache, 321 339 &gensec_krb5_state->enc_ticket); 322 340 krb5_free_principal(gensec_krb5_state->smb_krb5_context->krb5_context, … … 329 347 gensec_get_target_service(gensec_security), 330 348 hostname, 331 &in_data, ccache_container->ccache,349 in_data_p, ccache_container->ccache, 332 350 &gensec_krb5_state->enc_ticket); 333 351 } 334 352 335 smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx);353 smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, ev); 336 354 337 355 switch (ret) { … … 383 401 } 384 402 385 /** 386 * Check if the packet is one for this mechansim 387 * 388 * @param gensec_security GENSEC state 389 * @param in The request, as a DATA_BLOB 390 * @return Error, INVALID_PARAMETER if it's not a packet for us 391 * or NT_STATUS_OK if the packet is ok. 392 */ 393 394 static NTSTATUS gensec_fake_gssapi_krb5_magic(struct gensec_security *gensec_security, 395 const DATA_BLOB *in) 396 { 397 if (gensec_gssapi_check_oid(in, GENSEC_OID_KERBEROS5)) { 398 return NT_STATUS_OK; 403 404 /* 405 generate a krb5 GSS-API wrapper packet given a ticket 406 */ 407 static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2]) 408 { 409 struct asn1_data *data; 410 DATA_BLOB ret = data_blob_null; 411 412 data = asn1_init(mem_ctx); 413 if (!data || !ticket->data) { 414 return ret; 415 } 416 417 if (!asn1_push_tag(data, ASN1_APPLICATION(0))) goto err; 418 if (!asn1_write_OID(data, GENSEC_OID_KERBEROS5)) goto err; 419 420 if (!asn1_write(data, tok_id, 2)) goto err; 421 if (!asn1_write(data, ticket->data, ticket->length)) goto err; 422 if (!asn1_pop_tag(data)) goto err; 423 424 425 if (!asn1_extract_blob(data, mem_ctx, &ret)) { 426 goto err; 427 } 428 asn1_free(data); 429 430 return ret; 431 432 err: 433 434 DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n", 435 (int)asn1_current_ofs(data))); 436 asn1_free(data); 437 return ret; 438 } 439 440 /* 441 parse a krb5 GSS-API wrapper packet giving a ticket 442 */ 443 static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2]) 444 { 445 bool ret = false; 446 struct asn1_data *data = asn1_init(mem_ctx); 447 int data_remaining; 448 449 if (!data) { 450 return false; 451 } 452 453 if (!asn1_load(data, *blob)) goto err; 454 if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err; 455 if (!asn1_check_OID(data, GENSEC_OID_KERBEROS5)) goto err; 456 457 data_remaining = asn1_tag_remaining(data); 458 459 if (data_remaining < 3) { 460 asn1_set_error(data); 399 461 } else { 400 return NT_STATUS_INVALID_PARAMETER; 401 } 402 } 403 462 if (!asn1_read(data, tok_id, 2)) goto err; 463 data_remaining -= 2; 464 *ticket = data_blob_talloc(mem_ctx, NULL, data_remaining); 465 if (!asn1_read(data, ticket->data, ticket->length)) goto err; 466 } 467 468 if (!asn1_end_tag(data)) goto err; 469 470 ret = !asn1_has_error(data); 471 472 err: 473 474 asn1_free(data); 475 476 return ret; 477 } 404 478 405 479 /** … … 416 490 static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, 417 491 TALLOC_CTX *out_mem_ctx, 492 struct tevent_context *ev, 418 493 const DATA_BLOB in, DATA_BLOB *out) 419 494 { … … 427 502 DATA_BLOB unwrapped_out; 428 503 504 nt_status = gensec_krb5_common_client_creds(gensec_security, ev, gensec_krb5_state->gssapi); 505 if (!NT_STATUS_IS_OK(nt_status)) { 506 return nt_status; 507 } 508 429 509 if (gensec_krb5_state->gssapi) { 430 510 unwrapped_out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length); … … 506 586 } 507 587 508 /* This ensures we lookup the correct entry in that keytab */ 588 /* This ensures we lookup the correct entry in that 589 * keytab. A NULL principal is acceptable, and means 590 * that the krb5 libs should search the keytab at 591 * accept time for any matching key */ 509 592 ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security), 510 593 gensec_krb5_state->smb_krb5_context, … … 514 597 DEBUG(2,("Failed to make credentials from principal: %s\n", error_string)); 515 598 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 599 } 600 601 if (keytab->password_based || obtained < CRED_SPECIFIED) { 602 /* 603 * Use match-by-key in this case (matches 604 * cli_credentials_get_server_gss_creds() 605 * behaviour). No need to free the memory, 606 * this is handled with a talloc destructor. 607 */ 608 server_in_keytab = NULL; 516 609 } 517 610 … … 557 650 558 651 static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, 652 TALLOC_CTX *mem_ctx, 559 653 DATA_BLOB *session_key) 560 654 { … … 567 661 if (gensec_krb5_state->state_position != GENSEC_KRB5_DONE) { 568 662 return NT_STATUS_NO_USER_SESSION_KEY; 569 }570 571 if (gensec_krb5_state->session_key.data) {572 *session_key = gensec_krb5_state->session_key;573 return NT_STATUS_OK;574 663 } 575 664 … … 585 674 DEBUG(10, ("Got KRB5 session key of length %d\n", 586 675 (int)KRB5_KEY_LENGTH(skey))); 587 gensec_krb5_state->session_key = data_blob_talloc(gensec_krb5_state, 588 KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); 589 *session_key = gensec_krb5_state->session_key; 676 *session_key = data_blob_talloc(mem_ctx, 677 KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); 590 678 dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); 591 679 … … 599 687 600 688 static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, 689 TALLOC_CTX *mem_ctx, 601 690 struct auth_session_info **_session_info) 602 691 { … … 604 693 struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; 605 694 krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; 606 struct auth_user_info_dc *user_info_dc = NULL;607 695 struct auth_session_info *session_info = NULL; 608 struct PAC_LOGON_INFO *logon_info;609 696 610 697 krb5_principal client_principal; 611 698 char *principal_string; 612 699 613 DATA_BLOB pac ;700 DATA_BLOB pac_blob, *pac_blob_ptr = NULL; 614 701 krb5_data pac_data; 615 702 616 703 krb5_error_code ret; 617 704 618 TALLOC_CTX * mem_ctx = talloc_new(gensec_security);619 if (! mem_ctx) {705 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 706 if (!tmp_ctx) { 620 707 return NT_STATUS_NO_MEMORY; 621 708 } … … 625 712 DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", 626 713 smb_get_krb5_error_message(context, 627 ret, mem_ctx)));628 talloc_free( mem_ctx);714 ret, tmp_ctx))); 715 talloc_free(tmp_ctx); 629 716 return NT_STATUS_NO_MEMORY; 630 717 } … … 635 722 DEBUG(1, ("Unable to parse client principal: %s\n", 636 723 smb_get_krb5_error_message(context, 637 ret, mem_ctx)));724 ret, tmp_ctx))); 638 725 krb5_free_principal(context, client_principal); 639 talloc_free( mem_ctx);726 talloc_free(tmp_ctx); 640 727 return NT_STATUS_NO_MEMORY; 641 728 } … … 645 732 &pac_data); 646 733 647 if (ret && gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { 648 DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s \n", 649 principal_string, 650 smb_get_krb5_error_message(context, 651 ret, mem_ctx))); 652 free(principal_string); 653 krb5_free_principal(context, client_principal); 654 talloc_free(mem_ctx); 655 return NT_STATUS_ACCESS_DENIED; 656 } else if (ret) { 734 if (ret) { 657 735 /* NO pac */ 658 736 DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", 659 737 smb_get_krb5_error_message(context, 660 ret, mem_ctx))); 661 if (gensec_security->auth_context && 662 !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { 663 DEBUG(1, ("Unable to find PAC for %s, resorting to local user lookup: %s", 664 principal_string, smb_get_krb5_error_message(context, 665 ret, mem_ctx))); 666 nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx, 667 gensec_security->auth_context, 668 principal_string, 669 NULL, &user_info_dc); 670 if (!NT_STATUS_IS_OK(nt_status)) { 671 free(principal_string); 672 krb5_free_principal(context, client_principal); 673 talloc_free(mem_ctx); 674 return nt_status; 675 } 676 } else { 677 DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", 678 principal_string)); 738 ret, tmp_ctx))); 739 } else { 740 /* Found pac */ 741 pac_blob = data_blob_talloc(tmp_ctx, pac_data.data, pac_data.length); 742 kerberos_free_data_contents(context, &pac_data); 743 if (!pac_blob.data) { 679 744 free(principal_string); 680 745 krb5_free_principal(context, client_principal); 681 talloc_free(mem_ctx); 682 return NT_STATUS_ACCESS_DENIED; 683 } 684 } else { 685 /* Found pac */ 686 union netr_Validation validation; 687 688 pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length); 689 if (!pac.data) { 690 free(principal_string); 691 krb5_free_principal(context, client_principal); 692 talloc_free(mem_ctx); 746 talloc_free(tmp_ctx); 693 747 return NT_STATUS_NO_MEMORY; 694 748 } 695 749 696 750 /* decode and verify the pac */ 697 nt_status = kerberos_ pac_logon_info(gensec_krb5_state,698 &logon_info, pac,699 700 701 702 751 nt_status = kerberos_decode_pac(gensec_krb5_state, 752 pac_blob, 753 gensec_krb5_state->smb_krb5_context->krb5_context, 754 NULL, gensec_krb5_state->keyblock, 755 client_principal, 756 gensec_krb5_state->ticket->ticket.authtime, NULL); 703 757 704 758 if (!NT_STATUS_IS_OK(nt_status)) { 705 759 free(principal_string); 706 760 krb5_free_principal(context, client_principal); 707 talloc_free( mem_ctx);761 talloc_free(tmp_ctx); 708 762 return nt_status; 709 763 } 710 764 711 validation.sam3 = &logon_info->info3; 712 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 713 NULL, 714 3, &validation, 715 &user_info_dc); 716 if (!NT_STATUS_IS_OK(nt_status)) { 717 free(principal_string); 718 krb5_free_principal(context, client_principal); 719 talloc_free(mem_ctx); 720 return nt_status; 721 } 722 } 765 pac_blob_ptr = &pac_blob; 766 } 767 768 nt_status = gensec_generate_session_info_pac(tmp_ctx, 769 gensec_security, 770 gensec_krb5_state->smb_krb5_context, 771 pac_blob_ptr, principal_string, 772 gensec_get_remote_address(gensec_security), 773 &session_info); 723 774 724 775 free(principal_string); 725 776 krb5_free_principal(context, client_principal); 726 777 727 /* references the user_info_dc into the session_info */728 nt_status = gensec_generate_session_info(mem_ctx, gensec_security, user_info_dc, &session_info);729 730 778 if (!NT_STATUS_IS_OK(nt_status)) { 731 talloc_free( mem_ctx);779 talloc_free(tmp_ctx); 732 780 return nt_status; 733 781 } 734 782 735 nt_status = gensec_krb5_session_key(gensec_security, &session_info->session_key);783 nt_status = gensec_krb5_session_key(gensec_security, session_info, &session_info->session_key); 736 784 737 785 if (!NT_STATUS_IS_OK(nt_status)) { 738 talloc_free( mem_ctx);786 talloc_free(tmp_ctx); 739 787 return nt_status; 740 788 } 741 789 742 *_session_info = session_info; 743 744 talloc_steal(gensec_krb5_state, session_info); 745 talloc_free(mem_ctx); 790 *_session_info = talloc_steal(mem_ctx, session_info); 791 792 talloc_free(tmp_ctx); 746 793 return NT_STATUS_OK; 747 794 } … … 836 883 .server_start = gensec_fake_gssapi_krb5_server_start, 837 884 .update = gensec_krb5_update, 838 .magic = gensec_ fake_gssapi_krb5_magic,885 .magic = gensec_magic_check_krb5_oid, 839 886 .session_key = gensec_krb5_session_key, 840 887 .session_info = gensec_krb5_session_info, … … 874 921 if (!NT_STATUS_IS_OK(ret)) { 875 922 DEBUG(0,("Failed to register '%s' gensec backend!\n", 876 gensec_ krb5_security_ops.name));923 gensec_fake_gssapi_krb5_security_ops.name)); 877 924 return ret; 878 925 } -
vendor/current/source4/auth/gensec/gensec_tstream.c
r740 r988 28 28 #include "lib/tsocket/tsocket.h" 29 29 #include "lib/tsocket/tsocket_internal.h" 30 30 #include "auth/gensec/gensec_toplevel_proto.h" 31 31 32 32 static const struct tstream_context_ops tstream_gensec_ops; … … 248 248 vector[0].iov_len = sizeof(state->wrapped.hdr); 249 249 } else if (!state->wrapped.asked_for_blob) { 250 uint32_t msg_len; 251 250 252 state->wrapped.asked_for_blob = true; 251 uint32_t msg_len;252 253 253 254 msg_len = RIVAL(state->wrapped.hdr, 0); 254 255 255 if (msg_len > 0x00FFFFFF) { 256 /* 257 * I got a Windows 2012R2 server responding with 258 * a message of 0x1b28a33. 259 */ 260 if (msg_len > 0x0FFFFFFF) { 256 261 errno = EMSGSIZE; 257 262 return -1; -
vendor/current/source4/auth/gensec/pygensec.c
r740 r988 21 21 #include "param/pyparam.h" 22 22 #include "auth/gensec/gensec.h" 23 #include "auth/gensec/gensec_internal.h" /* TODO: remove this */ 23 24 #include "auth/credentials/pycredentials.h" 24 25 #include "libcli/util/pyerrors.h" 25 #include " scripting/python/modules.h"26 #include "lib/talloc/pytalloc.h"26 #include "python/modules.h" 27 #include <pytalloc.h> 27 28 #include <tevent.h> 28 29 #include "librpc/rpc/pyrpc_util.h" … … 37 38 return NULL; 38 39 39 security = py _talloc_get_type(self, struct gensec_security);40 security = pytalloc_get_type(self, struct gensec_security); 40 41 41 42 name = gensec_get_name_by_authtype(security, type); … … 79 80 { 80 81 NTSTATUS status; 81 py_talloc_Object *self;82 PyObject *self; 82 83 struct gensec_settings *settings; 83 84 const char *kwnames[] = { "settings", NULL }; 84 PyObject *py_settings; 85 struct tevent_context *ev; 85 PyObject *py_settings = Py_None; 86 86 struct gensec_security *gensec; 87 TALLOC_CTX *frame; 87 88 88 89 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings)) 89 90 return NULL; 90 91 91 self = (py_talloc_Object*)type->tp_alloc(type, 0); 92 if (self == NULL) { 93 PyErr_NoMemory(); 94 return NULL; 95 } 96 self->talloc_ctx = talloc_new(NULL); 97 if (self->talloc_ctx == NULL) { 98 PyErr_NoMemory(); 99 return NULL; 100 } 92 frame = talloc_stackframe(); 101 93 102 94 if (py_settings != Py_None) { 103 settings = settings_from_object( self->talloc_ctx, py_settings);95 settings = settings_from_object(frame, py_settings); 104 96 if (settings == NULL) { 105 PyObject_DEL(self); 97 PyErr_NoMemory(); 98 TALLOC_FREE(frame); 106 99 return NULL; 107 100 } 108 101 } else { 109 settings = talloc_zero( self->talloc_ctx, struct gensec_settings);102 settings = talloc_zero(frame, struct gensec_settings); 110 103 if (settings == NULL) { 111 PyObject_DEL(self); 104 PyErr_NoMemory(); 105 TALLOC_FREE(frame); 112 106 return NULL; 113 107 } 114 108 115 109 settings->lp_ctx = loadparm_init_global(true); 116 } 117 118 ev = tevent_context_init(self->talloc_ctx); 119 if (ev == NULL) { 120 PyErr_NoMemory(); 121 PyObject_Del(self); 122 return NULL; 123 } 124 125 status = gensec_init(settings->lp_ctx); 126 if (!NT_STATUS_IS_OK(status)) { 127 PyErr_SetNTSTATUS(status); 128 PyObject_DEL(self); 129 return NULL; 130 } 131 132 status = gensec_client_start(self->talloc_ctx, &gensec, ev, settings); 133 if (!NT_STATUS_IS_OK(status)) { 134 PyErr_SetNTSTATUS(status); 135 PyObject_DEL(self); 136 return NULL; 137 } 138 139 self->ptr = gensec; 110 if (settings->lp_ctx == NULL) { 111 PyErr_NoMemory(); 112 TALLOC_FREE(frame); 113 return NULL; 114 } 115 } 116 117 status = gensec_init(); 118 if (!NT_STATUS_IS_OK(status)) { 119 PyErr_SetNTSTATUS(status); 120 TALLOC_FREE(frame); 121 return NULL; 122 } 123 124 status = gensec_client_start(frame, &gensec, settings); 125 if (!NT_STATUS_IS_OK(status)) { 126 PyErr_SetNTSTATUS(status); 127 TALLOC_FREE(frame); 128 return NULL; 129 } 130 131 self = pytalloc_steal(type, gensec); 132 TALLOC_FREE(frame); 140 133 141 134 return (PyObject *)self; … … 145 138 { 146 139 NTSTATUS status; 147 py_talloc_Object *self;140 PyObject *self; 148 141 struct gensec_settings *settings = NULL; 149 142 const char *kwnames[] = { "settings", "auth_context", NULL }; 150 143 PyObject *py_settings = Py_None; 151 144 PyObject *py_auth_context = Py_None; 152 struct tevent_context *ev;153 145 struct gensec_security *gensec; 154 struct auth_context *auth_context = NULL; 146 struct auth4_context *auth_context = NULL; 147 TALLOC_CTX *frame; 155 148 156 149 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) 157 150 return NULL; 158 151 159 self = (py_talloc_Object*)type->tp_alloc(type, 0); 160 if (self == NULL) { 161 PyErr_NoMemory(); 162 return NULL; 163 } 164 self->talloc_ctx = talloc_new(NULL); 165 if (self->talloc_ctx == NULL) { 166 PyErr_NoMemory(); 167 return NULL; 168 } 152 frame = talloc_stackframe(); 169 153 170 154 if (py_settings != Py_None) { 171 settings = settings_from_object( self->talloc_ctx, py_settings);155 settings = settings_from_object(frame, py_settings); 172 156 if (settings == NULL) { 173 PyObject_DEL(self); 157 PyErr_NoMemory(); 158 TALLOC_FREE(frame); 174 159 return NULL; 175 160 } 176 161 } else { 177 settings = talloc_zero( self->talloc_ctx, struct gensec_settings);162 settings = talloc_zero(frame, struct gensec_settings); 178 163 if (settings == NULL) { 179 PyObject_DEL(self); 164 PyErr_NoMemory(); 165 TALLOC_FREE(frame); 180 166 return NULL; 181 167 } 182 168 183 169 settings->lp_ctx = loadparm_init_global(true); 184 } 185 186 ev = tevent_context_init(self->talloc_ctx); 187 if (ev == NULL) { 188 PyErr_NoMemory(); 189 PyObject_Del(self); 190 return NULL; 170 if (settings->lp_ctx == NULL) { 171 PyErr_NoMemory(); 172 TALLOC_FREE(frame); 173 return NULL; 174 } 191 175 } 192 176 193 177 if (py_auth_context != Py_None) { 194 auth_context = py _talloc_get_type(py_auth_context, struct auth_context);178 auth_context = pytalloc_get_type(py_auth_context, struct auth4_context); 195 179 if (!auth_context) { 196 180 PyErr_Format(PyExc_TypeError, 197 181 "Expected auth.AuthContext for auth_context argument, got %s", 198 talloc_get_name(py _talloc_get_ptr(py_auth_context)));182 talloc_get_name(pytalloc_get_ptr(py_auth_context))); 199 183 return NULL; 200 184 } 201 185 } 202 186 203 status = gensec_init(settings->lp_ctx); 204 if (!NT_STATUS_IS_OK(status)) { 205 PyErr_SetNTSTATUS(status); 206 PyObject_DEL(self); 207 return NULL; 208 } 209 210 status = gensec_server_start(self->talloc_ctx, ev, settings, auth_context, &gensec); 211 if (!NT_STATUS_IS_OK(status)) { 212 PyErr_SetNTSTATUS(status); 213 PyObject_DEL(self); 214 return NULL; 215 } 216 217 self->ptr = gensec; 218 219 return (PyObject *)self; 187 status = gensec_init(); 188 if (!NT_STATUS_IS_OK(status)) { 189 PyErr_SetNTSTATUS(status); 190 TALLOC_FREE(frame); 191 return NULL; 192 } 193 194 status = gensec_server_start(frame, settings, auth_context, &gensec); 195 if (!NT_STATUS_IS_OK(status)) { 196 PyErr_SetNTSTATUS(status); 197 TALLOC_FREE(frame); 198 return NULL; 199 } 200 201 self = pytalloc_steal(type, gensec); 202 TALLOC_FREE(frame); 203 204 return self; 205 } 206 207 static PyObject *py_gensec_set_target_hostname(PyObject *self, PyObject *args) 208 { 209 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 210 char *target_hostname; 211 NTSTATUS status; 212 213 if (!PyArg_ParseTuple(args, "s", &target_hostname)) 214 return NULL; 215 216 status = gensec_set_target_hostname(security, target_hostname); 217 if (!NT_STATUS_IS_OK(status)) { 218 PyErr_SetNTSTATUS(status); 219 return NULL; 220 } 221 222 Py_RETURN_NONE; 223 } 224 225 static PyObject *py_gensec_set_target_service(PyObject *self, PyObject *args) 226 { 227 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 228 char *target_service; 229 NTSTATUS status; 230 231 if (!PyArg_ParseTuple(args, "s", &target_service)) 232 return NULL; 233 234 status = gensec_set_target_service(security, target_service); 235 if (!NT_STATUS_IS_OK(status)) { 236 PyErr_SetNTSTATUS(status); 237 return NULL; 238 } 239 240 Py_RETURN_NONE; 220 241 } 221 242 … … 224 245 PyObject *py_creds = Py_None; 225 246 struct cli_credentials *creds; 226 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);247 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 227 248 NTSTATUS status; 228 249 … … 234 255 PyErr_Format(PyExc_TypeError, 235 256 "Expected samba.credentaials for credentials argument got %s", 236 talloc_get_name(py _talloc_get_ptr(py_creds)));257 talloc_get_name(pytalloc_get_ptr(py_creds))); 237 258 } 238 259 … … 248 269 static PyObject *py_gensec_session_info(PyObject *self) 249 270 { 271 TALLOC_CTX *mem_ctx; 250 272 NTSTATUS status; 251 273 PyObject *py_session_info; 252 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);274 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 253 275 struct auth_session_info *info; 254 276 if (security->ops == NULL) { … … 256 278 return NULL; 257 279 } 258 status = gensec_session_info(security, &info); 280 mem_ctx = talloc_new(NULL); 281 282 status = gensec_session_info(security, mem_ctx, &info); 259 283 if (NT_STATUS_IS_ERR(status)) { 260 284 PyErr_SetNTSTATUS(status); … … 262 286 } 263 287 264 py_session_info = py_return_ndr_struct("samba. auth", "AuthSession",288 py_session_info = py_return_ndr_struct("samba.dcerpc.auth", "session_info", 265 289 info, info); 290 talloc_free(mem_ctx); 266 291 return py_session_info; 267 292 } 268 293 294 static PyObject *py_gensec_session_key(PyObject *self) 295 { 296 TALLOC_CTX *mem_ctx; 297 NTSTATUS status; 298 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 299 DATA_BLOB session_key = data_blob_null; 300 static PyObject *session_key_obj = NULL; 301 302 if (security->ops == NULL) { 303 PyErr_SetString(PyExc_RuntimeError, "no mechanism selected"); 304 return NULL; 305 } 306 mem_ctx = talloc_new(NULL); 307 308 status = gensec_session_key(security, mem_ctx, &session_key); 309 if (!NT_STATUS_IS_OK(status)) { 310 talloc_free(mem_ctx); 311 PyErr_SetNTSTATUS(status); 312 return NULL; 313 } 314 315 session_key_obj = PyString_FromStringAndSize((const char *)session_key.data, 316 session_key.length); 317 talloc_free(mem_ctx); 318 return session_key_obj; 319 } 320 269 321 static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args) 270 322 { 271 323 char *name; 272 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);324 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 273 325 NTSTATUS status; 274 326 … … 288 340 { 289 341 char *sasl_name; 290 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);342 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 291 343 NTSTATUS status; 292 344 … … 306 358 { 307 359 int authtype, level; 308 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);360 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 309 361 NTSTATUS status; 310 362 if (!PyArg_ParseTuple(args, "ii", &authtype, &level)) … … 323 375 { 324 376 int feature; 325 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);377 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 326 378 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 327 379 if (!PyArg_ParseTuple(args, "i", &feature)) … … 336 388 { 337 389 int feature; 338 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);390 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 339 391 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 340 392 if (!PyArg_ParseTuple(args, "i", &feature)) … … 347 399 } 348 400 401 static PyObject *py_gensec_set_max_update_size(PyObject *self, PyObject *args) 402 { 403 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 404 unsigned int max_update_size = 0; 405 406 if (!PyArg_ParseTuple(args, "I", &max_update_size)) 407 return NULL; 408 409 gensec_set_max_update_size(security, max_update_size); 410 411 Py_RETURN_NONE; 412 } 413 414 static PyObject *py_gensec_max_update_size(PyObject *self) 415 { 416 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 417 unsigned int max_update_size = gensec_max_update_size(security); 418 419 return PyInt_FromLong(max_update_size); 420 } 421 349 422 static PyObject *py_gensec_update(PyObject *self, PyObject *args) 350 423 { … … 353 426 DATA_BLOB in, out; 354 427 PyObject *ret, *py_in; 355 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);428 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 356 429 PyObject *finished_processing; 357 430 … … 396 469 DATA_BLOB in, out; 397 470 PyObject *ret, *py_in; 398 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);471 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 399 472 400 473 if (!PyArg_ParseTuple(args, "O", &py_in)) … … 430 503 DATA_BLOB in, out; 431 504 PyObject *ret, *py_in; 432 struct gensec_security *security = py _talloc_get_type(self, struct gensec_security);505 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 433 506 434 507 if (!PyArg_ParseTuple(args, "O", &py_in)) … … 456 529 talloc_free(mem_ctx); 457 530 return ret; 531 } 532 533 static PyObject *py_gensec_sig_size(PyObject *self, PyObject *args) 534 { 535 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 536 Py_ssize_t data_size = 0; 537 size_t sig_size = 0; 538 539 if (!PyArg_ParseTuple(args, "n", &data_size)) { 540 return NULL; 541 } 542 543 sig_size = gensec_sig_size(security, data_size); 544 545 return PyLong_FromSize_t(sig_size); 546 } 547 548 static PyObject *py_gensec_sign_packet(PyObject *self, PyObject *args) 549 { 550 NTSTATUS status; 551 TALLOC_CTX *mem_ctx = NULL; 552 Py_ssize_t data_length = 0; 553 Py_ssize_t pdu_length = 0; 554 DATA_BLOB data, pdu, sig; 555 PyObject *py_sig; 556 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 557 558 if (!PyArg_ParseTuple(args, "z#z#", &data.data, &data_length, &pdu.data, &pdu_length)) { 559 return NULL; 560 } 561 data.length = data_length; 562 pdu.length = pdu_length; 563 564 mem_ctx = talloc_new(NULL); 565 566 status = gensec_sign_packet(security, mem_ctx, 567 data.data, data.length, 568 pdu.data, pdu.length, &sig); 569 if (!NT_STATUS_IS_OK(status)) { 570 PyErr_SetNTSTATUS(status); 571 talloc_free(mem_ctx); 572 return NULL; 573 } 574 575 py_sig = PyBytes_FromStringAndSize((const char *)sig.data, sig.length); 576 talloc_free(mem_ctx); 577 return py_sig; 578 } 579 580 static PyObject *py_gensec_check_packet(PyObject *self, PyObject *args) 581 { 582 NTSTATUS status; 583 Py_ssize_t data_length = 0; 584 Py_ssize_t pdu_length = 0; 585 Py_ssize_t sig_length = 0; 586 DATA_BLOB data, pdu, sig; 587 struct gensec_security *security = pytalloc_get_type(self, struct gensec_security); 588 589 if (!PyArg_ParseTuple(args, "z#z#z#", 590 &data.data, &data_length, 591 &pdu.data, &pdu_length, 592 &sig.data, &sig_length)) { 593 return NULL; 594 } 595 data.length = data_length; 596 pdu.length = pdu_length; 597 sig.length = sig_length; 598 599 status = gensec_check_packet(security, 600 data.data, data.length, 601 pdu.data, pdu.length, &sig); 602 if (!NT_STATUS_IS_OK(status)) { 603 PyErr_SetNTSTATUS(status); 604 return NULL; 605 } 606 607 Py_RETURN_NONE; 458 608 } 459 609 … … 465 615 { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, 466 616 "S.start_client(credentials)" }, 617 { "set_target_hostname", (PyCFunction)py_gensec_set_target_hostname, METH_VARARGS, 618 "S.start_target_hostname(target_hostname)" }, 619 { "set_target_service", (PyCFunction)py_gensec_set_target_service, METH_VARARGS, 620 "S.start_target_service(target_service)" }, 467 621 { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS, 468 "S.session_info() -> info" }, 622 "S.session_info() -> info" }, 623 { "session_key", (PyCFunction)py_gensec_session_key, METH_NOARGS, 624 "S.session_key() -> key" }, 469 625 { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS, 470 626 "S.start_mech_by_name(name)" }, 471 627 { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS, 472 "S.start_mech_by_sasl_name(name)" }, 473 { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, "S.start_mech_by_authtype(authtype, level)" }, 628 "S.start_mech_by_sasl_name(name)" }, 629 { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, 630 "S.start_mech_by_authtype(authtype, level)" }, 474 631 { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS, 475 632 "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." }, 476 633 { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS, 477 634 "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." }, 478 635 { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS, 479 "S.have_feature()\n Return True if GENSEC negotiated a particular feature." }, 636 "S.have_feature()\n Return True if GENSEC negotiated a particular feature." }, 637 { "set_max_update_size", (PyCFunction)py_gensec_set_max_update_size, METH_VARARGS, 638 "S.set_max_update_size(max_size) \n Some mechs can fragment update packets, needs to be use before the mech is started." }, 639 { "max_update_size", (PyCFunction)py_gensec_max_update_size, 0, 640 "S.max_update_size() \n Return the current max_update_size." }, 480 641 { "update", (PyCFunction)py_gensec_update, METH_VARARGS, 481 642 "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance. Repeat with new packets until finished is true or exception." }, … … 484 645 { "unwrap", (PyCFunction)py_gensec_unwrap, METH_VARARGS, 485 646 "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." }, 486 647 { "sig_size", (PyCFunction)py_gensec_sig_size, METH_VARARGS, 648 "S.sig_size(data_size) -> sig_size\nSize of the DCERPC packet signature" }, 649 { "sign_packet", (PyCFunction)py_gensec_sign_packet, METH_VARARGS, 650 "S.sign_packet(data, whole_pdu) -> sig\nSign a DCERPC packet." }, 651 { "check_packet", (PyCFunction)py_gensec_check_packet, METH_VARARGS, 652 "S.check_packet(data, whole_pdu, sig)\nCheck a DCERPC packet." }, 487 653 { NULL } 488 654 }; 489 655 490 656 static PyTypeObject Py_Security = { 491 .tp_name = " Security",657 .tp_name = "gensec.Security", 492 658 .tp_flags = Py_TPFLAGS_DEFAULT, 493 659 .tp_methods = py_gensec_security_methods, 494 .tp_basicsize = sizeof(py_talloc_Object),495 660 }; 496 661 … … 500 665 PyObject *m; 501 666 502 Py_Security.tp_base = PyTalloc_GetObjectType(); 503 if (Py_Security.tp_base == NULL) 504 return; 505 506 if (PyType_Ready(&Py_Security) < 0) 667 if (pytalloc_BaseObject_PyType_Ready(&Py_Security) < 0) 507 668 return; 508 669 -
vendor/current/source4/auth/gensec/wscript_build
r740 r988 1 1 #!/usr/bin/env python 2 2 3 bld.SAMBA_LIBRARY('gensec', 4 source='gensec.c socket.c gensec_tstream.c', 5 pc_files='gensec.pc', 6 autoproto='gensec_proto.h', 7 public_deps='UTIL_TEVENT samba-util errors LIBPACKET auth_system_session', 8 public_headers='gensec.h', 9 deps='com_err', 10 vnum='0.0.1' 11 ) 3 bld.SAMBA_SUBSYSTEM('gensec_util', 4 source='gensec_tstream.c', 5 deps='tevent-util tevent samba-util LIBTSOCKET', 6 autoproto='gensec_proto.h') 12 7 13 8 bld.SAMBA_MODULE('gensec_krb5', 14 source='gensec_krb5.c ',9 source='gensec_krb5.c gensec_krb5_util.c', 15 10 subsystem='gensec', 16 11 init_function='gensec_krb5_init', 17 deps=' credentials authkrb5 auth_session com_err',12 deps='samba-credentials authkrb5 com_err gensec_util', 18 13 internal_module=False, 14 enabled=bld.AD_DC_BUILD_IS_ENABLED() and bld.CONFIG_SET('SAMBA4_USES_HEIMDAL') 19 15 ) 20 16 … … 24 20 subsystem='gensec', 25 21 init_function='gensec_gssapi_init', 26 deps='gssapi credentials authkrb5 com_err'22 deps='gssapi samba-credentials authkrb5 com_err gensec_util' 27 23 ) 28 29 30 bld.SAMBA_MODULE('cyrus_sasl',31 source='cyrus_sasl.c',32 subsystem='gensec',33 init_function='gensec_sasl_init',34 deps='credentials sasl2',35 enabled=bld.CONFIG_SET('HAVE_SASL')36 )37 38 39 bld.SAMBA_MODULE('gensec_spnego',40 source='spnego.c',41 autoproto='spnego_proto.h',42 subsystem='gensec',43 init_function='gensec_spnego_init',44 deps='ASN1_UTIL credentials SPNEGO_PARSE'45 )46 47 48 bld.SAMBA_MODULE('gensec_schannel',49 source='schannel.c',50 subsystem='gensec',51 deps='COMMON_SCHANNEL NDR_SCHANNEL credentials ndr auth_session',52 internal_module=True,53 autoproto='schannel_proto.h',54 init_function='gensec_schannel_init'55 )56 57 24 58 25 bld.SAMBA_PYTHON('pygensec', -
vendor/current/source4/auth/kerberos/kerberos-notes.txt
r414 r988 7 7 ------------------------------------ 8 8 9 This document should be read in conju ction with the Samba4 source code.9 This document should be read in conjunction with the Samba4 source code. 10 10 DAL and KDC requirements are expressed (as an implementation against Heimdal's 11 11 HDB abstraction layer) in Samba4's source4/kdc/hdb-samba4.c in particular. … … 160 160 correctly implement the GSSAPI specification, particularly on top of the 161 161 (inflexible) MIT Kerberos API. It did not seem possible to write a correct, 162 sep erate GSSAPI implementation on top of MIT Kerberos's public krb5lib API,162 separate GSSAPI implementation on top of MIT Kerberos's public krb5lib API, 163 163 and at the time, the effort did not need to extend beyond what Windows would 164 164 require. … … 528 528 529 529 Traditional 'MIT' behaviour is to use a keytab, containing salted key 530 data, extracted from the KDC. (In this mod al, there is no 'service530 data, extracted from the KDC. (In this model, there is no 'service 531 531 password', instead the keys are often simply application of random 532 532 bytes). Heimdal also implements this behaviour. 533 533 534 The windows mod al is very different - instead of sharing a keytab with534 The windows model is very different - instead of sharing a keytab with 535 535 each member server, a random utf-16 pseudo-textual password is stored 536 536 for the whole machine. -
vendor/current/source4/auth/kerberos/kerberos.h
r740 r988 19 19 */ 20 20 21 #ifndef _AUTH_KERBEROS_H_ 22 #define _AUTH_KERBEROS_H_ 23 21 24 #if defined(HAVE_KRB5) 22 25 26 #include "system/kerberos.h" 23 27 #include "auth/kerberos/krb5_init_context.h" 24 28 #include "librpc/gen_ndr/krb5pac.h" 29 #include "lib/krb5_wrap/krb5_samba.h" 30 #include "lib/krb5_wrap/gss_samba.h" 25 31 26 32 struct auth_user_info_dc; … … 35 41 struct smb_krb5_context *smb_krb5_context; 36 42 krb5_keytab keytab; 43 bool password_based; 37 44 }; 38 45 … … 44 51 #define TOK_ID_GSS_WRAP ((const uint8_t *)"\x02\x01") 45 52 46 #ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE47 #define KRB5_KEY_TYPE(k) ((k)->keytype)48 #define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length)49 #define KRB5_KEY_DATA(k) ((k)->keyvalue.data)50 #else51 #define KRB5_KEY_TYPE(k) ((k)->enctype)52 #define KRB5_KEY_LENGTH(k) ((k)->length)53 #define KRB5_KEY_DATA(k) ((k)->contents)54 #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */55 56 53 #define ENC_ALL_TYPES (ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5 | \ 57 54 ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256) 58 59 #ifndef HAVE_KRB5_SET_REAL_TIME60 krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds);61 #endif62 55 63 56 #ifndef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES … … 69 62 #endif 70 63 71 #ifndef HAVE_KRB5_FREE_UNPARSED_NAME72 void krb5_free_unparsed_name(krb5_context ctx, char *val);73 #endif74 75 64 #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) 76 65 const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ); … … 78 67 79 68 /* Samba wrapper function for krb5 functionality. */ 80 void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);81 int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);82 int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);83 krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);84 krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);85 void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);86 bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote);87 krb5_error_code ads_krb5_mk_req(krb5_context context,88 krb5_auth_context *auth_context,89 const krb5_flags ap_req_options,90 const char *principal,91 krb5_ccache ccache,92 krb5_data *outbuf);93 bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);94 krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,95 krb5_principal principal, const char *password,96 krb5_principal impersonate_principal, const char *target_service,97 krb5_get_init_creds_opt *krb_options,98 time_t *expire_time, time_t *kdc_time);99 krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,100 krb5_principal principal, krb5_keyblock *keyblock,101 const char *target_service,102 krb5_get_init_creds_opt *krb_options,103 time_t *expire_time, time_t *kdc_time);104 krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,105 krb5_principal host_princ,106 int enctype);107 void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype);108 bool kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2);109 void kerberos_free_data_contents(krb5_context context, krb5_data *pdata);110 krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);111 char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx);112 NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,113 struct PAC_DATA **pac_data_out,114 DATA_BLOB blob,115 krb5_context context,116 const krb5_keyblock *krbtgt_keyblock,117 const krb5_keyblock *service_keyblock,118 krb5_const_principal client_principal,119 time_t tgs_authtime,120 krb5_error_code *k5ret);121 NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,122 struct PAC_LOGON_INFO **logon_info,123 DATA_BLOB blob,124 krb5_context context,125 const krb5_keyblock *krbtgt_keyblock,126 const krb5_keyblock *service_keyblock,127 krb5_const_principal client_principal,128 time_t tgs_authtime,129 krb5_error_code *k5ret);130 69 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx, 131 70 struct PAC_DATA *pac_data, … … 142 81 time_t tgs_authtime, 143 82 DATA_BLOB *pac); 144 struct loadparm_context;145 struct ldb_message;146 struct ldb_context;147 uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum);148 /* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */149 krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap);150 krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,151 struct smb_krb5_context *smb_krb5_context,152 struct ldb_context *ldb,153 struct ldb_message *msg,154 bool delete_all_kvno,155 const char **error_string);156 83 157 84 #include "auth/kerberos/proto.h" 158 85 159 86 #endif /* HAVE_KRB5 */ 87 88 #endif /* _AUTH_KERBEROS_H_ */ -
vendor/current/source4/auth/kerberos/kerberos_credentials.h
r740 r988 28 28 enum credentials_obtained *obtained, 29 29 const char **error_string); 30 31 /* Manually prototyped here to avoid needing krb5 headers in most callers */ 32 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 33 struct cli_credentials *credentials, 34 struct smb_krb5_context *smb_krb5_context, 35 krb5_principal *princ, 36 enum credentials_obtained *obtained, 37 const char **error_string); -
vendor/current/source4/auth/kerberos/kerberos_pac.c
r740 r988 31 31 #include <ldb.h> 32 32 #include "auth/auth_sam_reply.h" 33 34 krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, 35 DATA_BLOB pac_data, 36 struct PAC_SIGNATURE_DATA *sig, 37 krb5_context context, 38 const krb5_keyblock *keyblock) 39 { 40 krb5_error_code ret; 41 krb5_crypto crypto; 42 Checksum cksum; 43 44 cksum.cksumtype = (CKSUMTYPE)sig->type; 45 cksum.checksum.length = sig->signature.length; 46 cksum.checksum.data = sig->signature.data; 47 48 ret = krb5_crypto_init(context, 49 keyblock, 50 0, 51 &crypto); 52 if (ret) { 53 DEBUG(0,("krb5_crypto_init() failed: %s\n", 54 smb_get_krb5_error_message(context, ret, mem_ctx))); 55 return ret; 56 } 57 ret = krb5_verify_checksum(context, 58 crypto, 59 KRB5_KU_OTHER_CKSUM, 60 pac_data.data, 61 pac_data.length, 62 &cksum); 63 krb5_crypto_destroy(context, crypto); 64 65 return ret; 66 } 67 68 NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, 69 struct PAC_DATA **pac_data_out, 70 DATA_BLOB blob, 71 krb5_context context, 72 const krb5_keyblock *krbtgt_keyblock, 73 const krb5_keyblock *service_keyblock, 74 krb5_const_principal client_principal, 75 time_t tgs_authtime, 76 krb5_error_code *k5ret) 77 { 78 krb5_error_code ret; 79 NTSTATUS status; 80 enum ndr_err_code ndr_err; 81 struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL; 82 struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL; 83 struct PAC_SIGNATURE_DATA *srv_sig_wipe = NULL; 84 struct PAC_SIGNATURE_DATA *kdc_sig_wipe = NULL; 85 struct PAC_LOGON_INFO *logon_info = NULL; 86 struct PAC_LOGON_NAME *logon_name = NULL; 87 struct PAC_DATA *pac_data; 88 struct PAC_DATA_RAW *pac_data_raw; 89 90 DATA_BLOB *srv_sig_blob = NULL; 91 DATA_BLOB *kdc_sig_blob = NULL; 92 93 DATA_BLOB modified_pac_blob; 94 NTTIME tgs_authtime_nttime; 95 krb5_principal client_principal_pac; 96 uint32_t i; 97 98 krb5_clear_error_message(context); 99 100 if (k5ret) { 101 *k5ret = KRB5_PARSE_MALFORMED; 102 } 103 104 pac_data = talloc(mem_ctx, struct PAC_DATA); 105 pac_data_raw = talloc(mem_ctx, struct PAC_DATA_RAW); 106 kdc_sig_wipe = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); 107 srv_sig_wipe = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); 108 if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) { 109 if (k5ret) { 110 *k5ret = ENOMEM; 111 } 112 return NT_STATUS_NO_MEMORY; 113 } 114 115 ndr_err = ndr_pull_struct_blob(&blob, pac_data, 116 pac_data, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); 117 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 118 status = ndr_map_error2ntstatus(ndr_err); 119 DEBUG(0,("can't parse the PAC: %s\n", 120 nt_errstr(status))); 121 return status; 122 } 123 124 if (pac_data->num_buffers < 4) { 125 /* we need logon_ingo, service_key and kdc_key */ 126 DEBUG(0,("less than 4 PAC buffers\n")); 127 return NT_STATUS_INVALID_PARAMETER; 128 } 129 130 ndr_err = ndr_pull_struct_blob(&blob, pac_data_raw, 131 pac_data_raw, 132 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW); 133 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 134 status = ndr_map_error2ntstatus(ndr_err); 135 DEBUG(0,("can't parse the PAC: %s\n", 136 nt_errstr(status))); 137 return status; 138 } 139 140 if (pac_data_raw->num_buffers < 4) { 141 /* we need logon_ingo, service_key and kdc_key */ 142 DEBUG(0,("less than 4 PAC buffers\n")); 143 return NT_STATUS_INVALID_PARAMETER; 144 } 145 146 if (pac_data->num_buffers != pac_data_raw->num_buffers) { 147 /* we need logon_ingo, service_key and kdc_key */ 148 DEBUG(0,("misparse! PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n", 149 pac_data->num_buffers, pac_data_raw->num_buffers)); 150 return NT_STATUS_INVALID_PARAMETER; 151 } 152 153 for (i=0; i < pac_data->num_buffers; i++) { 154 if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) { 155 DEBUG(0,("misparse! PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n", 156 i, pac_data->buffers[i].type, pac_data->buffers[i].type)); 157 return NT_STATUS_INVALID_PARAMETER; 158 } 159 switch (pac_data->buffers[i].type) { 160 case PAC_TYPE_LOGON_INFO: 161 if (!pac_data->buffers[i].info) { 162 break; 163 } 164 logon_info = pac_data->buffers[i].info->logon_info.info; 165 break; 166 case PAC_TYPE_SRV_CHECKSUM: 167 if (!pac_data->buffers[i].info) { 168 break; 169 } 170 srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum; 171 srv_sig_blob = &pac_data_raw->buffers[i].info->remaining; 172 break; 173 case PAC_TYPE_KDC_CHECKSUM: 174 if (!pac_data->buffers[i].info) { 175 break; 176 } 177 kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum; 178 kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining; 179 break; 180 case PAC_TYPE_LOGON_NAME: 181 logon_name = &pac_data->buffers[i].info->logon_name; 182 break; 183 default: 184 break; 185 } 186 } 187 188 if (!logon_info) { 189 DEBUG(0,("PAC no logon_info\n")); 190 return NT_STATUS_INVALID_PARAMETER; 191 } 192 193 if (!logon_name) { 194 DEBUG(0,("PAC no logon_name\n")); 195 return NT_STATUS_INVALID_PARAMETER; 196 } 197 198 if (!srv_sig_ptr || !srv_sig_blob) { 199 DEBUG(0,("PAC no srv_key\n")); 200 return NT_STATUS_INVALID_PARAMETER; 201 } 202 203 if (!kdc_sig_ptr || !kdc_sig_blob) { 204 DEBUG(0,("PAC no kdc_key\n")); 205 return NT_STATUS_INVALID_PARAMETER; 206 } 207 208 /* Find and zero out the signatures, as required by the signing algorithm */ 209 210 /* We find the data blobs above, now we parse them to get at the exact portion we should zero */ 211 ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, 212 kdc_sig_wipe, 213 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 214 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 215 status = ndr_map_error2ntstatus(ndr_err); 216 DEBUG(0,("can't parse the KDC signature: %s\n", 217 nt_errstr(status))); 218 return status; 219 } 220 221 ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, 222 srv_sig_wipe, 223 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 224 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 225 status = ndr_map_error2ntstatus(ndr_err); 226 DEBUG(0,("can't parse the SRV signature: %s\n", 227 nt_errstr(status))); 228 return status; 229 } 230 231 /* Now zero the decoded structure */ 232 memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length); 233 memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length); 234 235 /* and reencode, back into the same place it came from */ 236 ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, 237 kdc_sig_wipe, 238 (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); 239 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 240 status = ndr_map_error2ntstatus(ndr_err); 241 DEBUG(0,("can't repack the KDC signature: %s\n", 242 nt_errstr(status))); 243 return status; 244 } 245 ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, 246 srv_sig_wipe, 247 (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); 248 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 249 status = ndr_map_error2ntstatus(ndr_err); 250 DEBUG(0,("can't repack the SRV signature: %s\n", 251 nt_errstr(status))); 252 return status; 253 } 254 255 /* push out the whole structure, but now with zero'ed signatures */ 256 ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw, 257 pac_data_raw, 258 (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW); 259 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 260 status = ndr_map_error2ntstatus(ndr_err); 261 DEBUG(0,("can't repack the RAW PAC: %s\n", 262 nt_errstr(status))); 263 return status; 264 } 265 266 /* verify by service_key */ 267 ret = check_pac_checksum(mem_ctx, 268 modified_pac_blob, srv_sig_ptr, 269 context, 270 service_keyblock); 271 if (ret) { 272 DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n", 273 smb_get_krb5_error_message(context, ret, mem_ctx))); 274 if (k5ret) { 275 *k5ret = ret; 276 } 277 return NT_STATUS_ACCESS_DENIED; 278 } 279 280 if (krbtgt_keyblock) { 281 ret = check_pac_checksum(mem_ctx, 282 srv_sig_ptr->signature, kdc_sig_ptr, 283 context, krbtgt_keyblock); 284 if (ret) { 285 DEBUG(1, ("PAC Decode: Failed to verify the KDC signature: %s\n", 286 smb_get_krb5_error_message(context, ret, mem_ctx))); 287 if (k5ret) { 288 *k5ret = ret; 289 } 290 return NT_STATUS_ACCESS_DENIED; 291 } 292 } 293 294 /* Convert to NT time, so as not to loose accuracy in comparison */ 295 unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); 296 297 if (tgs_authtime_nttime != logon_name->logon_time) { 298 DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n")); 299 DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time))); 300 DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime))); 301 return NT_STATUS_ACCESS_DENIED; 302 } 303 304 ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM, 305 &client_principal_pac); 306 if (ret) { 307 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", 308 logon_name->account_name, 309 smb_get_krb5_error_message(context, ret, mem_ctx))); 310 if (k5ret) { 311 *k5ret = ret; 312 } 313 return NT_STATUS_INVALID_PARAMETER; 314 } 315 316 if (!krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { 317 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", 318 logon_name->account_name)); 319 krb5_free_principal(context, client_principal_pac); 320 return NT_STATUS_ACCESS_DENIED; 321 } 322 323 krb5_free_principal(context, client_principal_pac); 324 325 #if 0 326 if (strcasecmp(logon_info->info3.base.account_name.string, 327 "Administrator")== 0) { 328 file_save("tmp_pac_data-admin.dat",blob.data,blob.length); 329 } 330 #endif 331 332 DEBUG(3,("Found account name from PAC: %s [%s]\n", 333 logon_info->info3.base.account_name.string, 334 logon_info->info3.base.full_name.string)); 335 *pac_data_out = pac_data; 336 337 return NT_STATUS_OK; 338 } 339 340 _PUBLIC_ NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx, 341 struct PAC_LOGON_INFO **logon_info, 342 DATA_BLOB blob, 343 krb5_context context, 344 const krb5_keyblock *krbtgt_keyblock, 345 const krb5_keyblock *service_keyblock, 346 krb5_const_principal client_principal, 347 time_t tgs_authtime, 348 krb5_error_code *k5ret) 349 { 350 NTSTATUS nt_status; 351 struct PAC_DATA *pac_data; 352 int i; 353 nt_status = kerberos_decode_pac(mem_ctx, 354 &pac_data, 355 blob, 356 context, 357 krbtgt_keyblock, 358 service_keyblock, 359 client_principal, 360 tgs_authtime, 361 k5ret); 362 if (!NT_STATUS_IS_OK(nt_status)) { 363 return nt_status; 364 } 365 366 *logon_info = NULL; 367 for (i=0; i < pac_data->num_buffers; i++) { 368 if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) { 369 continue; 370 } 371 *logon_info = pac_data->buffers[i].info->logon_info.info; 372 } 373 if (!*logon_info) { 374 return NT_STATUS_INVALID_PARAMETER; 375 } 376 return NT_STATUS_OK; 377 } 378 379 static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx, 380 DATA_BLOB *pac_data, 381 struct PAC_SIGNATURE_DATA *sig, 382 krb5_context context, 383 const krb5_keyblock *keyblock) 384 { 385 krb5_error_code ret; 386 krb5_crypto crypto; 387 Checksum cksum; 388 389 390 ret = krb5_crypto_init(context, 391 keyblock, 392 0, 393 &crypto); 394 if (ret) { 395 DEBUG(0,("krb5_crypto_init() failed: %s\n", 396 smb_get_krb5_error_message(context, ret, mem_ctx))); 397 return ret; 398 } 399 ret = krb5_create_checksum(context, 400 crypto, 401 KRB5_KU_OTHER_CKSUM, 402 0, 403 pac_data->data, 404 pac_data->length, 405 &cksum); 406 if (ret) { 407 DEBUG(2, ("PAC Verification failed: %s\n", 408 smb_get_krb5_error_message(context, ret, mem_ctx))); 409 } 410 411 krb5_crypto_destroy(context, crypto); 412 413 if (ret) { 414 return ret; 415 } 416 417 sig->type = cksum.cksumtype; 418 sig->signature = data_blob_talloc(mem_ctx, cksum.checksum.data, cksum.checksum.length); 419 free_Checksum(&cksum); 420 421 return 0; 422 } 33 #include "auth/credentials/credentials.h" 34 #include "auth/kerberos/kerberos_util.h" 35 #include "auth/kerberos/pac_utils.h" 423 36 424 37 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx, … … 444 57 } 445 58 kdc_checksum = &pac_data->buffers[i].info->kdc_cksum, 446 ret = make_pac_checksum(mem_ctx, &zero_blob, 447 kdc_checksum, 448 context, krbtgt_keyblock); 59 ret = smb_krb5_make_pac_checksum(mem_ctx, 60 &zero_blob, 61 context, 62 krbtgt_keyblock, 63 &kdc_checksum->type, 64 &kdc_checksum->signature); 449 65 if (ret) { 450 66 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", … … 460 76 } 461 77 srv_checksum = &pac_data->buffers[i].info->srv_cksum; 462 ret = make_pac_checksum(mem_ctx, &zero_blob, 463 srv_checksum, 464 context, service_keyblock); 78 ret = smb_krb5_make_pac_checksum(mem_ctx, 79 &zero_blob, 80 context, 81 service_keyblock, 82 &srv_checksum->type, 83 &srv_checksum->signature); 465 84 if (ret) { 466 85 DEBUG(2, ("making service PAC checksum failed: %s\n", … … 495 114 496 115 /* Then sign the result of the previous push, where the sig was zero'ed out */ 497 ret = make_pac_checksum(mem_ctx, &tmp_blob, srv_checksum, 498 context, service_keyblock); 116 ret = smb_krb5_make_pac_checksum(mem_ctx, 117 &tmp_blob, 118 context, 119 service_keyblock, 120 &srv_checksum->type, 121 &srv_checksum->signature); 499 122 500 123 /* Then sign Server checksum */ 501 ret = make_pac_checksum(mem_ctx, &srv_checksum->signature, kdc_checksum, context, krbtgt_keyblock); 124 ret = smb_krb5_make_pac_checksum(mem_ctx, 125 &srv_checksum->signature, 126 context, 127 krbtgt_keyblock, 128 &kdc_checksum->type, 129 &kdc_checksum->signature); 502 130 if (ret) { 503 131 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", … … 624 252 625 253 ret = krb5_unparse_name_flags(context, client_principal, 626 KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); 254 KRB5_PRINCIPAL_UNPARSE_NO_REALM | 255 KRB5_PRINCIPAL_UNPARSE_DISPLAY, 256 &name); 627 257 if (ret) { 628 258 return ret; … … 680 310 PAC_TYPE_LOGON_INFO, 681 311 (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO); 682 k rb5_data_free(&k5pac_logon_info_in);312 kerberos_free_data_contents(context, &k5pac_logon_info_in); 683 313 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || !info.logon_info.info) { 684 314 nt_status = ndr_map_error2ntstatus(ndr_err); … … 709 339 pac_srv_sig, 710 340 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 711 k rb5_data_free(&k5pac_srv_checksum_in);341 kerberos_free_data_contents(context, &k5pac_srv_checksum_in); 712 342 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 713 343 nt_status = ndr_map_error2ntstatus(ndr_err); … … 730 360 pac_kdc_sig, 731 361 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 732 k rb5_data_free(&k5pac_kdc_checksum_in);362 kerberos_free_data_contents(context, &k5pac_kdc_checksum_in); 733 363 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 734 364 nt_status = ndr_map_error2ntstatus(ndr_err); … … 757 387 &pac); 758 388 if (ret) { 759 return map_nt_error_from_unix (ret);389 return map_nt_error_from_unix_common(ret); 760 390 } 761 391 … … 764 394 krb5_pac_free(context, pac); 765 395 if (ret) { 766 return map_nt_error_from_unix (ret);396 return map_nt_error_from_unix_common(ret); 767 397 } 768 398 return NT_STATUS_OK; -
vendor/current/source4/auth/kerberos/kerberos_util.c
r740 r988 29 29 #include "auth/kerberos/kerberos_credentials.h" 30 30 #include "auth/kerberos/kerberos_util.h" 31 #include <ldb.h>32 #include "param/secrets.h"33 31 34 32 struct principal_container { … … 64 62 65 63 if (ret) { 66 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); 64 (*error_string) = smb_get_krb5_error_message( 65 smb_krb5_context->krb5_context, 66 ret, parent_ctx); 67 67 return ret; 68 68 } … … 76 76 /* This song-and-dance effectivly puts the principal 77 77 * into talloc, so we can't loose it. */ 78 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); 78 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, 79 smb_krb5_context); 79 80 mem_ctx->principal = *princ; 80 81 talloc_set_destructor(mem_ctx, free_principal); 81 82 return 0; 82 }83 84 static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx,85 struct ldb_message *msg,86 struct smb_krb5_context *smb_krb5_context,87 struct principal_container ***principals_out,88 const char **error_string)89 {90 unsigned int i;91 krb5_error_code ret;92 char *upper_realm;93 const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);94 const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);95 struct ldb_message_element *spn_el = ldb_msg_find_element(msg, "servicePrincipalName");96 TALLOC_CTX *tmp_ctx;97 struct principal_container **principals;98 tmp_ctx = talloc_new(parent_ctx);99 if (!tmp_ctx) {100 *error_string = "Cannot allocate tmp_ctx";101 return ENOMEM;102 }103 104 if (!realm) {105 *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";106 return EINVAL;107 }108 109 upper_realm = strupper_talloc(tmp_ctx, realm);110 if (!upper_realm) {111 talloc_free(tmp_ctx);112 *error_string = "Cannot allocate full upper case realm";113 return ENOMEM;114 }115 116 principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2);117 118 spn_el = ldb_msg_find_element(msg, "servicePrincipalName");119 for (i=0; spn_el && i < spn_el->num_values; i++) {120 principals[i] = talloc(principals, struct principal_container);121 if (!principals[i]) {122 talloc_free(tmp_ctx);123 *error_string = "Cannot allocate mem_ctx";124 return ENOMEM;125 }126 127 principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);128 principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s",129 (int)spn_el->values[i].length,130 (int)spn_el->values[i].length,131 (const char *)spn_el->values[i].data, upper_realm);132 if (!principals[i]->string_form) {133 talloc_free(tmp_ctx);134 *error_string = "Cannot allocate full samAccountName";135 return ENOMEM;136 }137 138 ret = krb5_parse_name(smb_krb5_context->krb5_context,139 principals[i]->string_form, &principals[i]->principal);140 141 if (ret) {142 talloc_free(tmp_ctx);143 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);144 return ret;145 }146 147 /* This song-and-dance effectivly puts the principal148 * into talloc, so we can't loose it. */149 talloc_set_destructor(principals[i], free_principal);150 }151 152 if (samAccountName) {153 principals[i] = talloc(principals, struct principal_container);154 if (!principals[i]) {155 talloc_free(tmp_ctx);156 *error_string = "Cannot allocate mem_ctx";157 return ENOMEM;158 }159 160 principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);161 principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm);162 if (!principals[i]->string_form) {163 talloc_free(tmp_ctx);164 *error_string = "Cannot allocate full samAccountName";165 return ENOMEM;166 }167 168 ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName,169 NULL);170 if (ret) {171 talloc_free(tmp_ctx);172 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);173 return ret;174 }175 176 /* This song-and-dance effectivly puts the principal177 * into talloc, so we can't loose it. */178 talloc_set_destructor(principals[i], free_principal);179 i++;180 }181 182 principals[i] = NULL;183 *principals_out = talloc_steal(parent_ctx, principals);184 185 talloc_free(tmp_ctx);186 return ret;187 }188 189 static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx,190 struct ldb_message *msg,191 struct smb_krb5_context *smb_krb5_context,192 krb5_principal *salt_princ,193 const char **error_string)194 {195 const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL);196 const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);197 const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);198 if (salt_principal) {199 return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string);200 } else if (samAccountName) {201 krb5_error_code ret;202 char *machine_username;203 char *salt_body;204 char *lower_realm;205 char *upper_realm;206 207 TALLOC_CTX *tmp_ctx;208 struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);209 if (!mem_ctx) {210 *error_string = "Cannot allocate mem_ctx";211 return ENOMEM;212 }213 214 tmp_ctx = talloc_new(mem_ctx);215 if (!tmp_ctx) {216 talloc_free(mem_ctx);217 *error_string = "Cannot allocate tmp_ctx";218 return ENOMEM;219 }220 221 if (!realm) {222 *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";223 return EINVAL;224 }225 226 machine_username = talloc_strdup(tmp_ctx, samAccountName);227 if (!machine_username) {228 talloc_free(mem_ctx);229 *error_string = "Cannot duplicate samAccountName";230 return ENOMEM;231 }232 233 if (machine_username[strlen(machine_username)-1] == '$') {234 machine_username[strlen(machine_username)-1] = '\0';235 }236 237 lower_realm = strlower_talloc(tmp_ctx, realm);238 if (!lower_realm) {239 talloc_free(mem_ctx);240 *error_string = "Cannot allocate to lower case realm";241 return ENOMEM;242 }243 244 upper_realm = strupper_talloc(tmp_ctx, realm);245 if (!upper_realm) {246 talloc_free(mem_ctx);247 *error_string = "Cannot allocate to upper case realm";248 return ENOMEM;249 }250 251 salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username,252 lower_realm);253 talloc_free(lower_realm);254 talloc_free(machine_username);255 if (!salt_body) {256 talloc_free(mem_ctx);257 *error_string = "Cannot form salt principal body";258 return ENOMEM;259 }260 261 ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ,262 upper_realm,263 "host", salt_body, NULL);264 if (ret == 0) {265 /* This song-and-dance effectivly puts the principal266 * into talloc, so we can't loose it. */267 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);268 mem_ctx->principal = *salt_princ;269 talloc_set_destructor(mem_ctx, free_principal);270 } else {271 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);272 }273 talloc_free(tmp_ctx);274 return ret;275 } else {276 (*error_string) = "Cannot determine salt principal, no saltPrincipal or samAccountName specified";277 return EINVAL;278 }279 83 } 280 84 … … 284 88 * system by means of a destructor (do *not* free). */ 285 89 286 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 287 struct cli_credentials *credentials,288 289 290 291 90 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 91 struct cli_credentials *credentials, 92 struct smb_krb5_context *smb_krb5_context, 93 krb5_principal *princ, 94 enum credentials_obtained *obtained, 95 const char **error_string) 292 96 { 293 97 krb5_error_code ret; 294 98 const char *princ_string; 295 99 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 100 *obtained = CRED_UNINITIALISED; 101 296 102 if (!mem_ctx) { 297 103 (*error_string) = error_message(ENOMEM); 298 104 return ENOMEM; 299 105 } 300 princ_string = cli_credentials_get_principal_and_obtained(credentials, mem_ctx, obtained); 106 princ_string = cli_credentials_get_principal_and_obtained(credentials, 107 mem_ctx, 108 obtained); 301 109 if (!princ_string) { 302 (*error_string) = error_message(ENOMEM);303 return ENOMEM;110 *princ = NULL; 111 return 0; 304 112 } 305 113 … … 315 123 * system by means of a destructor (do *not* free). */ 316 124 317 krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx, 318 struct cli_credentials *credentials, 319 struct smb_krb5_context *smb_krb5_context, 320 krb5_principal *princ, 321 const char **error_string) 322 { 323 return parse_principal(parent_ctx, cli_credentials_get_impersonate_principal(credentials), 324 smb_krb5_context, princ, error_string); 125 static krb5_error_code impersonate_principal_from_credentials( 126 TALLOC_CTX *parent_ctx, 127 struct cli_credentials *credentials, 128 struct smb_krb5_context *smb_krb5_context, 129 krb5_principal *princ, 130 const char **error_string) 131 { 132 return parse_principal(parent_ctx, 133 cli_credentials_get_impersonate_principal(credentials), 134 smb_krb5_context, princ, error_string); 135 } 136 137 krb5_error_code smb_krb5_create_principals_array(TALLOC_CTX *mem_ctx, 138 krb5_context context, 139 const char *account_name, 140 const char *realm, 141 uint32_t num_spns, 142 const char *spns[], 143 uint32_t *pnum_principals, 144 krb5_principal **pprincipals, 145 const char **error_string) 146 { 147 krb5_error_code code; 148 TALLOC_CTX *tmp_ctx; 149 uint32_t num_principals = 0; 150 krb5_principal *principals; 151 uint32_t i; 152 153 tmp_ctx = talloc_new(mem_ctx); 154 if (tmp_ctx == NULL) { 155 *error_string = "Cannot allocate tmp_ctx"; 156 return ENOMEM; 157 } 158 159 if (realm == NULL) { 160 *error_string = "Cannot create principal without a realm"; 161 code = EINVAL; 162 goto done; 163 } 164 165 if (account_name == NULL && (num_spns == 0 || spns == NULL)) { 166 *error_string = "Cannot create principal without an account or SPN"; 167 code = EINVAL; 168 goto done; 169 } 170 171 if (account_name != NULL && account_name[0] != '\0') { 172 num_principals++; 173 } 174 num_principals += num_spns; 175 176 principals = talloc_zero_array(tmp_ctx, 177 krb5_principal, 178 num_principals); 179 if (principals == NULL) { 180 *error_string = "Cannot allocate principals"; 181 code = ENOMEM; 182 goto done; 183 } 184 185 for (i = 0; i < num_spns; i++) { 186 code = krb5_parse_name(context, spns[i], &(principals[i])); 187 if (code != 0) { 188 *error_string = smb_get_krb5_error_message(context, 189 code, 190 mem_ctx); 191 goto done; 192 } 193 } 194 195 if (account_name != NULL && account_name[0] != '\0') { 196 code = smb_krb5_make_principal(context, 197 &(principals[i]), 198 realm, 199 account_name, 200 NULL); 201 if (code != 0) { 202 *error_string = smb_get_krb5_error_message(context, 203 code, 204 mem_ctx); 205 goto done; 206 } 207 } 208 209 if (pnum_principals != NULL) { 210 *pnum_principals = num_principals; 211 212 if (pprincipals != NULL) { 213 *pprincipals = talloc_steal(mem_ctx, principals); 214 } 215 } 216 217 code = 0; 218 done: 219 talloc_free(tmp_ctx); 220 return code; 325 221 } 326 222 … … 339 235 { 340 236 krb5_error_code ret; 341 const char *password, *target_service; 237 const char *password; 238 #ifdef SAMBA4_USES_HEIMDAL 239 const char *self_service; 240 #endif 241 const char *target_service; 342 242 time_t kdc_time = 0; 343 243 krb5_principal princ; … … 358 258 } 359 259 260 if (princ == NULL) { 261 (*error_string) = talloc_asprintf(credentials, "principal, username or realm was not specified in the credentials"); 262 talloc_free(mem_ctx); 263 return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; 264 } 265 360 266 ret = impersonate_principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &impersonate_principal, error_string); 361 267 if (ret) { … … 364 270 } 365 271 272 #ifdef SAMBA4_USES_HEIMDAL 273 self_service = cli_credentials_get_self_service(credentials); 274 #endif 366 275 target_service = cli_credentials_get_target_service(credentials); 367 276 … … 377 286 } 378 287 288 #ifdef SAMBA4_USES_HEIMDAL /* Disable for now MIT reads defaults when needed */ 379 289 /* get the defaults */ 380 290 krb5_get_init_creds_opt_set_default_flags(smb_krb5_context->krb5_context, NULL, NULL, krb_options); 381 291 #endif 382 292 /* set if we want a forwardable ticket */ 383 293 switch (cli_credentials_get_krb_forwardable(credentials)) { … … 392 302 } 393 303 304 #ifdef SAMBA4_USES_HEIMDAL /* FIXME: MIT does not have this yet */ 305 /* 306 * In order to work against windows KDCs even if we use 307 * the netbios domain name as realm, we need to add the following 308 * flags: 309 * KRB5_INIT_CREDS_NO_C_CANON_CHECK; 310 * KRB5_INIT_CREDS_NO_C_NO_EKU_CHECK; 311 * 312 * On MIT: Set pkinit_eku_checking to none 313 */ 314 krb5_get_init_creds_opt_set_win2k(smb_krb5_context->krb5_context, 315 krb_options, true); 316 #else /* MIT */ 317 krb5_get_init_creds_opt_set_canonicalize(krb_options, true); 318 #endif 319 394 320 tries = 2; 395 321 while (tries--) { 322 #ifdef SAMBA4_USES_HEIMDAL 396 323 struct tevent_context *previous_ev; 397 324 /* Do this every time, in case we have weird recursive issues here */ … … 401 328 return ret; 402 329 } 330 #endif 403 331 if (password) { 404 ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, 405 princ, password, 406 impersonate_principal, target_service, 407 krb_options, 408 NULL, &kdc_time); 332 if (impersonate_principal) { 333 #ifdef SAMBA4_USES_HEIMDAL 334 ret = kerberos_kinit_s4u2_cc( 335 smb_krb5_context->krb5_context, 336 ccache, princ, password, 337 impersonate_principal, 338 self_service, target_service, 339 krb_options, NULL, &kdc_time); 340 #else 341 talloc_free(mem_ctx); 342 (*error_string) = "INTERNAL error: s4u2 ops " 343 "are not supported with MIT build yet"; 344 return EINVAL; 345 #endif 346 } else { 347 ret = kerberos_kinit_password_cc( 348 smb_krb5_context->krb5_context, 349 ccache, princ, password, 350 target_service, 351 krb_options, NULL, &kdc_time); 352 } 409 353 } else if (impersonate_principal) { 410 354 talloc_free(mem_ctx); … … 421 365 (*error_string) = "kinit_to_ccache: No password available for kinit\n"; 422 366 krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options); 367 #ifdef SAMBA4_USES_HEIMDAL 423 368 smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx); 369 #endif 424 370 return EINVAL; 425 371 } 426 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,372 ret = smb_krb5_keyblock_init_contents(smb_krb5_context->krb5_context, 427 373 ENCTYPE_ARCFOUR_HMAC, 428 374 mach_pwd->hash, sizeof(mach_pwd->hash), … … 438 384 } 439 385 386 #ifdef SAMBA4_USES_HEIMDAL 440 387 smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx); 388 #endif 441 389 442 390 if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) { … … 485 433 talloc_free(mem_ctx); 486 434 return ret; 487 } 435 } 436 437 DEBUG(10,("kinit for %s succeeded\n", 438 cli_credentials_get_principal(credentials, mem_ctx))); 439 440 488 441 talloc_free(mem_ctx); 489 442 return 0; 490 443 } 491 444 492 static krb5_error_code free_keytab (struct keytab_container *ktc)445 static krb5_error_code free_keytab_container(struct keytab_container *ktc) 493 446 { 494 447 return krb5_kt_close(ktc->smb_krb5_context->krb5_context, ktc->keytab); 495 448 } 496 449 497 krb5_error_code smb_krb5_open_keytab(TALLOC_CTX *mem_ctx, 498 struct smb_krb5_context *smb_krb5_context, 499 const char *keytab_name, struct keytab_container **ktc) 450 krb5_error_code smb_krb5_get_keytab_container(TALLOC_CTX *mem_ctx, 451 struct smb_krb5_context *smb_krb5_context, 452 krb5_keytab opt_keytab, 453 const char *keytab_name, 454 struct keytab_container **ktc) 500 455 { 501 456 krb5_keytab keytab; 502 457 krb5_error_code ret; 503 ret = krb5_kt_resolve(smb_krb5_context->krb5_context, keytab_name, &keytab); 504 if (ret) { 505 DEBUG(1,("failed to open krb5 keytab: %s\n", 506 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 507 ret, mem_ctx))); 508 return ret; 458 459 if (opt_keytab) { 460 keytab = opt_keytab; 461 } else { 462 ret = krb5_kt_resolve(smb_krb5_context->krb5_context, 463 keytab_name, &keytab); 464 if (ret) { 465 DEBUG(1,("failed to open krb5 keytab: %s\n", 466 smb_get_krb5_error_message( 467 smb_krb5_context->krb5_context, 468 ret, mem_ctx))); 469 return ret; 470 } 509 471 } 510 472 … … 516 478 (*ktc)->smb_krb5_context = talloc_reference(*ktc, smb_krb5_context); 517 479 (*ktc)->keytab = keytab; 518 talloc_set_destructor(*ktc, free_keytab); 480 (*ktc)->password_based = false; 481 talloc_set_destructor(*ktc, free_keytab_container); 519 482 520 483 return 0; 521 484 } 522 485 523 static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,524 struct principal_container **principals,525 krb5_principal salt_princ,526 int kvno,527 const char *password_s,528 struct smb_krb5_context *smb_krb5_context,529 krb5_enctype *enctypes,530 krb5_keytab keytab,531 const char **error_string)532 {533 unsigned int i, p;534 krb5_error_code ret;535 krb5_data password;536 537 password.data = discard_const_p(char *, password_s);538 password.length = strlen(password_s);539 540 for (i=0; enctypes[i]; i++) {541 krb5_keytab_entry entry;542 543 ZERO_STRUCT(entry);544 545 ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context,546 salt_princ, &password, &entry.keyblock, enctypes[i]);547 if (ret != 0) {548 return ret;549 }550 551 entry.vno = kvno;552 553 for (p=0; principals[p]; p++) {554 entry.principal = principals[p]->principal;555 ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry);556 if (ret != 0) {557 char *k5_error_string = smb_get_krb5_error_message(smb_krb5_context->krb5_context,558 ret, NULL);559 *error_string = talloc_asprintf(parent_ctx, "Failed to add enctype %d entry for %s(kvno %d) to keytab: %s\n",560 (int)enctypes[i],561 principals[p]->string_form,562 kvno,563 k5_error_string);564 talloc_free(k5_error_string);565 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);566 return ret;567 }568 569 DEBUG(5, ("Added %s(kvno %d) to keytab (enctype %d)\n",570 principals[p]->string_form, kvno,571 (int)enctypes[i]));572 }573 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);574 }575 return 0;576 }577 578 static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx,579 struct ldb_message *msg,580 struct principal_container **principals,581 struct smb_krb5_context *smb_krb5_context,582 krb5_keytab keytab,583 bool add_old,584 const char **error_string)585 {586 krb5_error_code ret;587 const char *password_s;588 const char *old_secret;589 int kvno;590 uint32_t enctype_bitmap;591 krb5_principal salt_princ;592 krb5_enctype *enctypes;593 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);594 if (!mem_ctx) {595 *error_string = "unable to allocate tmp_ctx for create_keytab";596 return ENOMEM;597 }598 599 /* The salt used to generate these entries may be different however, fetch that */600 ret = salt_principal_from_msg(mem_ctx, msg,601 smb_krb5_context,602 &salt_princ, error_string);603 if (ret) {604 talloc_free(mem_ctx);605 return ret;606 }607 608 kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0);609 610 /* Finally, do the dance to get the password to put in the entry */611 password_s = ldb_msg_find_attr_as_string(msg, "secret", NULL);612 613 if (!password_s) {614 /* There is no password here, so nothing to do */615 talloc_free(mem_ctx);616 return 0;617 }618 619 if (add_old && kvno != 0) {620 old_secret = ldb_msg_find_attr_as_string(msg, "priorSecret", NULL);621 } else {622 old_secret = NULL;623 }624 625 enctype_bitmap = (uint32_t)ldb_msg_find_attr_as_int(msg, "msDS-SupportedEncryptionTypes", ENC_ALL_TYPES);626 627 ret = kerberos_enctype_bitmap_to_enctypes(mem_ctx, enctype_bitmap, &enctypes);628 if (ret) {629 *error_string = talloc_asprintf(parent_ctx, "create_keytab: generating list of encryption types failed (%s)\n",630 smb_get_krb5_error_message(smb_krb5_context->krb5_context,631 ret, mem_ctx));632 talloc_free(mem_ctx);633 return ret;634 }635 636 ret = keytab_add_keys(mem_ctx, principals,637 salt_princ,638 kvno, password_s, smb_krb5_context,639 enctypes, keytab, error_string);640 if (ret) {641 talloc_free(mem_ctx);642 return ret;643 }644 645 if (old_secret) {646 ret = keytab_add_keys(mem_ctx, principals,647 salt_princ,648 kvno - 1, old_secret, smb_krb5_context,649 enctypes, keytab, error_string);650 if (ret) {651 talloc_free(mem_ctx);652 return ret;653 }654 }655 656 talloc_free(mem_ctx);657 return ret;658 }659 660 486 /* 661 * Walk the keytab, looking for entries of this principal name, with KVNO other than current kvno -1. 487 * Walk the keytab, looking for entries of this principal name, 488 * with KVNO other than current kvno -1. 662 489 * 663 * These entries are now stale, we only keep the current, and previous entries around. 490 * These entries are now stale, 491 * we only keep the current and previous entries around. 664 492 * 665 493 * Inspired by the code in Samba3 for 'use kerberos keytab'. 666 *667 494 */ 668 669 static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, 670 struct ldb_message *msg, 671 struct principal_container **principals, 672 bool delete_all_kvno, 673 struct smb_krb5_context *smb_krb5_context, 674 krb5_keytab keytab, bool *found_previous, 675 const char **error_string) 676 { 677 krb5_error_code ret, ret2; 495 krb5_error_code smb_krb5_remove_obsolete_keytab_entries(TALLOC_CTX *mem_ctx, 496 krb5_context context, 497 krb5_keytab keytab, 498 uint32_t num_principals, 499 krb5_principal *principals, 500 krb5_kvno kvno, 501 bool *found_previous, 502 const char **error_string) 503 { 504 TALLOC_CTX *tmp_ctx; 505 krb5_error_code code; 678 506 krb5_kt_cursor cursor; 679 int kvno; 680 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);681 682 if (!mem_ctx) {507 508 tmp_ctx = talloc_new(mem_ctx); 509 if (tmp_ctx == NULL) { 510 *error_string = "Cannot allocate tmp_ctx"; 683 511 return ENOMEM; 684 512 } 685 513 686 *found_previous = false; 687 688 kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0); 689 690 /* for each entry in the keytab */ 691 ret = krb5_kt_start_seq_get(smb_krb5_context->krb5_context, keytab, &cursor); 692 switch (ret) { 514 *found_previous = true; 515 516 code = krb5_kt_start_seq_get(context, keytab, &cursor); 517 switch (code) { 693 518 case 0: 694 519 break; 520 #ifdef HEIM_ERR_OPNOTSUPP 695 521 case HEIM_ERR_OPNOTSUPP: 522 #endif 696 523 case ENOENT: 697 524 case KRB5_KT_END: 698 525 /* no point enumerating if there isn't anything here */ 699 talloc_free(mem_ctx);700 return 0;526 code = 0; 527 goto done; 701 528 default: 702 *error_string = talloc_asprintf( parent_ctx, "failed to open keytab for read of old entries: %s\n",703 smb_get_krb5_error_message(smb_krb5_context->krb5_context,704 ret, mem_ctx));705 talloc_free(mem_ctx);706 return ret;707 } 708 709 while (!ret) {710 unsigned int i;529 *error_string = talloc_asprintf(mem_ctx, 530 "failed to open keytab for read of old entries: %s\n", 531 smb_get_krb5_error_message(context, code, mem_ctx)); 532 goto done; 533 } 534 535 do { 536 krb5_kvno old_kvno = kvno - 1; 537 krb5_keytab_entry entry; 711 538 bool matched = false; 712 krb5_keytab_entry entry; 713 ret = krb5_kt_next_entry(smb_krb5_context->krb5_context, keytab, &entry, &cursor); 714 if (ret) { 539 uint32_t i; 540 541 code = krb5_kt_next_entry(context, keytab, &entry, &cursor); 542 if (code) { 715 543 break; 716 544 } 717 for (i = 0; principals[i]; i++) { 718 /* if it matches our principal */ 719 if (krb5_kt_compare(smb_krb5_context->krb5_context, &entry, principals[i]->principal, 0, 0)) { 545 546 for (i = 0; i < num_principals; i++) { 547 krb5_boolean ok; 548 549 ok = smb_krb5_kt_compare(context, 550 &entry, 551 principals[i], 552 0, 553 0); 554 if (ok) { 720 555 matched = true; 721 556 break; … … 724 559 725 560 if (!matched) { 726 /* Free the entry, it wasn't the one we were looking for anyway */ 727 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry); 561 /* 562 * Free the entry, it wasn't the one we were looking 563 * for anyway 564 */ 565 krb5_kt_free_entry(context, &entry); 566 /* Make sure we do not double free */ 567 ZERO_STRUCT(entry); 728 568 continue; 729 569 } 730 570 731 /* delete it, if it is not kvno -1 */ 732 if (entry.vno != (kvno - 1 )) { 571 /* 572 * Delete it, if it is not kvno - 1. 573 * 574 * Some keytab files store the kvno only in 8bits. Limit the 575 * compare to 8bits, so that we don't miss old keys and delete 576 * them. 577 */ 578 if ((entry.vno & 0xff) != (old_kvno & 0xff)) { 579 krb5_error_code rc; 580 733 581 /* Release the enumeration. We are going to 734 582 * have to start this from the top again, 735 583 * because deletes during enumeration may not 736 * always be consist ant.584 * always be consistent. 737 585 * 738 586 * Also, the enumeration locks a FILE: keytab 739 587 */ 740 741 krb5_kt_end_seq_get(smb_krb5_context->krb5_context, keytab, &cursor); 742 743 ret = krb5_kt_remove_entry(smb_krb5_context->krb5_context, keytab, &entry); 744 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry); 588 krb5_kt_end_seq_get(context, keytab, &cursor); 589 590 code = krb5_kt_remove_entry(context, keytab, &entry); 591 krb5_kt_free_entry(context, &entry); 592 593 /* Make sure we do not double free */ 594 ZERO_STRUCT(entry); 745 595 746 596 /* Deleted: Restart from the top */ 747 ret2 = krb5_kt_start_seq_get(smb_krb5_context->krb5_context, keytab, &cursor); 748 if (ret2) { 749 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry); 750 DEBUG(1,("failed to restart enumeration of keytab: %s\n", 751 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 752 ret, mem_ctx))); 753 754 talloc_free(mem_ctx); 755 return ret2; 597 rc = krb5_kt_start_seq_get(context, keytab, &cursor); 598 if (rc != 0) { 599 krb5_kt_free_entry(context, &entry); 600 601 /* Make sure we do not double free */ 602 ZERO_STRUCT(entry); 603 604 DEBUG(1, ("failed to restart enumeration of keytab: %s\n", 605 smb_get_krb5_error_message(context, 606 code, 607 tmp_ctx))); 608 609 talloc_free(tmp_ctx); 610 return rc; 756 611 } 757 612 758 if ( ret) {613 if (code != 0) { 759 614 break; 760 615 } 761 616 762 617 } else { 763 618 *found_previous = true; 764 619 } 765 620 766 621 /* Free the entry, we don't need it any more */ 767 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry); 768 769 770 } 771 krb5_kt_end_seq_get(smb_krb5_context->krb5_context, keytab, &cursor); 772 773 switch (ret) { 622 krb5_kt_free_entry(context, &entry); 623 /* Make sure we do not double free */ 624 ZERO_STRUCT(entry); 625 } while (code != 0); 626 627 krb5_kt_end_seq_get(context, keytab, &cursor); 628 629 switch (code) { 774 630 case 0: 775 631 break; 776 632 case ENOENT: 777 633 case KRB5_KT_END: 778 ret= 0;634 code = 0; 779 635 break; 780 636 default: 781 *error_string = talloc_asprintf(parent_ctx, "failed in deleting old entries for principal: %s\n", 782 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 783 ret, mem_ctx)); 784 } 785 talloc_free(mem_ctx); 786 return ret; 787 } 788 789 krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, 790 struct smb_krb5_context *smb_krb5_context, 791 struct ldb_context *ldb, 792 struct ldb_message *msg, 793 bool delete_all_kvno, 794 const char **error_string) 795 { 796 krb5_error_code ret; 797 bool found_previous; 798 TALLOC_CTX *mem_ctx = talloc_new(NULL); 799 struct keytab_container *keytab_container; 800 struct principal_container **principals; 801 const char *keytab_name; 802 803 if (!mem_ctx) { 804 return ENOMEM; 805 } 806 807 keytab_name = keytab_name_from_msg(mem_ctx, ldb, msg); 808 if (!keytab_name) { 809 return ENOENT; 810 } 811 812 ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, &keytab_container); 813 814 if (ret != 0) { 815 talloc_free(mem_ctx); 816 return ret; 817 } 818 819 DEBUG(5, ("Opened keytab %s\n", keytab_name)); 820 821 /* Get the principal we will store the new keytab entries under */ 822 ret = principals_from_msg(mem_ctx, msg, smb_krb5_context, &principals, error_string); 823 824 if (ret != 0) { 825 *error_string = talloc_asprintf(parent_ctx, "Failed to load principals from ldb message: %s\n", *error_string); 826 talloc_free(mem_ctx); 827 return ret; 828 } 829 830 ret = remove_old_entries(mem_ctx, msg, principals, delete_all_kvno, 831 smb_krb5_context, keytab_container->keytab, &found_previous, error_string); 832 if (ret != 0) { 833 *error_string = talloc_asprintf(parent_ctx, "Failed to remove old principals from keytab: %s\n", *error_string); 834 talloc_free(mem_ctx); 835 return ret; 836 } 837 838 if (!delete_all_kvno) { 839 /* Create a new keytab. If during the cleanout we found 840 * entires for kvno -1, then don't try and duplicate them. 841 * Otherwise, add kvno, and kvno -1 */ 842 843 ret = create_keytab(mem_ctx, msg, principals, 844 smb_krb5_context, 845 keytab_container->keytab, 846 found_previous ? false : true, error_string); 847 } 848 talloc_free(mem_ctx); 849 return ret; 850 } 851 852 krb5_error_code smb_krb5_create_memory_keytab(TALLOC_CTX *parent_ctx, 853 struct cli_credentials *machine_account, 854 struct smb_krb5_context *smb_krb5_context, 855 struct keytab_container **keytab_container) 856 { 857 krb5_error_code ret; 858 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 859 const char *rand_string; 860 const char *keytab_name; 861 struct ldb_message *msg; 862 const char *error_string; 863 if (!mem_ctx) { 864 return ENOMEM; 865 } 866 867 *keytab_container = talloc(mem_ctx, struct keytab_container); 868 869 rand_string = generate_random_str(mem_ctx, 16); 870 if (!rand_string) { 871 talloc_free(mem_ctx); 872 return ENOMEM; 873 } 874 875 keytab_name = talloc_asprintf(mem_ctx, "MEMORY:%s", 876 rand_string); 877 if (!keytab_name) { 878 talloc_free(mem_ctx); 879 return ENOMEM; 880 } 881 882 ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, keytab_container); 883 if (ret) { 884 return ret; 885 } 886 887 msg = ldb_msg_new(mem_ctx); 888 if (!msg) { 889 talloc_free(mem_ctx); 890 return ENOMEM; 891 } 892 ldb_msg_add_string(msg, "krb5Keytab", keytab_name); 893 ldb_msg_add_string(msg, "secret", cli_credentials_get_password(machine_account)); 894 ldb_msg_add_string(msg, "samAccountName", cli_credentials_get_username(machine_account)); 895 ldb_msg_add_string(msg, "realm", cli_credentials_get_realm(machine_account)); 896 ldb_msg_add_fmt(msg, "msDS-KeyVersionNumber", "%d", (int)cli_credentials_get_kvno(machine_account)); 897 898 ret = smb_krb5_update_keytab(mem_ctx, smb_krb5_context, NULL, msg, false, &error_string); 899 if (ret == 0) { 900 talloc_steal(parent_ctx, *keytab_container); 901 } else { 902 DEBUG(0, ("Failed to create in-memory keytab: %s\n", error_string)); 903 *keytab_container = NULL; 904 } 905 talloc_free(mem_ctx); 906 return ret; 907 } 908 /* Translate between the IETF encryption type values and the Microsoft msDS-SupportedEncryptionTypes values */ 909 uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum) 910 { 911 switch (enc_type_enum) { 912 case ENCTYPE_DES_CBC_CRC: 913 return ENC_CRC32; 914 case ENCTYPE_DES_CBC_MD5: 915 return ENC_RSA_MD5; 916 case ENCTYPE_ARCFOUR_HMAC_MD5: 917 return ENC_RC4_HMAC_MD5; 918 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 919 return ENC_HMAC_SHA1_96_AES128; 920 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 921 return ENC_HMAC_SHA1_96_AES256; 922 default: 923 return 0; 924 } 925 } 926 927 /* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */ 928 krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap) 929 { 930 switch (enctype_bitmap) { 931 case ENC_CRC32: 932 return ENCTYPE_DES_CBC_CRC; 933 case ENC_RSA_MD5: 934 return ENCTYPE_DES_CBC_MD5; 935 case ENC_RC4_HMAC_MD5: 936 return ENCTYPE_ARCFOUR_HMAC_MD5; 937 case ENC_HMAC_SHA1_96_AES128: 938 return ENCTYPE_AES128_CTS_HMAC_SHA1_96; 939 case ENC_HMAC_SHA1_96_AES256: 940 return ENCTYPE_AES256_CTS_HMAC_SHA1_96; 941 default: 942 return 0; 943 } 944 } 945 946 /* Return an array of krb5_enctype values */ 947 krb5_error_code kerberos_enctype_bitmap_to_enctypes(TALLOC_CTX *mem_ctx, uint32_t enctype_bitmap, krb5_enctype **enctypes) 948 { 949 unsigned int i, j = 0; 950 *enctypes = talloc_zero_array(mem_ctx, krb5_enctype, (8*sizeof(enctype_bitmap))+1); 951 if (!*enctypes) { 952 return ENOMEM; 953 } 954 for (i=0; i<(8*sizeof(enctype_bitmap)); i++) { 955 uint32_t bit_value = (1 << i) & enctype_bitmap; 956 if (bit_value & enctype_bitmap) { 957 (*enctypes)[j] = kerberos_enctype_bitmap_to_enctype(bit_value); 958 if (!(*enctypes)[j]) { 959 continue; 960 } 961 j++; 962 } 963 } 964 (*enctypes)[j] = 0; 965 return 0; 966 } 637 *error_string = talloc_asprintf(mem_ctx, 638 "failed in deleting old entries for principal: %s\n", 639 smb_get_krb5_error_message(context, 640 code, 641 mem_ctx)); 642 } 643 644 code = 0; 645 done: 646 talloc_free(tmp_ctx); 647 return code; 648 } -
vendor/current/source4/auth/kerberos/krb5_init_context.c
r740 r988 23 23 #include "includes.h" 24 24 #include "system/kerberos.h" 25 #include "system/gssapi.h" 25 26 #include <tevent.h> 26 27 #include "auth/kerberos/kerberos.h" … … 31 32 #include "libcli/resolve/resolve.h" 32 33 #include "../lib/tsocket/tsocket.h" 33 34 #include "krb5_init_context.h" 34 35 /* 35 36 context structure for operations on cldap packets … … 47 48 48 49 size_t partial_read; 49 50 #ifdef SAMBA4_USES_HEIMDAL 50 51 krb5_krbhst_info *hi; 52 #endif 51 53 }; 52 54 53 55 static krb5_error_code smb_krb5_context_destroy(struct smb_krb5_context *ctx) 54 56 { 55 /* Otherwise krb5_free_context will try and close what we have already free()ed */ 56 krb5_set_warn_dest(ctx->krb5_context, NULL); 57 krb5_closelog(ctx->krb5_context, ctx->logf); 57 #ifdef SAMBA4_USES_HEIMDAL 58 if (ctx->pvt_log_data) { 59 /* Otherwise krb5_free_context will try and close what we 60 * have already free()ed */ 61 krb5_set_warn_dest(ctx->krb5_context, NULL); 62 krb5_closelog(ctx->krb5_context, 63 (krb5_log_facility *)ctx->pvt_log_data); 64 } 65 #endif 58 66 krb5_free_context(ctx->krb5_context); 59 67 return 0; 60 68 } 61 69 70 #ifdef SAMBA4_USES_HEIMDAL 62 71 /* We never close down the DEBUG system, and no need to unreference the use */ 63 72 static void smb_krb5_debug_close(void *private_data) { 64 73 return; 65 74 } 66 75 #endif 76 77 #ifdef SAMBA4_USES_HEIMDAL 67 78 static void smb_krb5_debug_wrapper(const char *timestr, const char *msg, void *private_data) 68 79 { 69 80 DEBUG(3, ("Kerberos: %s\n", msg)); 70 81 } 71 82 #endif 83 84 #ifdef SAMBA4_USES_HEIMDAL 72 85 /* 73 86 handle recv events on a smb_krb5 socket … … 105 118 } 106 119 107 DEBUG( 2,("Received smb_krb5 packet of length %d\n",120 DEBUG(4,("Received smb_krb5 packet of length %d\n", 108 121 (int)blob.length)); 109 122 … … 198 211 } 199 212 200 201 krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, 202 void *data, 203 krb5_krbhst_info *hi, 204 time_t timeout, 205 const krb5_data *send_buf, 206 krb5_data *recv_buf) 213 static krb5_error_code smb_krb5_send_and_recv_func_int(krb5_context context, 214 struct tevent_context *ev, 215 krb5_krbhst_info *hi, 216 struct addrinfo *ai, 217 krb5_send_to_kdc_func func, 218 void *data, 219 time_t timeout, 220 const krb5_data *send_buf, 221 krb5_data *recv_buf) 207 222 { 208 223 krb5_error_code ret; 209 224 NTSTATUS status; 210 225 const char *name; 211 struct addrinfo *a i, *a;226 struct addrinfo *a; 212 227 struct smb_krb5_socket *smb_krb5; 213 228 214 229 DATA_BLOB send_blob; 215 230 216 struct tevent_context *ev; 217 TALLOC_CTX *tmp_ctx = talloc_new(NULL); 218 if (!tmp_ctx) { 231 TALLOC_CTX *frame = talloc_stackframe(); 232 if (frame == NULL) { 219 233 return ENOMEM; 220 234 } 221 235 222 if (!data) {223 /* If no event context was available, then create one for this loop */224 ev = tevent_context_init(tmp_ctx);225 if (!ev) {226 talloc_free(tmp_ctx);227 return ENOMEM;228 }229 } else {230 ev = talloc_get_type_abort(data, struct tevent_context);231 }232 233 236 send_blob = data_blob_const(send_buf->data, send_buf->length); 234 235 ret = krb5_krbhst_get_addrinfo(context, hi, &ai);236 if (ret) {237 talloc_free(tmp_ctx);238 return ret;239 }240 237 241 238 for (a = ai; a; a = a->ai_next) { 242 239 struct socket_address *remote_addr; 243 smb_krb5 = talloc( tmp_ctx, struct smb_krb5_socket);240 smb_krb5 = talloc(frame, struct smb_krb5_socket); 244 241 if (!smb_krb5) { 245 talloc_free(tmp_ctx);242 TALLOC_FREE(frame); 246 243 return ENOMEM; 247 244 } … … 258 255 #endif 259 256 default: 260 talloc_free(tmp_ctx);257 TALLOC_FREE(frame); 261 258 return EINVAL; 262 259 } … … 271 268 break; 272 269 case KRB5_KRBHST_HTTP: 273 talloc_free(tmp_ctx);270 TALLOC_FREE(frame); 274 271 return EINVAL; 275 272 } … … 339 336 break; 340 337 case KRB5_KRBHST_HTTP: 341 talloc_free(tmp_ctx);338 TALLOC_FREE(frame); 342 339 return EINVAL; 343 340 } 344 341 while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) { 345 342 if (tevent_loop_once(ev) != 0) { 346 talloc_free(tmp_ctx);343 TALLOC_FREE(frame); 347 344 return EINVAL; 348 345 } 349 346 350 /* After each and every event loop, reset the 351 * send_to_kdc pointers to what they were when 352 * we entered this loop. That way, if a 353 * nested event has invalidated them, we put 354 * it back before we return to the heimdal 355 * code */ 356 ret = krb5_set_send_to_kdc_func(context, 357 smb_krb5_send_and_recv_func, 358 data); 359 if (ret != 0) { 360 talloc_free(tmp_ctx); 361 return ret; 347 if (func) { 348 /* After each and every event loop, reset the 349 * send_to_kdc pointers to what they were when 350 * we entered this loop. That way, if a 351 * nested event has invalidated them, we put 352 * it back before we return to the heimdal 353 * code */ 354 ret = krb5_set_send_to_kdc_func(context, 355 func, 356 data); 357 if (ret != 0) { 358 TALLOC_FREE(frame); 359 return ret; 360 } 362 361 } 363 362 } … … 383 382 ret = krb5_data_copy(recv_buf, smb_krb5->reply.data, smb_krb5->reply.length); 384 383 if (ret) { 385 talloc_free(tmp_ctx);384 TALLOC_FREE(frame); 386 385 return ret; 387 386 } … … 390 389 break; 391 390 } 392 talloc_free(tmp_ctx);391 TALLOC_FREE(frame); 393 392 if (a) { 394 393 return 0; … … 396 395 return KRB5_KDC_UNREACH; 397 396 } 397 398 krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, 399 void *data, 400 krb5_krbhst_info *hi, 401 time_t timeout, 402 const krb5_data *send_buf, 403 krb5_data *recv_buf) 404 { 405 krb5_error_code ret; 406 struct addrinfo *ai; 407 408 struct tevent_context *ev; 409 TALLOC_CTX *frame = talloc_stackframe(); 410 if (frame == NULL) { 411 return ENOMEM; 412 } 413 414 if (data == NULL) { 415 /* If no event context was available, then create one for this loop */ 416 ev = samba_tevent_context_init(frame); 417 if (ev == NULL) { 418 TALLOC_FREE(frame); 419 return ENOMEM; 420 } 421 } else { 422 ev = talloc_get_type_abort(data, struct tevent_context); 423 } 424 425 ret = krb5_krbhst_get_addrinfo(context, hi, &ai); 426 if (ret) { 427 TALLOC_FREE(frame); 428 return ret; 429 } 430 431 ret = smb_krb5_send_and_recv_func_int(context, ev, hi, ai, smb_krb5_send_and_recv_func, data, timeout, send_buf, recv_buf); 432 TALLOC_FREE(frame); 433 return ret; 434 } 435 436 krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context, 437 void *data, /* struct addrinfo */ 438 krb5_krbhst_info *hi, 439 time_t timeout, 440 const krb5_data *send_buf, 441 krb5_data *recv_buf) 442 { 443 krb5_error_code k5ret; 444 struct addrinfo *ai = data; 445 446 struct tevent_context *ev; 447 TALLOC_CTX *frame = talloc_stackframe(); 448 if (frame == NULL) { 449 return ENOMEM; 450 } 451 452 /* no event context is passed in, create one for this loop */ 453 ev = samba_tevent_context_init(frame); 454 if (ev == NULL) { 455 TALLOC_FREE(frame); 456 return ENOMEM; 457 } 458 459 /* No need to pass in send_and_recv functions, we won't nest on this private event loop */ 460 k5ret = smb_krb5_send_and_recv_func_int(context, ev, hi, ai, NULL, NULL, 461 timeout, send_buf, recv_buf); 462 TALLOC_FREE(frame); 463 return k5ret; 464 } 465 #endif 398 466 399 467 krb5_error_code … … 403 471 { 404 472 krb5_error_code ret; 473 #ifdef SAMBA4_USES_HEIMDAL 405 474 char **config_files; 406 475 const char *config_file, *realm; 476 #endif 407 477 krb5_context krb5_ctx; 408 478 … … 416 486 } 417 487 418 config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf"); 488 /* The MIT Kerberos build relies on using the system krb5.conf file. 489 * If you really want to use another file please set KRB5_CONFIG 490 * accordingly. */ 491 #ifdef SAMBA4_USES_HEIMDAL 492 config_file = lpcfg_config_path(tmp_ctx, lp_ctx, "krb5.conf"); 419 493 if (!config_file) { 420 494 krb5_free_context(krb5_ctx); … … 423 497 424 498 /* Use our local krb5.conf file by default */ 425 ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files);499 ret = krb5_prepend_config_files_default(config_file, &config_files); 426 500 if (ret) { 427 501 DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n", … … 450 524 } 451 525 } 452 526 #endif 453 527 *_krb5_context = krb5_ctx; 454 528 return 0; … … 456 530 457 531 krb5_error_code smb_krb5_init_context(void *parent_ctx, 458 struct tevent_context *ev,459 532 struct loadparm_context *lp_ctx, 460 533 struct smb_krb5_context **smb_krb5_context) … … 462 535 krb5_error_code ret; 463 536 TALLOC_CTX *tmp_ctx; 537 krb5_context kctx; 538 #ifdef SAMBA4_USES_HEIMDAL 539 krb5_log_facility *logf; 540 #endif 464 541 465 542 initialize_krb5_error_table(); … … 473 550 } 474 551 475 ret = smb_krb5_init_context_basic(tmp_ctx, lp_ctx, 476 &(*smb_krb5_context)->krb5_context); 552 ret = smb_krb5_init_context_basic(tmp_ctx, lp_ctx, &kctx); 477 553 if (ret) { 478 554 DEBUG(1,("smb_krb5_context_init_basic failed (%s)\n", … … 481 557 return ret; 482 558 } 483 559 (*smb_krb5_context)->krb5_context = kctx; 560 561 talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy); 562 563 #ifdef SAMBA4_USES_HEIMDAL 484 564 /* TODO: Should we have a different name here? */ 485 ret = krb5_initlog( (*smb_krb5_context)->krb5_context, "Samba", &(*smb_krb5_context)->logf);565 ret = krb5_initlog(kctx, "Samba", &logf); 486 566 487 567 if (ret) { 488 568 DEBUG(1,("krb5_initlog failed (%s)\n", 489 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx))); 490 krb5_free_context((*smb_krb5_context)->krb5_context); 491 talloc_free(tmp_ctx); 492 return ret; 493 } 494 495 talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy); 496 497 ret = krb5_addlog_func((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf, 0 /* min */, -1 /* max */, 498 smb_krb5_debug_wrapper, smb_krb5_debug_close, NULL); 569 smb_get_krb5_error_message(kctx, ret, tmp_ctx))); 570 talloc_free(tmp_ctx); 571 return ret; 572 } 573 (*smb_krb5_context)->pvt_log_data = logf; 574 575 ret = krb5_addlog_func(kctx, logf, 0 /* min */, -1 /* max */, 576 smb_krb5_debug_wrapper, 577 smb_krb5_debug_close, NULL); 499 578 if (ret) { 500 579 DEBUG(1,("krb5_addlog_func failed (%s)\n", 501 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx))); 502 talloc_free(tmp_ctx); 503 return ret; 504 } 505 krb5_set_warn_dest((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf); 506 507 /* Set use of our socket lib */ 508 if (ev) { 509 struct tevent_context *previous_ev; 510 ret = smb_krb5_context_set_event_ctx(*smb_krb5_context, 511 ev, &previous_ev); 512 if (ret) { 513 talloc_free(tmp_ctx); 514 return ret; 515 } 516 } 517 580 smb_get_krb5_error_message(kctx, ret, tmp_ctx))); 581 talloc_free(tmp_ctx); 582 return ret; 583 } 584 krb5_set_warn_dest(kctx, logf); 585 586 /* Set options in kerberos */ 587 588 krb5_set_dns_canonicalize_hostname(kctx, 589 lpcfg_parm_bool(lp_ctx, NULL, "krb5", 590 "set_dns_canonicalize", false)); 591 #endif 518 592 talloc_steal(parent_ctx, *smb_krb5_context); 519 593 talloc_free(tmp_ctx); 520 594 521 /* Set options in kerberos */522 523 krb5_set_dns_canonicalize_hostname((*smb_krb5_context)->krb5_context,524 lpcfg_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false));525 526 595 return 0; 527 596 } 528 597 598 #ifdef SAMBA4_USES_HEIMDAL 529 599 krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context, 530 600 struct tevent_context *ev, … … 580 650 return 0; 581 651 } 652 #endif -
vendor/current/source4/auth/kerberos/krb5_init_context.h
r740 r988 18 18 */ 19 19 20 #ifndef _KRB5_INIT_CONTEXT_H_ 21 #define _KRB5_INIT_CONTEXT_H_ 22 20 23 struct smb_krb5_context { 21 24 krb5_context krb5_context; 22 krb5_log_facility *logf;25 void *pvt_log_data; 23 26 struct tevent_context *current_ev; 24 27 }; 25 28 26 29 struct tevent_context; 27 30 struct loadparm_context; … … 32 35 krb5_context *_krb5_context); 33 36 34 krb5_error_code smb_krb5_init_context(void *parent_ctx, struct tevent_context *ev,37 krb5_error_code smb_krb5_init_context(void *parent_ctx, 35 38 struct loadparm_context *lp_ctx, 36 39 struct smb_krb5_context **smb_krb5_context); 37 40 41 #ifdef SAMBA4_USES_HEIMDAL 38 42 krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, 39 43 void *data, … … 42 46 const krb5_data *send_buf, 43 47 krb5_data *recv_buf); 48 krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context, 49 void *data, /* struct addrinfo */ 50 krb5_krbhst_info *hi, 51 time_t timeout, 52 const krb5_data *send_buf, 53 krb5_data *recv_buf); 54 krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context, 55 struct tevent_context *ev, 56 struct tevent_context **previous_ev); 57 krb5_error_code smb_krb5_context_remove_event_ctx(struct smb_krb5_context *smb_krb5_context, 58 struct tevent_context *previous_ev, 59 struct tevent_context *ev); 60 #endif 61 62 #endif /* _KRB5_INIT_CONTEXT_H_ */ -
vendor/current/source4/auth/kerberos/wscript_build
r740 r988 1 1 #!/usr/bin/env python 2 2 3 bld.SAMBA_SUBSYSTEM('KRB_INIT_CTX', 4 source='krb5_init_context.c', 5 deps='gssapi krb5samba' 6 ) 7 3 8 bld.SAMBA_LIBRARY('authkrb5', 4 source='kerberos .c clikrb5.c kerberos_heimdal.c kerberos_pac.c gssapi_parse.c krb5_init_context.c keytab_copy.c',9 source='kerberos_pac.c', 5 10 autoproto='proto.h', 6 public_deps=' krb5 ndr-krb5pac samba_socket LIBCLI_RESOLVE com_errasn1',7 deps=' ASN1_UTIL auth_sam_reply tevent LIBPACKET ndr ldb',11 public_deps='ndr-krb5pac krb5samba samba_socket LIBCLI_RESOLVE asn1', 12 deps='auth_sam_reply tevent LIBPACKET ndr ldb krb5samba KRB_INIT_CTX KRB5_PAC samba-errors', 8 13 private_library=True 9 14 ) … … 12 17 autoproto='kerberos_util.h', 13 18 source='kerberos_util.c', 14 deps='authkrb5 com_err ldb CREDENTIALS_KRB5 SECRETS',19 deps='authkrb5 krb5samba com_err CREDENTIALS_KRB5', 15 20 ) 16 21 22 bld.SAMBA_SUBSYSTEM('KERBEROS_SRV_KEYTAB', 23 autoproto='kerberos_srv_keytab.h', 24 source='srv_keytab.c', 25 deps='authkrb5', 26 ) -
vendor/current/source4/auth/ntlm/auth.c
r740 r988 27 27 #include "param/param.h" 28 28 #include "dsdb/samdb/samdb.h" 29 29 #include "libcli/wbclient/wbclient.h" 30 #include "lib/util/samba_modules.h" 31 #include "auth/credentials/credentials.h" 32 #include "system/kerberos.h" 33 #include "auth/kerberos/kerberos.h" 34 #include "auth/kerberos/kerberos_util.h" 35 #include "libds/common/roles.h" 36 37 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context, 38 TALLOC_CTX *mem_ctx, 39 void *server_returned_info, 40 const char *original_user_name, 41 uint32_t session_info_flags, 42 struct auth_session_info **session_info); 30 43 31 44 /*************************************************************************** 32 45 Set a fixed challenge 33 46 ***************************************************************************/ 34 _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth _context *auth_ctx, const uint8_t chal[8], const char *set_by)47 _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by) 35 48 { 36 49 auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by); … … 41 54 42 55 return NT_STATUS_OK; 43 }44 45 /***************************************************************************46 Set a fixed challenge47 ***************************************************************************/48 _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)49 {50 return auth_ctx->challenge.may_be_modified;51 56 } 52 57 … … 55 60 Returns a const char of length 8 bytes. 56 61 ****************************************************************************/ 57 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) 58 { 59 NTSTATUS nt_status; 60 struct auth_method_context *method; 62 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]) 63 { 61 64 62 65 if (auth_ctx->challenge.data.length == 8) { … … 67 70 } 68 71 69 for (method = auth_ctx->methods; method; method = method->next) {70 nt_status = method->ops->get_challenge(method, auth_ctx, chal);71 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {72 continue;73 }74 75 NT_STATUS_NOT_OK_RETURN(nt_status);76 77 auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8);78 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);79 auth_ctx->challenge.set_by = method->ops->name;80 81 break;82 }83 84 72 if (!auth_ctx->challenge.set_by) { 85 73 generate_random_buffer(chal, 8); … … 88 76 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data); 89 77 auth_ctx->challenge.set_by = "random"; 90 91 auth_ctx->challenge.may_be_modified = true;92 78 } 93 79 … … 104 90 Supply either a principal or a DN 105 91 ****************************************************************************/ 106 _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, 107 struct auth_context *auth_ctx, 108 const char *principal, 109 struct ldb_dn *user_dn, 110 struct auth_user_info_dc **user_info_dc) 92 static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx, 93 TALLOC_CTX *mem_ctx, 94 const char *principal, 95 struct ldb_dn *user_dn, 96 uint32_t session_info_flags, 97 struct auth_session_info **session_info) 111 98 { 112 99 NTSTATUS nt_status; 113 100 struct auth_method_context *method; 101 struct auth_user_info_dc *user_info_dc; 114 102 115 103 for (method = auth_ctx->methods; method; method = method->next) { … … 118 106 } 119 107 120 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, user_info_dc);108 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc); 121 109 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { 122 110 continue; 123 111 } 112 if (!NT_STATUS_IS_OK(nt_status)) { 113 return nt_status; 114 } 115 116 nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 117 user_info_dc, 118 user_info_dc->info->account_name, 119 session_info_flags, session_info); 120 talloc_free(user_info_dc); 124 121 125 122 return nt_status; … … 156 153 **/ 157 154 158 _PUBLIC_ NTSTATUS auth_check_password(struct auth _context *auth_ctx,155 _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, 159 156 TALLOC_CTX *mem_ctx, 160 157 const struct auth_usersupplied_info *user_info, … … 188 185 } 189 186 187 _PUBLIC_ NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx, 188 TALLOC_CTX *mem_ctx, 189 const struct auth_usersupplied_info *user_info, 190 void **server_returned_info, 191 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 192 { 193 struct auth_user_info_dc *user_info_dc; 194 NTSTATUS status = auth_check_password(auth_ctx, mem_ctx, user_info, &user_info_dc); 195 196 if (NT_STATUS_IS_OK(status)) { 197 *server_returned_info = user_info_dc; 198 199 if (user_session_key) { 200 DEBUG(10, ("Got NT session key of length %u\n", 201 (unsigned)user_info_dc->user_session_key.length)); 202 *user_session_key = user_info_dc->user_session_key; 203 talloc_steal(mem_ctx, user_session_key->data); 204 user_info_dc->user_session_key = data_blob_null; 205 } 206 207 if (lm_session_key) { 208 DEBUG(10, ("Got LM session key of length %u\n", 209 (unsigned)user_info_dc->lm_session_key.length)); 210 *lm_session_key = user_info_dc->lm_session_key; 211 talloc_steal(mem_ctx, lm_session_key->data); 212 user_info_dc->lm_session_key = data_blob_null; 213 } 214 } 215 216 return status; 217 } 218 190 219 struct auth_check_password_state { 191 struct auth _context *auth_ctx;220 struct auth4_context *auth_ctx; 192 221 const struct auth_usersupplied_info *user_info; 193 222 struct auth_user_info_dc *user_info_dc; … … 226 255 _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, 227 256 struct tevent_context *ev, 228 struct auth _context *auth_ctx,257 struct auth4_context *auth_ctx, 229 258 const struct auth_usersupplied_info *user_info) 230 259 { … … 252 281 253 282 if (!user_info->mapped_state) { 254 nt_status = map_user_info( req, lpcfg_workgroup(auth_ctx->lp_ctx),283 nt_status = map_user_info(auth_ctx->sam_ctx, req, lpcfg_workgroup(auth_ctx->lp_ctx), 255 284 user_info, &user_info_tmp); 256 285 if (tevent_req_nterror(req, nt_status)) { … … 315 344 for (method=state->auth_ctx->methods; method; method = method->next) { 316 345 346 if (state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY 347 && !(method->ops->flags & AUTH_METHOD_LOCAL_SAM)) { 348 continue; 349 } 350 317 351 /* we fill in state->method here so debug messages in 318 352 the callers know which method failed */ … … 343 377 344 378 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 345 /* don't expose the NT_STATUS_NOT_IMPLEMENTED 346 internals */ 347 status = NT_STATUS_NO_SUCH_USER; 379 if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) { 380 /* don't expose the NT_STATUS_NOT_IMPLEMENTED 381 * internals, except when the caller is only probing 382 * one method, as they may do the fallback 383 */ 384 status = NT_STATUS_NO_SUCH_USER; 385 } 348 386 } 349 387 … … 407 445 } 408 446 447 /* Wrapper because we don't want to expose all callers to needing to 448 * know that session_info is generated from the main ldb, and because 449 * we need to break a depenency loop between the DCE/RPC layer and the 450 * generation of unix tokens via IRPC */ 451 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context, 452 TALLOC_CTX *mem_ctx, 453 void *server_returned_info, 454 const char *original_user_name, 455 uint32_t session_info_flags, 456 struct auth_session_info **session_info) 457 { 458 NTSTATUS status; 459 struct auth_user_info_dc *user_info_dc = talloc_get_type_abort(server_returned_info, struct auth_user_info_dc); 460 461 if (user_info_dc->info->authenticated) { 462 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; 463 } 464 465 status = auth_generate_session_info(mem_ctx, auth_context->lp_ctx, 466 auth_context->sam_ctx, user_info_dc, 467 session_info_flags, session_info); 468 if (!NT_STATUS_IS_OK(status)) { 469 return status; 470 } 471 472 if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN) 473 && NT_STATUS_IS_OK(status)) { 474 status = auth_session_info_fill_unix(auth_context->event_ctx, 475 auth_context->lp_ctx, 476 original_user_name, *session_info); 477 if (!NT_STATUS_IS_OK(status)) { 478 TALLOC_FREE(*session_info); 479 } 480 } 481 return status; 482 } 483 409 484 /* Wrapper because we don't want to expose all callers to needing to 410 * know that session_info is generated from the main ldb */ 411 static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, 412 struct auth_context *auth_context, 413 struct auth_user_info_dc *user_info_dc, 414 uint32_t session_info_flags, 415 struct auth_session_info **session_info) 416 { 417 return auth_generate_session_info(mem_ctx, auth_context->lp_ctx, 418 auth_context->sam_ctx, user_info_dc, 419 session_info_flags, session_info); 485 * know anything about the PAC or auth subsystem internal structures 486 * before we output a struct auth session_info */ 487 static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx, 488 TALLOC_CTX *mem_ctx, 489 struct smb_krb5_context *smb_krb5_context, 490 DATA_BLOB *pac_blob, 491 const char *principal_name, 492 const struct tsocket_address *remote_address, 493 uint32_t session_info_flags, 494 struct auth_session_info **session_info) 495 { 496 NTSTATUS status; 497 struct auth_user_info_dc *user_info_dc; 498 TALLOC_CTX *tmp_ctx; 499 500 if (!pac_blob) { 501 return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name, 502 NULL, session_info_flags, session_info); 503 } 504 505 tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); 506 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 507 508 status = kerberos_pac_blob_to_user_info_dc(tmp_ctx, 509 *pac_blob, 510 smb_krb5_context->krb5_context, 511 &user_info_dc, NULL, NULL); 512 if (!NT_STATUS_IS_OK(status)) { 513 talloc_free(tmp_ctx); 514 return status; 515 } 516 517 if (user_info_dc->info->authenticated) { 518 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED; 519 } 520 521 status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 522 user_info_dc, 523 user_info_dc->info->account_name, 524 session_info_flags, session_info); 525 talloc_free(tmp_ctx); 526 return status; 420 527 } 421 528 … … 424 531 - Allow the caller to specify the methods to use, including optionally the SAM to use 425 532 ***************************************************************************/ 426 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * *methods,533 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods, 427 534 struct tevent_context *ev, 428 struct messaging_context *msg,535 struct imessaging_context *msg, 429 536 struct loadparm_context *lp_ctx, 430 537 struct ldb_context *sam_ctx, 431 struct auth _context **auth_ctx)538 struct auth4_context **auth_ctx) 432 539 { 433 540 int i; 434 struct auth _context *ctx;541 struct auth4_context *ctx; 435 542 436 543 auth4_init(); … … 441 548 } 442 549 443 ctx = talloc (mem_ctx, struct auth_context);550 ctx = talloc_zero(mem_ctx, struct auth4_context); 444 551 NT_STATUS_HAVE_NO_MEMORY(ctx); 445 ctx->challenge.set_by = NULL;446 ctx->challenge.may_be_modified = false;447 552 ctx->challenge.data = data_blob(NULL, 0); 448 553 ctx->methods = NULL; … … 471 576 method->auth_ctx = ctx; 472 577 method->depth = i; 473 DLIST_ADD_END(ctx->methods, method, struct auth_method_context *); 474 } 475 476 ctx->check_password = auth_check_password; 477 ctx->get_challenge = auth_get_challenge; 478 ctx->set_challenge = auth_context_set_challenge; 479 ctx->challenge_may_be_modified = auth_challenge_may_be_modified; 480 ctx->get_user_info_dc_principal = auth_get_user_info_dc_principal; 578 DLIST_ADD_END(ctx->methods, method); 579 } 580 581 ctx->check_ntlm_password = auth_check_password_wrapper; 582 ctx->get_ntlm_challenge = auth_get_challenge; 583 ctx->set_ntlm_challenge = auth_context_set_challenge; 481 584 ctx->generate_session_info = auth_generate_session_info_wrapper; 585 ctx->generate_session_info_pac = auth_generate_session_info_pac; 482 586 483 587 *auth_ctx = ctx; … … 488 592 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 489 593 { 490 const char **auth_methods = NULL; 594 char **auth_methods = NULL; 595 491 596 switch (lpcfg_server_role(lp_ctx)) { 492 597 case ROLE_STANDALONE: 493 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);598 auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL); 494 599 break; 495 600 case ROLE_DOMAIN_MEMBER: 496 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);601 auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL); 497 602 break; 498 case ROLE_DOMAIN_CONTROLLER: 499 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); 603 case ROLE_DOMAIN_BDC: 604 case ROLE_DOMAIN_PDC: 605 case ROLE_ACTIVE_DIRECTORY_DC: 606 auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL); 500 607 break; 501 608 } 502 return auth_methods;609 return discard_const_p(const char *, auth_methods); 503 610 } 504 611 … … 509 616 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 510 617 struct tevent_context *ev, 511 struct messaging_context *msg,618 struct imessaging_context *msg, 512 619 struct loadparm_context *lp_ctx, 513 struct auth _context **auth_ctx)620 struct auth4_context **auth_ctx) 514 621 { 515 622 NTSTATUS status; … … 525 632 } 526 633 status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx); 527 talloc_free(tmp_ctx);528 return status;529 }530 531 /* Create an auth context from an open LDB.532 533 This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups)534 535 */536 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx)537 {538 NTSTATUS status;539 const char **auth_methods;540 struct loadparm_context *lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);541 struct tevent_context *ev = ldb_get_event_context(ldb);542 543 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);544 if (!tmp_ctx) {545 return NT_STATUS_NO_MEMORY;546 }547 548 auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);549 if (!auth_methods) {550 return NT_STATUS_INVALID_PARAMETER;551 }552 status = auth_context_create_methods(mem_ctx, auth_methods, ev, NULL, lp_ctx, ldb, auth_ctx);553 634 talloc_free(tmp_ctx); 554 635 return status; … … 621 702 { 622 703 static const struct auth_critical_sizes critical_sizes = { 623 AUTH _INTERFACE_VERSION,704 AUTH4_INTERFACE_VERSION, 624 705 sizeof(struct auth_operations), 625 706 sizeof(struct auth_method_context), 626 sizeof(struct auth _context),707 sizeof(struct auth4_context), 627 708 sizeof(struct auth_usersupplied_info), 628 709 sizeof(struct auth_user_info_dc) -
vendor/current/source4/auth/ntlm/auth_anonymous.c
r740 r988 25 25 #include "param/param.h" 26 26 27 _PUBLIC_ NTSTATUS auth4_anonymous_init(void); 28 27 29 /** 28 30 * Return a anonymous logon for anonymous users (username = "") … … 38 40 if (user_info->client.account_name && *user_info->client.account_name) { 39 41 return NT_STATUS_NOT_IMPLEMENTED; 42 } 43 44 switch (user_info->password_state) { 45 case AUTH_PASSWORD_PLAIN: 46 if (user_info->password.plaintext != NULL && 47 strlen(user_info->password.plaintext) > 0) 48 { 49 return NT_STATUS_NOT_IMPLEMENTED; 50 } 51 break; 52 case AUTH_PASSWORD_HASH: 53 if (user_info->password.hash.lanman != NULL) { 54 return NT_STATUS_NOT_IMPLEMENTED; 55 } 56 if (user_info->password.hash.nt != NULL) { 57 return NT_STATUS_NOT_IMPLEMENTED; 58 } 59 break; 60 case AUTH_PASSWORD_RESPONSE: 61 if (user_info->password.response.lanman.length == 1) { 62 if (user_info->password.response.lanman.data[0] != '\0') { 63 return NT_STATUS_NOT_IMPLEMENTED; 64 } 65 } else if (user_info->password.response.lanman.length > 1) { 66 return NT_STATUS_NOT_IMPLEMENTED; 67 } 68 if (user_info->password.response.nt.length > 0) { 69 return NT_STATUS_NOT_IMPLEMENTED; 70 } 71 break; 40 72 } 41 73 … … 60 92 static const struct auth_operations anonymous_auth_ops = { 61 93 .name = "anonymous", 62 .get_challenge = auth_get_challenge_not_implemented,63 94 .want_check = anonymous_want_check, 64 95 .check_password = anonymous_check_password 65 96 }; 66 97 67 _PUBLIC_ NTSTATUS auth _anonymous_init(void)98 _PUBLIC_ NTSTATUS auth4_anonymous_init(void) 68 99 { 69 100 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/auth_developer.c
r740 r988 24 24 #include "auth/ntlm/auth_proto.h" 25 25 #include "libcli/security/security.h" 26 27 _PUBLIC_ NTSTATUS auth4_developer_init(void); 26 28 27 29 static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, … … 132 134 static const struct auth_operations name_to_ntstatus_auth_ops = { 133 135 .name = "name_to_ntstatus", 134 .get_challenge = auth_get_challenge_not_implemented,135 136 .want_check = name_to_ntstatus_want_check, 136 137 .check_password = name_to_ntstatus_check_password 137 138 }; 138 139 139 /** 140 * Return a 'fixed' challenge instead of a variable one. 141 * 142 * The idea of this function is to make packet snifs consistant 143 * with a fixed challenge, so as to aid debugging. 144 * 145 * This module is of no value to end-users. 146 * 147 * This module does not actually authenticate the user, but 148 * just pretenteds to need a specified challenge. 149 * This module removes *all* security from the challenge-response system 150 * 151 * @return NT_STATUS_UNSUCCESSFUL 152 **/ 153 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 154 { 155 const char *challenge = "I am a teapot"; 156 157 memcpy(chal, challenge, 8); 158 159 return NT_STATUS_OK; 160 } 161 162 static NTSTATUS fixed_challenge_want_check(struct auth_method_context *ctx, 163 TALLOC_CTX *mem_ctx, 164 const struct auth_usersupplied_info *user_info) 165 { 166 /* don't handle any users */ 167 return NT_STATUS_NOT_IMPLEMENTED; 168 } 169 170 static NTSTATUS fixed_challenge_check_password(struct auth_method_context *ctx, 171 TALLOC_CTX *mem_ctx, 172 const struct auth_usersupplied_info *user_info, 173 struct auth_user_info_dc **_user_info_dc) 174 { 175 /* don't handle any users */ 176 return NT_STATUS_NO_SUCH_USER; 177 } 178 179 static const struct auth_operations fixed_challenge_auth_ops = { 180 .name = "fixed_challenge", 181 .get_challenge = fixed_challenge_get_challenge, 182 .want_check = fixed_challenge_want_check, 183 .check_password = fixed_challenge_check_password 184 }; 185 186 _PUBLIC_ NTSTATUS auth_developer_init(void) 140 _PUBLIC_ NTSTATUS auth4_developer_init(void) 187 141 { 188 142 NTSTATUS ret; … … 194 148 } 195 149 196 ret = auth_register(&fixed_challenge_auth_ops);197 if (!NT_STATUS_IS_OK(ret)) {198 DEBUG(0,("Failed to register 'fixed_challenge' auth backend!\n"));199 return ret;200 }201 202 150 return ret; 203 151 } -
vendor/current/source4/auth/ntlm/auth_sam.c
r740 r988 34 34 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 35 #include "lib/messaging/irpc.h" 36 #include "libcli/auth/libcli_auth.h" 37 #include "libds/common/roles.h" 38 39 NTSTATUS auth_sam_init(void); 36 40 37 41 extern const char *user_attrs[]; … … 71 75 the lanman and NT responses. 72 76 ****************************************************************************/ 73 static NTSTATUS authsam_password_ok(struct auth _context *auth_context,77 static NTSTATUS authsam_password_ok(struct auth4_context *auth_context, 74 78 TALLOC_CTX *mem_ctx, 75 79 uint16_t acct_flags, … … 126 130 } 127 131 128 if (user_sess_key && user_sess_key->data) {129 talloc_steal(auth_context, user_sess_key->data);130 }131 if (lm_sess_key && lm_sess_key->data) {132 talloc_steal(auth_context, lm_sess_key->data);133 }134 135 132 return NT_STATUS_OK; 136 133 } … … 141 138 REPL_SECRET getncchanges extended op to fetch the users secrets 142 139 */ 143 static void auth_sam_trigger_repl_secret( TALLOC_CTX *mem_ctx, struct auth_context *auth_context,140 static void auth_sam_trigger_repl_secret(struct auth4_context *auth_context, 144 141 struct ldb_dn *user_dn) 145 142 { … … 147 144 struct drepl_trigger_repl_secret r; 148 145 struct tevent_req *req; 149 150 irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx, 146 TALLOC_CTX *tmp_ctx; 147 148 tmp_ctx = talloc_new(auth_context); 149 if (tmp_ctx == NULL) { 150 return; 151 } 152 153 irpc_handle = irpc_binding_handle_by_name(tmp_ctx, auth_context->msg_ctx, 151 154 "dreplsrv", 152 155 &ndr_table_irpc); 153 156 if (irpc_handle == NULL) { 154 157 DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n")); 158 TALLOC_FREE(tmp_ctx); 155 159 return; 156 160 } … … 158 162 r.in.user_dn = ldb_dn_get_linearized(user_dn); 159 163 160 req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx, 164 /* 165 * This seem to rely on the current IRPC implementation, 166 * which delivers the message in the _send function. 167 * 168 * TODO: we need a ONE_WAY IRPC handle and register 169 * a callback and wait for it to be triggered! 170 */ 171 req = dcerpc_drepl_trigger_repl_secret_r_send(tmp_ctx, 161 172 auth_context->event_ctx, 162 173 irpc_handle, … … 165 176 /* we aren't interested in a reply */ 166 177 talloc_free(req); 167 talloc_free(irpc_handle); 168 } 169 170 171 static NTSTATUS authsam_authenticate(struct auth_context *auth_context, 172 TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 173 struct ldb_dn *domain_dn, 174 struct ldb_message *msg, 175 const struct auth_usersupplied_info *user_info, 176 DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) 177 { 178 struct samr_Password *lm_pwd, *nt_pwd; 178 TALLOC_FREE(tmp_ctx); 179 } 180 181 182 /* 183 * Check that a password is OK, and update badPwdCount if required. 184 */ 185 186 static NTSTATUS authsam_password_check_and_record(struct auth4_context *auth_context, 187 TALLOC_CTX *mem_ctx, 188 struct ldb_dn *domain_dn, 189 struct ldb_message *msg, 190 uint16_t acct_flags, 191 const struct auth_usersupplied_info *user_info, 192 DATA_BLOB *user_sess_key, 193 DATA_BLOB *lm_sess_key) 194 { 179 195 NTSTATUS nt_status; 180 181 uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn); 182 183 /* Quit if the account was locked out. */ 184 if (acct_flags & ACB_AUTOLOCK) { 185 DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", 186 user_info->mapped.account_name)); 187 return NT_STATUS_ACCOUNT_LOCKED_OUT; 188 } 189 190 /* You can only do an interactive login to normal accounts */ 191 if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) { 192 if (!(acct_flags & ACB_NORMAL)) { 193 return NT_STATUS_NO_SUCH_USER; 194 } 195 } 196 197 nt_status = samdb_result_passwords(mem_ctx, auth_context->lp_ctx, msg, &lm_pwd, &nt_pwd); 198 NT_STATUS_NOT_OK_RETURN(nt_status); 196 NTSTATUS auth_status; 197 TALLOC_CTX *tmp_ctx; 198 int i, ret; 199 int history_len = 0; 200 struct ldb_context *sam_ctx = auth_context->sam_ctx; 201 const char * const attrs[] = { "pwdHistoryLength", NULL }; 202 struct ldb_message *dom_msg; 203 struct samr_Password *lm_pwd; 204 struct samr_Password *nt_pwd; 205 206 tmp_ctx = talloc_new(mem_ctx); 207 if (tmp_ctx == NULL) { 208 return NT_STATUS_NO_MEMORY; 209 } 210 211 /* 212 * This call does more than what it appears to do, it also 213 * checks for the account lockout. 214 * 215 * It is done here so that all parts of Samba that read the 216 * password refuse to even operate on it if the account is 217 * locked out, to avoid mistakes like CVE-2013-4496. 218 */ 219 nt_status = samdb_result_passwords(tmp_ctx, auth_context->lp_ctx, 220 msg, &lm_pwd, &nt_pwd); 221 if (!NT_STATUS_IS_OK(nt_status)) { 222 TALLOC_FREE(tmp_ctx); 223 return nt_status; 224 } 199 225 200 226 if (lm_pwd == NULL && nt_pwd == NULL) { 201 227 bool am_rodc; 202 228 if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) { 203 /* we don't have passwords for this 229 /* 230 * we don't have passwords for this 204 231 * account. We are an RODC, and this account 205 232 * may be one for which we either are denied … … 212 239 * replicate the secrets for this account. 213 240 */ 214 auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn); 241 auth_sam_trigger_repl_secret(auth_context, msg->dn); 242 TALLOC_FREE(tmp_ctx); 215 243 return NT_STATUS_NOT_IMPLEMENTED; 216 244 } 217 245 } 218 246 219 nt_status = authsam_password_ok(auth_context, mem_ctx, 220 acct_flags, lm_pwd, nt_pwd, 221 user_info, user_sess_key, lm_sess_key); 222 NT_STATUS_NOT_OK_RETURN(nt_status); 223 224 nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx, 247 auth_status = authsam_password_ok(auth_context, tmp_ctx, 248 acct_flags, 249 lm_pwd, nt_pwd, 250 user_info, 251 user_sess_key, lm_sess_key); 252 if (NT_STATUS_IS_OK(auth_status)) { 253 if (user_sess_key->data) { 254 talloc_steal(mem_ctx, user_sess_key->data); 255 } 256 if (lm_sess_key->data) { 257 talloc_steal(mem_ctx, lm_sess_key->data); 258 } 259 TALLOC_FREE(tmp_ctx); 260 return NT_STATUS_OK; 261 } 262 *user_sess_key = data_blob_null; 263 *lm_sess_key = data_blob_null; 264 265 if (!NT_STATUS_EQUAL(auth_status, NT_STATUS_WRONG_PASSWORD)) { 266 TALLOC_FREE(tmp_ctx); 267 return auth_status; 268 } 269 270 /* 271 * We only continue if this was a wrong password 272 * and we'll always return NT_STATUS_WRONG_PASSWORD 273 * no matter what error happens. 274 */ 275 276 /* pull the domain password property attributes */ 277 ret = dsdb_search_one(sam_ctx, tmp_ctx, &dom_msg, domain_dn, LDB_SCOPE_BASE, 278 attrs, 0, "objectClass=domain"); 279 if (ret == LDB_SUCCESS) { 280 history_len = ldb_msg_find_attr_as_uint(dom_msg, "pwdHistoryLength", 0); 281 } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { 282 DEBUG(3,("Couldn't find domain %s: %s!\n", 283 ldb_dn_get_linearized(domain_dn), 284 ldb_errstring(sam_ctx))); 285 } else { 286 DEBUG(3,("error finding domain %s: %s!\n", 287 ldb_dn_get_linearized(domain_dn), 288 ldb_errstring(sam_ctx))); 289 } 290 291 for (i = 1; i < MIN(history_len, 3); i++) { 292 static const struct samr_Password zero_hash; 293 struct samr_Password zero_string_hash; 294 struct samr_Password zero_string_des_hash; 295 struct samr_Password *nt_history_pwd = NULL; 296 struct samr_Password *lm_history_pwd = NULL; 297 NTTIME pwdLastSet; 298 struct timeval tv_now; 299 NTTIME now; 300 int allowed_period_mins; 301 NTTIME allowed_period; 302 303 nt_status = samdb_result_passwords_from_history(tmp_ctx, 304 auth_context->lp_ctx, 305 msg, i, 306 &lm_history_pwd, 307 &nt_history_pwd); 308 if (!NT_STATUS_IS_OK(nt_status)) { 309 /* 310 * If we don't find element 'i' we won't find 311 * 'i+1' ... 312 */ 313 break; 314 } 315 316 /* 317 * We choose to avoid any issues 318 * around different LM and NT history 319 * lengths by only checking the NT 320 * history 321 */ 322 if (nt_history_pwd == NULL) { 323 /* 324 * If we don't find element 'i' we won't find 325 * 'i+1' ... 326 */ 327 break; 328 } 329 330 /* Skip over all-zero hashes in the history */ 331 if (memcmp(nt_history_pwd->hash, zero_hash.hash, 332 sizeof(zero_hash.hash)) == 0) { 333 continue; 334 } 335 336 /* 337 * This looks odd, but the password_hash module writes this in if 338 * (somehow) we didn't have an old NT hash 339 */ 340 341 E_md4hash("", zero_string_hash.hash); 342 if (memcmp(nt_history_pwd->hash, zero_string_hash.hash, 16) == 0) { 343 continue; 344 } 345 346 E_deshash("", zero_string_des_hash.hash); 347 if (!lm_history_pwd || memcmp(lm_history_pwd->hash, zero_string_des_hash.hash, 16) == 0) { 348 lm_history_pwd = NULL; 349 } 350 351 auth_status = authsam_password_ok(auth_context, tmp_ctx, 352 acct_flags, 353 lm_history_pwd, 354 nt_history_pwd, 355 user_info, 356 user_sess_key, 357 lm_sess_key); 358 if (!NT_STATUS_IS_OK(auth_status)) { 359 /* 360 * If this was not a correct password, try the next 361 * one from the history 362 */ 363 *user_sess_key = data_blob_null; 364 *lm_sess_key = data_blob_null; 365 continue; 366 } 367 368 if (i != 1) { 369 /* 370 * The authentication was OK, but not against 371 * the previous password, which is stored at index 1. 372 * 373 * We just return the original wrong password. 374 * This skips the update of the bad pwd count, 375 * because this is almost certainly user error 376 * (or automatic login on a computer using a cached 377 * password from before the password change), 378 * not an attack. 379 */ 380 TALLOC_FREE(tmp_ctx); 381 return NT_STATUS_WRONG_PASSWORD; 382 } 383 384 if (user_info->password_state != AUTH_PASSWORD_RESPONSE) { 385 /* 386 * The authentication was OK against the previous password, 387 * but it's not a NTLM network authentication. 388 * 389 * We just return the original wrong password. 390 * This skips the update of the bad pwd count, 391 * because this is almost certainly user error 392 * (or automatic login on a computer using a cached 393 * password from before the password change), 394 * not an attack. 395 */ 396 TALLOC_FREE(tmp_ctx); 397 return NT_STATUS_WRONG_PASSWORD; 398 } 399 400 /* 401 * If the password was OK, it's a NTLM network authentication 402 * and it was the previous password. 403 * 404 * Now we see if it is within the grace period, 405 * so that we don't break cached sessions on other computers 406 * before the user can lock and unlock their other screens 407 * (resetting their cached password). 408 * 409 * See http://support.microsoft.com/kb/906305 410 * OldPasswordAllowedPeriod ("old password allowed period") 411 * is specified in minutes. The default is 60. 412 */ 413 allowed_period_mins = lpcfg_old_password_allowed_period(auth_context->lp_ctx); 414 /* 415 * NTTIME uses 100ns units 416 */ 417 allowed_period = allowed_period_mins * 60 * 1000*1000*10; 418 pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0); 419 tv_now = timeval_current(); 420 now = timeval_to_nttime(&tv_now); 421 422 if (now < pwdLastSet) { 423 /* 424 * time jump? 425 * 426 * We just return the original wrong password. 427 * This skips the update of the bad pwd count, 428 * because this is almost certainly user error 429 * (or automatic login on a computer using a cached 430 * password from before the password change), 431 * not an attack. 432 */ 433 TALLOC_FREE(tmp_ctx); 434 return NT_STATUS_WRONG_PASSWORD; 435 } 436 437 if ((now - pwdLastSet) >= allowed_period) { 438 /* 439 * The allowed period is over. 440 * 441 * We just return the original wrong password. 442 * This skips the update of the bad pwd count, 443 * because this is almost certainly user error 444 * (or automatic login on a computer using a cached 445 * password from before the password change), 446 * not an attack. 447 */ 448 TALLOC_FREE(tmp_ctx); 449 return NT_STATUS_WRONG_PASSWORD; 450 } 451 452 /* 453 * We finally allow the authentication with the 454 * previous password within the allowed period. 455 */ 456 if (user_sess_key->data) { 457 talloc_steal(mem_ctx, user_sess_key->data); 458 } 459 if (lm_sess_key->data) { 460 talloc_steal(mem_ctx, lm_sess_key->data); 461 } 462 463 TALLOC_FREE(tmp_ctx); 464 return auth_status; 465 } 466 467 /* 468 * If we are not in the allowed period or match an old password, 469 * we didn't return early. Now update the badPwdCount et al. 470 */ 471 nt_status = authsam_update_bad_pwd_count(auth_context->sam_ctx, 472 msg, domain_dn); 473 if (!NT_STATUS_IS_OK(nt_status)) { 474 /* 475 * We need to return the original 476 * NT_STATUS_WRONG_PASSWORD error, so there isn't 477 * anything more we can do than write something into 478 * the log 479 */ 480 DEBUG(0, ("Failed to note bad password for user [%s]: %s\n", 481 user_info->mapped.account_name, 482 nt_errstr(nt_status))); 483 } 484 485 TALLOC_FREE(tmp_ctx); 486 return NT_STATUS_WRONG_PASSWORD; 487 } 488 489 static NTSTATUS authsam_authenticate(struct auth4_context *auth_context, 490 TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 491 struct ldb_dn *domain_dn, 492 struct ldb_message *msg, 493 const struct auth_usersupplied_info *user_info, 494 DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) 495 { 496 NTSTATUS nt_status; 497 bool interactive = (user_info->password_state == AUTH_PASSWORD_HASH); 498 uint16_t acct_flags = samdb_result_acct_flags(msg, NULL); 499 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 500 if (!tmp_ctx) { 501 return NT_STATUS_NO_MEMORY; 502 } 503 504 /* You can only do an interactive login to normal accounts */ 505 if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) { 506 if (!(acct_flags & ACB_NORMAL)) { 507 TALLOC_FREE(tmp_ctx); 508 return NT_STATUS_NO_SUCH_USER; 509 } 510 } 511 512 nt_status = authsam_password_check_and_record(auth_context, tmp_ctx, 513 domain_dn, msg, acct_flags, 514 user_info, 515 user_sess_key, lm_sess_key); 516 if (!NT_STATUS_IS_OK(nt_status)) { 517 TALLOC_FREE(tmp_ctx); 518 return nt_status; 519 } 520 521 nt_status = authsam_account_ok(tmp_ctx, auth_context->sam_ctx, 225 522 user_info->logon_parameters, 226 523 domain_dn, … … 229 526 user_info->mapped.account_name, 230 527 false, false); 231 528 if (!NT_STATUS_IS_OK(nt_status)) { 529 TALLOC_FREE(tmp_ctx); 530 return nt_status; 531 } 532 533 nt_status = authsam_logon_success_accounting(auth_context->sam_ctx, 534 msg, domain_dn, 535 interactive); 536 if (!NT_STATUS_IS_OK(nt_status)) { 537 TALLOC_FREE(tmp_ctx); 538 return nt_status; 539 } 540 541 if (user_sess_key && user_sess_key->data) { 542 talloc_steal(mem_ctx, user_sess_key->data); 543 } 544 if (lm_sess_key && lm_sess_key->data) { 545 talloc_steal(mem_ctx, lm_sess_key->data); 546 } 547 548 TALLOC_FREE(tmp_ctx); 232 549 return nt_status; 233 550 } … … 340 657 return NT_STATUS_OK; 341 658 342 case ROLE_ DOMAIN_CONTROLLER:659 case ROLE_ACTIVE_DIRECTORY_DC: 343 660 if (!is_local_name && !is_my_domain) { 344 661 DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n", … … 356 673 /* Wrapper for the auth subsystem pointer */ 357 674 static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, 358 struct auth _context *auth_context,675 struct auth4_context *auth_context, 359 676 const char *principal, 360 677 struct ldb_dn *user_dn, … … 366 683 static const struct auth_operations sam_ignoredomain_ops = { 367 684 .name = "sam_ignoredomain", 368 .get_challenge = auth_get_challenge_not_implemented,369 685 .want_check = authsam_ignoredomain_want_check, 370 686 .check_password = authsam_check_password_internals, 371 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 687 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, 688 .flags = AUTH_METHOD_LOCAL_SAM 372 689 }; 373 690 374 691 static const struct auth_operations sam_ops = { 375 692 .name = "sam", 376 .get_challenge = auth_get_challenge_not_implemented,377 693 .want_check = authsam_want_check, 378 694 .check_password = authsam_check_password_internals, 379 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 695 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, 696 .flags = AUTH_METHOD_LOCAL_SAM 380 697 }; 381 698 382 _PUBLIC_ NTSTATUS auth_sam_init(void) 699 _PUBLIC_ NTSTATUS auth4_sam_init(void); 700 _PUBLIC_ NTSTATUS auth4_sam_init(void) 383 701 { 384 702 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/auth_simple.c
r740 r988 31 31 _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, 32 32 struct tevent_context *ev, 33 struct messaging_context *msg,33 struct imessaging_context *msg, 34 34 struct loadparm_context *lp_ctx, 35 35 const char *nt4_domain, … … 39 39 struct auth_session_info **session_info) 40 40 { 41 struct auth _context *auth_context;41 struct auth4_context *auth_context; 42 42 struct auth_usersupplied_info *user_info; 43 43 struct auth_user_info_dc *user_info_dc; … … 95 95 flags |= AUTH_SESSION_INFO_AUTHENTICATED; 96 96 } 97 nt_status = auth_context->generate_session_info(tmp_ctx, auth_context, 97 nt_status = auth_context->generate_session_info(auth_context, 98 tmp_ctx, 98 99 user_info_dc, 100 nt4_username, 99 101 flags, 100 102 session_info); -
vendor/current/source4/auth/ntlm/auth_unix.c
r740 r988 29 29 #include "param/param.h" 30 30 31 _PUBLIC_ NTSTATUS auth4_unix_init(void); 32 31 33 /* TODO: look at how to best fill in parms retrieveing a struct passwd info 32 34 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set … … 262 264 pam_error = pam_end(*pamh, 0); 263 265 if (pam_error != PAM_SUCCESS) { 264 /* no va ild pamh here, can we reliably call pam_strerror ? */266 /* no valid pamh here, can we reliably call pam_strerror ? */ 265 267 DEBUG(4,("smb_pam_start: clean up failed, pam_end gave error %d.\n", 266 268 pam_error)); … … 282 284 pam_error = pam_end(*pamh, 0); 283 285 if (pam_error != PAM_SUCCESS) { 284 /* no va ild pamh here, can we reliably call pam_strerror ? */286 /* no valid pamh here, can we reliably call pam_strerror ? */ 285 287 DEBUG(4,("smb_pam_start: clean up failed, pam_end gave error %d.\n", 286 288 pam_error)); … … 302 304 pam_error = pam_end(pamh, 0); 303 305 if (pam_error != PAM_SUCCESS) { 304 /* no va ild pamh here, can we reliably call pam_strerror ? */306 /* no valid pamh here, can we reliably call pam_strerror ? */ 305 307 DEBUG(4,("smb_pam_end: clean up failed, pam_end gave error %d.\n", 306 308 pam_error)); … … 512 514 bool ret; 513 515 514 #ifdef WITH_AFS 515 if (afs_auth(username, password)) 516 return NT_STATUS_OK; 517 #endif /* WITH_AFS */ 518 519 #ifdef WITH_DFS 520 if (dfs_auth(username, password)) 521 return NT_STATUS_OK; 522 #endif /* WITH_DFS */ 516 523 517 524 518 #ifdef OSF1_ENH_SEC … … 549 543 #endif /* ULTRIX_AUTH */ 550 544 551 #ifdef LINUX_BIGCRYPT 552 ret = (linux_bigcrypt(password, salt, crypted)); 553 if (ret) { 554 return NT_STATUS_OK; 555 } else { 556 return NT_STATUS_WRONG_PASSWORD; 557 } 558 #endif /* LINUX_BIGCRYPT */ 559 560 #if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS) 561 562 /* 563 * Some systems have bigcrypt in the C library but might not 564 * actually use it for the password hashes (HPUX 10.20) is 565 * a noteable example. So we try bigcrypt first, followed 566 * by crypt. 567 */ 568 569 if (strcmp(bigcrypt(password, salt), crypted) == 0) 570 return NT_STATUS_OK; 571 else 572 ret = (strcmp((char *)crypt(password, salt), crypted) == 0); 573 if (ret) { 574 return NT_STATUS_OK; 575 } else { 576 return NT_STATUS_WRONG_PASSWORD; 577 } 578 #else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */ 545 579 546 580 547 #ifdef HAVE_BIGCRYPT … … 598 565 } 599 566 #endif /* HAVE_CRYPT */ 600 #endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */601 567 } 602 568 … … 606 572 char *username; 607 573 char *password; 608 char *pwcopy;609 574 char *salt; 610 575 char *crypted; 611 576 struct passwd *pws; 612 577 NTSTATUS nt_status; 613 int level = lpcfg_passwordlevel(lp_ctx);614 578 615 579 *ret_passwd = NULL; … … 659 623 #endif 660 624 661 #ifdef HAVE_GETPRPWNAM662 {663 struct pr_passwd *pr_pw = getprpwnam(pws->pw_name);664 if (pr_pw && pr_pw->ufld.fd_encrypt) {665 crypted = talloc_strdup(ctx, pr_pw->ufld.fd_encrypt);666 NT_STATUS_HAVE_NO_MEMORY(crypted);667 }668 }669 #endif670 625 671 626 #ifdef HAVE_GETPWANAM … … 707 662 #endif 708 663 709 #if defined(HAVE_TRUNCATED_SALT)710 /* crypt on some platforms (HPUX in particular)711 won't work with more than 2 salt characters. */712 salt[2] = 0;713 #endif714 664 715 665 if (crypted[0] == '\0') { … … 736 686 } 737 687 738 if ( user_info->flags | USER_INFO_CASE_INSENSITIVE_PASSWORD) { 739 return nt_status; 740 } 741 742 /* if the password was given to us with mixed case then we don't 743 * need to proceed as we know it hasn't been case modified by the 744 * client */ 745 if (strhasupper(password) && strhaslower(password)) { 746 return nt_status; 747 } 748 749 /* make a copy of it */ 750 pwcopy = talloc_strdup(ctx, password); 751 if (!pwcopy) 752 return NT_STATUS_NO_MEMORY; 753 754 /* try all lowercase if it's currently all uppercase */ 755 if (strhasupper(pwcopy)) { 756 strlower(pwcopy); 757 nt_status = password_check(username, pwcopy, crypted, salt); 758 if NT_STATUS_IS_OK(nt_status) { 759 *ret_passwd = pws; 760 return nt_status; 761 } 762 } 763 764 /* give up? */ 765 if (level < 1) { 766 return NT_STATUS_WRONG_PASSWORD; 767 } 768 769 /* last chance - all combinations of up to level chars upper! */ 770 strlower(pwcopy); 771 772 #if 0 773 if (NT_STATUS_IS_OK(nt_status = string_combinations(pwcopy, password_check, level))) { 774 *ret_passwd = pws; 775 return nt_status; 776 } 777 #endif 688 /* we no longer try different case combinations here. The use 689 * of this code is now web auth, where trying different case 690 * combinations makes no sense 691 */ 692 778 693 return NT_STATUS_WRONG_PASSWORD; 779 694 } … … 833 748 static const struct auth_operations unix_ops = { 834 749 .name = "unix", 835 .get_challenge = auth_get_challenge_not_implemented,836 750 .want_check = authunix_want_check, 837 751 .check_password = authunix_check_password 838 752 }; 839 753 840 _PUBLIC_ NTSTATUS auth _unix_init(void)754 _PUBLIC_ NTSTATUS auth4_unix_init(void) 841 755 { 842 756 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/auth_util.c
r740 r988 26 26 #include "libcli/auth/libcli_auth.h" 27 27 #include "param/param.h" 28 #include "auth/ntlm/auth_proto.h" 29 #include "librpc/gen_ndr/drsuapi.h" 30 #include "dsdb/samdb/samdb.h" 28 31 29 32 /* this default function can be used by mostly all backends … … 39 42 Create an auth_usersupplied_data structure after appropriate mapping. 40 43 ****************************************************************************/ 41 42 NTSTATUS map_user_info(TALLOC_CTX *mem_ctx, 44 static NTSTATUS map_user_info_cracknames(struct ldb_context *sam_ctx, 45 TALLOC_CTX *mem_ctx, 46 const char *default_domain, 47 const struct auth_usersupplied_info *user_info, 48 struct auth_usersupplied_info **user_info_mapped) 49 { 50 char *domain; 51 char *account_name; 52 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 53 WERROR werr; 54 struct drsuapi_DsNameInfo1 info1; 55 56 DEBUG(5,("map_user_info_cracknames: Mapping user [%s]\\[%s] from workstation [%s]\n", 57 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); 58 59 account_name = talloc_strdup(tmp_ctx, user_info->client.account_name); 60 if (!account_name) { 61 talloc_free(tmp_ctx); 62 return NT_STATUS_NO_MEMORY; 63 } 64 65 /* use cracknames to work out what domain is being 66 asked for */ 67 if (strchr_m(user_info->client.account_name, '@') != NULL) { 68 werr = DsCrackNameOneName(sam_ctx, tmp_ctx, 0, 69 DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, 70 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, 71 user_info->client.account_name, 72 &info1); 73 if (!W_ERROR_IS_OK(werr)) { 74 DEBUG(2,("map_user_info: Failed cracknames of account '%s'\n", 75 user_info->client.account_name)); 76 talloc_free(tmp_ctx); 77 return werror_to_ntstatus(werr); 78 } 79 switch (info1.status) { 80 case DRSUAPI_DS_NAME_STATUS_OK: 81 break; 82 case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: 83 DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_FOUND\n", 84 user_info->client.account_name)); 85 talloc_free(tmp_ctx); 86 return NT_STATUS_NO_SUCH_USER; 87 case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: 88 DEBUG(2,("map_user_info: Cracknames of account '%s' -> DOMAIN_ONLY\n", 89 user_info->client.account_name)); 90 talloc_free(tmp_ctx); 91 return NT_STATUS_NO_SUCH_USER; 92 case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: 93 DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_UNIQUE\n", 94 user_info->client.account_name)); 95 talloc_free(tmp_ctx); 96 return NT_STATUS_NO_SUCH_USER; 97 case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: 98 DEBUG(2,("map_user_info: Cracknames of account '%s' -> RESOLVE_ERROR\n", 99 user_info->client.account_name)); 100 talloc_free(tmp_ctx); 101 return NT_STATUS_NO_SUCH_USER; 102 default: 103 DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n", 104 user_info->client.account_name, info1.status)); 105 talloc_free(tmp_ctx); 106 return NT_STATUS_NO_SUCH_USER; 107 } 108 /* info1.result_name is in DOMAIN\username 109 * form, which we need to split up into the 110 * user_info_mapped structure 111 */ 112 domain = talloc_strdup(tmp_ctx, info1.result_name); 113 if (domain == NULL) { 114 talloc_free(tmp_ctx); 115 return NT_STATUS_NO_MEMORY; 116 } 117 account_name = strchr_m(domain, '\\'); 118 if (account_name == NULL) { 119 DEBUG(2,("map_user_info: Cracknames of account '%s' gave invalid result '%s'\n", 120 user_info->client.account_name, info1.result_name)); 121 talloc_free(tmp_ctx); 122 return NT_STATUS_NO_SUCH_USER; 123 } 124 *account_name = 0; 125 account_name = talloc_strdup(tmp_ctx, account_name+1); 126 if (account_name == NULL) { 127 talloc_free(tmp_ctx); 128 return NT_STATUS_NO_MEMORY; 129 } 130 } else { 131 char *domain_name; 132 if (user_info->client.domain_name && *user_info->client.domain_name) { 133 domain_name = talloc_asprintf(tmp_ctx, "%s\\", user_info->client.domain_name); 134 } else { 135 domain_name = talloc_strdup(tmp_ctx, default_domain); 136 } 137 if (domain_name == NULL) { 138 talloc_free(tmp_ctx); 139 return NT_STATUS_NO_MEMORY; 140 } 141 werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0, 142 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, 143 DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, 144 domain_name, 145 &info1); 146 if (!W_ERROR_IS_OK(werr)) { 147 DEBUG(2,("map_user_info: Failed cracknames of domain '%s'\n", 148 domain_name)); 149 talloc_free(tmp_ctx); 150 return werror_to_ntstatus(werr); 151 } 152 153 /* we use the account_name as-is, but get the 154 * domain name from cracknames if possible */ 155 account_name = talloc_strdup(mem_ctx, user_info->client.account_name); 156 if (account_name == NULL) { 157 talloc_free(tmp_ctx); 158 return NT_STATUS_NO_MEMORY; 159 } 160 161 switch (info1.status) { 162 case DRSUAPI_DS_NAME_STATUS_OK: 163 case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: 164 domain = talloc_strdup(tmp_ctx, info1.result_name); 165 if (domain == NULL) { 166 talloc_free(tmp_ctx); 167 return NT_STATUS_NO_MEMORY; 168 } 169 if (domain[strlen_m(domain)-1] == '\\') { 170 domain[strlen_m(domain)-1] = 0; 171 } 172 break; 173 case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: 174 /* the domain is unknown - use the 175 default domain */ 176 domain = talloc_strdup(tmp_ctx, default_domain); 177 break; 178 case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: 179 DEBUG(2,("map_user_info: Cracknames of domain '%s' -> NOT_UNIQUE\n", 180 domain_name)); 181 talloc_free(tmp_ctx); 182 return NT_STATUS_NO_SUCH_USER; 183 case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: 184 DEBUG(2,("map_user_info: Cracknames of domain '%s' -> RESOLVE_ERROR\n", 185 domain_name)); 186 talloc_free(tmp_ctx); 187 return NT_STATUS_NO_SUCH_USER; 188 default: 189 DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n", 190 domain_name, info1.status)); 191 talloc_free(tmp_ctx); 192 return NT_STATUS_NO_SUCH_USER; 193 } 194 /* domain and account_name are filled in above */ 195 } 196 197 *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); 198 if (!*user_info_mapped) { 199 talloc_free(tmp_ctx); 200 return NT_STATUS_NO_MEMORY; 201 } 202 if (!talloc_reference(*user_info_mapped, user_info)) { 203 talloc_free(tmp_ctx); 204 return NT_STATUS_NO_MEMORY; 205 } 206 **user_info_mapped = *user_info; 207 (*user_info_mapped)->mapped_state = true; 208 (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain); 209 (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name); 210 talloc_free(tmp_ctx); 211 if (!(*user_info_mapped)->mapped.domain_name 212 || !(*user_info_mapped)->mapped.account_name) { 213 return NT_STATUS_NO_MEMORY; 214 } 215 216 return NT_STATUS_OK; 217 } 218 219 220 /**************************************************************************** 221 Create an auth_usersupplied_data structure after appropriate mapping. 222 ****************************************************************************/ 223 NTSTATUS map_user_info(struct ldb_context *sam_ctx, 224 TALLOC_CTX *mem_ctx, 43 225 const char *default_domain, 44 226 const struct auth_usersupplied_info *user_info, 45 227 struct auth_usersupplied_info **user_info_mapped) 46 228 { 47 c onst char *domain;229 char *domain; 48 230 char *account_name; 49 231 char *d; 50 DEBUG(5,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s]\n", 51 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); 52 53 account_name = talloc_strdup(mem_ctx, user_info->client.account_name); 232 TALLOC_CTX *tmp_ctx; 233 234 if (sam_ctx != NULL) { 235 /* if possible, use cracknames to parse the 236 domain/account */ 237 return map_user_info_cracknames(sam_ctx, mem_ctx, default_domain, user_info, user_info_mapped); 238 } 239 240 DEBUG(0,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s] default_domain=%s\n", 241 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name, 242 default_domain)); 243 244 tmp_ctx = talloc_new(mem_ctx); 245 246 account_name = talloc_strdup(tmp_ctx, user_info->client.account_name); 54 247 if (!account_name) { 248 talloc_free(tmp_ctx); 55 249 return NT_STATUS_NO_MEMORY; 56 250 } 57 251 58 /* don't allow "" as a domain, fixes a Win9X bug 59 where it doesn't supply a domain for logon script 60 'net use' commands. */ 61 62 /* Split user@realm names into user and realm components. This is TODO to fix with proper userprincipalname support */ 252 /* don't allow "" as a domain, fixes a Win9X bug where it 253 doesn't supply a domain for logon script 'net use' 254 commands. */ 255 256 /* Split user@realm names into user and realm components. 257 * This is TODO to fix with proper userprincipalname 258 * support */ 63 259 if (user_info->client.domain_name && *user_info->client.domain_name) { 64 domain = user_info->client.domain_name;260 domain = talloc_strdup(tmp_ctx, user_info->client.domain_name); 65 261 } else if (strchr_m(user_info->client.account_name, '@')) { 66 262 d = strchr_m(account_name, '@'); 67 263 if (!d) { 264 talloc_free(tmp_ctx); 68 265 return NT_STATUS_INTERNAL_ERROR; 69 266 } … … 72 269 domain = d; 73 270 } else { 74 domain = default_domain; 75 } 76 271 domain = talloc_strdup(tmp_ctx, default_domain); 272 } 273 274 if (domain == NULL) { 275 talloc_free(tmp_ctx); 276 return NT_STATUS_NO_MEMORY; 277 } 77 278 *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); 78 279 if (!*user_info_mapped) { 280 talloc_free(tmp_ctx); 79 281 return NT_STATUS_NO_MEMORY; 80 282 } 81 283 if (!talloc_reference(*user_info_mapped, user_info)) { 284 talloc_free(tmp_ctx); 82 285 return NT_STATUS_NO_MEMORY; 83 286 } … … 86 289 (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain); 87 290 (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name); 88 talloc_free( account_name);291 talloc_free(tmp_ctx); 89 292 if (!(*user_info_mapped)->mapped.domain_name 90 293 || !(*user_info_mapped)->mapped.account_name) { … … 99 302 ****************************************************************************/ 100 303 101 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth _context *auth_context,304 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, 102 305 enum auth_password_state to_state, 103 306 const struct auth_usersupplied_info *user_info_in, … … 148 351 user_info_in->client.account_name, 149 352 user_info_in->client.domain_name, 150 user_info_in->password.hash.nt->hash, &chall_blob, 353 user_info_in->password.hash.nt->hash, 354 &chall_blob, 355 NULL, /* server_timestamp */ 151 356 &names_blob, 152 357 &lmv2_response, &ntlmv2_response, -
vendor/current/source4/auth/ntlm/auth_winbind.c
r740 r988 25 25 #include "auth/auth.h" 26 26 #include "auth/ntlm/auth_proto.h" 27 #include "auth/auth_sam_reply.h"28 27 #include "librpc/gen_ndr/ndr_winbind_c.h" 29 28 #include "lib/messaging/irpc.h" 30 29 #include "param/param.h" 31 30 #include "nsswitch/libwbclient/wbclient.h" 31 #include "auth/auth_sam_reply.h" 32 32 #include "libcli/security/security.h" 33 33 34 static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, 35 struct wbcAuthUserInfo *info, 36 struct netr_SamInfo3 *info3) 37 { 38 int i, j; 39 struct samr_RidWithAttribute *rids = NULL; 40 struct dom_sid *user_sid; 41 struct dom_sid *group_sid; 42 43 user_sid = (struct dom_sid *)(void *)&info->sids[0].sid; 44 group_sid = (struct dom_sid *)(void *)&info->sids[1].sid; 45 46 info3->base.last_logon = info->logon_time; 47 info3->base.last_logoff = info->logoff_time; 48 info3->base.acct_expiry = info->kickoff_time; 49 info3->base.last_password_change = info->pass_last_set_time; 50 info3->base.allow_password_change = info->pass_can_change_time; 51 info3->base.force_password_change = info->pass_must_change_time; 52 53 info3->base.account_name.string = talloc_strdup(mem_ctx, 54 info->account_name); 55 info3->base.full_name.string = talloc_strdup(mem_ctx, 56 info->full_name); 57 info3->base.logon_script.string = talloc_strdup(mem_ctx, 58 info->logon_script); 59 info3->base.profile_path.string = talloc_strdup(mem_ctx, 60 info->profile_path); 61 info3->base.home_directory.string = talloc_strdup(mem_ctx, 62 info->home_directory); 63 info3->base.home_drive.string = talloc_strdup(mem_ctx, 64 info->home_drive); 65 info3->base.logon_server.string = talloc_strdup(mem_ctx, 66 info->logon_server); 67 info3->base.domain.string = talloc_strdup(mem_ctx, 68 info->domain_name); 69 70 info3->base.logon_count = info->logon_count; 71 info3->base.bad_password_count = info->bad_password_count; 72 info3->base.user_flags = info->user_flags; 73 memcpy(info3->base.key.key, info->user_session_key, 74 sizeof(info3->base.key.key)); 75 memcpy(info3->base.LMSessKey.key, info->lm_session_key, 76 sizeof(info3->base.LMSessKey.key)); 77 info3->base.acct_flags = info->acct_flags; 78 memset(info3->base.unknown, 0, sizeof(info3->base.unknown)); 79 80 if (info->num_sids < 2) { 81 return NT_STATUS_INVALID_PARAMETER; 82 } 83 84 dom_sid_split_rid(mem_ctx, user_sid, 85 &info3->base.domain_sid, 86 &info3->base.rid); 87 dom_sid_split_rid(mem_ctx, group_sid, NULL, 88 &info3->base.primary_gid); 89 90 /* We already handled the first two, now take care of the rest */ 91 info3->base.groups.count = info->num_sids - 2; 92 93 rids = talloc_array(mem_ctx, struct samr_RidWithAttribute, 94 info3->base.groups.count); 95 NT_STATUS_HAVE_NO_MEMORY(rids); 96 97 for (i = 2, j = 0; i < info->num_sids; ++i, ++j) { 98 struct dom_sid *tmp_sid; 99 tmp_sid = (struct dom_sid *)(void *)&info->sids[1].sid; 100 101 rids[j].attributes = info->sids[i].attributes; 102 dom_sid_split_rid(mem_ctx, tmp_sid, 103 NULL, &rids[j].rid); 104 } 105 info3->base.groups.rids = rids; 106 107 return NT_STATUS_OK; 108 } 109 34 _PUBLIC_ NTSTATUS auth4_winbind_init(void); 110 35 111 36 static NTSTATUS winbind_want_check(struct auth_method_context *ctx, … … 212 137 s->req.in.validation_level = 3; 213 138 139 /* Note: this makes use of nested event loops... */ 140 dcerpc_binding_handle_set_sync_ev(irpc_handle, ctx->auth_ctx->event_ctx); 214 141 status = dcerpc_winbind_SamLogon_r(irpc_handle, s, &s->req); 215 142 NT_STATUS_NOT_OK_RETURN(status); … … 219 146 s->req.in.validation_level, 220 147 &s->req.out.validation, 148 true, /* This user was authenticated */ 221 149 user_info_dc); 222 150 NT_STATUS_NOT_OK_RETURN(status); … … 239 167 wbcErr wbc_status; 240 168 NTSTATUS nt_status; 241 struct netr_SamInfo3 info3;169 struct netr_SamInfo3 *info3; 242 170 union netr_Validation validation; 243 171 … … 266 194 params.workstation_name = user_info->workstation_name; 267 195 268 d_fprintf(stderr,"looking up %s@%s logging in from %s\n",196 DEBUG(5,("looking up %s@%s logging in from %s\n", 269 197 params.account_name, params.domain_name, 270 params.workstation_name) ;198 params.workstation_name)); 271 199 272 200 memcpy(params.password.response.challenge, … … 286 214 wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); 287 215 if (wbc_status == WBC_ERR_AUTH_ERROR) { 288 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 289 err->nt_string, err->nt_status, err->display_string)); 290 216 if (err) { 217 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 218 err->nt_string, err->nt_status, err->display_string)); 219 } 291 220 nt_status = NT_STATUS(err->nt_status); 292 221 wbcFreeMemory(err); … … 295 224 DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n", 296 225 wbc_status, wbcErrorString(wbc_status))); 226 if (err) { 227 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 228 err->nt_string, err->nt_status, err->display_string)); 229 } 297 230 return NT_STATUS_LOGON_FAILURE; 298 231 } 299 nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, info, &info3);232 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info); 300 233 wbcFreeMemory(info); 301 NT_STATUS_NOT_OK_RETURN(nt_status); 302 303 validation.sam3 = &info3; 234 if (!info3) { 235 DEBUG(1, ("wbcAuthUserInfo_to_netr_SamInfo3 failed\n")); 236 return NT_STATUS_NO_MEMORY; 237 } 238 239 validation.sam3 = info3; 304 240 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 305 user_info->client.account_name, 306 3, &validation, user_info_dc); 241 user_info->client.account_name, 242 3, &validation, 243 true, /* This user was authenticated */ 244 user_info_dc); 307 245 return nt_status; 308 246 … … 311 249 static const struct auth_operations winbind_ops = { 312 250 .name = "winbind", 313 .get_challenge = auth_get_challenge_not_implemented,314 251 .want_check = winbind_want_check, 315 252 .check_password = winbind_check_password … … 318 255 static const struct auth_operations winbind_wbclient_ops = { 319 256 .name = "winbind_wbclient", 320 .get_challenge = auth_get_challenge_not_implemented,321 257 .want_check = winbind_want_check, 322 258 .check_password = winbind_check_password_wbclient 323 259 }; 324 260 325 _PUBLIC_ NTSTATUS auth _winbind_init(void)261 _PUBLIC_ NTSTATUS auth4_winbind_init(void) 326 262 { 327 263 NTSTATUS ret; -
vendor/current/source4/auth/ntlm/wscript_build
r740 r988 4 4 source='auth_sam.c', 5 5 subsystem='auth4', 6 init_function='auth _sam_init',7 deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig '6 init_function='auth4_sam_init', 7 deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig RPC_NDR_IRPC MESSAGING' 8 8 ) 9 9 … … 12 12 source='auth_anonymous.c', 13 13 subsystem='auth4', 14 init_function='auth _anonymous_init',14 init_function='auth4_anonymous_init', 15 15 deps='talloc' 16 )17 18 19 bld.SAMBA_MODULE('auth4_server',20 source='auth_server.c',21 subsystem='auth4',22 init_function='auth_server_init',23 deps='samba-util LIBCLI_SMB CREDENTIALS_NTLM'24 16 ) 25 17 … … 28 20 source='auth_winbind.c', 29 21 subsystem='auth4', 30 init_function='auth _winbind_init',22 init_function='auth4_winbind_init', 31 23 deps='RPC_NDR_WINBIND MESSAGING wbclient' 32 24 ) … … 36 28 source='auth_developer.c', 37 29 subsystem='auth4', 38 init_function='auth _developer_init',30 init_function='auth4_developer_init', 39 31 deps='talloc' 40 32 ) … … 44 36 source='auth_unix.c', 45 37 subsystem='auth4', 46 init_function='auth _unix_init',38 init_function='auth4_unix_init', 47 39 deps='pam PAM_ERRORS LIBTSOCKET' 48 40 ) … … 52 44 source='auth.c auth_util.c auth_simple.c', 53 45 autoproto='auth_proto.h', 54 deps='samba-util s ecurity samdb credentials UTIL_TEVENT',46 deps='samba-util samba-security samdb samba-credentials tevent-util LIBWBCLIENT_OLD auth_unix_token samba-modules KERBEROS_UTIL', 55 47 private_library=True 56 48 ) -
vendor/current/source4/auth/pyauth.c
r740 r988 31 31 #include <tevent.h> 32 32 #include "librpc/rpc/pyrpc_util.h" 33 #include "lib/events/events.h" 34 35 void initauth(void); 33 36 34 37 staticforward PyTypeObject PyAuthContext; 35 38 36 /* There's no Py_ssize_t in 2.4, apparently */ 37 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 38 typedef int Py_ssize_t; 39 typedef inquiry lenfunc; 40 typedef intargfunc ssizeargfunc; 41 #endif 42 43 #ifndef Py_RETURN_NONE 44 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None 45 #endif 46 47 static PyObject *py_auth_session_get_security_token(PyObject *self, void *closure) 48 { 49 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 50 PyObject *py_security_token; 51 py_security_token = py_return_ndr_struct("samba.dcerpc.security", "token", 52 session->security_token, session->security_token); 53 return py_security_token; 54 } 55 56 static int py_auth_session_set_security_token(PyObject *self, PyObject *value, void *closure) 57 { 58 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 59 session->security_token = talloc_reference(session, py_talloc_get_ptr(value)); 60 return 0; 61 } 62 63 static PyObject *py_auth_session_get_session_key(PyObject *self, void *closure) 64 { 65 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 66 return PyString_FromStringAndSize((char *)session->session_key.data, session->session_key.length); 67 } 68 69 static int py_auth_session_set_session_key(PyObject *self, PyObject *value, void *closure) 70 { 71 DATA_BLOB val; 72 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 73 val.data = (uint8_t *)PyString_AsString(value); 74 val.length = PyString_Size(value); 75 76 session->session_key = data_blob_talloc(session, val.data, val.length); 77 return 0; 78 } 79 80 static PyObject *py_auth_session_get_credentials(PyObject *self, void *closure) 81 { 82 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 83 PyObject *py_credentials; 84 /* This is evil, as the credentials are not IDL structures */ 85 py_credentials = py_return_ndr_struct("samba.credentials", "Credentials", session->credentials, session->credentials); 86 return py_credentials; 87 } 88 89 static int py_auth_session_set_credentials(PyObject *self, PyObject *value, void *closure) 90 { 91 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 92 session->credentials = talloc_reference(session, PyCredentials_AsCliCredentials(value)); 93 return 0; 94 } 95 96 static PyGetSetDef py_auth_session_getset[] = { 97 { discard_const_p(char, "security_token"), (getter)py_auth_session_get_security_token, (setter)py_auth_session_set_security_token, NULL }, 98 { discard_const_p(char, "session_key"), (getter)py_auth_session_get_session_key, (setter)py_auth_session_set_session_key, NULL }, 99 { discard_const_p(char, "credentials"), (getter)py_auth_session_get_credentials, (setter)py_auth_session_set_credentials, NULL }, 100 { NULL } 101 }; 102 103 static PyTypeObject PyAuthSession = { 104 .tp_name = "AuthSession", 105 .tp_basicsize = sizeof(py_talloc_Object), 106 .tp_flags = Py_TPFLAGS_DEFAULT, 107 .tp_getset = py_auth_session_getset, 108 }; 109 110 PyObject *PyAuthSession_FromSession(struct auth_session_info *session) 111 { 112 return py_talloc_reference(&PyAuthSession, session); 39 static PyObject *PyAuthSession_FromSession(struct auth_session_info *session) 40 { 41 return py_return_ndr_struct("samba.dcerpc.auth", "session_info", session, session); 113 42 } 114 43 … … 208 137 } 209 138 210 ldb_ctx = PyLdb_AsLdbContext(py_ldb);139 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); 211 140 212 141 if (py_dn == Py_None) { 213 142 user_dn = NULL; 214 143 } else { 215 if (! PyObject_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) {144 if (!pyldb_Object_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) { 216 145 talloc_free(mem_ctx); 217 146 return NULL; … … 267 196 } 268 197 269 static PyObject *PyAuthContext_FromContext(struct auth _context *auth_context)270 { 271 return py _talloc_reference(&PyAuthContext, auth_context);198 static PyObject *PyAuthContext_FromContext(struct auth4_context *auth_context) 199 { 200 return pytalloc_reference(&PyAuthContext, auth_context); 272 201 } 273 202 … … 276 205 PyObject *py_lp_ctx = Py_None; 277 206 PyObject *py_ldb = Py_None; 278 PyObject *py_ messaging_ctx = Py_None;207 PyObject *py_imessaging_ctx = Py_None; 279 208 PyObject *py_auth_context = Py_None; 280 209 PyObject *py_methods = Py_None; 281 210 TALLOC_CTX *mem_ctx; 282 struct auth _context *auth_context;283 struct messaging_context *messaging_context = NULL;211 struct auth4_context *auth_context; 212 struct imessaging_context *imessaging_context = NULL; 284 213 struct loadparm_context *lp_ctx; 285 214 struct tevent_context *ev; 286 struct ldb_context *ldb ;215 struct ldb_context *ldb = NULL; 287 216 NTSTATUS nt_status; 288 217 const char **methods; … … 292 221 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", 293 222 discard_const_p(char *, kwnames), 294 &py_lp_ctx, &py_ messaging_ctx, &py_ldb, &py_methods))223 &py_lp_ctx, &py_imessaging_ctx, &py_ldb, &py_methods)) 295 224 return NULL; 296 225 … … 302 231 303 232 if (py_ldb != Py_None) { 304 ldb = PyLdb_AsLdbContext(py_ldb);233 ldb = pyldb_Ldb_AsLdbContext(py_ldb); 305 234 } 306 235 307 236 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 308 309 ev = tevent_context_init(mem_ctx); 237 if (lp_ctx == NULL) { 238 PyErr_NoMemory(); 239 return NULL; 240 } 241 242 ev = s4_event_context_init(mem_ctx); 310 243 if (ev == NULL) { 311 244 PyErr_NoMemory(); … … 313 246 } 314 247 315 if (py_ messaging_ctx != Py_None) {316 messaging_context = py_talloc_get_type(py_messaging_ctx, structmessaging_context);248 if (py_imessaging_ctx != Py_None) { 249 imessaging_context = pytalloc_get_type(py_imessaging_ctx, struct imessaging_context); 317 250 } 318 251 319 252 if (py_methods == Py_None && py_ldb == Py_None) { 320 nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context);253 nt_status = auth_context_create(mem_ctx, ev, imessaging_context, lp_ctx, &auth_context); 321 254 } else { 322 255 if (py_methods != Py_None) { … … 330 263 } 331 264 nt_status = auth_context_create_methods(mem_ctx, methods, ev, 332 messaging_context, lp_ctx,265 imessaging_context, lp_ctx, 333 266 ldb, &auth_context); 334 267 } … … 360 293 static PyTypeObject PyAuthContext = { 361 294 .tp_name = "AuthContext", 362 .tp_basicsize = sizeof(py_talloc_Object),363 295 .tp_flags = Py_TPFLAGS_DEFAULT, 364 296 .tp_new = py_auth_context_new, 365 .tp_basicsize = sizeof(py_talloc_Object),366 297 }; 367 298 … … 377 308 PyObject *m; 378 309 379 PyAuthSession.tp_base = PyTalloc_GetObjectType(); 380 if (PyAuthSession.tp_base == NULL) 381 return; 382 383 if (PyType_Ready(&PyAuthSession) < 0) 384 return; 385 386 PyAuthContext.tp_base = PyTalloc_GetObjectType(); 387 if (PyAuthContext.tp_base == NULL) 388 return; 389 390 if (PyType_Ready(&PyAuthContext) < 0) 310 if (pytalloc_BaseObject_PyType_Ready(&PyAuthContext) < 0) 391 311 return; 392 312 … … 396 316 return; 397 317 398 Py_INCREF(&PyAuthSession);399 PyModule_AddObject(m, "AuthSession", (PyObject *)&PyAuthSession);400 318 Py_INCREF(&PyAuthContext); 401 319 PyModule_AddObject(m, "AuthContext", (PyObject *)&PyAuthContext); -
vendor/current/source4/auth/pyauth.h
r740 r988 24 24 #include "auth/session.h" 25 25 26 #define PyAuthSession_AsSession(obj) py_talloc_get_type(obj, struct auth_session_info) 27 #define PyAuthSession_Check(obj) PyObject_TypeCheck(obj, &PyAuthSession) 26 #define PyAuthSession_AsSession(obj) pytalloc_get_type(obj, struct auth_session_info) 28 27 struct auth_session_info *PyObject_AsSession(PyObject *obj); 29 PyObject *PyAuthSession_FromSession(struct auth_session_info *session);30 28 31 29 #endif /* _PYAUTH_H */ -
vendor/current/source4/auth/sam.c
r740 r988 42 42 "msDS-SupportedEncryptionTypes", \ 43 43 "supplementalCredentials", \ 44 "msDS-AllowedToDelegateTo", \ 44 45 \ 45 46 /* passwords */ \ … … 47 48 "unicodePwd", \ 48 49 \ 49 "userAccountControl", \ 50 "userAccountControl", \ 51 "msDS-User-Account-Control-Computed", \ 50 52 "objectSid", \ 51 53 \ … … 65 67 66 68 "logonHours", 69 70 /* 71 * To allow us to zero the badPwdCount and lockoutTime on 72 * successful logon, without database churn 73 */ 74 "lockoutTime", 67 75 68 76 /* check 'allowed workstations' */ … … 76 84 "homeDrive", 77 85 "lastLogon", 86 "lastLogonTimestamp", 78 87 "lastLogoff", 79 88 "accountExpires", … … 82 91 "primaryGroupID", 83 92 "memberOf", 93 "badPasswordTime", 94 "lmPwdHistory", 95 "ntPwdHistory", 84 96 NULL, 85 97 }; … … 165 177 NTTIME acct_expiry; 166 178 NTTIME must_change_time; 167 168 NTTIME now; 179 struct timeval tv_now = timeval_current(); 180 NTTIME now = timeval_to_nttime(&tv_now); 181 169 182 DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs)); 170 183 171 acct_flags = samdb_result_acct_flags( sam_ctx, mem_ctx, msg, domain_dn);184 acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed"); 172 185 173 186 acct_expiry = samdb_result_account_expires(msg); … … 193 206 194 207 /* Test account expire time */ 195 unix_to_nt_time(&now, time(NULL));196 208 if (now > acct_expiry) { 197 209 DEBUG(2,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs)); … … 221 233 bool invalid_ws = true; 222 234 int i; 223 c onst char **workstations = (const char **)str_list_make(mem_ctx, workstation_list, ",");224 235 char **workstations = str_list_make(mem_ctx, workstation_list, ","); 236 225 237 for (i = 0; workstations && workstations[i]; i++) { 226 238 DEBUG(10,("sam_account_ok: checking for workstation match '%s' and '%s'\n", … … 298 310 299 311 tmp_ctx = talloc_new(user_info_dc); 300 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc); 312 if (user_info_dc == NULL) { 313 TALLOC_FREE(user_info_dc); 314 return NT_STATUS_NO_MEMORY; 315 } 301 316 302 317 sids = talloc_array(user_info_dc, struct dom_sid, 2); 303 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc); 318 if (sids == NULL) { 319 TALLOC_FREE(user_info_dc); 320 return NT_STATUS_NO_MEMORY; 321 } 304 322 305 323 num_sids = 2; 306 324 307 325 account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid"); 308 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc); 326 if (account_sid == NULL) { 327 TALLOC_FREE(user_info_dc); 328 return NT_STATUS_NO_MEMORY; 329 } 309 330 310 331 status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL); … … 322 343 * on SamLogon validation info */ 323 344 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED); 324 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc); 345 if (filter == NULL) { 346 TALLOC_FREE(user_info_dc); 347 return NT_STATUS_NO_MEMORY; 348 } 325 349 326 350 primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]); 327 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc); 351 if (primary_group_string == NULL) { 352 TALLOC_FREE(user_info_dc); 353 return NT_STATUS_NO_MEMORY; 354 } 328 355 329 356 primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string); 330 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc); 357 if (primary_group_dn == NULL) { 358 TALLOC_FREE(user_info_dc); 359 return NT_STATUS_NO_MEMORY; 360 } 331 361 332 362 primary_group_blob = data_blob_string_const(primary_group_dn); … … 372 402 373 403 info->domain_name = talloc_strdup(info, domain_name); 374 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name, 375 user_info_dc); 404 if (info->domain_name == NULL) { 405 TALLOC_FREE(user_info_dc); 406 return NT_STATUS_NO_MEMORY; 407 } 376 408 377 409 str = ldb_msg_find_attr_as_string(msg, "displayName", ""); 378 410 info->full_name = talloc_strdup(info, str); 379 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc); 411 if (info->full_name == NULL) { 412 TALLOC_FREE(user_info_dc); 413 return NT_STATUS_NO_MEMORY; 414 } 380 415 381 416 str = ldb_msg_find_attr_as_string(msg, "scriptPath", ""); 382 417 info->logon_script = talloc_strdup(info, str); 383 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script, 384 user_info_dc); 418 if (info->logon_script == NULL) { 419 TALLOC_FREE(user_info_dc); 420 return NT_STATUS_NO_MEMORY; 421 } 385 422 386 423 str = ldb_msg_find_attr_as_string(msg, "profilePath", ""); 387 424 info->profile_path = talloc_strdup(info, str); 388 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path, 389 user_info_dc); 425 if (info->profile_path == NULL) { 426 TALLOC_FREE(user_info_dc); 427 return NT_STATUS_NO_MEMORY; 428 } 390 429 391 430 str = ldb_msg_find_attr_as_string(msg, "homeDirectory", ""); 392 431 info->home_directory = talloc_strdup(info, str); 393 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory, 394 user_info_dc); 432 if (info->home_directory == NULL) { 433 TALLOC_FREE(user_info_dc); 434 return NT_STATUS_NO_MEMORY; 435 } 395 436 396 437 str = ldb_msg_find_attr_as_string(msg, "homeDrive", ""); 397 438 info->home_drive = talloc_strdup(info, str); 398 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc); 439 if (info->home_drive == NULL) { 440 TALLOC_FREE(user_info_dc); 441 return NT_STATUS_NO_MEMORY; 442 } 399 443 400 444 info->logon_server = talloc_strdup(info, netbios_name); 401 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server, 402 user_info_dc); 445 if (info->logon_server == NULL) { 446 TALLOC_FREE(user_info_dc); 447 return NT_STATUS_NO_MEMORY; 448 } 403 449 404 450 info->last_logon = samdb_result_nttime(msg, "lastLogon", 0); … … 417 463 0); 418 464 419 info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, 420 msg, domain_dn); 465 info->acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed"); 421 466 422 467 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, … … 424 469 user_sess_key.length); 425 470 if (user_sess_key.data) { 426 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data, 427 user_info_dc); 471 if (user_info_dc->user_session_key.data == NULL) { 472 TALLOC_FREE(user_info_dc); 473 return NT_STATUS_NO_MEMORY; 474 } 428 475 } 429 476 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, … … 431 478 lm_sess_key.length); 432 479 if (lm_sess_key.data) { 433 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data, 434 user_info_dc); 480 if (user_info_dc->lm_session_key.data == NULL) { 481 TALLOC_FREE(user_info_dc); 482 return NT_STATUS_NO_MEMORY; 483 } 435 484 } 436 485 … … 442 491 struct dom_sid, 443 492 user_info_dc->num_sids+1); 444 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc); 493 if (user_info_dc->sids == NULL) { 494 TALLOC_FREE(user_info_dc); 495 return NT_STATUS_NO_MEMORY; 496 } 445 497 user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs; 446 498 user_info_dc->num_sids++; … … 454 506 struct dom_sid, 455 507 user_info_dc->num_sids+1); 456 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc); 508 if (user_info_dc->sids == NULL) { 509 TALLOC_FREE(user_info_dc); 510 return NT_STATUS_NO_MEMORY; 511 } 457 512 user_info_dc->sids[user_info_dc->num_sids] = *domain_sid; 458 513 sid_append_rid(&user_info_dc->sids[user_info_dc->num_sids], … … 493 548 /* pull the user attributes */ 494 549 ret = dsdb_search_one(sam_ctx, tmp_ctx, msg, user_dn, 495 LDB_SCOPE_BASE, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)"); 550 LDB_SCOPE_BASE, attrs, 551 DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG, 552 "(objectClass=*)"); 496 553 if (ret != LDB_SUCCESS) { 497 554 talloc_free(tmp_ctx); … … 540 597 /* pull the user attributes */ 541 598 ret = dsdb_search_one(sam_ctx, tmp_ctx, &msg, user_dn, 542 LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)"); 599 LDB_SCOPE_BASE, user_attrs, 600 DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG, 601 "(objectClass=*)"); 543 602 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 544 603 talloc_free(tmp_ctx); … … 586 645 return NT_STATUS_OK; 587 646 } 647 648 NTSTATUS authsam_update_bad_pwd_count(struct ldb_context *sam_ctx, 649 struct ldb_message *msg, 650 struct ldb_dn *domain_dn) 651 { 652 const char *attrs[] = { "lockoutThreshold", 653 "lockOutObservationWindow", 654 "lockoutDuration", 655 "pwdProperties", 656 NULL }; 657 int ret; 658 NTSTATUS status; 659 struct ldb_result *domain_res; 660 struct ldb_message *msg_mod = NULL; 661 TALLOC_CTX *mem_ctx; 662 663 mem_ctx = talloc_new(msg); 664 if (mem_ctx == NULL) { 665 return NT_STATUS_NO_MEMORY; 666 } 667 668 ret = dsdb_search_dn(sam_ctx, mem_ctx, &domain_res, domain_dn, attrs, 0); 669 if (ret != LDB_SUCCESS) { 670 TALLOC_FREE(mem_ctx); 671 return NT_STATUS_INTERNAL_DB_CORRUPTION; 672 } 673 674 status = dsdb_update_bad_pwd_count(mem_ctx, sam_ctx, 675 msg, domain_res->msgs[0], &msg_mod); 676 if (!NT_STATUS_IS_OK(status)) { 677 TALLOC_FREE(mem_ctx); 678 return status; 679 } 680 681 if (msg_mod != NULL) { 682 ret = dsdb_modify(sam_ctx, msg_mod, 0); 683 if (ret != LDB_SUCCESS) { 684 DEBUG(0, ("Failed to update badPwdCount, badPasswordTime or set lockoutTime on %s: %s\n", 685 ldb_dn_get_linearized(msg_mod->dn), ldb_errstring(sam_ctx))); 686 TALLOC_FREE(mem_ctx); 687 return NT_STATUS_INTERNAL_ERROR; 688 } 689 } 690 691 TALLOC_FREE(mem_ctx); 692 return NT_STATUS_OK; 693 } 694 695 696 static NTSTATUS authsam_update_lastlogon_timestamp(struct ldb_context *sam_ctx, 697 struct ldb_message *msg_mod, 698 struct ldb_dn *domain_dn, 699 NTTIME old_timestamp, 700 NTTIME now) 701 { 702 /* 703 * We only set lastLogonTimestamp if the current value is older than 704 * now - msDS-LogonTimeSyncInterval days. 705 * 706 * msDS-LogonTimeSyncInterval is an int32_t number of days, while 707 * lastLogonTimestamp is in the 64 bit 100ns NTTIME format. 708 * 709 * The docs say: "the initial update, after the domain functional 710 * level is raised to DS_BEHAVIOR_WIN2003 or higher, is calculated as 711 * 14 days minus a random percentage of 5 days", but we aren't doing 712 * that. The blogosphere seems to think that this randomised update 713 * happens everytime, but [MS-ADA1] doesn't agree. 714 * 715 * Dochelp referred us to the following blog post: 716 * http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx 717 * 718 * en msDS-LogonTimeSyncInterval is zero, the lastLogonTimestamp is 719 * not changed. 720 */ 721 static const char *attrs[] = { "msDS-LogonTimeSyncInterval", 722 NULL }; 723 int ret; 724 struct ldb_result *domain_res = NULL; 725 TALLOC_CTX *mem_ctx = NULL; 726 int32_t sync_interval; 727 NTTIME sync_interval_nt; 728 729 mem_ctx = talloc_new(msg_mod); 730 if (mem_ctx == NULL) { 731 return NT_STATUS_NO_MEMORY; 732 } 733 734 ret = dsdb_search_dn(sam_ctx, mem_ctx, &domain_res, domain_dn, attrs, 735 0); 736 if (ret != LDB_SUCCESS || domain_res->count != 1) { 737 TALLOC_FREE(mem_ctx); 738 return NT_STATUS_INTERNAL_DB_CORRUPTION; 739 } 740 741 sync_interval = ldb_msg_find_attr_as_int(domain_res->msgs[0], 742 "msDS-LogonTimeSyncInterval", 743 14); 744 DEBUG(5, ("sync interval is %d\n", sync_interval)); 745 if (sync_interval == 0){ 746 /* 747 * Setting msDS-LogonTimeSyncInterval to zero is how you ask 748 * that nothing happens here. 749 */ 750 TALLOC_FREE(mem_ctx); 751 return NT_STATUS_OK; 752 } 753 else if (sync_interval >= 5){ 754 /* 755 * Subtract "a random percentage of 5" days. Presumably this 756 * percentage is between 0 and 100, and modulus is accurate 757 * enough. 758 */ 759 uint32_t r = generate_random() % 6; 760 sync_interval -= r; 761 DEBUG(5, ("randomised sync interval is %d (-%d)\n", sync_interval, r)); 762 } 763 /* In the case where sync_interval < 5 there is no randomisation */ 764 765 sync_interval_nt = sync_interval * 24LL * 3600LL * 10000000LL; 766 767 DEBUG(5, ("old timestamp is %lld, threshold %lld, diff %lld\n", 768 (long long int)old_timestamp, 769 (long long int)(now - sync_interval_nt), 770 (long long int)(old_timestamp - now + sync_interval_nt))); 771 772 if (old_timestamp > now){ 773 DEBUG(0, ("lastLogonTimestamp is in the future! (%lld > %lld)\n", 774 (long long int)old_timestamp, (long long int)now)); 775 /* then what? */ 776 777 } else if (old_timestamp < now - sync_interval_nt){ 778 DEBUG(5, ("updating lastLogonTimestamp to %lld\n", 779 (long long int)now)); 780 781 /* The time has come to update lastLogonTimestamp */ 782 ret = samdb_msg_add_int64(sam_ctx, msg_mod, msg_mod, 783 "lastLogonTimestamp", now); 784 785 if (ret != LDB_SUCCESS) { 786 TALLOC_FREE(mem_ctx); 787 return NT_STATUS_NO_MEMORY; 788 } 789 } 790 TALLOC_FREE(mem_ctx); 791 return NT_STATUS_OK; 792 } 793 794 795 796 /* Reset the badPwdCount to zero and update the lastLogon time. */ 797 NTSTATUS authsam_logon_success_accounting(struct ldb_context *sam_ctx, 798 const struct ldb_message *msg, 799 struct ldb_dn *domain_dn, 800 bool interactive_or_kerberos) 801 { 802 int ret; 803 NTSTATUS status; 804 int badPwdCount; 805 int64_t lockoutTime; 806 struct ldb_message *msg_mod; 807 TALLOC_CTX *mem_ctx; 808 struct timeval tv_now; 809 NTTIME now; 810 NTTIME lastLogonTimestamp; 811 NTTIME lastLogon; 812 813 lockoutTime = ldb_msg_find_attr_as_int64(msg, "lockoutTime", 0); 814 badPwdCount = ldb_msg_find_attr_as_int(msg, "badPwdCount", 0); 815 lastLogonTimestamp = \ 816 ldb_msg_find_attr_as_int64(msg, "lastLogonTimestamp", 0); 817 lastLogon = ldb_msg_find_attr_as_int64(msg, "lastLogon", 0); 818 819 DEBUG(5, ("lastLogonTimestamp is %lld\n", 820 (long long int)lastLogonTimestamp)); 821 822 mem_ctx = talloc_new(msg); 823 if (mem_ctx == NULL) { 824 return NT_STATUS_NO_MEMORY; 825 } 826 msg_mod = ldb_msg_new(mem_ctx); 827 if (msg_mod == NULL) { 828 TALLOC_FREE(mem_ctx); 829 return NT_STATUS_NO_MEMORY; 830 } 831 msg_mod->dn = msg->dn; 832 833 if (lockoutTime != 0) { 834 /* 835 * This implies "badPwdCount" = 0, see samldb_lockout_time() 836 */ 837 ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, "lockoutTime", 0); 838 if (ret != LDB_SUCCESS) { 839 TALLOC_FREE(mem_ctx); 840 return NT_STATUS_NO_MEMORY; 841 } 842 } else if (badPwdCount != 0) { 843 ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, "badPwdCount", 0); 844 if (ret != LDB_SUCCESS) { 845 TALLOC_FREE(mem_ctx); 846 return NT_STATUS_NO_MEMORY; 847 } 848 } 849 850 tv_now = timeval_current(); 851 now = timeval_to_nttime(&tv_now); 852 853 if (interactive_or_kerberos || lastLogon == 0 || 854 (badPwdCount != 0 && lockoutTime == 0)) { 855 ret = samdb_msg_add_int64(sam_ctx, msg_mod, msg_mod, 856 "lastLogon", now); 857 if (ret != LDB_SUCCESS) { 858 TALLOC_FREE(mem_ctx); 859 return NT_STATUS_NO_MEMORY; 860 } 861 } 862 status = authsam_update_lastlogon_timestamp(sam_ctx, msg_mod, domain_dn, 863 lastLogonTimestamp, now); 864 if (!NT_STATUS_IS_OK(status)) { 865 TALLOC_FREE(mem_ctx); 866 return NT_STATUS_NO_MEMORY; 867 } 868 869 if (msg_mod->num_elements > 0) { 870 ret = dsdb_replace(sam_ctx, msg_mod, 0); 871 if (ret != LDB_SUCCESS) { 872 DEBUG(0, ("Failed to set badPwdCount and lockoutTime " 873 "to 0 and/or lastlogon to now (%lld) " 874 "%s: %s\n", (long long int)now, 875 ldb_dn_get_linearized(msg_mod->dn), 876 ldb_errstring(sam_ctx))); 877 TALLOC_FREE(mem_ctx); 878 return NT_STATUS_INTERNAL_ERROR; 879 } 880 } 881 TALLOC_FREE(mem_ctx); 882 return NT_STATUS_OK; 883 } -
vendor/current/source4/auth/samba_server_gensec.c
r740 r988 30 30 NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, 31 31 struct tevent_context *event_ctx, 32 struct messaging_context *msg_ctx,32 struct imessaging_context *msg_ctx, 33 33 struct loadparm_context *lp_ctx, 34 34 struct cli_credentials *server_credentials, … … 38 38 NTSTATUS nt_status; 39 39 struct gensec_security *gensec_ctx; 40 struct auth _context *auth_context;40 struct auth4_context *auth_context; 41 41 42 42 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); … … 58 58 59 59 nt_status = gensec_server_start(tmp_ctx, 60 event_ctx,61 60 lpcfg_gensec_settings(mem_ctx, lp_ctx), 62 61 auth_context, -
vendor/current/source4/auth/session.c
r740 r988 33 33 #include "system/kerberos.h" 34 34 #include <gssapi/gssapi.h> 35 #include "libcli/wbclient/wbclient.h" 35 36 36 37 _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, … … 65 66 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 66 67 67 session_info = talloc(tmp_ctx, struct auth_session_info); 68 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx); 68 session_info = talloc_zero(tmp_ctx, struct auth_session_info); 69 if (session_info == NULL) { 70 TALLOC_FREE(tmp_ctx); 71 return NT_STATUS_NO_MEMORY; 72 } 69 73 70 74 session_info->info = talloc_reference(session_info, user_info_dc->info); 71 75 72 76 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); 77 if (session_info->torture == NULL) { 78 TALLOC_FREE(tmp_ctx); 79 return NT_STATUS_NO_MEMORY; 80 } 74 81 session_info->torture->num_dc_sids = user_info_dc->num_sids; 75 82 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); 83 if (session_info->torture->dc_sids == NULL) { 84 TALLOC_FREE(tmp_ctx); 85 return NT_STATUS_NO_MEMORY; 86 } 77 87 78 88 /* unless set otherwise, the session key is the user session … … 80 90 session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length); 81 91 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); 92 if (session_info->session_key.data == NULL) { 93 TALLOC_FREE(tmp_ctx); 94 return NT_STATUS_NO_MEMORY; 95 } 83 96 } 84 97 85 98 anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS); 86 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx); 99 if (anonymous_sid == NULL) { 100 TALLOC_FREE(tmp_ctx); 101 return NT_STATUS_NO_MEMORY; 102 } 87 103 88 104 system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM); 89 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx); 105 if (system_sid == NULL) { 106 TALLOC_FREE(tmp_ctx); 107 return NT_STATUS_NO_MEMORY; 108 } 90 109 91 110 sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids); 92 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx); 111 if (sids == NULL) { 112 TALLOC_FREE(tmp_ctx); 113 return NT_STATUS_NO_MEMORY; 114 } 93 115 if (!sids) { 94 116 talloc_free(tmp_ctx); … … 102 124 } 103 125 104 if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) { 126 /* 127 * Finally add the "standard" sids. 128 * The only difference between guest and "anonymous" 129 * is the addition of Authenticated_Users. 130 */ 131 132 if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) { 133 sids = talloc_realloc(tmp_ctx, sids, struct dom_sid, num_sids + 2); 134 NT_STATUS_HAVE_NO_MEMORY(sids); 135 136 if (!dom_sid_parse(SID_WORLD, &sids[num_sids])) { 137 return NT_STATUS_INTERNAL_ERROR; 138 } 139 num_sids++; 140 141 if (!dom_sid_parse(SID_NT_NETWORK, &sids[num_sids])) { 142 return NT_STATUS_INTERNAL_ERROR; 143 } 144 num_sids++; 145 } 146 147 if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) { 148 sids = talloc_realloc(tmp_ctx, sids, struct dom_sid, num_sids + 1); 149 NT_STATUS_HAVE_NO_MEMORY(sids); 150 151 if (!dom_sid_parse(SID_NT_AUTHENTICATED_USERS, &sids[num_sids])) { 152 return NT_STATUS_INTERNAL_ERROR; 153 } 154 num_sids++; 155 } 156 157 158 159 if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &sids[PRIMARY_USER_SID_INDEX])) { 105 160 /* 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])) {161 } else if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &sids[PRIMARY_USER_SID_INDEX])) { 107 162 /* Don't expand nested groups of system, anonymous etc*/ 108 163 } else if (sam_ctx) { … … 111 166 112 167 /* Search for each group in the token */ 113 for (i = 0; i < user_info_dc->num_sids; i++) {168 for (i = 0; i < num_sids; i++) { 114 169 char *sid_string; 115 170 const char *sid_dn; 116 171 DATA_BLOB sid_blob; 117 172 118 173 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); 174 &sids[i]); 175 if (sid_string == NULL) { 176 TALLOC_FREE(user_info_dc); 177 return NT_STATUS_NO_MEMORY; 178 } 121 179 122 180 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string); 123 181 talloc_free(sid_string); 124 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc); 182 if (sid_dn == NULL) { 183 TALLOC_FREE(user_info_dc); 184 return NT_STATUS_NO_MEMORY; 185 } 125 186 sid_blob = data_blob_string_const(sid_dn); 126 187 … … 146 207 session_info_flags, 147 208 &session_info->security_token); 148 NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx); 209 if (!NT_STATUS_IS_OK(nt_status)) { 210 TALLOC_FREE(tmp_ctx); 211 return nt_status; 212 } 149 213 150 214 session_info->credentials = NULL; … … 156 220 } 157 221 158 /* Create a session_info structure from the 159 * auth_session_info_transport we were forwarded over named pipe160 * forwarding.222 223 /* Fill out the auth_session_info with a cli_credentials based on the 224 * auth_session_info we were forwarded over named pipe forwarding. 161 225 * 162 226 * NOTE: The stucture members of session_info_transport are stolen … … 169 233 { 170 234 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 235 session_info = talloc_steal(mem_ctx, session_info_transport->session_info); 236 /* 237 * This is to allow us to check the type of this pointer using 238 * talloc_get_type() 239 */ 240 talloc_set_name(session_info, "struct auth_session_info"); 241 #ifdef HAVE_GSS_IMPORT_CRED 182 242 if (session_info_transport->exported_gssapi_credentials.length) { 183 243 struct cli_credentials *creds; … … 230 290 231 291 } 232 292 #endif 233 293 return session_info; 234 294 } … … 237 297 /* Create a auth_session_info_transport from an auth_session_info. 238 298 * 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 299 * NOTE: Members of the auth_session_info_transport structure are 300 * talloc_referenced() into this structure, and should not be changed. 242 301 */ 243 302 NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx, … … 248 307 { 249 308 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 309 struct auth_session_info_transport *session_info_transport 310 = talloc_zero(mem_ctx, struct auth_session_info_transport); 311 if (!session_info_transport) { 312 return NT_STATUS_NO_MEMORY; 313 }; 314 session_info_transport->session_info = talloc_reference(session_info_transport, session_info); 315 if (!session_info_transport->session_info) { 316 return NT_STATUS_NO_MEMORY; 317 }; 318 #ifdef HAVE_GSS_EXPORT_CRED 263 319 if (session_info->credentials) { 264 320 struct gssapi_creds_container *gcc; … … 294 350 } 295 351 } 352 #endif 296 353 *transport_out = session_info_transport; 297 354 return NT_STATUS_OK; … … 350 407 security_token_debug(0, dbg_lev, session_info->security_token); 351 408 } 352 -
vendor/current/source4/auth/system_session.c
r740 r988 191 191 192 192 user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; 193 sid_append_rid(&user_info_dc->sids[PRIMARY_ USER_SID_INDEX], DOMAIN_RID_USERS);193 sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS); 194 194 195 195 user_info_dc->sids[2] = global_sid_Builtin_Administrators; … … 268 268 struct auth_user_info_dc *user_info_dc = NULL; 269 269 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 270 271 NT_STATUS_HAVE_NO_MEMORY(mem_ctx); 270 272 271 273 nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx), -
vendor/current/source4/auth/wscript_build
r740 r988 3 3 bld.RECURSE('gensec') 4 4 bld.RECURSE('kerberos') 5 bld.RECURSE('ntlmssp')6 5 bld.RECURSE('ntlm') 7 bld.RECURSE('credentials')8 6 9 7 bld.SAMBA_SUBSYSTEM('auth_session', 10 8 source='session.c', 11 9 autoproto='session_proto.h', 12 public_deps=' credentials',10 public_deps='samba-credentials', 13 11 public_headers='session.h', 14 12 header_path='samba', … … 16 14 ) 17 15 16 bld.SAMBA_LIBRARY('auth_unix_token', 17 source='unix_token.c', 18 autoproto='unix_token_proto.h', 19 public_deps='LIBWBCLIENT_OLD', 20 private_library=True, 21 ) 22 18 23 19 24 bld.SAMBA_SUBSYSTEM('samba_server_gensec', 20 25 source='samba_server_gensec.c', 21 public_deps=' credentials gensec auth4'26 public_deps='samba-credentials gensec auth4' 22 27 ) 23 28 … … 26 31 source='system_session.c', 27 32 autoproto='system_session_proto.h', 28 public_deps=' credentials',33 public_deps='samba-credentials', 29 34 deps='auth_session', 30 35 ) … … 34 39 source='sam.c', 35 40 autoproto='auth_sam.h', 36 public_deps='samdb s ecurity ldb tevent',41 public_deps='samdb samba-security ldb tevent', 37 42 deps='' 38 43 ) -
vendor/current/source4/auth/wscript_configure
r740 r988 3 3 conf.CHECK_HEADERS('security/pam_appl.h') 4 4 conf.CHECK_FUNCS_IN('pam_start', 'pam', checklibc=True) 5 6 if (conf.CHECK_HEADERS('sasl/sasl.h') and7 conf.CHECK_FUNCS_IN('sasl_client_init', 'sasl2')):8 conf.DEFINE('HAVE_SASL', 1)
Note:
See TracChangeset
for help on using the changeset viewer.