Changeset 740 for vendor/current/source4/auth/gensec
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source4/auth/gensec
- Files:
-
- 3 added
- 4 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/auth/gensec/cyrus_sasl.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include " auth/auth.h"23 #include "lib/tsocket/tsocket.h" 24 24 #include "auth/credentials/credentials.h" 25 25 #include "auth/gensec/gensec.h" 26 26 #include "auth/gensec/gensec_proto.h" 27 #include "lib/socket/socket.h"28 27 #include <sasl/sasl.h> 29 28 … … 31 30 sasl_conn_t *conn; 32 31 int step; 32 bool wrap; 33 33 }; 34 34 … … 119 119 const char *service = gensec_get_target_service(gensec_security); 120 120 const char *target_name = gensec_get_target_hostname(gensec_security); 121 struct socket_address *local_socket_addr = gensec_get_my_addr(gensec_security);122 struct socket_address *remote_socket_addr = gensec_get_peer_addr(gensec_security);121 const struct tsocket_address *tlocal_addr = gensec_get_local_address(gensec_security); 122 const struct tsocket_address *tremote_addr = gensec_get_remote_address(gensec_security); 123 123 char *local_addr = NULL; 124 124 char *remote_addr = NULL; … … 127 127 sasl_callback_t *callbacks; 128 128 129 gensec_sasl_state = talloc (gensec_security, struct gensec_sasl_state);129 gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state); 130 130 if (!gensec_sasl_state) { 131 131 return NT_STATUS_NO_MEMORY; … … 155 155 gensec_security->private_data = gensec_sasl_state; 156 156 157 if ( local_socket_addr) {158 local_addr = talloc_asprintf(gensec_sasl_state, 159 160 local_socket_addr->addr,161 local_socket_addr->port);162 } 163 164 if ( remote_socket_addr) {165 remote_addr = talloc_asprintf(gensec_sasl_state, 166 167 remote_socket_addr->addr,168 remote_socket_addr->port);157 if (tlocal_addr) { 158 local_addr = talloc_asprintf(gensec_sasl_state, 159 "%s;%d", 160 tsocket_address_inet_addr_string(tlocal_addr, gensec_sasl_state), 161 tsocket_address_inet_port(tlocal_addr)); 162 } 163 164 if (tremote_addr) { 165 remote_addr = talloc_asprintf(gensec_sasl_state, 166 "%s;%d", 167 tsocket_address_inet_addr_string(tremote_addr, gensec_sasl_state), 168 tsocket_address_inet_port(tremote_addr)); 169 169 } 170 170 gensec_sasl_state->step = 0; … … 175 175 &gensec_sasl_state->conn); 176 176 177 if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) {177 if (sasl_ret == SASL_OK) { 178 178 sasl_security_properties_t props; 179 179 talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose); 180 180 181 181 ZERO_STRUCT(props); 182 182 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 183 183 props.min_ssf = 1; 184 props.max_ssf = 1; 185 props.maxbufsize = 65536; 186 gensec_sasl_state->wrap = true; 184 187 } 185 188 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 186 189 props.min_ssf = 40; 187 } 188 189 props.max_ssf = UINT_MAX; 190 props.maxbufsize = 65536; 190 props.max_ssf = UINT_MAX; 191 props.maxbufsize = 65536; 192 gensec_sasl_state->wrap = true; 193 } 194 191 195 sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props); 192 if (sasl_ret != SASL_OK) { 193 return sasl_nt_status(sasl_ret); 194 } 195 196 } else { 196 } 197 if (sasl_ret != SASL_OK) { 197 198 DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn))); 198 199 } … … 263 264 const char *out_data; 264 265 unsigned int out_len; 265 266 int sasl_ret = sasl_encode(gensec_sasl_state->conn, 267 (char*)in->data, in->length, &out_data, 268 &out_len); 266 unsigned len_permitted; 267 int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, 268 (const void**)&len_permitted); 269 if (sasl_ret != SASL_OK) { 270 return sasl_nt_status(sasl_ret); 271 } 272 len_permitted = MIN(len_permitted, in->length); 273 274 sasl_ret = sasl_encode(gensec_sasl_state->conn, 275 (char*)in->data, len_permitted, &out_data, 276 &out_len); 269 277 if (sasl_ret == SASL_OK) { 270 278 *out = data_blob_talloc(out_mem_ctx, out_data, out_len); … … 283 291 struct gensec_sasl_state); 284 292 sasl_ssf_t ssf; 285 int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, 293 int sasl_ret; 294 295 /* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */ 296 if (!gensec_sasl_state->wrap) { 297 return false; 298 } 299 300 sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, 286 301 (const void**)&ssf); 287 302 if (sasl_ret != SASL_OK) { -
vendor/current/source4/auth/gensec/gensec.c
r414 r740 22 22 23 23 #include "includes.h" 24 #include " auth/auth.h"24 #include "system/network.h" 25 25 #include "lib/events/events.h" 26 #include "lib/socket/socket.h" 27 #include "lib/tsocket/tsocket.h" 28 #include "../lib/util/tevent_ntstatus.h" 26 29 #include "librpc/rpc/dcerpc.h" 27 30 #include "auth/credentials/credentials.h" 28 31 #include "auth/gensec/gensec.h" 29 #include "auth/gensec/gensec_proto.h" 32 #include "auth/auth.h" 33 #include "auth/system_session_proto.h" 30 34 #include "param/param.h" 35 #include "lib/util/tsort.h" 31 36 32 37 /* the list of currently registered GENSEC backends */ … … 43 48 bool gensec_security_ops_enabled(struct gensec_security_ops *ops, struct gensec_security *security) 44 49 { 45 return lp _parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);50 return lpcfg_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled); 46 51 } 47 52 … … 503 508 @param gensec_security Returned GENSEC context pointer. 504 509 @note The mem_ctx is only a parent and may be NULL. 505 @note, the auth context is moved to be a childof the510 @note, the auth context is moved to be a referenced pointer of the 506 511 @ gensec_security return 507 512 */ … … 517 522 } 518 523 519 (*gensec_security) = talloc (mem_ctx, struct gensec_security);524 (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security); 520 525 NT_STATUS_HAVE_NO_MEMORY(*gensec_security); 521 522 (*gensec_security)->ops = NULL;523 (*gensec_security)->private_data = NULL;524 525 ZERO_STRUCT((*gensec_security)->target);526 ZERO_STRUCT((*gensec_security)->peer_addr);527 ZERO_STRUCT((*gensec_security)->my_addr);528 529 (*gensec_security)->subcontext = false;530 (*gensec_security)->want_features = 0;531 526 532 527 (*gensec_security)->event_ctx = ev; 533 528 SMB_ASSERT(settings->lp_ctx != NULL); 534 529 (*gensec_security)->settings = talloc_reference(*gensec_security, settings); 535 (*gensec_security)->auth_context = talloc_steal(*gensec_security, auth_context); 530 531 /* We need to reference this, not steal, as the caller may be 532 * python, which won't like it if we steal it's object away 533 * from it */ 534 (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context); 536 535 537 536 return NT_STATUS_OK; … … 550 549 struct gensec_security **gensec_security) 551 550 { 552 (*gensec_security) = talloc (mem_ctx, struct gensec_security);551 (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security); 553 552 NT_STATUS_HAVE_NO_MEMORY(*gensec_security); 554 553 … … 593 592 return status; 594 593 } 594 595 595 596 596 597 /** … … 712 713 return oid_string; 713 714 } 714 715 716 /** 717 * Start a GENSEC sub-mechanism with a specifed mechansim structure, used in SPNEGO 715 716 /** 717 * Start a GENSEC sub-mechanism with a specified mechansim structure, used in SPNEGO 718 718 * 719 719 */ … … 982 982 } 983 983 984 static void gensec_update_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te, 985 struct timeval t, void *ptr) 986 { 987 struct gensec_update_request *req = talloc_get_type(ptr, struct gensec_update_request); 988 req->status = req->gensec_security->ops->update(req->gensec_security, req, req->in, &req->out); 989 req->callback.fn(req, req->callback.private_data); 990 } 991 984 struct gensec_update_state { 985 struct tevent_immediate *im; 986 struct gensec_security *gensec_security; 987 DATA_BLOB in; 988 DATA_BLOB out; 989 }; 990 991 static void gensec_update_async_trigger(struct tevent_context *ctx, 992 struct tevent_immediate *im, 993 void *private_data); 992 994 /** 993 995 * Next state function for the GENSEC state machine async version 994 * 996 * 997 * @param mem_ctx The memory context for the request 998 * @param ev The event context for the request 995 999 * @param gensec_security GENSEC State 996 1000 * @param in The request, as a DATA_BLOB 997 * @param callback The function that will be called when the operation is 998 * finished, it should return gensec_update_recv() to get output 999 * @param private_data A private pointer that will be passed to the callback function 1000 */ 1001 1002 _PUBLIC_ void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in, 1003 void (*callback)(struct gensec_update_request *req, void *private_data), 1004 void *private_data) 1005 { 1006 struct gensec_update_request *req = NULL; 1007 struct tevent_timer *te = NULL; 1008 1009 req = talloc(gensec_security, struct gensec_update_request); 1010 if (!req) goto failed; 1011 req->gensec_security = gensec_security; 1012 req->in = in; 1013 req->out = data_blob(NULL, 0); 1014 req->callback.fn = callback; 1015 req->callback.private_data = private_data; 1016 1017 te = event_add_timed(gensec_security->event_ctx, req, 1018 timeval_zero(), 1019 gensec_update_async_timed_handler, req); 1020 if (!te) goto failed; 1021 1022 return; 1023 1024 failed: 1025 talloc_free(req); 1026 callback(NULL, private_data); 1001 * 1002 * @return The request handle or NULL on no memory failure 1003 */ 1004 1005 _PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx, 1006 struct tevent_context *ev, 1007 struct gensec_security *gensec_security, 1008 const DATA_BLOB in) 1009 { 1010 struct tevent_req *req; 1011 struct gensec_update_state *state = NULL; 1012 1013 req = tevent_req_create(mem_ctx, &state, 1014 struct gensec_update_state); 1015 if (req == NULL) { 1016 return NULL; 1017 } 1018 1019 state->gensec_security = gensec_security; 1020 state->in = in; 1021 state->out = data_blob(NULL, 0); 1022 state->im = tevent_create_immediate(state); 1023 if (tevent_req_nomem(state->im, req)) { 1024 return tevent_req_post(req, ev); 1025 } 1026 1027 tevent_schedule_immediate(state->im, ev, 1028 gensec_update_async_trigger, 1029 req); 1030 1031 return req; 1032 } 1033 1034 static void gensec_update_async_trigger(struct tevent_context *ctx, 1035 struct tevent_immediate *im, 1036 void *private_data) 1037 { 1038 struct tevent_req *req = 1039 talloc_get_type_abort(private_data, struct tevent_req); 1040 struct gensec_update_state *state = 1041 tevent_req_data(req, struct gensec_update_state); 1042 NTSTATUS status; 1043 1044 status = gensec_update(state->gensec_security, state, 1045 state->in, &state->out); 1046 if (tevent_req_nterror(req, status)) { 1047 return; 1048 } 1049 1050 tevent_req_done(req); 1027 1051 } 1028 1052 … … 1030 1054 * Next state function for the GENSEC state machine 1031 1055 * 1032 * @param req GENSEC updaterequest state1056 * @param req request state 1033 1057 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on 1034 1058 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx … … 1036 1060 * or NT_STATUS_OK if the user is authenticated. 1037 1061 */ 1038 _PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out) 1039 { 1062 _PUBLIC_ NTSTATUS gensec_update_recv(struct tevent_req *req, 1063 TALLOC_CTX *out_mem_ctx, 1064 DATA_BLOB *out) 1065 { 1066 struct gensec_update_state *state = 1067 tevent_req_data(req, struct gensec_update_state); 1040 1068 NTSTATUS status; 1041 1069 1042 NT_STATUS_HAVE_NO_MEMORY(req); 1043 1044 *out = req->out; 1070 if (tevent_req_is_nterror(req, &status)) { 1071 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1072 tevent_req_received(req); 1073 return status; 1074 } 1075 } else { 1076 status = NT_STATUS_OK; 1077 } 1078 1079 *out = state->out; 1045 1080 talloc_steal(out_mem_ctx, out->data); 1046 status = req->status; 1047 1048 talloc_free(req); 1081 1082 tevent_req_received(req); 1049 1083 return status; 1050 1084 } … … 1162 1196 } 1163 1197 1164 /** 1165 * Set (and talloc_reference) local and peer socket addresses onto a socket context on the GENSEC context 1198 /** 1199 * Set (and talloc_reference) local and peer socket addresses onto a socket 1200 * context on the GENSEC context. 1166 1201 * 1167 1202 * This is so that kerberos can include these addresses in … … 1169 1204 */ 1170 1205 1171 _PUBLIC_ NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr) 1172 { 1173 gensec_security->my_addr = my_addr; 1174 if (my_addr && !talloc_reference(gensec_security, my_addr)) { 1206 /** 1207 * @brief Set the local gensec address. 1208 * 1209 * @param gensec_security The gensec security context to use. 1210 * 1211 * @param remote The local address to set. 1212 * 1213 * @return On success NT_STATUS_OK is returned or an NT_STATUS 1214 * error. 1215 */ 1216 _PUBLIC_ NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security, 1217 const struct tsocket_address *local) 1218 { 1219 TALLOC_FREE(gensec_security->local_addr); 1220 1221 if (local == NULL) { 1222 return NT_STATUS_OK; 1223 } 1224 1225 gensec_security->local_addr = tsocket_address_copy(local, gensec_security); 1226 if (gensec_security->local_addr == NULL) { 1175 1227 return NT_STATUS_NO_MEMORY; 1176 1228 } 1229 1177 1230 return NT_STATUS_OK; 1178 1231 } 1179 1232 1180 _PUBLIC_ NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr) 1181 { 1182 gensec_security->peer_addr = peer_addr; 1183 if (peer_addr && !talloc_reference(gensec_security, peer_addr)) { 1233 /** 1234 * @brief Set the remote gensec address. 1235 * 1236 * @param gensec_security The gensec security context to use. 1237 * 1238 * @param remote The remote address to set. 1239 * 1240 * @return On success NT_STATUS_OK is returned or an NT_STATUS 1241 * error. 1242 */ 1243 _PUBLIC_ NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security, 1244 const struct tsocket_address *remote) 1245 { 1246 TALLOC_FREE(gensec_security->remote_addr); 1247 1248 if (remote == NULL) { 1249 return NT_STATUS_OK; 1250 } 1251 1252 gensec_security->remote_addr = tsocket_address_copy(remote, gensec_security); 1253 if (gensec_security->remote_addr == NULL) { 1184 1254 return NT_STATUS_NO_MEMORY; 1185 1255 } 1256 1186 1257 return NT_STATUS_OK; 1187 1258 } 1188 1259 1189 struct socket_address *gensec_get_my_addr(struct gensec_security *gensec_security) 1190 { 1191 if (gensec_security->my_addr) { 1192 return gensec_security->my_addr; 1193 } 1194 1195 /* We could add a 'set sockaddr' call, and do a lookup. This 1196 * would avoid needing to do system calls if nothing asks. */ 1197 return NULL; 1198 } 1199 1200 _PUBLIC_ struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security) 1201 { 1202 if (gensec_security->peer_addr) { 1203 return gensec_security->peer_addr; 1204 } 1205 1206 /* We could add a 'set sockaddr' call, and do a lookup. This 1207 * would avoid needing to do system calls if nothing asks. 1208 * However, this is not appropriate for the peer addres on 1209 * datagram sockets */ 1210 return NULL; 1211 } 1212 1213 1260 /** 1261 * @brief Get the local address from a gensec security context. 1262 * 1263 * @param gensec_security The security context to get the address from. 1264 * 1265 * @return The address as tsocket_address which could be NULL if 1266 * no address is set. 1267 */ 1268 _PUBLIC_ const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security) 1269 { 1270 if (gensec_security == NULL) { 1271 return NULL; 1272 } 1273 return gensec_security->local_addr; 1274 } 1275 1276 /** 1277 * @brief Get the remote address from a gensec security context. 1278 * 1279 * @param gensec_security The security context to get the address from. 1280 * 1281 * @return The address as tsocket_address which could be NULL if 1282 * no address is set. 1283 */ 1284 _PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security) 1285 { 1286 if (gensec_security == NULL) { 1287 return NULL; 1288 } 1289 return gensec_security->remote_addr; 1290 } 1214 1291 1215 1292 /** … … 1219 1296 */ 1220 1297 1221 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) 1298 _PUBLIC_ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) 1222 1299 { 1223 1300 gensec_security->target.principal = talloc_strdup(gensec_security, principal); … … 1235 1312 1236 1313 return NULL; 1314 } 1315 1316 NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx, 1317 struct gensec_security *gensec_security, 1318 struct auth_user_info_dc *user_info_dc, 1319 struct auth_session_info **session_info) 1320 { 1321 NTSTATUS nt_status; 1322 uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; 1323 if (user_info_dc->info->authenticated) { 1324 flags |= AUTH_SESSION_INFO_AUTHENTICATED; 1325 } 1326 if (gensec_security->auth_context) { 1327 nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context, 1328 user_info_dc, 1329 flags, 1330 session_info); 1331 } else { 1332 flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES; 1333 nt_status = auth_generate_session_info(mem_ctx, 1334 NULL, 1335 NULL, 1336 user_info_dc, flags, 1337 session_info); 1338 } 1339 return nt_status; 1237 1340 } 1238 1341 … … 1292 1395 int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value) 1293 1396 { 1294 return lp _parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);1397 return lpcfg_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value); 1295 1398 } 1296 1399 1297 1400 bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value) 1298 1401 { 1299 return lp _parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);1402 return lpcfg_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value); 1300 1403 } 1301 1404 … … 1306 1409 { 1307 1410 static bool initialized = false; 1308 extern NTSTATUS gensec_sasl_init(void); 1309 extern NTSTATUS gensec_krb5_init(void); 1310 extern NTSTATUS gensec_schannel_init(void); 1311 extern NTSTATUS gensec_spnego_init(void); 1312 extern NTSTATUS gensec_gssapi_init(void); 1313 extern NTSTATUS gensec_ntlmssp_init(void); 1314 1411 #define _MODULE_PROTO(init) extern NTSTATUS init(void); 1412 STATIC_gensec_MODULES_PROTO; 1315 1413 init_module_fn static_init[] = { STATIC_gensec_MODULES }; 1316 1414 init_module_fn *shared_init; … … 1326 1424 talloc_free(shared_init); 1327 1425 1328 qsort(generic_security_ops, gensec_num_backends, sizeof(*generic_security_ops), QSORT_CASTsort_gensec);1426 TYPESAFE_QSORT(generic_security_ops, gensec_num_backends, sort_gensec); 1329 1427 1330 1428 return NT_STATUS_OK; -
vendor/current/source4/auth/gensec/gensec.h
r414 r740 27 27 #include "libcli/util/ntstatus.h" 28 28 29 #define GENSEC_SASL_NAME_NTLMSSP "NTLM" 30 29 31 #define GENSEC_OID_NTLMSSP "1.3.6.1.4.1.311.2.2.10" 30 32 #define GENSEC_OID_SPNEGO "1.3.6.1.5.5.2" … … 70 72 struct gensec_settings; 71 73 struct tevent_context; 72 73 struct gensec_update_request { 74 struct gensec_security *gensec_security; 75 void *private_data; 76 DATA_BLOB in; 77 DATA_BLOB out; 78 NTSTATUS status; 79 struct { 80 void (*fn)(struct gensec_update_request *req, void *private_data); 81 void *private_data; 82 } callback; 83 }; 74 struct tevent_req; 84 75 85 76 struct gensec_settings { 86 77 struct loadparm_context *lp_ctx; 87 struct smb_iconv_convenience *iconv_convenience;88 78 const char *target_hostname; 89 79 }; … … 170 160 uint32_t want_features; 171 161 struct tevent_context *event_ctx; 172 struct socket_address *my_addr, *peer_addr;162 struct tsocket_address *local_addr, *remote_addr; 173 163 struct gensec_settings *settings; 174 164 … … 191 181 struct socket_context; 192 182 struct auth_context; 183 struct auth_user_info_dc; 193 184 194 185 NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, … … 232 223 NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 233 224 const DATA_BLOB in, DATA_BLOB *out); 234 void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in, 235 void (*callback)(struct gensec_update_request *req, void *private_data), 236 void *private_data); 237 NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); 225 struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx, 226 struct tevent_context *ev, 227 struct gensec_security *gensec_security, 228 const DATA_BLOB in); 229 NTSTATUS gensec_update_recv(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); 238 230 void gensec_want_feature(struct gensec_security *gensec_security, 239 231 uint32_t feature); … … 251 243 const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string); 252 244 struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security); 253 struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security);254 245 NTSTATUS gensec_init(struct loadparm_context *lp_ctx); 255 246 NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, … … 284 275 NTSTATUS gensec_session_info(struct gensec_security *gensec_security, 285 276 struct auth_session_info **session_info); 286 NTSTATUS auth_nt_status_squash(NTSTATUS nt_status);277 NTSTATUS nt_status_squash(NTSTATUS nt_status); 287 278 struct netlogon_creds_CredentialState; 288 279 NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, 289 280 TALLOC_CTX *mem_ctx, 290 281 struct netlogon_creds_CredentialState **creds); 291 NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr); 292 NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr); 282 283 284 NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security, 285 const struct tsocket_address *local); 286 NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security, 287 const struct tsocket_address *remote); 288 const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security); 289 const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security); 293 290 294 291 NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security, … … 316 313 bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value); 317 314 315 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal); 316 318 317 #endif /* __GENSEC_H__ */ -
vendor/current/source4/auth/gensec/gensec.pc.in
r414 r740 7 7 Name: gensec 8 8 Description: Generic Security Library 9 Version: 0.0.110 Libs: -L${libdir} -lgensec9 Version: @PACKAGE_VERSION@ 10 Libs: @LIB_RPATH@ -L${libdir} -lgensec 11 11 Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -
vendor/current/source4/auth/gensec/gensec_gssapi.c
r414 r740 28 28 #include "librpc/gen_ndr/krb5pac.h" 29 29 #include "auth/auth.h" 30 #include "lib/ldb/include/ldb.h"30 #include <ldb.h> 31 31 #include "auth/auth_sam.h" 32 32 #include "librpc/rpc/dcerpc.h" … … 41 41 #include <gssapi/gssapi_spnego.h> 42 42 #include "auth/gensec/gensec_gssapi.h" 43 #include "lib/util/util_net.h" 43 44 44 45 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); … … 147 148 struct gensec_gssapi_state *gensec_gssapi_state; 148 149 krb5_error_code ret; 149 struct gsskrb5_send_to_kdc send_to_kdc;150 151 gensec_gssapi_state = talloc (gensec_security, struct gensec_gssapi_state);150 const char *realm; 151 152 gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state); 152 153 if (!gensec_gssapi_state) { 153 154 return NT_STATUS_NO_MEMORY; 154 155 } 155 156 gensec_gssapi_state->gss_exchange_count = 0;157 gensec_gssapi_state->max_wrap_buf_size158 = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);159 160 gensec_gssapi_state->sasl = false;161 gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;162 156 163 157 gensec_security->private_data = gensec_gssapi_state; 164 158 165 159 gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT; 160 161 /* TODO: Fill in channel bindings */ 162 gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; 163 166 164 gensec_gssapi_state->server_name = GSS_C_NO_NAME; 167 165 gensec_gssapi_state->client_name = GSS_C_NO_NAME; 168 gensec_gssapi_state->lucid = NULL;169 170 /* TODO: Fill in channel bindings */171 gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;172 166 173 167 gensec_gssapi_state->want_flags = 0; 168 174 169 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) { 175 170 gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG; … … 188 183 } 189 184 190 gensec_gssapi_state->got_flags = 0;191 192 gensec_gssapi_state->session_key = data_blob(NULL, 0);193 gensec_gssapi_state->pac = data_blob(NULL, 0);194 195 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;196 gensec_gssapi_state->sig_size = 0;197 198 talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);199 200 185 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 201 186 gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; … … 207 192 gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; 208 193 } 194 195 gensec_gssapi_state->got_flags = 0; 209 196 210 197 switch (gensec_security->ops->auth_type) { … … 218 205 } 219 206 220 send_to_kdc.func = smb_krb5_send_and_recv_func; 221 send_to_kdc.ptr = gensec_security->event_ctx; 222 223 ret = gsskrb5_set_send_to_kdc(&send_to_kdc); 224 if (ret) { 225 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); 226 talloc_free(gensec_gssapi_state); 227 return NT_STATUS_INTERNAL_ERROR; 228 } 229 if (lp_realm(gensec_security->settings->lp_ctx) && *lp_realm(gensec_security->settings->lp_ctx)) { 230 char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->settings->lp_ctx)); 231 if (!upper_realm) { 232 DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->settings->lp_ctx))); 233 talloc_free(gensec_gssapi_state); 234 return NT_STATUS_NO_MEMORY; 235 } 236 ret = gsskrb5_set_default_realm(upper_realm); 237 talloc_free(upper_realm); 238 if (ret) { 239 DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n")); 240 talloc_free(gensec_gssapi_state); 241 return NT_STATUS_INTERNAL_ERROR; 242 } 243 } 244 245 /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ 246 ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); 247 if (ret) { 248 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); 249 talloc_free(gensec_gssapi_state); 250 return NT_STATUS_INTERNAL_ERROR; 251 } 252 253 ret = smb_krb5_init_context(gensec_gssapi_state, 254 gensec_security->event_ctx, 207 gensec_gssapi_state->session_key = data_blob(NULL, 0); 208 gensec_gssapi_state->pac = data_blob(NULL, 0); 209 210 ret = smb_krb5_init_context(gensec_gssapi_state, 211 NULL, 255 212 gensec_security->settings->lp_ctx, 256 213 &gensec_gssapi_state->smb_krb5_context); … … 261 218 return NT_STATUS_INTERNAL_ERROR; 262 219 } 220 221 gensec_gssapi_state->client_cred = NULL; 222 gensec_gssapi_state->server_cred = NULL; 223 224 gensec_gssapi_state->lucid = NULL; 225 226 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; 227 228 gensec_gssapi_state->sasl = false; 229 gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; 230 gensec_gssapi_state->sasl_protection = 0; 231 232 gensec_gssapi_state->max_wrap_buf_size 233 = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536); 234 gensec_gssapi_state->gss_exchange_count = 0; 235 gensec_gssapi_state->sig_size = 0; 236 237 talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor); 238 239 realm = lpcfg_realm(gensec_security->settings->lp_ctx); 240 if (realm != NULL) { 241 ret = gsskrb5_set_default_realm(realm); 242 if (ret) { 243 DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n")); 244 talloc_free(gensec_gssapi_state); 245 return NT_STATUS_INTERNAL_ERROR; 246 } 247 } 248 249 /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ 250 ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); 251 if (ret) { 252 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); 253 talloc_free(gensec_gssapi_state); 254 return NT_STATUS_INTERNAL_ERROR; 255 } 256 263 257 return NT_STATUS_OK; 264 258 } … … 286 280 } else { 287 281 ret = cli_credentials_get_server_gss_creds(machine_account, 288 gensec_security->event_ctx,289 282 gensec_security->settings->lp_ctx, &gcc); 290 283 if (ret) { … … 323 316 OM_uint32 maj_stat, min_stat; 324 317 const char *hostname = gensec_get_target_hostname(gensec_security); 325 const char *principal;326 318 struct gssapi_creds_container *gcc; 319 const char *error_string; 327 320 328 321 if (!hostname) { … … 346 339 gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 347 340 348 principal = gensec_get_target_principal(gensec_security);349 if ( principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {341 gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); 342 if (gensec_gssapi_state->target_principal) { 350 343 name_type = GSS_C_NULL_OID; 351 344 } else { 352 principal = talloc_asprintf(gensec_gssapi_state, "%s@%s",345 gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s", 353 346 gensec_get_target_service(gensec_security), 354 hostname );355 356 name_type = GSS_C_NT_ HOSTBASED_SERVICE;357 } 358 name_token.value = discard_const_p(uint8_t, principal);359 name_token.length = strlen( principal);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); 360 353 361 354 … … 373 366 ret = cli_credentials_get_client_gss_creds(creds, 374 367 gensec_security->event_ctx, 375 gensec_security->settings->lp_ctx, &gcc );368 gensec_security->settings->lp_ctx, &gcc, &error_string); 376 369 switch (ret) { 377 370 case 0: 378 371 break; 379 372 case KRB5KDC_ERR_PREAUTH_FAILED: 373 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 374 DEBUG(1, ("Wrong username or password: %s\n", error_string)); 380 375 return NT_STATUS_LOGON_FAILURE; 381 376 case KRB5_KDC_UNREACH: 382 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); 383 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 377 DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string)); 378 return NT_STATUS_NO_LOGON_SERVERS; 379 case KRB5_CC_NOTFOUND: 380 case KRB5_CC_END: 381 DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string)); 382 return NT_STATUS_TIME_DIFFERENCE_AT_DC; 384 383 default: 385 DEBUG(1, ("Aquiring initiator credentials failed \n"));384 DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string)); 386 385 return NT_STATUS_UNSUCCESSFUL; 387 386 } … … 460 459 case GENSEC_CLIENT: 461 460 { 461 struct gsskrb5_send_to_kdc send_to_kdc; 462 krb5_error_code ret; 463 send_to_kdc.func = smb_krb5_send_and_recv_func; 464 send_to_kdc.ptr = gensec_security->event_ctx; 465 466 min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc); 467 if (min_stat) { 468 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); 469 return NT_STATUS_INTERNAL_ERROR; 470 } 471 462 472 maj_stat = gss_init_sec_context(&min_stat, 463 473 gensec_gssapi_state->client_cred->creds, … … 476 486 gensec_gssapi_state->gss_oid = gss_oid_p; 477 487 } 488 489 send_to_kdc.func = smb_krb5_send_and_recv_func; 490 send_to_kdc.ptr = NULL; 491 492 ret = gsskrb5_set_send_to_kdc(&send_to_kdc); 493 if (ret) { 494 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); 495 return NT_STATUS_INTERNAL_ERROR; 496 } 497 478 498 break; 479 499 } … … 516 536 * is more work to do */ 517 537 if (gensec_gssapi_state->sasl) { 518 /* Due to a very subtle interaction519 * with SASL and the LDAP libs, we520 * must ensure the data pointer is521 * != NULL, but the length is 0.522 *523 * This ensures we send a 'zero524 * length' (rather than NULL) response525 */526 527 if (!out->data) {528 out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0");529 }530 531 538 gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG; 532 539 return NT_STATUS_MORE_PROCESSING_REQUIRED; … … 535 542 536 543 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 537 DEBUG(5, ("GSSAPI Connection will be cryptographic ly sealed\n"));544 DEBUG(5, ("GSSAPI Connection will be cryptographically sealed\n")); 538 545 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 539 DEBUG(5, ("GSSAPI Connection will be cryptographic ly signed\n"));546 DEBUG(5, ("GSSAPI Connection will be cryptographically signed\n")); 540 547 } else { 541 548 DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n")); … … 551 558 } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { 552 559 switch (min_stat) { 560 case KRB5KRB_AP_ERR_TKT_NYV: 561 DEBUG(1, ("Error with ticket to contact %s: possible clock skew between us and the KDC or target server: %s\n", 562 gensec_gssapi_state->target_principal, 563 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 564 return NT_STATUS_TIME_DIFFERENCE_AT_DC; /* Make SPNEGO ignore us, we can't go any further here */ 565 case KRB5KRB_AP_ERR_TKT_EXPIRED: 566 DEBUG(1, ("Error with ticket to contact %s: ticket is expired, possible clock skew between us and the KDC or target server: %s\n", 567 gensec_gssapi_state->target_principal, 568 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 569 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 553 570 case KRB5_KDC_UNREACH: 554 DEBUG(3, ("Cannot reach a KDC we require: %s\n", 555 gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 556 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 571 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticetk to %s: %s\n", 572 gensec_gssapi_state->target_principal, 573 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 574 return NT_STATUS_NO_LOGON_SERVERS; /* Make SPNEGO ignore us, we can't go any further here */ 557 575 case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: 558 DEBUG(3, ("Server is not registered with our KDC: %s\n", 559 gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 576 DEBUG(3, ("Server %s is not registered with our KDC: %s\n", 577 gensec_gssapi_state->target_principal, 578 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 560 579 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 561 580 case KRB5KRB_AP_ERR_MSG_TYPE: … … 563 582 return NT_STATUS_INVALID_PARAMETER; 564 583 default: 565 DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n", 584 DEBUG(1, ("GSS %s Update(krb5)(%d) Update failed: %s\n", 585 gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server", 566 586 gensec_gssapi_state->gss_exchange_count, 567 587 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); … … 569 589 } 570 590 } else { 571 DEBUG(1, ("GSS Update(%d) failed: %s\n", 591 DEBUG(1, ("GSS %s Update(%d) failed: %s\n", 592 gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server", 572 593 gensec_gssapi_state->gss_exchange_count, 573 594 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); … … 623 644 gensec_gssapi_state->max_wrap_buf_size); 624 645 gensec_gssapi_state->sasl_protection = 0; 625 if ( gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {626 if ( security_supported & NEG_SEAL) {646 if (security_supported & NEG_SEAL) { 647 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 627 648 gensec_gssapi_state->sasl_protection |= NEG_SEAL; 628 649 } 629 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 630 if (security_supported & NEG_SIGN) { 650 } 651 if (security_supported & NEG_SIGN) { 652 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 631 653 gensec_gssapi_state->sasl_protection |= NEG_SIGN; 632 654 } 633 } else if (security_supported & NEG_NONE) { 655 } 656 if (security_supported & NEG_NONE) { 634 657 gensec_gssapi_state->sasl_protection |= NEG_NONE; 635 } else { 636 DEBUG(1, ("Remote server does not support unprotected connections")); 658 } 659 if (gensec_gssapi_state->sasl_protection == 0) { 660 DEBUG(1, ("Remote server does not support unprotected connections\n")); 637 661 return NT_STATUS_ACCESS_DENIED; 638 662 } … … 667 691 668 692 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 669 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographic ly sealed\n"));693 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically sealed\n")); 670 694 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 671 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographic ly signed\n"));695 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically signed\n")); 672 696 } else { 673 DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographic ly protection\n"));697 DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographically protection\n")); 674 698 } 675 699 … … 768 792 security_accepted = maxlength_accepted[0]; 769 793 maxlength_accepted[0] = '\0'; 770 794 771 795 /* Rest is the proposed max wrap length */ 772 796 gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_accepted, 0), … … 774 798 775 799 gensec_gssapi_state->sasl_protection = 0; 776 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 777 if (security_accepted & NEG_SEAL) { 778 gensec_gssapi_state->sasl_protection |= NEG_SEAL; 779 } 780 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 781 if (security_accepted & NEG_SIGN) { 782 gensec_gssapi_state->sasl_protection |= NEG_SIGN; 783 } 784 } else if (security_accepted & NEG_NONE) { 800 if (security_accepted & NEG_SEAL) { 801 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 802 DEBUG(1, ("Remote client wanted seal, but gensec refused\n")); 803 return NT_STATUS_ACCESS_DENIED; 804 } 805 gensec_gssapi_state->sasl_protection |= NEG_SEAL; 806 } 807 if (security_accepted & NEG_SIGN) { 808 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 809 DEBUG(1, ("Remote client wanted sign, but gensec refused\n")); 810 return NT_STATUS_ACCESS_DENIED; 811 } 812 gensec_gssapi_state->sasl_protection |= NEG_SIGN; 813 } 814 if (security_accepted & NEG_NONE) { 785 815 gensec_gssapi_state->sasl_protection |= NEG_NONE; 786 } else {787 DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better"));788 return NT_STATUS_ACCESS_DENIED;789 816 } 790 817 … … 792 819 gensec_gssapi_state->sasl_state = STAGE_DONE; 793 820 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 794 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographic ly sealed\n"));821 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically sealed\n")); 795 822 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 796 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographic ly signed\n"));823 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically signed\n")); 797 824 } else { 798 825 DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n")); … … 1231 1258 struct gensec_gssapi_state *gensec_gssapi_state 1232 1259 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1233 struct auth_ serversupplied_info *server_info= NULL;1260 struct auth_user_info_dc *user_info_dc = NULL; 1234 1261 struct auth_session_info *session_info = NULL; 1235 1262 OM_uint32 maj_stat, min_stat; 1236 1263 gss_buffer_desc pac; 1237 1264 DATA_BLOB pac_blob; 1265 struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; 1266 struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; 1238 1267 1239 1268 if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length) … … 1266 1295 */ 1267 1296 if (pac_blob.length) { 1268 nt_status = kerberos_pac_blob_to_server_info(mem_ctx, 1269 gensec_security->settings->iconv_convenience, 1270 pac_blob, 1271 gensec_gssapi_state->smb_krb5_context->krb5_context, 1272 &server_info); 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); 1273 1314 if (!NT_STATUS_IS_OK(nt_status)) { 1274 1315 talloc_free(mem_ctx); … … 1305 1346 DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", 1306 1347 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1307 nt_status = gensec_security->auth_context->get_ server_info_principal(mem_ctx,1348 nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx, 1308 1349 gensec_security->auth_context, 1309 1350 principal_string, 1310 &server_info); 1351 NULL, 1352 &user_info_dc); 1311 1353 1312 1354 if (!NT_STATUS_IS_OK(nt_status)) { … … 1322 1364 } 1323 1365 1324 /* references the server_infointo the session_info */1325 nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx,1326 gensec_security->settings->lp_ctx, server_info, &session_info);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); 1327 1369 if (!NT_STATUS_IS_OK(nt_status)) { 1328 1370 talloc_free(mem_ctx); … … 1336 1378 } 1337 1379 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 1338 1386 if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) { 1339 1387 DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); 1340 1388 } else { 1341 1389 krb5_error_code ret; 1390 const char *error_string; 1391 1342 1392 DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); 1343 1393 session_info->credentials = cli_credentials_init(session_info); … … 1352 1402 1353 1403 ret = cli_credentials_set_client_gss_creds(session_info->credentials, 1354 gensec_security->event_ctx, 1355 gensec_security->settings->lp_ctx, 1404 gensec_security->settings->lp_ctx, 1356 1405 gensec_gssapi_state->delegated_cred_handle, 1357 CRED_SPECIFIED );1406 CRED_SPECIFIED, &error_string); 1358 1407 if (ret) { 1359 1408 talloc_free(mem_ctx); 1409 DEBUG(2,("Failed to get gss creds: %s\n", error_string)); 1360 1410 return NT_STATUS_NO_MEMORY; 1361 1411 } -
vendor/current/source4/auth/gensec/gensec_gssapi.h
r414 r740 65 65 int gss_exchange_count; 66 66 size_t sig_size; 67 68 const char *target_principal; 67 69 }; 68 70 -
vendor/current/source4/auth/gensec/gensec_krb5.c
r414 r740 27 27 #include "system/kerberos.h" 28 28 #include "auth/kerberos/kerberos.h" 29 #include "librpc/gen_ndr/krb5pac.h"30 29 #include "auth/auth.h" 31 #include "lib/ldb/include/ldb.h"32 #include "auth/auth_sam.h"33 30 #include "lib/socket/socket.h" 31 #include "lib/tsocket/tsocket.h" 34 32 #include "librpc/rpc/dcerpc.h" 35 33 #include "auth/credentials/credentials.h" 36 34 #include "auth/credentials/credentials_krb5.h" 35 #include "auth/kerberos/kerberos_credentials.h" 37 36 #include "auth/gensec/gensec.h" 38 37 #include "auth/gensec/gensec_proto.h" 39 38 #include "param/param.h" 40 #include "auth/session_proto.h"41 39 #include "auth/auth_sam_reply.h" 40 #include "lib/util/util_net.h" 42 41 43 42 enum GENSEC_KRB5_STATE { … … 95 94 struct gensec_krb5_state *gensec_krb5_state; 96 95 struct cli_credentials *creds; 97 const struct socket_address *my_addr, *peer_addr;96 const struct tsocket_address *tlocal_addr, *tremote_addr; 98 97 krb5_address my_krb5_addr, peer_krb5_addr; 99 98 … … 121 120 122 121 if (cli_credentials_get_krb5_context(creds, 123 gensec_security->event_ctx,124 122 gensec_security->settings->lp_ctx, &gensec_krb5_state->smb_krb5_context)) { 125 123 talloc_free(gensec_krb5_state); … … 147 145 } 148 146 149 my_addr = gensec_get_my_addr(gensec_security); 150 if (my_addr && my_addr->sockaddr) { 151 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 152 my_addr->sockaddr, &my_krb5_addr); 147 tlocal_addr = gensec_get_local_address(gensec_security); 148 if (tlocal_addr) { 149 ssize_t socklen; 150 struct sockaddr_storage ss; 151 152 socklen = tsocket_address_bsd_sockaddr(tlocal_addr, 153 (struct sockaddr *) &ss, 154 sizeof(struct sockaddr_storage)); 155 if (socklen < 0) { 156 talloc_free(gensec_krb5_state); 157 return NT_STATUS_INTERNAL_ERROR; 158 } 159 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 160 (const struct sockaddr *) &ss, &my_krb5_addr); 153 161 if (ret) { 154 162 DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", … … 160 168 } 161 169 162 peer_addr = gensec_get_peer_addr(gensec_security); 163 if (peer_addr && peer_addr->sockaddr) { 164 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 165 peer_addr->sockaddr, &peer_krb5_addr); 170 tremote_addr = gensec_get_remote_address(gensec_security); 171 if (tremote_addr) { 172 ssize_t socklen; 173 struct sockaddr_storage ss; 174 175 socklen = tsocket_address_bsd_sockaddr(tremote_addr, 176 (struct sockaddr *) &ss, 177 sizeof(struct sockaddr_storage)); 178 if (socklen < 0) { 179 talloc_free(gensec_krb5_state); 180 return NT_STATUS_INTERNAL_ERROR; 181 } 182 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 183 (const struct sockaddr *) &ss, &peer_krb5_addr); 166 184 if (ret) { 167 185 DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", … … 175 193 ret = krb5_auth_con_setaddrs(gensec_krb5_state->smb_krb5_context->krb5_context, 176 194 gensec_krb5_state->auth_context, 177 my_addr ? &my_krb5_addr : NULL,178 peer_addr ? &peer_krb5_addr : NULL);195 tlocal_addr ? &my_krb5_addr : NULL, 196 tremote_addr ? &peer_krb5_addr : NULL); 179 197 if (ret) { 180 198 DEBUG(1,("gensec_krb5_start: krb5_auth_con_setaddrs failed (%s)\n", … … 221 239 struct ccache_container *ccache_container; 222 240 const char *hostname; 223 241 const char *error_string; 224 242 const char *principal; 225 243 krb5_data in_data; 244 struct tevent_context *previous_ev; 226 245 227 246 hostname = gensec_get_target_hostname(gensec_security); … … 264 283 ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security), 265 284 gensec_security->event_ctx, 266 gensec_security->settings->lp_ctx, &ccache_container );285 gensec_security->settings->lp_ctx, &ccache_container, &error_string); 267 286 switch (ret) { 268 287 case 0: 269 288 break; 270 289 case KRB5KDC_ERR_PREAUTH_FAILED: 290 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 271 291 return NT_STATUS_LOGON_FAILURE; 272 292 case KRB5_KDC_UNREACH: 273 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); 293 DEBUG(3, ("Cannot reach a KDC we require to contact %s: %s\n", principal, error_string)); 294 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 295 case KRB5_CC_NOTFOUND: 296 case KRB5_CC_END: 297 DEBUG(3, ("Error preparing credentials we require to contact %s : %s\n", principal, error_string)); 274 298 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 275 299 default: 276 DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_ message(ret)));300 DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_string)); 277 301 return NT_STATUS_UNSUCCESSFUL; 278 302 } 279 303 in_data.length = 0; 280 304 281 if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) { 305 /* 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); 307 if (ret != 0) { 308 DEBUG(1, ("gensec_krb5_start: Setting event context failed\n")); 309 return NT_STATUS_NO_MEMORY; 310 } 311 if (principal) { 282 312 krb5_principal target_principal; 283 313 ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal, … … 302 332 &gensec_krb5_state->enc_ticket); 303 333 } 334 335 smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx); 336 304 337 switch (ret) { 305 338 case 0: … … 459 492 struct keytab_container *keytab; 460 493 krb5_principal server_in_keytab; 494 const char *error_string; 495 enum credentials_obtained obtained; 461 496 462 497 if (!in.data) { … … 466 501 /* Grab the keytab, however generated */ 467 502 ret = cli_credentials_get_keytab(gensec_get_credentials(gensec_security), 468 gensec_security->event_ctx,469 503 gensec_security->settings->lp_ctx, &keytab); 470 504 if (ret) { … … 475 509 ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security), 476 510 gensec_krb5_state->smb_krb5_context, 477 &server_in_keytab );511 &server_in_keytab, &obtained, &error_string); 478 512 479 513 if (ret) { 514 DEBUG(2,("Failed to make credentials from principal: %s\n", error_string)); 480 515 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 481 516 } … … 569 604 struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; 570 605 krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; 571 struct auth_ serversupplied_info *server_info= NULL;606 struct auth_user_info_dc *user_info_dc = NULL; 572 607 struct auth_session_info *session_info = NULL; 573 608 struct PAC_LOGON_INFO *logon_info; … … 601 636 smb_get_krb5_error_message(context, 602 637 ret, mem_ctx))); 638 krb5_free_principal(context, client_principal); 603 639 talloc_free(mem_ctx); 604 640 return NT_STATUS_NO_MEMORY; … … 614 650 smb_get_krb5_error_message(context, 615 651 ret, mem_ctx))); 652 free(principal_string); 616 653 krb5_free_principal(context, client_principal); 617 free(principal_string);654 talloc_free(mem_ctx); 618 655 return NT_STATUS_ACCESS_DENIED; 619 656 } else if (ret) { … … 627 664 principal_string, smb_get_krb5_error_message(context, 628 665 ret, mem_ctx))); 629 nt_status = gensec_security->auth_context->get_ server_info_principal(mem_ctx,666 nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx, 630 667 gensec_security->auth_context, 631 668 principal_string, 632 &server_info);669 NULL, &user_info_dc); 633 670 if (!NT_STATUS_IS_OK(nt_status)) { 671 free(principal_string); 672 krb5_free_principal(context, client_principal); 634 673 talloc_free(mem_ctx); 635 674 return nt_status; … … 638 677 DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", 639 678 principal_string)); 679 free(principal_string); 680 krb5_free_principal(context, client_principal); 681 talloc_free(mem_ctx); 640 682 return NT_STATUS_ACCESS_DENIED; 641 }642 643 krb5_free_principal(context, client_principal);644 free(principal_string);645 646 if (!NT_STATUS_IS_OK(nt_status)) {647 talloc_free(mem_ctx);648 return nt_status;649 683 } 650 684 } else { 651 685 /* Found pac */ 652 686 union netr_Validation validation; 653 free(principal_string);654 687 655 688 pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length); 656 689 if (!pac.data) { 690 free(principal_string); 657 691 krb5_free_principal(context, client_principal); 658 692 talloc_free(mem_ctx); … … 662 696 /* decode and verify the pac */ 663 697 nt_status = kerberos_pac_logon_info(gensec_krb5_state, 664 gensec_security->settings->iconv_convenience,665 698 &logon_info, pac, 666 699 gensec_krb5_state->smb_krb5_context->krb5_context, … … 668 701 client_principal, 669 702 gensec_krb5_state->ticket->ticket.authtime, NULL); 670 krb5_free_principal(context, client_principal);671 703 672 704 if (!NT_STATUS_IS_OK(nt_status)) { 705 free(principal_string); 706 krb5_free_principal(context, client_principal); 673 707 talloc_free(mem_ctx); 674 708 return nt_status; … … 676 710 677 711 validation.sam3 = &logon_info->info3; 678 nt_status = make_ server_info_netlogon_validation(mem_ctx,712 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 679 713 NULL, 680 714 3, &validation, 681 & server_info);715 &user_info_dc); 682 716 if (!NT_STATUS_IS_OK(nt_status)) { 717 free(principal_string); 718 krb5_free_principal(context, client_principal); 683 719 talloc_free(mem_ctx); 684 720 return nt_status; … … 686 722 } 687 723 688 /* references the server_info into the session_info */ 689 nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info); 724 free(principal_string); 725 krb5_free_principal(context, client_principal); 726 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); 690 729 691 730 if (!NT_STATUS_IS_OK(nt_status)) { -
vendor/current/source4/auth/gensec/pygensec.c
r414 r740 17 17 */ 18 18 19 #include <Python.h> 19 20 #include "includes.h" 20 #include <Python.h> 21 #include "param/param.h" 21 #include "param/pyparam.h" 22 22 #include "auth/gensec/gensec.h" 23 #include "auth/credentials/pycredentials.h" 23 24 #include "libcli/util/pyerrors.h" 24 #include "pytalloc.h" 25 #include "scripting/python/modules.h" 26 #include "lib/talloc/pytalloc.h" 25 27 #include <tevent.h> 26 27 #ifndef Py_RETURN_NONE 28 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None 29 #endif 28 #include "librpc/rpc/pyrpc_util.h" 30 29 31 30 static PyObject *py_get_name_by_authtype(PyObject *self, PyObject *args) … … 38 37 return NULL; 39 38 40 security = (struct gensec_security *)py_talloc_get_ptr(self);39 security = py_talloc_get_type(self, struct gensec_security); 41 40 42 41 name = gensec_get_name_by_authtype(security, type); … … 47 46 } 48 47 49 static struct gensec_settings *settings_from_object(PyObject *object) 50 { 51 return NULL; /* FIXME */ 48 static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObject *object) 49 { 50 struct gensec_settings *s; 51 PyObject *py_hostname, *py_lp_ctx; 52 53 if (!PyDict_Check(object)) { 54 PyErr_SetString(PyExc_ValueError, "settings should be a dictionary"); 55 return NULL; 56 } 57 58 s = talloc_zero(mem_ctx, struct gensec_settings); 59 if (!s) return NULL; 60 61 py_hostname = PyDict_GetItemString(object, "target_hostname"); 62 if (!py_hostname) { 63 PyErr_SetString(PyExc_ValueError, "settings.target_hostname not found"); 64 return NULL; 65 } 66 67 py_lp_ctx = PyDict_GetItemString(object, "lp_ctx"); 68 if (!py_lp_ctx) { 69 PyErr_SetString(PyExc_ValueError, "settings.lp_ctx not found"); 70 return NULL; 71 } 72 73 s->target_hostname = PyString_AsString(py_hostname); 74 s->lp_ctx = lpcfg_from_py_object(s, py_lp_ctx); 75 return s; 52 76 } 53 77 … … 60 84 PyObject *py_settings; 61 85 struct tevent_context *ev; 62 63 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_settings)) 64 return NULL; 65 66 settings = settings_from_object(py_settings); 67 if (settings == NULL) 68 return NULL; 69 86 struct gensec_security *gensec; 87 88 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings)) 89 return NULL; 90 70 91 self = (py_talloc_Object*)type->tp_alloc(type, 0); 71 92 if (self == NULL) { … … 78 99 return NULL; 79 100 } 101 102 if (py_settings != Py_None) { 103 settings = settings_from_object(self->talloc_ctx, py_settings); 104 if (settings == NULL) { 105 PyObject_DEL(self); 106 return NULL; 107 } 108 } else { 109 settings = talloc_zero(self->talloc_ctx, struct gensec_settings); 110 if (settings == NULL) { 111 PyObject_DEL(self); 112 return NULL; 113 } 114 115 settings->lp_ctx = loadparm_init_global(true); 116 } 117 80 118 ev = tevent_context_init(self->talloc_ctx); 81 119 if (ev == NULL) { … … 84 122 return NULL; 85 123 } 86 status = gensec_client_start(self->talloc_ctx, 87 (struct gensec_security **)&self->ptr, ev, settings);124 125 status = gensec_init(settings->lp_ctx); 88 126 if (!NT_STATUS_IS_OK(status)) { 89 127 PyErr_SetNTSTATUS(status); … … 91 129 return NULL; 92 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; 140 93 141 return (PyObject *)self; 94 142 } 95 143 144 static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyObject *kwargs) 145 { 146 NTSTATUS status; 147 py_talloc_Object *self; 148 struct gensec_settings *settings = NULL; 149 const char *kwnames[] = { "settings", "auth_context", NULL }; 150 PyObject *py_settings = Py_None; 151 PyObject *py_auth_context = Py_None; 152 struct tevent_context *ev; 153 struct gensec_security *gensec; 154 struct auth_context *auth_context = NULL; 155 156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) 157 return NULL; 158 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 } 169 170 if (py_settings != Py_None) { 171 settings = settings_from_object(self->talloc_ctx, py_settings); 172 if (settings == NULL) { 173 PyObject_DEL(self); 174 return NULL; 175 } 176 } else { 177 settings = talloc_zero(self->talloc_ctx, struct gensec_settings); 178 if (settings == NULL) { 179 PyObject_DEL(self); 180 return NULL; 181 } 182 183 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; 191 } 192 193 if (py_auth_context != Py_None) { 194 auth_context = py_talloc_get_type(py_auth_context, struct auth_context); 195 if (!auth_context) { 196 PyErr_Format(PyExc_TypeError, 197 "Expected auth.AuthContext for auth_context argument, got %s", 198 talloc_get_name(py_talloc_get_ptr(py_auth_context))); 199 return NULL; 200 } 201 } 202 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; 220 } 221 222 static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args) 223 { 224 PyObject *py_creds = Py_None; 225 struct cli_credentials *creds; 226 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 227 NTSTATUS status; 228 229 if (!PyArg_ParseTuple(args, "O", &py_creds)) 230 return NULL; 231 232 creds = PyCredentials_AsCliCredentials(py_creds); 233 if (!creds) { 234 PyErr_Format(PyExc_TypeError, 235 "Expected samba.credentaials for credentials argument got %s", 236 talloc_get_name(py_talloc_get_ptr(py_creds))); 237 } 238 239 status = gensec_set_credentials(security, creds); 240 if (!NT_STATUS_IS_OK(status)) { 241 PyErr_SetNTSTATUS(status); 242 return NULL; 243 } 244 245 Py_RETURN_NONE; 246 } 247 96 248 static PyObject *py_gensec_session_info(PyObject *self) 97 249 { 98 250 NTSTATUS status; 99 struct gensec_security *security = (struct gensec_security *)py_talloc_get_ptr(self); 251 PyObject *py_session_info; 252 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 100 253 struct auth_session_info *info; 254 if (security->ops == NULL) { 255 PyErr_SetString(PyExc_RuntimeError, "no mechanism selected"); 256 return NULL; 257 } 101 258 status = gensec_session_info(security, &info); 102 259 if (NT_STATUS_IS_ERR(status)) { … … 105 262 } 106 263 107 /* FIXME */ 264 py_session_info = py_return_ndr_struct("samba.auth", "AuthSession", 265 info, info); 266 return py_session_info; 267 } 268 269 static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args) 270 { 271 char *name; 272 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 273 NTSTATUS status; 274 275 if (!PyArg_ParseTuple(args, "s", &name)) 276 return NULL; 277 278 status = gensec_start_mech_by_name(security, name); 279 if (!NT_STATUS_IS_OK(status)) { 280 PyErr_SetNTSTATUS(status); 281 return NULL; 282 } 283 108 284 Py_RETURN_NONE; 285 } 286 287 static PyObject *py_gensec_start_mech_by_sasl_name(PyObject *self, PyObject *args) 288 { 289 char *sasl_name; 290 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 291 NTSTATUS status; 292 293 if (!PyArg_ParseTuple(args, "s", &sasl_name)) 294 return NULL; 295 296 status = gensec_start_mech_by_sasl_name(security, sasl_name); 297 if (!NT_STATUS_IS_OK(status)) { 298 PyErr_SetNTSTATUS(status); 299 return NULL; 300 } 301 302 Py_RETURN_NONE; 303 } 304 305 static PyObject *py_gensec_start_mech_by_authtype(PyObject *self, PyObject *args) 306 { 307 int authtype, level; 308 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 309 NTSTATUS status; 310 if (!PyArg_ParseTuple(args, "ii", &authtype, &level)) 311 return NULL; 312 313 status = gensec_start_mech_by_authtype(security, authtype, level); 314 if (!NT_STATUS_IS_OK(status)) { 315 PyErr_SetNTSTATUS(status); 316 return NULL; 317 } 318 319 Py_RETURN_NONE; 320 } 321 322 static PyObject *py_gensec_want_feature(PyObject *self, PyObject *args) 323 { 324 int feature; 325 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 326 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 327 if (!PyArg_ParseTuple(args, "i", &feature)) 328 return NULL; 329 330 gensec_want_feature(security, feature); 331 332 Py_RETURN_NONE; 333 } 334 335 static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args) 336 { 337 int feature; 338 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 339 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 340 if (!PyArg_ParseTuple(args, "i", &feature)) 341 return NULL; 342 343 if (gensec_have_feature(security, feature)) { 344 return Py_True; 345 } 346 return Py_False; 347 } 348 349 static PyObject *py_gensec_update(PyObject *self, PyObject *args) 350 { 351 NTSTATUS status; 352 TALLOC_CTX *mem_ctx; 353 DATA_BLOB in, out; 354 PyObject *ret, *py_in; 355 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 356 PyObject *finished_processing; 357 358 if (!PyArg_ParseTuple(args, "O", &py_in)) 359 return NULL; 360 361 mem_ctx = talloc_new(NULL); 362 363 if (!PyString_Check(py_in)) { 364 PyErr_Format(PyExc_TypeError, "expected a string"); 365 return NULL; 366 } 367 368 in.data = (uint8_t *)PyString_AsString(py_in); 369 in.length = PyString_Size(py_in); 370 371 status = gensec_update(security, mem_ctx, in, &out); 372 373 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) 374 && !NT_STATUS_IS_OK(status)) { 375 PyErr_SetNTSTATUS(status); 376 talloc_free(mem_ctx); 377 return NULL; 378 } 379 ret = PyString_FromStringAndSize((const char *)out.data, out.length); 380 talloc_free(mem_ctx); 381 382 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 383 finished_processing = Py_False; 384 } else { 385 finished_processing = Py_True; 386 } 387 388 return PyTuple_Pack(2, finished_processing, ret); 389 } 390 391 static PyObject *py_gensec_wrap(PyObject *self, PyObject *args) 392 { 393 NTSTATUS status; 394 395 TALLOC_CTX *mem_ctx; 396 DATA_BLOB in, out; 397 PyObject *ret, *py_in; 398 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 399 400 if (!PyArg_ParseTuple(args, "O", &py_in)) 401 return NULL; 402 403 mem_ctx = talloc_new(NULL); 404 405 if (!PyString_Check(py_in)) { 406 PyErr_Format(PyExc_TypeError, "expected a string"); 407 return NULL; 408 } 409 in.data = (uint8_t *)PyString_AsString(py_in); 410 in.length = PyString_Size(py_in); 411 412 status = gensec_wrap(security, mem_ctx, &in, &out); 413 414 if (!NT_STATUS_IS_OK(status)) { 415 PyErr_SetNTSTATUS(status); 416 talloc_free(mem_ctx); 417 return NULL; 418 } 419 420 ret = PyString_FromStringAndSize((const char *)out.data, out.length); 421 talloc_free(mem_ctx); 422 return ret; 423 } 424 425 static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) 426 { 427 NTSTATUS status; 428 429 TALLOC_CTX *mem_ctx; 430 DATA_BLOB in, out; 431 PyObject *ret, *py_in; 432 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 433 434 if (!PyArg_ParseTuple(args, "O", &py_in)) 435 return NULL; 436 437 mem_ctx = talloc_new(NULL); 438 439 if (!PyString_Check(py_in)) { 440 PyErr_Format(PyExc_TypeError, "expected a string"); 441 return NULL; 442 } 443 444 in.data = (uint8_t *)PyString_AsString(py_in); 445 in.length = PyString_Size(py_in); 446 447 status = gensec_unwrap(security, mem_ctx, &in, &out); 448 449 if (!NT_STATUS_IS_OK(status)) { 450 PyErr_SetNTSTATUS(status); 451 talloc_free(mem_ctx); 452 return NULL; 453 } 454 455 ret = PyString_FromStringAndSize((const char *)out.data, out.length); 456 talloc_free(mem_ctx); 457 return ret; 109 458 } 110 459 … … 112 461 { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS, 113 462 "S.start_client(settings) -> gensec" }, 114 /* { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS, 115 "S.start_server(auth_ctx, settings) -> gensec" },*/ 463 { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS, 464 "S.start_server(auth_ctx, settings) -> gensec" }, 465 { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, 466 "S.start_client(credentials)" }, 116 467 { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS, 117 "S.session_info() -> info" }, 468 "S.session_info() -> info" }, 469 { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS, 470 "S.start_mech_by_name(name)" }, 471 { "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)" }, 118 474 { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS, 119 475 "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." }, 476 { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS, 477 "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." }, 478 { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS, 479 "S.have_feature()\n Return True if GENSEC negotiated a particular feature." }, 480 { "update", (PyCFunction)py_gensec_update, METH_VARARGS, 481 "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance. Repeat with new packets until finished is true or exception." }, 482 { "wrap", (PyCFunction)py_gensec_wrap, METH_VARARGS, 483 "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." }, 484 { "unwrap", (PyCFunction)py_gensec_unwrap, METH_VARARGS, 485 "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." }, 486 120 487 { NULL } 121 488 }; … … 126 493 .tp_methods = py_gensec_security_methods, 127 494 .tp_basicsize = sizeof(py_talloc_Object), 128 .tp_dealloc = py_talloc_dealloc,129 495 }; 130 496 497 void initgensec(void); 131 498 void initgensec(void) 132 499 { 133 500 PyObject *m; 501 502 Py_Security.tp_base = PyTalloc_GetObjectType(); 503 if (Py_Security.tp_base == NULL) 504 return; 134 505 135 506 if (PyType_Ready(&Py_Security) < 0) … … 140 511 return; 141 512 513 PyModule_AddObject(m, "FEATURE_SESSION_KEY", PyInt_FromLong(GENSEC_FEATURE_SESSION_KEY)); 514 PyModule_AddObject(m, "FEATURE_SIGN", PyInt_FromLong(GENSEC_FEATURE_SIGN)); 515 PyModule_AddObject(m, "FEATURE_SEAL", PyInt_FromLong(GENSEC_FEATURE_SEAL)); 516 PyModule_AddObject(m, "FEATURE_DCE_STYLE", PyInt_FromLong(GENSEC_FEATURE_DCE_STYLE)); 517 PyModule_AddObject(m, "FEATURE_ASYNC_REPLIES", PyInt_FromLong(GENSEC_FEATURE_ASYNC_REPLIES)); 518 PyModule_AddObject(m, "FEATURE_DATAGRAM_MODE", PyInt_FromLong(GENSEC_FEATURE_DATAGRAM_MODE)); 519 PyModule_AddObject(m, "FEATURE_SIGN_PKT_HEADER", PyInt_FromLong(GENSEC_FEATURE_SIGN_PKT_HEADER)); 520 PyModule_AddObject(m, "FEATURE_NEW_SPNEGO", PyInt_FromLong(GENSEC_FEATURE_NEW_SPNEGO)); 521 142 522 Py_INCREF(&Py_Security); 143 523 PyModule_AddObject(m, "Security", (PyObject *)&Py_Security); -
vendor/current/source4/auth/gensec/schannel.c
r414 r740 28 28 #include "auth/gensec/gensec_proto.h" 29 29 #include "../libcli/auth/schannel.h" 30 #include "auth/gensec/schannel_state.h"31 30 #include "librpc/rpc/dcerpc.h" 32 31 #include "param/param.h" 33 #include "auth/session_proto.h"34 32 35 33 static size_t schannel_sig_size(struct gensec_security *gensec_security, size_t data_size) 36 34 { 37 return 32; 35 struct schannel_state *state = (struct schannel_state *)gensec_security->private_data; 36 uint32_t sig_size; 37 38 sig_size = netsec_outgoing_sig_size(state); 39 40 return sig_size; 38 41 } 39 42 … … 53 56 struct NL_AUTH_MESSAGE bind_schannel_ack; 54 57 struct netlogon_creds_CredentialState *creds; 55 struct ldb_context *schannel_ldb;56 58 const char *workstation; 57 59 const char *domain; 58 uint32_t required_flags;59 60 60 61 *out = data_blob(NULL, 0); … … 91 92 #endif 92 93 93 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, 94 gensec_security->settings->iconv_convenience, &bind_schannel, 94 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel, 95 95 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); 96 96 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 106 106 case GENSEC_SERVER: 107 107 108 required_flags = NL_FLAG_OEM_NETBIOS_COMPUTER_NAME |109 NL_FLAG_OEM_NETBIOS_DOMAIN_NAME;110 111 108 if (state->state != SCHANNEL_STATE_START) { 112 109 /* no third leg on this protocol */ … … 115 112 116 113 /* parse the schannel startup blob */ 117 ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, 118 gensec_security->settings->iconv_convenience, 119 &bind_schannel, 114 ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, 120 115 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE); 121 116 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 126 121 } 127 122 128 if (!(required_flags == (bind_schannel.Flags & required_flags))) { 129 return NT_STATUS_INVALID_PARAMETER; 130 } 131 132 workstation = bind_schannel.oem_netbios_computer.a; 133 domain = bind_schannel.oem_netbios_domain.a; 134 135 if (strcasecmp_m(domain, lp_workgroup(gensec_security->settings->lp_ctx)) != 0) { 136 DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", 137 domain, lp_workgroup(gensec_security->settings->lp_ctx))); 138 123 if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_DOMAIN_NAME) { 124 domain = bind_schannel.oem_netbios_domain.a; 125 if (strcasecmp_m(domain, lpcfg_workgroup(gensec_security->settings->lp_ctx)) != 0) { 126 DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", 127 domain, lpcfg_workgroup(gensec_security->settings->lp_ctx))); 128 return NT_STATUS_LOGON_FAILURE; 129 } 130 } else if (bind_schannel.Flags & NL_FLAG_UTF8_DNS_DOMAIN_NAME) { 131 domain = bind_schannel.utf8_dns_domain.u; 132 if (strcasecmp_m(domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx)) != 0) { 133 DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", 134 domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx))); 135 return NT_STATUS_LOGON_FAILURE; 136 } 137 } else { 138 DEBUG(3, ("Request for schannel to without domain\n")); 139 139 return NT_STATUS_LOGON_FAILURE; 140 140 } 141 141 142 schannel_ldb = schannel_db_connect(out_mem_ctx, gensec_security->event_ctx, 143 gensec_security->settings->lp_ctx); 144 if (!schannel_ldb) { 145 return NT_STATUS_ACCESS_DENIED; 146 } 147 /* pull the session key for this client */ 148 status = schannel_fetch_session_key_ldb(schannel_ldb, 149 out_mem_ctx, workstation, &creds); 150 talloc_free(schannel_ldb); 142 if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME) { 143 workstation = bind_schannel.oem_netbios_computer.a; 144 } else if (bind_schannel.Flags & NL_FLAG_UTF8_NETBIOS_COMPUTER_NAME) { 145 workstation = bind_schannel.utf8_netbios_computer.u; 146 } else { 147 DEBUG(3, ("Request for schannel to without netbios workstation\n")); 148 return NT_STATUS_LOGON_FAILURE; 149 } 150 151 status = schannel_get_creds_state(out_mem_ctx, 152 lpcfg_private_dir(gensec_security->settings->lp_ctx), 153 workstation, &creds); 151 154 if (!NT_STATUS_IS_OK(status)) { 152 155 DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", … … 158 161 } 159 162 160 state->creds = talloc_ reference(state, creds);163 state->creds = talloc_steal(state, creds); 161 164 162 165 bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE; … … 167 170 * - gd */ 168 171 169 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, 170 gensec_security->settings->iconv_convenience, &bind_schannel_ack, 172 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack, 171 173 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); 172 174 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 215 217 { 216 218 struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); 217 return auth_anonymous_session_info(state, gensec_security-> event_ctx, gensec_security->settings->lp_ctx, _session_info);219 return auth_anonymous_session_info(state, gensec_security->settings->lp_ctx, _session_info); 218 220 } 219 221 -
vendor/current/source4/auth/gensec/socket.c
r414 r740 78 78 &unwrapped, &wrapped); 79 79 if (!NT_STATUS_IS_OK(nt_status)) { 80 talloc_free(mem_ctx);81 80 return nt_status; 82 81 } -
vendor/current/source4/auth/gensec/spnego.c
r414 r740 29 29 #include "auth/gensec/gensec.h" 30 30 #include "auth/gensec/gensec_proto.h" 31 #include "param/param.h" 31 32 32 33 enum spnego_state_position { … … 420 421 421 422 if (spnego_state->state_position == SPNEGO_SERVER_START) { 422 for (i=0; all_sec && all_sec[i].op; i++) {423 /* optomisitic token */424 if (strcmp(all_sec[i].oid, mechType[0]) == 0) {423 uint32_t j; 424 for (j=0; mechType && mechType[j]; j++) { 425 for (i=0; all_sec && all_sec[i].op; i++) { 425 426 nt_status = gensec_subcontext_start(spnego_state, 426 427 gensec_security, … … 437 438 break; 438 439 } 439 440 441 if (j > 0) { 442 /* no optimistic token */ 443 spnego_state->neg_oid = all_sec[i].oid; 444 *unwrapped_out = data_blob_null; 445 nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; 446 break; 447 } 448 440 449 nt_status = gensec_update(spnego_state->sub_sec_security, 441 450 out_mem_ctx, … … 456 465 break; 457 466 } 458 } 459 } 460 461 /* Having tried any optomisitc token from the client (if we 467 if (spnego_state->sub_sec_security) { 468 break; 469 } 470 } 471 472 if (!spnego_state->sub_sec_security) { 473 DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); 474 return NT_STATUS_INVALID_PARAMETER; 475 } 476 } 477 478 /* Having tried any optimistic token from the client (if we 462 479 * were the server), if we didn't get anywhere, walk our list 463 480 * in our preference order */ … … 495 512 if (spnego_state->state_position != SPNEGO_SERVER_START) { 496 513 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) || 514 NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_LOGON_SERVERS) || 515 NT_STATUS_EQUAL(nt_status, NT_STATUS_TIME_DIFFERENCE_AT_DC) || 497 516 NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) { 498 517 /* Pretend we never started it (lets the first run find some incompatible demand) */ … … 566 585 DATA_BLOB unwrapped_out = data_blob(NULL, 0); 567 586 const struct gensec_security_ops_wrapper *all_sec; 568 const char *principal = NULL;569 587 570 588 mechTypes = gensec_security_oids(gensec_security, … … 633 651 634 652 if (spnego_state->state_position == SPNEGO_SERVER_START) { 635 /* server credentials */636 struct cli_credentials *creds = gensec_get_credentials(gensec_security);637 if (creds) {638 principal = cli_credentials_get_principal(creds, out_mem_ctx);639 }640 }641 if (principal) {642 653 spnego_out.negTokenInit.mechListMIC 643 = data_blob_string_const( principal);654 = data_blob_string_const(ADS_IGNORE_PRINCIPAL); 644 655 } else { 645 656 spnego_out.negTokenInit.mechListMIC = null_data_blob; … … 825 836 } 826 837 827 if (spnego.negTokenInit.targetPrincipal) { 838 if (spnego.negTokenInit.targetPrincipal 839 && strcmp(spnego.negTokenInit.targetPrincipal, ADS_IGNORE_PRINCIPAL) != 0) { 828 840 DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal)); 829 gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal); 841 if (lpcfg_client_use_spnego_principal(gensec_security->settings->lp_ctx)) { 842 gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal); 843 } 830 844 } 831 845
Note:
See TracChangeset
for help on using the changeset viewer.