Changeset 745 for trunk/server/source4/auth/gensec/gensec.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/auth/gensec/gensec.c
r414 r745 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;
Note:
See TracChangeset
for help on using the changeset viewer.