Changeset 745 for trunk/server/source4/rpc_server
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 1 deleted
- 33 edited
- 8 copied
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/rpc_server/browser/dcesrv_browser.c
r414 r745 73 73 return WERR_UNKNOWN_LEVEL; 74 74 } 75 76 return WERR_INVALID_PARAM;77 75 } 78 76 -
trunk/server/source4/rpc_server/common/common.h
r414 r745 25 25 26 26 struct share_config; 27 struct dcesrv_connection; 27 28 struct dcesrv_context; 28 29 struct dcesrv_context; 30 struct dcesrv_call_state; 31 struct ndr_interface_table; 32 struct ncacn_packet; 29 33 30 34 struct dcerpc_server_info { … … 35 39 }; 36 40 37 struct ndr_interface_table;38 struct dcesrv_call_state;39 41 #include "rpc_server/common/proto.h" 40 42 -
trunk/server/source4/rpc_server/common/forward.c
r414 r745 21 21 22 22 #include "includes.h" 23 #include <tevent.h> 23 24 #include "rpc_server/dcerpc_server.h" 25 #include "librpc/gen_ndr/dcerpc.h" 26 #include "rpc_server/common/common.h" 24 27 #include "messaging/irpc.h" 28 #include "auth/auth.h" 29 25 30 26 31 struct dcesrv_forward_state { … … 32 37 called when the forwarded rpc request is finished 33 38 */ 34 static void dcesrv_irpc_forward_callback(struct irpc_request *ireq)39 static void dcesrv_irpc_forward_callback(struct tevent_req *subreq) 35 40 { 36 struct dcesrv_forward_state *st = talloc_get_type(ireq->async.private_data, 37 struct dcesrv_forward_state); 41 struct dcesrv_forward_state *st = 42 tevent_req_callback_data(subreq, 43 struct dcesrv_forward_state); 38 44 const char *opname = st->opname; 39 45 NTSTATUS status; 40 if (!NT_STATUS_IS_OK(ireq->status)) { 46 47 status = dcerpc_binding_handle_call_recv(subreq); 48 TALLOC_FREE(subreq); 49 if (!NT_STATUS_IS_OK(status)) { 41 50 DEBUG(0,("IRPC callback failed for %s - %s\n", 42 opname, nt_errstr( ireq->status)));51 opname, nt_errstr(status))); 43 52 st->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 44 53 } 45 talloc_free(ireq);46 54 status = dcesrv_reply(st->dce_call); 47 55 if (!NT_STATUS_IS_OK(status)) { … … 53 61 54 62 55 /* 56 forward a RPC call using IRPC to another task63 /** 64 * Forward a RPC call using IRPC to another task 57 65 */ 58 66 void dcesrv_irpc_forward_rpc_call(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 59 67 void *r, uint32_t callid, 60 68 const struct ndr_interface_table *ndr_table, 61 const char *dest_task, const char *opname) 69 const char *dest_task, const char *opname, 70 uint32_t timeout) 62 71 { 63 struct server_id *sid;64 struct irpc_request *ireq;65 72 struct dcesrv_forward_state *st; 73 struct dcerpc_binding_handle *binding_handle; 74 struct tevent_req *subreq; 75 struct security_token *token; 66 76 67 77 st = talloc(mem_ctx, struct dcesrv_forward_state); … … 83 93 } 84 94 85 /* find the server task */ 86 sid = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, dest_task); 87 if (sid == NULL || sid[0].id == 0) { 88 DEBUG(0,("%s: Unable to find %s task\n", dest_task, opname)); 95 binding_handle = irpc_binding_handle_by_name(st, dce_call->msg_ctx, 96 dest_task, ndr_table); 97 if (binding_handle == NULL) { 98 DEBUG(0,("%s: Failed to forward request to %s task\n", 99 opname, dest_task)); 89 100 dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 90 101 return; 91 102 } 92 103 104 /* reset timeout for the handle */ 105 dcerpc_binding_handle_set_timeout(binding_handle, timeout); 106 107 /* add security token to the handle*/ 108 token = dce_call->conn->auth_state.session_info->security_token; 109 irpc_binding_handle_add_security_token(binding_handle, token); 110 93 111 /* forward the call */ 94 ireq = irpc_call_send(dce_call->msg_ctx, sid[0], ndr_table, callid, r, mem_ctx); 95 if (ireq == NULL) { 112 subreq = dcerpc_binding_handle_call_send(st, dce_call->event_ctx, 113 binding_handle, 114 NULL, ndr_table, 115 callid, 116 dce_call, r); 117 if (subreq == NULL) { 96 118 DEBUG(0,("%s: Failed to forward request to %s task\n", 97 119 opname, dest_task)); … … 104 126 105 127 /* setup the callback */ 106 ireq->async.fn = dcesrv_irpc_forward_callback; 107 ireq->async.private_data = st; 128 tevent_req_set_callback(subreq, dcesrv_irpc_forward_callback, st); 108 129 } -
trunk/server/source4/rpc_server/common/server_info.c
r414 r745 21 21 22 22 #include "includes.h" 23 #include "librpc/gen_ndr/ ndr_srvsvc.h"23 #include "librpc/gen_ndr/srvsvc.h" 24 24 #include "rpc_server/dcerpc_server.h" 25 25 #include "dsdb/samdb/samdb.h" 26 26 #include "auth/auth.h" 27 27 #include "param/param.h" 28 #include "rpc_server/common/common.h"29 28 30 29 /* … … 37 36 enum srvsvc_PlatformId id; 38 37 39 id = lp _parm_int(dce_ctx->lp_ctx, NULL, "server_info", "platform_id", PLATFORM_ID_NT);38 id = lpcfg_parm_int(dce_ctx->lp_ctx, NULL, "server_info", "platform_id", PLATFORM_ID_NT); 40 39 41 40 return id; … … 48 47 /* if there's no string return our NETBIOS name */ 49 48 if (!p) { 50 return talloc_strdup(mem_ctx, lp _netbios_name(dce_ctx->lp_ctx));49 return talloc_strdup(mem_ctx, lpcfg_netbios_name(dce_ctx->lp_ctx)); 51 50 } 52 51 … … 68 67 default_server_announce |= SV_TYPE_SERVER_UNIX; 69 68 70 switch (lp _announce_as(dce_ctx->lp_ctx)) {69 switch (lpcfg_announce_as(dce_ctx->lp_ctx)) { 71 70 case ANNOUNCE_AS_NT_SERVER: 72 71 default_server_announce |= SV_TYPE_SERVER_NT; … … 85 84 } 86 85 87 switch (lp _server_role(dce_ctx->lp_ctx)) {86 switch (lpcfg_server_role(dce_ctx->lp_ctx)) { 88 87 case ROLE_DOMAIN_MEMBER: 89 88 default_server_announce |= SV_TYPE_DOMAIN_MEMBER; … … 97 96 } 98 97 /* open main ldb */ 99 samctx = samdb_connect(tmp_ctx, event_ctx, dce_ctx->lp_ctx, anonymous_session(tmp_ctx, event_ctx, dce_ctx->lp_ctx));98 samctx = samdb_connect(tmp_ctx, event_ctx, dce_ctx->lp_ctx, anonymous_session(tmp_ctx, dce_ctx->lp_ctx), 0); 100 99 if (samctx == NULL) { 101 100 DEBUG(2,("Unable to open samdb in determining server announce flags\n")); … … 117 116 break; 118 117 } 119 if (lp _time_server(dce_ctx->lp_ctx))118 if (lpcfg_time_server(dce_ctx->lp_ctx)) 120 119 default_server_announce |= SV_TYPE_TIME_SOURCE; 121 120 122 if (lp _host_msdfs(dce_ctx->lp_ctx))121 if (lpcfg_host_msdfs(dce_ctx->lp_ctx)) 123 122 default_server_announce |= SV_TYPE_DFS_SERVER; 124 123 -
trunk/server/source4/rpc_server/dcerpc_server.c
r414 r745 22 22 23 23 #include "includes.h" 24 #include "librpc/gen_ndr/ndr_dcerpc.h"25 24 #include "auth/auth.h" 26 25 #include "auth/gensec/gensec.h" … … 28 27 #include "rpc_server/dcerpc_server.h" 29 28 #include "rpc_server/dcerpc_server_proto.h" 29 #include "rpc_server/common/proto.h" 30 30 #include "librpc/rpc/dcerpc_proto.h" 31 #include "lib/events/events.h"32 #include "smbd/service_task.h"33 #include "smbd/service_stream.h"34 #include "smbd/service.h"35 31 #include "system/filesys.h" 36 32 #include "libcli/security/security.h" 37 33 #include "param/param.h" 34 #include "../lib/tsocket/tsocket.h" 35 #include "../libcli/named_pipe_auth/npa_tstream.h" 36 #include "smbd/service_stream.h" 37 #include "../lib/tsocket/tsocket.h" 38 #include "lib/socket/socket.h" 39 #include "smbd/process_model.h" 40 #include "lib/messaging/irpc.h" 41 #include "librpc/rpc/rpc_common.h" 38 42 39 43 /* this is only used when the client asks for an unknown interface */ … … 337 341 } 338 342 339 NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p,340 DATA_BLOB *session_key)341 {342 /* this took quite a few CPU cycles to find ... */343 session_key->data = discard_const_p(uint8_t, "SystemLibraryDTC");344 session_key->length = 16;345 return NT_STATUS_OK;346 }347 348 343 /* 349 344 fetch the user session key - may be default (above) or the SMB session key … … 395 390 p->contexts = NULL; 396 391 p->call_list = NULL; 397 p->packet_log_dir = lp _lockdir(dce_ctx->lp_ctx);392 p->packet_log_dir = lpcfg_lockdir(dce_ctx->lp_ctx); 398 393 p->incoming_fragmented_call_list = NULL; 399 394 p->pending_call_list = NULL; … … 415 410 } 416 411 417 static void dcesrv_init_hdr(struct ncacn_packet *pkt, bool bigendian)418 {419 pkt->rpc_vers = 5;420 pkt->rpc_vers_minor = 0;421 if (bigendian) {422 pkt->drep[0] = 0;423 } else {424 pkt->drep[0] = DCERPC_DREP_LE;425 }426 pkt->drep[1] = 0;427 pkt->drep[2] = 0;428 pkt->drep[3] = 0;429 }430 431 412 /* 432 413 move a call from an existing linked list to the specified list. This … … 466 447 } 467 448 468 /*469 return a dcerpc fault470 */471 static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code)472 {473 struct ncacn_packet pkt;474 struct data_blob_list_item *rep;475 uint8_t zeros[4];476 NTSTATUS status;477 478 /* setup a bind_ack */479 dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx));480 pkt.auth_length = 0;481 pkt.call_id = call->pkt.call_id;482 pkt.ptype = DCERPC_PKT_FAULT;483 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;484 pkt.u.fault.alloc_hint = 0;485 pkt.u.fault.context_id = 0;486 pkt.u.fault.cancel_count = 0;487 pkt.u.fault.status = fault_code;488 489 ZERO_STRUCT(zeros);490 pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros));491 492 rep = talloc(call, struct data_blob_list_item);493 if (!rep) {494 return NT_STATUS_NO_MEMORY;495 }496 497 status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx), &pkt, NULL);498 if (!NT_STATUS_IS_OK(status)) {499 return status;500 }501 502 dcerpc_set_frag_length(&rep->blob, rep->blob.length);503 504 DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);505 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);506 507 if (call->conn->call_list && call->conn->call_list->replies) {508 if (call->conn->transport.report_output_data) {509 call->conn->transport.report_output_data(call->conn);510 }511 }512 513 return NT_STATUS_OK;514 }515 516 449 517 450 /* … … 525 458 526 459 /* setup a bind_nak */ 527 dcesrv_init_hdr(&pkt, lp _rpc_big_endian(call->conn->dce_ctx->lp_ctx));460 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); 528 461 pkt.auth_length = 0; 529 462 pkt.call_id = call->pkt.call_id; … … 540 473 } 541 474 542 status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx),&pkt, NULL);475 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL); 543 476 if (!NT_STATUS_IS_OK(status)) { 544 477 return status; … … 563 496 DLIST_REMOVE(c->conn->contexts, c); 564 497 565 if (c->iface ) {498 if (c->iface && c->iface->unbind) { 566 499 c->iface->unbind(c, c->iface); 567 500 } … … 589 522 */ 590 523 if (call->pkt.u.bind.assoc_group_id != 0 && 591 lp _parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) &&524 lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && 592 525 dcesrv_assoc_group_find(call->conn->dce_ctx, call->pkt.u.bind.assoc_group_id) == NULL) { 593 526 return dcesrv_bind_nak(call, 0); … … 657 590 talloc_set_destructor(context, dcesrv_connection_context_destructor); 658 591 659 status = iface->bind(call, iface );592 status = iface->bind(call, iface, if_version); 660 593 if (!NT_STATUS_IS_OK(status)) { 661 594 char *uuid_str = GUID_string(call, &uuid); … … 676 609 677 610 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) && 678 lp _parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","header signing", false)) {611 lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","header signing", false)) { 679 612 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_HEADER_SIGNING; 680 613 extra_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; … … 689 622 690 623 /* setup a bind_ack */ 691 dcesrv_init_hdr(&pkt, lp _rpc_big_endian(call->conn->dce_ctx->lp_ctx));624 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); 692 625 pkt.auth_length = 0; 693 626 pkt.call_id = call->pkt.call_id; … … 741 674 } 742 675 743 status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx), &pkt, call->conn->auth_state.auth_info); 676 status = ncacn_push_auth(&rep->blob, call, &pkt, 677 call->conn->auth_state.auth_info); 744 678 if (!NT_STATUS_IS_OK(status)) { 745 679 talloc_free(call->context); … … 836 770 talloc_set_destructor(context, dcesrv_connection_context_destructor); 837 771 838 status = iface->bind(call, iface );772 status = iface->bind(call, iface, if_version); 839 773 if (!NT_STATUS_IS_OK(status)) { 840 774 /* we don't want to trigger the iface->unbind() hook */ … … 883 817 if (result == 0 && 884 818 call->pkt.u.alter.assoc_group_id != 0 && 885 lp _parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) &&819 lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && 886 820 call->pkt.u.alter.assoc_group_id != call->context->assoc_group->id) { 887 821 DEBUG(0,(__location__ ": Failed attempt to use new assoc_group in alter context (0x%08x 0x%08x)\n", … … 893 827 894 828 /* setup a alter_resp */ 895 dcesrv_init_hdr(&pkt, lp _rpc_big_endian(call->conn->dce_ctx->lp_ctx));829 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); 896 830 pkt.auth_length = 0; 897 831 pkt.call_id = call->pkt.call_id; … … 932 866 } 933 867 934 status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx),&pkt, call->conn->auth_state.auth_info);868 status = ncacn_push_auth(&rep->blob, call, &pkt, call->conn->auth_state.auth_info); 935 869 if (!NT_STATUS_IS_OK(status)) { 936 870 return status; … … 949 883 950 884 return NT_STATUS_OK; 885 } 886 887 /* 888 possibly save the call for inspection with ndrdump 889 */ 890 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why) 891 { 892 #ifdef DEVELOPER 893 char *fname; 894 const char *dump_dir; 895 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory"); 896 if (!dump_dir) { 897 return; 898 } 899 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat", 900 dump_dir, 901 call->context->iface->name, 902 call->pkt.u.request.opnum, 903 why); 904 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) { 905 DEBUG(0,("RPC SAVED %s\n", fname)); 906 } 907 talloc_free(fname); 908 #endif 951 909 } 952 910 … … 971 929 } 972 930 973 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call, 974 lp_iconv_convenience(call->conn->dce_ctx->lp_ctx)); 931 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); 975 932 NT_STATUS_HAVE_NO_MEMORY(pull); 976 933 … … 987 944 status = context->iface->ndr_pull(call, call, pull, &call->r); 988 945 if (!NT_STATUS_IS_OK(status)) { 946 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) { 947 /* we got an unknown call */ 948 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n", 949 call->pkt.u.request.opnum, context->iface->name)); 950 dcesrv_save_call(call, "unknown"); 951 } else { 952 dcesrv_save_call(call, "pullfail"); 953 } 989 954 return dcesrv_fault(call, call->fault_code); 990 955 } 991 956 992 957 if (pull->offset != pull->data_size) { 958 dcesrv_save_call(call, "extrabytes"); 993 959 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", 994 960 pull->data_size - pull->offset)); 995 dump_data(10, pull->data+pull->offset, pull->data_size - pull->offset);996 961 } 997 962 … … 1016 981 } 1017 982 1018 _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)1019 {1020 struct ndr_push *push;1021 NTSTATUS status;1022 DATA_BLOB stub;1023 uint32_t total_length, chunk_size;1024 struct dcesrv_connection_context *context = call->context;1025 size_t sig_size = 0;1026 1027 /* call the reply function */1028 status = context->iface->reply(call, call, call->r);1029 if (!NT_STATUS_IS_OK(status)) {1030 return dcesrv_fault(call, call->fault_code);1031 }1032 1033 /* form the reply NDR */1034 push = ndr_push_init_ctx(call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx));1035 NT_STATUS_HAVE_NO_MEMORY(push);1036 1037 /* carry over the pointer count to the reply in case we are1038 using full pointer. See NDR specification for full1039 pointers */1040 push->ptr_count = call->ndr_pull->ptr_count;1041 1042 if (lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)) {1043 push->flags |= LIBNDR_FLAG_BIGENDIAN;1044 }1045 1046 status = context->iface->ndr_push(call, call, push, call->r);1047 if (!NT_STATUS_IS_OK(status)) {1048 return dcesrv_fault(call, call->fault_code);1049 }1050 1051 stub = ndr_push_blob(push);1052 1053 total_length = stub.length;1054 1055 /* we can write a full max_recv_frag size, minus the dcerpc1056 request header size */1057 chunk_size = call->conn->cli_max_recv_frag;1058 chunk_size -= DCERPC_REQUEST_LENGTH;1059 if (call->conn->auth_state.auth_info &&1060 call->conn->auth_state.gensec_security) {1061 sig_size = gensec_sig_size(call->conn->auth_state.gensec_security,1062 call->conn->cli_max_recv_frag);1063 if (sig_size) {1064 chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;1065 chunk_size -= sig_size;1066 }1067 }1068 chunk_size -= (chunk_size % 16);1069 1070 do {1071 uint32_t length;1072 struct data_blob_list_item *rep;1073 struct ncacn_packet pkt;1074 1075 rep = talloc(call, struct data_blob_list_item);1076 NT_STATUS_HAVE_NO_MEMORY(rep);1077 1078 length = MIN(chunk_size, stub.length);1079 1080 /* form the dcerpc response packet */1081 dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx));1082 pkt.auth_length = 0;1083 pkt.call_id = call->pkt.call_id;1084 pkt.ptype = DCERPC_PKT_RESPONSE;1085 pkt.pfc_flags = 0;1086 if (stub.length == total_length) {1087 pkt.pfc_flags |= DCERPC_PFC_FLAG_FIRST;1088 }1089 if (length == stub.length) {1090 pkt.pfc_flags |= DCERPC_PFC_FLAG_LAST;1091 }1092 pkt.u.response.alloc_hint = stub.length;1093 pkt.u.response.context_id = call->pkt.u.request.context_id;1094 pkt.u.response.cancel_count = 0;1095 pkt.u.response.stub_and_verifier.data = stub.data;1096 pkt.u.response.stub_and_verifier.length = length;1097 1098 if (!dcesrv_auth_response(call, &rep->blob, sig_size, &pkt)) {1099 return dcesrv_fault(call, DCERPC_FAULT_OTHER);1100 }1101 1102 dcerpc_set_frag_length(&rep->blob, rep->blob.length);1103 1104 DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);1105 1106 stub.data += length;1107 stub.length -= length;1108 } while (stub.length != 0);1109 1110 /* move the call from the pending to the finished calls list */1111 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);1112 1113 if (call->conn->call_list && call->conn->call_list->replies) {1114 if (call->conn->transport.report_output_data) {1115 call->conn->transport.report_output_data(call->conn);1116 }1117 }1118 1119 return NT_STATUS_OK;1120 }1121 1122 _PUBLIC_ struct socket_address *dcesrv_connection_get_my_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx)1123 {1124 if (!conn->transport.get_my_addr) {1125 return NULL;1126 }1127 1128 return conn->transport.get_my_addr(conn, mem_ctx);1129 }1130 1131 _PUBLIC_ struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx)1132 {1133 if (!conn->transport.get_peer_addr) {1134 return NULL;1135 }1136 1137 return conn->transport.get_peer_addr(conn, mem_ctx);1138 }1139 1140 983 1141 984 /* … … 1146 989 dcesrv_call_set_list(call, DCESRV_LIST_NONE); 1147 990 return 0; 991 } 992 993 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn) 994 { 995 return conn->local_address; 996 } 997 998 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn) 999 { 1000 return conn->remote_address; 1148 1001 } 1149 1002 … … 1195 1048 } 1196 1049 1197 /* this is a continuation of an existing call - find the call then1198 t ack it on the end */1050 /* this is a continuation of an existing call - find the call 1051 then tack it on the end */ 1199 1052 call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); 1200 1053 if (!call) { … … 1373 1226 { 1374 1227 static bool initialized; 1375 extern NTSTATUS dcerpc_server_wkssvc_init(void); 1376 extern NTSTATUS dcerpc_server_drsuapi_init(void); 1377 extern NTSTATUS dcerpc_server_winreg_init(void); 1378 extern NTSTATUS dcerpc_server_spoolss_init(void); 1379 extern NTSTATUS dcerpc_server_epmapper_init(void); 1380 extern NTSTATUS dcerpc_server_srvsvc_init(void); 1381 extern NTSTATUS dcerpc_server_netlogon_init(void); 1382 extern NTSTATUS dcerpc_server_rpcecho_init(void); 1383 extern NTSTATUS dcerpc_server_unixinfo_init(void); 1384 extern NTSTATUS dcerpc_server_samr_init(void); 1385 extern NTSTATUS dcerpc_server_remote_init(void); 1386 extern NTSTATUS dcerpc_server_lsa_init(void); 1387 extern NTSTATUS dcerpc_server_browser_init(void); 1228 #define _MODULE_PROTO(init) extern NTSTATUS init(void); 1229 STATIC_dcerpc_server_MODULES_PROTO; 1388 1230 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES }; 1389 1231 init_module_fn *shared_init; … … 1425 1267 } 1426 1268 1269 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason) 1270 { 1271 struct stream_connection *srv_conn; 1272 srv_conn = talloc_get_type(dce_conn->transport.private_data, 1273 struct stream_connection); 1274 1275 stream_terminate_connection(srv_conn, reason); 1276 } 1277 /* We need this include to be able to compile on some plateforms 1278 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included 1279 * correctly. 1280 * It has to be that deep because otherwise we have a conflict on 1281 * const struct dcesrv_interface declaration. 1282 * This is mostly due to socket_wrapper defining #define bind swrap_bind 1283 * which conflict with the bind used before. 1284 */ 1285 #include "system/network.h" 1286 1287 struct dcesrv_sock_reply_state { 1288 struct dcesrv_connection *dce_conn; 1289 struct dcesrv_call_state *call; 1290 struct iovec iov; 1291 }; 1292 1293 static void dcesrv_sock_reply_done(struct tevent_req *subreq); 1294 1295 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) 1296 { 1297 struct dcesrv_call_state *call; 1298 1299 call = dce_conn->call_list; 1300 if (!call || !call->replies) { 1301 return; 1302 } 1303 1304 while (call->replies) { 1305 struct data_blob_list_item *rep = call->replies; 1306 struct dcesrv_sock_reply_state *substate; 1307 struct tevent_req *subreq; 1308 1309 substate = talloc(call, struct dcesrv_sock_reply_state); 1310 if (!substate) { 1311 dcesrv_terminate_connection(dce_conn, "no memory"); 1312 return; 1313 } 1314 1315 substate->dce_conn = dce_conn; 1316 substate->call = NULL; 1317 1318 DLIST_REMOVE(call->replies, rep); 1319 1320 if (call->replies == NULL) { 1321 substate->call = call; 1322 } 1323 1324 substate->iov.iov_base = (void *) rep->blob.data; 1325 substate->iov.iov_len = rep->blob.length; 1326 1327 subreq = tstream_writev_queue_send(substate, 1328 dce_conn->event_ctx, 1329 dce_conn->stream, 1330 dce_conn->send_queue, 1331 &substate->iov, 1); 1332 if (!subreq) { 1333 dcesrv_terminate_connection(dce_conn, "no memory"); 1334 return; 1335 } 1336 tevent_req_set_callback(subreq, dcesrv_sock_reply_done, 1337 substate); 1338 } 1339 1340 DLIST_REMOVE(call->conn->call_list, call); 1341 call->list = DCESRV_LIST_NONE; 1342 } 1343 1344 static void dcesrv_sock_reply_done(struct tevent_req *subreq) 1345 { 1346 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq, 1347 struct dcesrv_sock_reply_state); 1348 int ret; 1349 int sys_errno; 1350 NTSTATUS status; 1351 struct dcesrv_call_state *call = substate->call; 1352 1353 ret = tstream_writev_queue_recv(subreq, &sys_errno); 1354 TALLOC_FREE(subreq); 1355 if (ret == -1) { 1356 status = map_nt_error_from_unix(sys_errno); 1357 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status)); 1358 return; 1359 } 1360 1361 talloc_free(substate); 1362 if (call) { 1363 talloc_free(call); 1364 } 1365 } 1366 1367 1368 1369 1370 struct dcesrv_socket_context { 1371 const struct dcesrv_endpoint *endpoint; 1372 struct dcesrv_context *dcesrv_ctx; 1373 }; 1374 1375 1376 static void dcesrv_read_fragment_done(struct tevent_req *subreq); 1377 1378 static void dcesrv_sock_accept(struct stream_connection *srv_conn) 1379 { 1380 NTSTATUS status; 1381 struct dcesrv_socket_context *dcesrv_sock = 1382 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context); 1383 struct dcesrv_connection *dcesrv_conn = NULL; 1384 int ret; 1385 struct tevent_req *subreq; 1386 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx; 1387 1388 if (!srv_conn->session_info) { 1389 status = auth_anonymous_session_info(srv_conn, 1390 lp_ctx, 1391 &srv_conn->session_info); 1392 if (!NT_STATUS_IS_OK(status)) { 1393 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n", 1394 nt_errstr(status))); 1395 stream_terminate_connection(srv_conn, nt_errstr(status)); 1396 return; 1397 } 1398 } 1399 1400 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx, 1401 srv_conn, 1402 dcesrv_sock->endpoint, 1403 srv_conn->session_info, 1404 srv_conn->event.ctx, 1405 srv_conn->msg_ctx, 1406 srv_conn->server_id, 1407 DCESRV_CALL_STATE_FLAG_MAY_ASYNC, 1408 &dcesrv_conn); 1409 if (!NT_STATUS_IS_OK(status)) { 1410 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 1411 nt_errstr(status))); 1412 stream_terminate_connection(srv_conn, nt_errstr(status)); 1413 return; 1414 } 1415 1416 dcesrv_conn->transport.private_data = srv_conn; 1417 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data; 1418 1419 TALLOC_FREE(srv_conn->event.fde); 1420 1421 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue"); 1422 if (!dcesrv_conn->send_queue) { 1423 status = NT_STATUS_NO_MEMORY; 1424 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n", 1425 nt_errstr(status))); 1426 stream_terminate_connection(srv_conn, nt_errstr(status)); 1427 return; 1428 } 1429 1430 if (dcesrv_sock->endpoint->ep_description->transport == NCACN_NP) { 1431 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key; 1432 dcesrv_conn->stream = talloc_move(dcesrv_conn, 1433 &srv_conn->tstream); 1434 } else { 1435 ret = tstream_bsd_existing_socket(dcesrv_conn, 1436 socket_get_fd(srv_conn->socket), 1437 &dcesrv_conn->stream); 1438 if (ret == -1) { 1439 status = map_nt_error_from_unix(errno); 1440 DEBUG(0, ("dcesrv_sock_accept: " 1441 "failed to setup tstream: %s\n", 1442 nt_errstr(status))); 1443 stream_terminate_connection(srv_conn, nt_errstr(status)); 1444 return; 1445 } 1446 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE); 1447 } 1448 1449 dcesrv_conn->local_address = srv_conn->local_address; 1450 dcesrv_conn->remote_address = srv_conn->remote_address; 1451 1452 srv_conn->private_data = dcesrv_conn; 1453 1454 irpc_add_name(srv_conn->msg_ctx, "rpc_server"); 1455 1456 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn, 1457 dcesrv_conn->event_ctx, 1458 dcesrv_conn->stream); 1459 if (!subreq) { 1460 status = NT_STATUS_NO_MEMORY; 1461 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n", 1462 nt_errstr(status))); 1463 stream_terminate_connection(srv_conn, nt_errstr(status)); 1464 return; 1465 } 1466 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn); 1467 1468 return; 1469 } 1470 1471 static void dcesrv_read_fragment_done(struct tevent_req *subreq) 1472 { 1473 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq, 1474 struct dcesrv_connection); 1475 struct ncacn_packet *pkt; 1476 DATA_BLOB buffer; 1477 NTSTATUS status; 1478 1479 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn, 1480 &pkt, &buffer); 1481 TALLOC_FREE(subreq); 1482 if (!NT_STATUS_IS_OK(status)) { 1483 dcesrv_terminate_connection(dce_conn, nt_errstr(status)); 1484 return; 1485 } 1486 1487 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer); 1488 if (!NT_STATUS_IS_OK(status)) { 1489 dcesrv_terminate_connection(dce_conn, nt_errstr(status)); 1490 return; 1491 } 1492 1493 subreq = dcerpc_read_ncacn_packet_send(dce_conn, 1494 dce_conn->event_ctx, 1495 dce_conn->stream); 1496 if (!subreq) { 1497 status = NT_STATUS_NO_MEMORY; 1498 dcesrv_terminate_connection(dce_conn, nt_errstr(status)); 1499 return; 1500 } 1501 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn); 1502 } 1503 1504 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags) 1505 { 1506 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data, 1507 struct dcesrv_connection); 1508 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered"); 1509 } 1510 1511 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags) 1512 { 1513 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data, 1514 struct dcesrv_connection); 1515 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered"); 1516 } 1517 1518 1519 static const struct stream_server_ops dcesrv_stream_ops = { 1520 .name = "rpc", 1521 .accept_connection = dcesrv_sock_accept, 1522 .recv_handler = dcesrv_sock_recv, 1523 .send_handler = dcesrv_sock_send, 1524 }; 1525 1526 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, 1527 struct loadparm_context *lp_ctx, 1528 struct dcesrv_endpoint *e, 1529 struct tevent_context *event_ctx, const struct model_ops *model_ops) 1530 { 1531 struct dcesrv_socket_context *dcesrv_sock; 1532 uint16_t port = 1; 1533 NTSTATUS status; 1534 1535 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); 1536 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1537 1538 /* remember the endpoint of this socket */ 1539 dcesrv_sock->endpoint = e; 1540 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); 1541 1542 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx, 1543 model_ops, &dcesrv_stream_ops, 1544 "unix", e->ep_description->endpoint, &port, 1545 lpcfg_socket_options(lp_ctx), 1546 dcesrv_sock); 1547 if (!NT_STATUS_IS_OK(status)) { 1548 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", 1549 e->ep_description->endpoint, nt_errstr(status))); 1550 } 1551 1552 return status; 1553 } 1554 1555 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, 1556 struct loadparm_context *lp_ctx, 1557 struct dcesrv_endpoint *e, 1558 struct tevent_context *event_ctx, const struct model_ops *model_ops) 1559 { 1560 struct dcesrv_socket_context *dcesrv_sock; 1561 uint16_t port = 1; 1562 char *full_path; 1563 NTSTATUS status; 1564 1565 if (!e->ep_description->endpoint) { 1566 /* No identifier specified: use DEFAULT. 1567 * DO NOT hardcode this value anywhere else. Rather, specify 1568 * no endpoint and let the epmapper worry about it. */ 1569 e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT"); 1570 } 1571 1572 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx), 1573 e->ep_description->endpoint); 1574 1575 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); 1576 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1577 1578 /* remember the endpoint of this socket */ 1579 dcesrv_sock->endpoint = e; 1580 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); 1581 1582 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx, 1583 model_ops, &dcesrv_stream_ops, 1584 "unix", full_path, &port, 1585 lpcfg_socket_options(lp_ctx), 1586 dcesrv_sock); 1587 if (!NT_STATUS_IS_OK(status)) { 1588 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n", 1589 e->ep_description->endpoint, full_path, nt_errstr(status))); 1590 } 1591 return status; 1592 } 1593 1594 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, 1595 struct loadparm_context *lp_ctx, 1596 struct dcesrv_endpoint *e, 1597 struct tevent_context *event_ctx, const struct model_ops *model_ops) 1598 { 1599 struct dcesrv_socket_context *dcesrv_sock; 1600 NTSTATUS status; 1601 1602 if (e->ep_description->endpoint == NULL) { 1603 DEBUG(0, ("Endpoint mandatory for named pipes\n")); 1604 return NT_STATUS_INVALID_PARAMETER; 1605 } 1606 1607 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); 1608 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1609 1610 /* remember the endpoint of this socket */ 1611 dcesrv_sock->endpoint = e; 1612 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); 1613 1614 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx, 1615 model_ops, &dcesrv_stream_ops, 1616 e->ep_description->endpoint, 1617 dcesrv_sock); 1618 if (!NT_STATUS_IS_OK(status)) { 1619 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n", 1620 e->ep_description->endpoint, nt_errstr(status))); 1621 return status; 1622 } 1623 1624 return NT_STATUS_OK; 1625 } 1626 1627 /* 1628 add a socket address to the list of events, one event per dcerpc endpoint 1629 */ 1630 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e, 1631 struct tevent_context *event_ctx, const struct model_ops *model_ops, 1632 const char *address) 1633 { 1634 struct dcesrv_socket_context *dcesrv_sock; 1635 uint16_t port = 0; 1636 NTSTATUS status; 1637 1638 if (e->ep_description->endpoint) { 1639 port = atoi(e->ep_description->endpoint); 1640 } 1641 1642 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); 1643 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1644 1645 /* remember the endpoint of this socket */ 1646 dcesrv_sock->endpoint = e; 1647 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); 1648 1649 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx, 1650 model_ops, &dcesrv_stream_ops, 1651 "ipv4", address, &port, 1652 lpcfg_socket_options(dce_ctx->lp_ctx), 1653 dcesrv_sock); 1654 if (!NT_STATUS_IS_OK(status)) { 1655 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 1656 address, port, nt_errstr(status))); 1657 } 1658 1659 if (e->ep_description->endpoint == NULL) { 1660 e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port); 1661 } 1662 1663 return status; 1664 } 1665 1666 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */ 1667 1668 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, 1669 struct loadparm_context *lp_ctx, 1670 struct dcesrv_endpoint *e, 1671 struct tevent_context *event_ctx, const struct model_ops *model_ops) 1672 { 1673 NTSTATUS status; 1674 1675 /* Add TCP/IP sockets */ 1676 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) { 1677 int num_interfaces; 1678 int i; 1679 struct interface *ifaces; 1680 1681 load_interfaces(dce_ctx, lpcfg_interfaces(lp_ctx), &ifaces); 1682 1683 num_interfaces = iface_count(ifaces); 1684 for(i = 0; i < num_interfaces; i++) { 1685 const char *address = iface_n_ip(ifaces, i); 1686 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address); 1687 NT_STATUS_NOT_OK_RETURN(status); 1688 } 1689 } else { 1690 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, 1691 lpcfg_socket_address(lp_ctx)); 1692 NT_STATUS_NOT_OK_RETURN(status); 1693 } 1694 1695 return NT_STATUS_OK; 1696 } 1697 1698 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, 1699 struct loadparm_context *lp_ctx, 1700 struct dcesrv_endpoint *e, 1701 struct tevent_context *event_ctx, 1702 const struct model_ops *model_ops) 1703 { 1704 switch (e->ep_description->transport) { 1705 case NCACN_UNIX_STREAM: 1706 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops); 1707 1708 case NCALRPC: 1709 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops); 1710 1711 case NCACN_IP_TCP: 1712 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops); 1713 1714 case NCACN_NP: 1715 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops); 1716 1717 default: 1718 return NT_STATUS_NOT_SUPPORTED; 1719 } 1720 } 1721 1722 1723 /** 1724 * retrieve credentials from a dce_call 1725 */ 1726 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call) 1727 { 1728 return dce_call->conn->auth_state.session_info->credentials; 1729 } 1730 1731 /** 1732 * returns true if this is an authenticated call 1733 */ 1734 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call) 1735 { 1736 enum security_user_level level; 1737 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL); 1738 return level >= SECURITY_USER; 1739 } 1740 1741 /** 1742 * retrieve account_name for a dce_call 1743 */ 1744 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call) 1745 { 1746 return dce_call->context->conn->auth_state.session_info->info->account_name; 1747 } -
trunk/server/source4/rpc_server/dcerpc_server.h
r414 r745 24 24 #define SAMBA_DCERPC_SERVER_H 25 25 26 #include "librpc/gen_ndr/server_id .h"26 #include "librpc/gen_ndr/server_id4.h" 27 27 #include "librpc/rpc/dcerpc.h" 28 28 #include "librpc/ndr/libndr.h" … … 45 45 46 46 /* this function is called when the client binds to this interface */ 47 NTSTATUS (*bind)(struct dcesrv_call_state *, const struct dcesrv_interface * );47 NTSTATUS (*bind)(struct dcesrv_call_state *, const struct dcesrv_interface *, uint32_t if_version); 48 48 49 49 /* this function is called when the client disconnects the endpoint */ … … 219 219 void *private_data; 220 220 void (*report_output_data)(struct dcesrv_connection *); 221 struct socket_address *(*get_my_addr)(struct dcesrv_connection *, TALLOC_CTX *mem_ctx);222 struct socket_address *(*get_peer_addr)(struct dcesrv_connection *, TALLOC_CTX *mem_ctx);223 221 } transport; 224 222 225 223 struct tstream_context *stream; 226 224 struct tevent_queue *send_queue; 225 226 const struct tsocket_address *local_address; 227 const struct tsocket_address *remote_address; 227 228 }; 228 229 … … 261 262 /* parent context */ 262 263 struct dcesrv_context *dce_ctx; 264 265 /* Remote association group ID (if proxied) */ 266 uint32_t proxied_id; 263 267 }; 264 268 … … 332 336 333 337 struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx); 338 const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn); 339 const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn); 334 340 335 341 NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key); … … 372 378 #define DCESRV_PULL_HANDLE_WERR(h, inhandle, t) DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, WERR_BADFID) 373 379 380 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, 381 struct loadparm_context *lp_ctx, 382 struct dcesrv_endpoint *e, 383 struct tevent_context *event_ctx, 384 const struct model_ops *model_ops); 385 386 /** 387 * retrieve credentials from a dce_call 388 */ 389 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call); 390 391 /** 392 * returns true if this is an authenticated call 393 */ 394 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call); 395 396 /** 397 * retrieve account_name for a dce_call 398 */ 399 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call); 374 400 375 401 -
trunk/server/source4/rpc_server/dcesrv_auth.c
r414 r745 24 24 #include "rpc_server/dcerpc_server.h" 25 25 #include "rpc_server/dcerpc_server_proto.h" 26 #include "rpc_server/common/proto.h" 26 27 #include "librpc/rpc/dcerpc_proto.h" 27 28 #include "librpc/gen_ndr/ndr_dcerpc.h" … … 30 31 #include "auth/auth.h" 31 32 #include "param/param.h" 33 #include "librpc/rpc/rpc_common.h" 32 34 33 35 /* … … 43 45 struct dcesrv_auth *auth = &dce_conn->auth_state; 44 46 NTSTATUS status; 45 enum ndr_err_code ndr_err;47 uint32_t auth_length; 46 48 47 49 if (pkt->u.bind.auth_info.length == 0) { … … 55 57 } 56 58 57 ndr_err = ndr_pull_struct_blob(&pkt->u.bind.auth_info, 58 call, NULL, 59 dce_conn->auth_state.auth_info, 60 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); 61 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 62 return false; 63 } 64 59 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, 60 dce_conn->auth_state.auth_info, 61 &auth_length, false); 65 62 server_credentials 66 63 = cli_credentials_init(call); … … 80 77 status = samba_server_gensec_start(dce_conn, call->event_ctx, 81 78 call->msg_ctx, 82 call->conn->dce_ctx->lp_ctx, 79 call->conn->dce_ctx->lp_ctx, 83 80 server_credentials, 84 81 NULL, … … 89 86 90 87 if (!NT_STATUS_IS_OK(status)) { 91 DEBUG( 1, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n",88 DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", 92 89 (int)auth->auth_info->auth_type, 93 90 (int)auth->auth_info->auth_level, … … 142 139 return NT_STATUS_OK; 143 140 } else { 144 DEBUG(2, ("Failed to start dcesrv auth negotiate: %s\n", nt_errstr(status))); 141 DEBUG(4, ("GENSEC mech rejected the incoming authentication at bind_ack: %s\n", 142 nt_errstr(status))); 145 143 return status; 146 144 } … … 156 154 struct dcesrv_connection *dce_conn = call->conn; 157 155 NTSTATUS status; 158 enum ndr_err_code ndr_err;156 uint32_t auth_length; 159 157 160 158 /* We can't work without an existing gensec state, and an new blob to feed it */ … … 165 163 } 166 164 167 ndr_err = ndr_pull_struct_blob(&pkt->u.auth3.auth_info, 168 call, NULL, 169 dce_conn->auth_state.auth_info, 170 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); 171 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 165 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, 166 dce_conn->auth_state.auth_info, &auth_length, true); 167 if (!NT_STATUS_IS_OK(status)) { 172 168 return false; 173 169 } … … 189 185 return true; 190 186 } else { 191 DEBUG(4, (" dcesrv_auth_auth3: failed to authenticate: %s\n",187 DEBUG(4, ("GENSEC mech rejected the incoming authentication at bind_auth3: %s\n", 192 188 nt_errstr(status))); 193 189 return false; 194 190 } 195 196 return true;197 191 } 198 192 … … 206 200 struct ncacn_packet *pkt = &call->pkt; 207 201 struct dcesrv_connection *dce_conn = call->conn; 208 enum ndr_err_code ndr_err; 202 NTSTATUS status; 203 uint32_t auth_length; 209 204 210 205 /* on a pure interface change there is no auth blob */ … … 223 218 } 224 219 225 ndr_err = ndr_pull_struct_blob(&pkt->u.alter.auth_info, 226 call, NULL, 227 dce_conn->auth_state.auth_info, 228 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); 229 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 220 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, 221 dce_conn->auth_state.auth_info, 222 &auth_length, true); 223 if (!NT_STATUS_IS_OK(status)) { 230 224 return false; 231 225 } … … 276 270 } 277 271 278 DEBUG(2, ("Failed to finish dcesrv auth alter_ack: %s\n", nt_errstr(status))); 272 DEBUG(4, ("GENSEC mech rejected the incoming authentication at auth alter_ack: %s\n", 273 nt_errstr(status))); 279 274 return status; 280 275 } … … 287 282 struct ncacn_packet *pkt = &call->pkt; 288 283 struct dcesrv_connection *dce_conn = call->conn; 289 DATA_BLOB auth_blob;290 284 struct dcerpc_auth auth; 291 struct ndr_pull *ndr; 292 NTSTATUS status; 293 enum ndr_err_code ndr_err; 285 NTSTATUS status; 286 uint32_t auth_length; 294 287 size_t hdr_size = DCERPC_REQUEST_LENGTH; 295 288 … … 297 290 !dce_conn->auth_state.gensec_security) { 298 291 return true; 292 } 293 294 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { 295 hdr_size += 16; 299 296 } 300 297 … … 319 316 } 320 317 321 auth_blob.length = 8 + pkt->auth_length; 322 323 /* check for a valid length */ 324 if (pkt->u.request.stub_and_verifier.length < auth_blob.length) { 325 return false; 326 } 327 328 auth_blob.data = 329 pkt->u.request.stub_and_verifier.data + 330 pkt->u.request.stub_and_verifier.length - auth_blob.length; 331 pkt->u.request.stub_and_verifier.length -= auth_blob.length; 332 333 /* pull the auth structure */ 334 ndr = ndr_pull_init_blob(&auth_blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx)); 335 if (!ndr) { 336 return false; 337 } 338 339 if (!(pkt->drep[0] & DCERPC_DREP_LE)) { 340 ndr->flags |= LIBNDR_FLAG_BIGENDIAN; 341 } 342 343 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { 344 ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; 345 hdr_size += 16; 346 } 347 348 ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth); 349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 350 talloc_free(ndr); 351 return false; 352 } 318 status = dcerpc_pull_auth_trailer(pkt, call, 319 &pkt->u.request.stub_and_verifier, 320 &auth, &auth_length, false); 321 if (!NT_STATUS_IS_OK(status)) { 322 return false; 323 } 324 325 pkt->u.request.stub_and_verifier.length -= auth_length; 353 326 354 327 /* check signature or unseal the packet */ … … 389 362 /* remove the indicated amount of padding */ 390 363 if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) { 391 talloc_free(ndr);392 364 return false; 393 365 } 394 366 pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length; 395 talloc_free(ndr);396 367 397 368 return NT_STATUS_IS_OK(status); … … 415 386 /* non-signed packets are simple */ 416 387 if (sig_size == 0) { 417 status = ncacn_push_auth(blob, call, lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx),pkt, NULL);388 status = ncacn_push_auth(blob, call, pkt, NULL); 418 389 return NT_STATUS_IS_OK(status); 419 390 } … … 426 397 case DCERPC_AUTH_LEVEL_CONNECT: 427 398 /* 428 * TODO: let the gensec mech decide if it wants to generate a signature429 * that might be needed for schannel...399 * TODO: let the gensec mech decide if it wants to generate a 400 * signature that might be needed for schannel... 430 401 */ 431 status = ncacn_push_auth(blob, call, lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx),pkt, NULL);402 status = ncacn_push_auth(blob, call, pkt, NULL); 432 403 return NT_STATUS_IS_OK(status); 433 404 434 405 case DCERPC_AUTH_LEVEL_NONE: 435 status = ncacn_push_auth(blob, call, lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx),pkt, NULL);406 status = ncacn_push_auth(blob, call, pkt, NULL); 436 407 return NT_STATUS_IS_OK(status); 437 408 … … 440 411 } 441 412 442 ndr = ndr_push_init_ctx(call , lp_iconv_convenience(dce_conn->dce_ctx->lp_ctx));413 ndr = ndr_push_init_ctx(call); 443 414 if (!ndr) { 444 415 return false; … … 454 425 } 455 426 456 /* pad to 16 byte multiple, match win2k3 */ 427 /* pad to 16 byte multiple in the payload portion of the 428 packet. This matches what w2k3 does. Note that we can't use 429 ndr_push_align() as that is relative to the start of the 430 whole packet, whereas w2k8 wants it relative to the start 431 of the stub */ 457 432 dce_conn->auth_state.auth_info->auth_pad_length = 458 433 (16 - (pkt->u.response.stub_and_verifier.length & 15)) & 15; 459 ndr_err = ndr_push_zero(ndr, dce_conn->auth_state.auth_info->auth_pad_length); 434 ndr_err = ndr_push_zero(ndr, 435 dce_conn->auth_state.auth_info->auth_pad_length); 460 436 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 461 437 return false; … … 470 446 /* add the auth verifier */ 471 447 ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, 472 dce_conn->auth_state.auth_info);448 dce_conn->auth_state.auth_info); 473 449 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 474 450 return false; … … 514 490 } 515 491 516 if (NT_STATUS_IS_OK(status)) {517 if (creds2.length != sig_size) {518 DEBUG(0,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",519 (unsigned)creds2.length, (uint32_t)sig_size,520 (unsigned)dce_conn->auth_state.auth_info->auth_pad_length,521 (unsigned)pkt->u.response.stub_and_verifier.length));522 data_blob_free(&creds2);523 status = NT_STATUS_INTERNAL_ERROR;524 }525 }526 527 if (NT_STATUS_IS_OK(status)) {528 if (!data_blob_append(call, blob, creds2.data, creds2.length)) {529 status = NT_STATUS_NO_MEMORY;530 }531 data_blob_free(&creds2);532 }533 534 492 if (!NT_STATUS_IS_OK(status)) { 535 493 return false; 536 494 } 537 495 496 if (creds2.length != sig_size) { 497 DEBUG(3,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", 498 (unsigned)creds2.length, (uint32_t)sig_size, 499 (unsigned)dce_conn->auth_state.auth_info->auth_pad_length, 500 (unsigned)pkt->u.response.stub_and_verifier.length)); 501 dcerpc_set_frag_length(blob, blob->length + creds2.length); 502 dcerpc_set_auth_length(blob, creds2.length); 503 } 504 505 if (!data_blob_append(call, blob, creds2.data, creds2.length)) { 506 status = NT_STATUS_NO_MEMORY; 507 return false; 508 } 509 data_blob_free(&creds2); 510 538 511 return true; 539 512 } -
trunk/server/source4/rpc_server/drsuapi/addentry.c
r414 r745 23 23 #include "includes.h" 24 24 #include "rpc_server/dcerpc_server.h" 25 #include "rpc_server/common/common.h"26 25 #include "dsdb/samdb/samdb.h" 27 #include " lib/ldb/include/ldb_errors.h"26 #include "dsdb/common/util.h" 28 27 #include "param/param.h" 29 #include "lib rpc/gen_ndr/ndr_drsblobs.h"30 #include " auth/auth.h"28 #include "libcli/security/security.h" 29 #include "libcli/security/session.h" 31 30 #include "rpc_server/drsuapi/dcesrv_drsuapi.h" 32 #include "libcli/security/security.h"33 #include "librpc/gen_ndr/ndr_drsblobs.h"34 31 #include "librpc/gen_ndr/ndr_drsuapi.h" 35 36 32 37 33 /* … … 50 46 const char *dn_string = obj->object.identifier->dn; 51 47 struct ldb_dn *dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, dn_string); 52 struct ldb_result *res ;48 struct ldb_result *res, *res2; 53 49 struct ldb_dn *ref_dn; 54 50 struct GUID ntds_guid; … … 57 53 const char *ntds_guid_str; 58 54 const char *dom_string; 55 const char *attrs2[] = { "dNSHostName", "cn", NULL }; 56 const char *dNSHostName, *cn; 59 57 60 58 DEBUG(6,(__location__ ": Adding SPNs for %s\n", … … 83 81 ntds_guid_str = GUID_string(res, &ntds_guid); 84 82 85 dom_string = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 83 dom_string = lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); 84 85 /* get the dNSHostName and cn */ 86 ret = ldb_search(b_state->sam_ctx, mem_ctx, &res2, 87 ref_dn, LDB_SCOPE_BASE, attrs2, NULL); 88 if (ret != LDB_SUCCESS) { 89 DEBUG(0,(__location__ ": Failed to find ref_dn '%s'\n", 90 ldb_dn_get_linearized(ref_dn))); 91 return WERR_DS_DRA_INTERNAL_ERROR; 92 } 93 94 dNSHostName = ldb_msg_find_attr_as_string(res2->msgs[0], "dNSHostName", NULL); 95 cn = ldb_msg_find_attr_as_string(res2->msgs[0], "cn", NULL); 86 96 87 97 /* … … 101 111 } 102 112 103 el->num_values = 2; 104 el->values = talloc_array(msg->elements, struct ldb_val, 2); 105 if (el->values == NULL) { 113 114 ldb_msg_add_steal_string(msg, "servicePrincipalName", 115 talloc_asprintf(el->values, 116 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s", 117 ntds_guid_str, dom_string)); 118 ldb_msg_add_steal_string(msg, "servicePrincipalName", 119 talloc_asprintf(el->values, "ldap/%s._msdcs.%s", 120 ntds_guid_str, dom_string)); 121 if (cn) { 122 ldb_msg_add_steal_string(msg, "servicePrincipalName", 123 talloc_asprintf(el->values, "ldap/%s", cn)); 124 } 125 if (dNSHostName) { 126 ldb_msg_add_steal_string(msg, "servicePrincipalName", 127 talloc_asprintf(el->values, "ldap/%s", dNSHostName)); 128 } 129 if (el->num_values < 2) { 106 130 return WERR_NOMEM; 107 131 } 108 /* the magic constant is the GUID of the DRSUAPI RPC 109 interface */ 110 el->values[0].data = (uint8_t *)talloc_asprintf(el->values, 111 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s", 112 ntds_guid_str, dom_string); 113 el->values[0].length = strlen((char *)el->values[0].data); 114 el->values[1].data = (uint8_t *)talloc_asprintf(el->values, "ldap/%s._msdcs.%s", 115 ntds_guid_str, dom_string); 116 el->values[1].length = strlen((char *)el->values[1].data); 117 118 ret = ldb_modify(b_state->sam_ctx, msg); 132 133 ret = dsdb_modify(b_state->sam_ctx, msg, DSDB_MODIFY_PERMISSIVE); 119 134 if (ret != LDB_SUCCESS) { 120 135 DEBUG(0,(__location__ ": Failed to add SPNs - %s\n", … … 152 167 ZERO_STRUCTP(r->out.ctr); 153 168 *r->out.level_out = 3; 154 r->out.ctr->ctr3. level= 1;155 r->out.ctr->ctr3.err or = talloc_zero(mem_ctx, union drsuapi_DsAddEntryError);169 r->out.ctr->ctr3.err_ver = 1; 170 r->out.ctr->ctr3.err_data = talloc_zero(mem_ctx, union drsuapi_DsAddEntry_ErrData); 156 171 157 172 DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); 158 173 b_state = h->data; 159 174 160 status = drs_security_level_check(dce_call, "DsAddEntry" );175 status = drs_security_level_check(dce_call, "DsAddEntry", SECURITY_DOMAIN_CONTROLLER, NULL); 161 176 if (!W_ERROR_IS_OK(status)) { 162 177 return status; … … 179 194 &ids); 180 195 if (!W_ERROR_IS_OK(status)) { 181 r->out.ctr->ctr3.err or->info1.status = status;196 r->out.ctr->ctr3.err_data->v1.status = status; 182 197 ldb_transaction_cancel(b_state->sam_ctx); 198 DEBUG(0,(__location__ ": DsAddEntry failed - %s\n", win_errstr(status))); 183 199 return status; 184 200 } … … 197 213 status = drsuapi_add_SPNs(b_state, dce_call, mem_ctx, first_object); 198 214 if (!W_ERROR_IS_OK(status)) { 199 r->out.ctr->ctr3.err or->info1.status = status;215 r->out.ctr->ctr3.err_data->v1.status = status; 200 216 ldb_transaction_cancel(b_state->sam_ctx); 217 DEBUG(0,(__location__ ": DsAddEntry add SPNs failed - %s\n", win_errstr(status))); 201 218 return status; 202 219 } … … 204 221 ret = ldb_transaction_commit(b_state->sam_ctx); 205 222 if (ret != LDB_SUCCESS) { 223 DEBUG(0,(__location__ ": DsAddEntry commit failed: %s\n", 224 ldb_errstring(b_state->sam_ctx))); 206 225 return WERR_DS_DRA_INTERNAL_ERROR; 207 226 } -
trunk/server/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
r414 r745 26 26 #include "rpc_server/common/common.h" 27 27 #include "dsdb/samdb/samdb.h" 28 #include "libcli/security/security.h" 29 #include "libcli/security/session.h" 28 30 #include "rpc_server/drsuapi/dcesrv_drsuapi.h" 29 #include "libcli/security/security.h" 31 #include "auth/auth.h" 32 #include "param/param.h" 33 #include "lib/messaging/irpc.h" 34 35 #define DRSUAPI_UNSUPPORTED(fname) do { \ 36 DEBUG(1,(__location__ ": Unsupported DRS call %s\n", #fname)); \ 37 if (DEBUGLVL(2)) NDR_PRINT_IN_DEBUG(fname, r); \ 38 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \ 39 } while (0) 30 40 31 41 /* … … 48 58 uint32_t repl_epoch; 49 59 int ret; 60 struct auth_session_info *auth_info; 61 WERROR werr; 62 bool connected_as_system = false; 50 63 51 64 r->out.bind_info = NULL; … … 55 68 W_ERROR_HAVE_NO_MEMORY(b_state); 56 69 70 /* if this is a DC connecting, give them system level access */ 71 werr = drs_security_level_check(dce_call, NULL, SECURITY_DOMAIN_CONTROLLER, NULL); 72 if (W_ERROR_IS_OK(werr)) { 73 DEBUG(3,(__location__ ": doing DsBind with system_session\n")); 74 auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx); 75 connected_as_system = true; 76 } else { 77 auth_info = dce_call->conn->auth_state.session_info; 78 } 79 57 80 /* 58 81 * connect to the samdb 59 82 */ 60 b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 83 b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx, 84 dce_call->conn->dce_ctx->lp_ctx, auth_info, 0); 61 85 if (!b_state->sam_ctx) { 62 86 return WERR_FOOBAR; 87 } 88 89 if (connected_as_system) { 90 b_state->sam_ctx_system = b_state->sam_ctx; 91 } else { 92 /* an RODC also needs system samdb access for secret 93 attribute replication */ 94 werr = drs_security_level_check(dce_call, NULL, SECURITY_RO_DOMAIN_CONTROLLER, 95 samdb_domain_sid(b_state->sam_ctx)); 96 if (W_ERROR_IS_OK(werr)) { 97 b_state->sam_ctx_system = samdb_connect(b_state, dce_call->event_ctx, 98 dce_call->conn->dce_ctx->lp_ctx, 99 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 100 if (!b_state->sam_ctx_system) { 101 return WERR_FOOBAR; 102 } 103 } 63 104 } 64 105 … … 95 136 return WERR_DS_DRA_INTERNAL_ERROR; 96 137 } 97 repl_epoch = samdb_result_uint(ntds_res->msgs[0], "ms-DS-ReplicationEpoch", 0); 138 repl_epoch = ldb_msg_find_attr_as_uint(ntds_res->msgs[0], 139 "ms-DS-ReplicationEpoch", 0); 98 140 99 141 /* … … 147 189 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE; 148 190 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2; 149 if (0 /*domain.behavior_version == 2*/) { 150 /* TODO: find out how this is really triggered! */ 151 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION; 152 } 191 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION; 153 192 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2; 154 193 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD; … … 160 199 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY; 161 200 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3; 162 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ 00100000;201 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V5; 163 202 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2; 164 203 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6; … … 173 212 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS; 174 213 #endif 214 b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10; 175 215 b_state->local_info28.site_guid = site_guid; 176 216 b_state->local_info28.pid = pid; … … 230 270 { 231 271 WERROR status; 232 233 status = drs_security_level_check(dce_call, "DsReplicaSync"); 272 uint32_t timeout; 273 274 status = drs_security_level_check(dce_call, "DsReplicaSync", SECURITY_DOMAIN_CONTROLLER, NULL); 234 275 if (!W_ERROR_IS_OK(status)) { 235 276 return status; 236 277 } 237 278 238 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICASYNC, 279 if (r->in.level != 1) { 280 DEBUG(0,("DsReplicaSync called with unsupported level %d\n", r->in.level)); 281 return WERR_DS_DRA_INVALID_PARAMETER; 282 } 283 284 if (r->in.req->req1.options & DRSUAPI_DRS_ASYNC_OP) { 285 timeout = IRPC_CALL_TIMEOUT; 286 } else { 287 /* 288 * use Infinite time for timeout in case 289 * the caller made a sync call 290 */ 291 timeout = IRPC_CALL_TIMEOUT_INF; 292 } 293 294 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, 295 r, NDR_DRSUAPI_DSREPLICASYNC, 239 296 &ndr_table_drsuapi, 240 "dreplsrv", "DsReplicaSync"); 297 "dreplsrv", "DsReplicaSync", 298 timeout); 241 299 242 300 return WERR_OK; … … 250 308 struct drsuapi_DsReplicaAdd *r) 251 309 { 252 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 310 WERROR status; 311 312 status = drs_security_level_check(dce_call, "DsReplicaAdd", SECURITY_DOMAIN_CONTROLLER, NULL); 313 if (!W_ERROR_IS_OK(status)) { 314 return status; 315 } 316 317 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, 318 r, NDR_DRSUAPI_DSREPLICAADD, 319 &ndr_table_drsuapi, 320 "dreplsrv", "DsReplicaAdd", 321 IRPC_CALL_TIMEOUT); 322 323 return WERR_OK; 253 324 } 254 325 … … 260 331 struct drsuapi_DsReplicaDel *r) 261 332 { 262 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 333 WERROR status; 334 335 status = drs_security_level_check(dce_call, "DsReplicaDel", SECURITY_DOMAIN_CONTROLLER, NULL); 336 if (!W_ERROR_IS_OK(status)) { 337 return status; 338 } 339 340 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, 341 r, NDR_DRSUAPI_DSREPLICADEL, 342 &ndr_table_drsuapi, 343 "dreplsrv", "DsReplicaDel", 344 IRPC_CALL_TIMEOUT); 345 346 return WERR_OK; 263 347 } 264 348 … … 270 354 struct drsuapi_DsReplicaMod *r) 271 355 { 272 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 356 WERROR status; 357 358 status = drs_security_level_check(dce_call, "DsReplicaMod", SECURITY_DOMAIN_CONTROLLER, NULL); 359 if (!W_ERROR_IS_OK(status)) { 360 return status; 361 } 362 363 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, 364 r, NDR_DRSUAPI_DSREPLICAMOD, 365 &ndr_table_drsuapi, 366 "dreplsrv", "DsReplicaMod", 367 IRPC_CALL_TIMEOUT); 368 369 return WERR_OK; 273 370 } 274 371 … … 280 377 struct DRSUAPI_VERIFY_NAMES *r) 281 378 { 282 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);379 DRSUAPI_UNSUPPORTED(DRSUAPI_VERIFY_NAMES); 283 380 } 284 381 … … 290 387 struct drsuapi_DsGetMemberships *r) 291 388 { 292 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);389 DRSUAPI_UNSUPPORTED(drsuapi_DsGetMemberships); 293 390 } 294 391 … … 300 397 struct DRSUAPI_INTER_DOMAIN_MOVE *r) 301 398 { 302 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);399 DRSUAPI_UNSUPPORTED(DRSUAPI_INTER_DOMAIN_MOVE); 303 400 } 304 401 … … 310 407 struct drsuapi_DsGetNT4ChangeLog *r) 311 408 { 312 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 313 } 314 409 DRSUAPI_UNSUPPORTED(drsuapi_DsGetNT4ChangeLog); 410 } 315 411 316 412 /* … … 320 416 struct drsuapi_DsCrackNames *r) 321 417 { 322 WERROR status;323 418 struct drsuapi_bind_state *b_state; 324 419 struct dcesrv_handle *h; … … 334 429 switch (r->in.level) { 335 430 case 1: { 336 struct drsuapi_DsNameCtr1 *ctr1; 337 struct drsuapi_DsNameInfo1 *names; 338 int count; 339 int i; 340 341 ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1); 342 W_ERROR_HAVE_NO_MEMORY(ctr1); 343 344 count = r->in.req->req1.count; 345 names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count); 346 W_ERROR_HAVE_NO_MEMORY(names); 347 348 for (i=0; i < count; i++) { 349 status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx, 350 r->in.req->req1.format_flags, 351 r->in.req->req1.format_offered, 352 r->in.req->req1.format_desired, 353 r->in.req->req1.names[i].str, 354 &names[i]); 355 if (!W_ERROR_IS_OK(status)) { 356 return status; 357 } 358 } 359 360 ctr1->count = count; 361 ctr1->array = names; 362 r->out.ctr->ctr1 = ctr1; 363 364 return WERR_OK; 365 } 366 } 367 368 return WERR_UNKNOWN_LEVEL; 369 } 370 371 /* 372 drsuapi_DsWriteAccountSpn 373 */ 374 static WERROR dcesrv_drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 375 struct drsuapi_DsWriteAccountSpn *r) 376 { 377 struct drsuapi_bind_state *b_state; 378 struct dcesrv_handle *h; 379 380 *r->out.level_out = r->in.level; 381 382 DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); 383 b_state = h->data; 384 385 r->out.res = talloc(mem_ctx, union drsuapi_DsWriteAccountSpnResult); 386 W_ERROR_HAVE_NO_MEMORY(r->out.res); 387 388 switch (r->in.level) { 389 case 1: { 390 struct drsuapi_DsWriteAccountSpnRequest1 *req; 391 struct ldb_message *msg; 392 int count, i, ret; 393 req = &r->in.req->req1; 394 count = req->count; 395 396 msg = ldb_msg_new(mem_ctx); 397 if (msg == NULL) { 398 return WERR_NOMEM; 399 } 400 401 msg->dn = ldb_dn_new(msg, b_state->sam_ctx, req->object_dn); 402 if ( ! ldb_dn_validate(msg->dn)) { 403 r->out.res->res1.status = WERR_OK; 431 switch(r->in.req->req1.format_offered){ 432 case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID: 433 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX: 434 case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS: 435 case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON: 436 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE: 437 case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME: 438 case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME: 439 case DRSUAPI_DS_NAME_FORMAT_LIST_NCS: 440 case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS: 441 case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID: 442 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN: 443 case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER: 444 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE: 445 case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE: 446 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE: 447 case DRSUAPI_DS_NAME_FORMAT_LIST_SITES: 448 DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X", 449 r->in.req->req1.format_offered)); 404 450 return WERR_OK; 405 } 406 407 /* construct mods */ 408 for (i = 0; i < count; i++) { 409 samdb_msg_add_string(b_state->sam_ctx, 410 msg, msg, "servicePrincipalName", 411 req->spn_names[i].str); 412 } 413 for (i=0;i<msg->num_elements;i++) { 414 switch (req->operation) { 415 case DRSUAPI_DS_SPN_OPERATION_ADD: 416 msg->elements[i].flags = LDB_FLAG_MOD_ADD; 417 break; 418 case DRSUAPI_DS_SPN_OPERATION_REPLACE: 419 msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; 420 break; 421 case DRSUAPI_DS_SPN_OPERATION_DELETE: 422 msg->elements[i].flags = LDB_FLAG_MOD_DELETE; 423 break; 424 } 425 } 426 427 /* Apply to database */ 428 429 ret = ldb_modify(b_state->sam_ctx, msg); 430 if (ret != 0) { 431 DEBUG(0,("Failed to modify SPNs on %s: %s\n", 432 ldb_dn_get_linearized(msg->dn), 433 ldb_errstring(b_state->sam_ctx))); 434 r->out.res->res1.status = WERR_ACCESS_DENIED; 435 } else { 436 r->out.res->res1.status = WERR_OK; 437 } 438 439 return WERR_OK; 440 } 441 } 442 451 case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES: 452 return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx, 453 &r->in.req->req1, &r->out.ctr->ctr1); 454 default:/* format_offered is in the enum drsuapi_DsNameFormat*/ 455 return dcesrv_drsuapi_CrackNamesByNameFormat(b_state->sam_ctx, mem_ctx, 456 &r->in.req->req1, &r->out.ctr->ctr1); 457 } 458 } 459 } 443 460 return WERR_UNKNOWN_LEVEL; 444 461 } … … 458 475 WERROR status; 459 476 460 ZERO_STRUCT(r->out.res);461 477 *r->out.level_out = 1; 462 478 463 status = drs_security_level_check(dce_call, "DsRemoveDSServer" );479 status = drs_security_level_check(dce_call, "DsRemoveDSServer", SECURITY_DOMAIN_CONTROLLER, NULL); 464 480 if (!W_ERROR_IS_OK(status)) { 465 481 return status; … … 508 524 struct DRSUAPI_REMOVE_DS_DOMAIN *r) 509 525 { 510 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);526 DRSUAPI_UNSUPPORTED(DRSUAPI_REMOVE_DS_DOMAIN); 511 527 } 512 528 513 529 /* Obtain the site name from a server DN */ 514 static const char *result_site_name(struct ldb_dn *s ite_dn)530 static const char *result_site_name(struct ldb_dn *server_dn) 515 531 { 516 532 /* Format is cn=<NETBIOS name>,cn=Servers,cn=<site>,cn=sites.... */ 517 const struct ldb_val *val = ldb_dn_get_component_val(s ite_dn, 2);518 const char *name = ldb_dn_get_component_name(s ite_dn, 2);533 const struct ldb_val *val = ldb_dn_get_component_val(server_dn, 2); 534 const char *name = ldb_dn_get_component_name(server_dn, 2); 519 535 520 536 if (!name || (ldb_attr_cmp(name, "cn") != 0)) { … … 556 572 struct drsuapi_DsGetDCInfoCtr2 *ctr2; 557 573 558 int ret, i; 574 int ret; 575 unsigned int i; 559 576 560 577 *r->out.level_out = r->in.req->req1.level; … … 686 703 if (ret == LDB_SUCCESS && res_ntds->count == 1) { 687 704 ctr2->array[i].is_gc 688 = (ldb_msg_find_attr_as_ int(res_ntds->msgs[0], "options", 0) == 1);705 = (ldb_msg_find_attr_as_uint(res_ntds->msgs[0], "options", 0) & DS_NTDSDSA_OPT_IS_GC); 689 706 ctr2->array[i].ntds_guid 690 707 = samdb_result_guid(res_ntds->msgs[0], "objectGUID"); … … 784 801 struct drsuapi_DsExecuteKCC *r) 785 802 { 786 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 803 WERROR status; 804 status = drs_security_level_check(dce_call, "DsExecuteKCC", SECURITY_DOMAIN_CONTROLLER, NULL); 805 806 if (!W_ERROR_IS_OK(status)) { 807 return status; 808 } 809 810 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSEXECUTEKCC, 811 &ndr_table_drsuapi, "kccsrv", "DsExecuteKCC", 812 IRPC_CALL_TIMEOUT); 813 return WERR_OK; 787 814 } 788 815 … … 794 821 struct drsuapi_DsReplicaGetInfo *r) 795 822 { 796 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 823 enum security_user_level level; 824 825 if (!lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, 826 "drs", "disable_sec_check", false)) { 827 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL); 828 if (level < SECURITY_DOMAIN_CONTROLLER) { 829 DEBUG(1,(__location__ ": Administrator access required for DsReplicaGetInfo\n")); 830 security_token_debug(0, 2, dce_call->conn->auth_state.session_info->security_token); 831 return WERR_DS_DRA_ACCESS_DENIED; 832 } 833 } 834 835 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICAGETINFO, 836 &ndr_table_drsuapi, "kccsrv", "DsReplicaGetInfo", 837 IRPC_CALL_TIMEOUT); 838 839 return WERR_OK; 797 840 } 798 841 … … 804 847 struct DRSUAPI_ADD_SID_HISTORY *r) 805 848 { 806 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);849 DRSUAPI_UNSUPPORTED(DRSUAPI_ADD_SID_HISTORY); 807 850 } 808 851 … … 813 856 struct drsuapi_DsGetMemberships2 *r) 814 857 { 815 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);858 DRSUAPI_UNSUPPORTED(drsuapi_DsGetMemberships2); 816 859 } 817 860 … … 822 865 struct DRSUAPI_REPLICA_VERIFY_OBJECTS *r) 823 866 { 824 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);867 DRSUAPI_UNSUPPORTED(DRSUAPI_REPLICA_VERIFY_OBJECTS); 825 868 } 826 869 … … 832 875 struct DRSUAPI_GET_OBJECT_EXISTENCE *r) 833 876 { 834 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);877 DRSUAPI_UNSUPPORTED(DRSUAPI_GET_OBJECT_EXISTENCE); 835 878 } 836 879 … … 842 885 struct drsuapi_QuerySitesByCost *r) 843 886 { 844 D CESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);887 DRSUAPI_UNSUPPORTED(drsuapi_QuerySitesByCost); 845 888 } 846 889 -
trunk/server/source4/rpc_server/drsuapi/dcesrv_drsuapi.h
r414 r745 32 32 struct drsuapi_bind_state { 33 33 struct ldb_context *sam_ctx; 34 struct ldb_context *sam_ctx_system; 34 35 struct GUID remote_bind_guid; 35 36 struct drsuapi_DsBindInfo28 remote_info28; … … 40 41 41 42 /* prototypes of internal functions */ 43 WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, 44 struct drsuapi_DsReplicaUpdateRefsRequest1 *req); 42 45 WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 43 46 struct drsuapi_DsReplicaUpdateRefs *r); … … 46 49 WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 47 50 struct drsuapi_DsAddEntry *r); 51 WERROR dcesrv_drsuapi_DsWriteAccountSpn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 52 struct drsuapi_DsWriteAccountSpn *r); 48 53 49 54 char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx, … … 56 61 enum ldb_scope scope, 57 62 const char * const *attrs, 58 const char *sort_attrib,59 63 const char *filter); 60 64 61 65 WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, 62 const char* call); 66 const char* call, enum security_user_level minimum_level, 67 const struct dom_sid *domain_sid); 63 68 64 69 void drsuapi_process_secret_attribute(struct drsuapi_DsReplicaAttribute *attr, 65 70 struct drsuapi_DsReplicaMetaData *meta_data); 71 72 WERROR drs_security_access_check(struct ldb_context *sam_ctx, 73 TALLOC_CTX *mem_ctx, 74 struct security_token *token, 75 struct drsuapi_DsReplicaObjectIdentifier *nc, 76 const char *ext_right); 77 78 WERROR drs_security_access_check_nc_root(struct ldb_context *sam_ctx, 79 TALLOC_CTX *mem_ctx, 80 struct security_token *token, 81 struct drsuapi_DsReplicaObjectIdentifier *nc, 82 const char *ext_right); -
trunk/server/source4/rpc_server/drsuapi/drsutil.c
r414 r745 23 23 #include "rpc_server/dcerpc_server.h" 24 24 #include "dsdb/samdb/samdb.h" 25 #include "libcli/security/dom_sid.h"26 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"27 25 #include "libcli/security/security.h" 26 #include "libcli/security/session.h" 28 27 #include "param/param.h" 29 30 /* 31 format a drsuapi_DsReplicaObjectIdentifier naming context as a string 32 */ 33 char *drs_ObjectIdentifier_to_string(TALLOC_CTX *mem_ctx, 34 struct drsuapi_DsReplicaObjectIdentifier *nc) 35 { 36 char *guid, *sid, *ret; 37 guid = GUID_string(mem_ctx, &nc->guid); 38 sid = dom_sid_string(mem_ctx, &nc->sid); 39 ret = talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", 40 guid, sid, nc->dn); 41 talloc_free(guid); 42 talloc_free(sid); 43 return ret; 44 } 28 #include "auth/session.h" 45 29 46 30 int drsuapi_search_with_extended_dn(struct ldb_context *ldb, … … 50 34 enum ldb_scope scope, 51 35 const char * const *attrs, 52 const char *sort_attrib,53 36 const char *filter) 54 37 { … … 84 67 } 85 68 86 ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL); 87 if (ret != LDB_SUCCESS) { 88 return ret; 89 } 90 91 if (sort_attrib) { 92 struct ldb_server_sort_control **sort_control; 93 sort_control = talloc_array(req, struct ldb_server_sort_control *, 2); 94 if (sort_control == NULL) { 95 talloc_free(tmp_ctx); 96 return LDB_ERR_OPERATIONS_ERROR; 97 } 98 sort_control[0] = talloc(req, struct ldb_server_sort_control); 99 sort_control[0]->attributeName = sort_attrib; 100 sort_control[0]->orderingRule = NULL; 101 sort_control[0]->reverse = 1; 102 sort_control[1] = NULL; 103 104 ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, sort_control); 105 if (ret != LDB_SUCCESS) { 106 return ret; 107 } 108 } 109 69 ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_RECYCLED_OID, true, NULL); 70 if (ret != LDB_SUCCESS) { 71 return ret; 72 } 73 74 ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL); 75 if (ret != LDB_SUCCESS) { 76 return ret; 77 } 110 78 111 79 ret = ldb_request(ldb, req); … … 119 87 } 120 88 121 WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, const char* call) 122 { 123 if (lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, 89 WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, 90 const char* call, 91 enum security_user_level minimum_level, 92 const struct dom_sid *domain_sid) 93 { 94 enum security_user_level level; 95 96 if (lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, 124 97 "drs", "disable_sec_check", false)) { 125 98 return WERR_OK; 126 99 } 127 100 128 if (security_session_user_level(dce_call->conn->auth_state.session_info) < 129 SECURITY_DOMAIN_CONTROLLER) { 130 DEBUG(0,("DsReplicaGetInfo refused for security token\n")); 101 level = security_session_user_level(dce_call->conn->auth_state.session_info, domain_sid); 102 if (level < minimum_level) { 103 if (call) { 104 DEBUG(0,("%s refused for security token (level=%u)\n", 105 call, (unsigned)level)); 106 security_token_debug(0, 2, dce_call->conn->auth_state.session_info->security_token); 107 } 131 108 return WERR_DS_DRA_ACCESS_DENIED; 132 109 } … … 143 120 144 121 switch (attr->attid) { 145 case DRSUAPI_ATT RIBUTE_dBCSPwd:146 case DRSUAPI_ATT RIBUTE_unicodePwd:147 case DRSUAPI_ATT RIBUTE_ntPwdHistory:148 case DRSUAPI_ATT RIBUTE_lmPwdHistory:149 case DRSUAPI_ATT RIBUTE_supplementalCredentials:150 case DRSUAPI_ATT RIBUTE_priorValue:151 case DRSUAPI_ATT RIBUTE_currentValue:152 case DRSUAPI_ATT RIBUTE_trustAuthOutgoing:153 case DRSUAPI_ATT RIBUTE_trustAuthIncoming:154 case DRSUAPI_ATT RIBUTE_initialAuthOutgoing:155 case DRSUAPI_ATT RIBUTE_initialAuthIncoming:122 case DRSUAPI_ATTID_dBCSPwd: 123 case DRSUAPI_ATTID_unicodePwd: 124 case DRSUAPI_ATTID_ntPwdHistory: 125 case DRSUAPI_ATTID_lmPwdHistory: 126 case DRSUAPI_ATTID_supplementalCredentials: 127 case DRSUAPI_ATTID_priorValue: 128 case DRSUAPI_ATTID_currentValue: 129 case DRSUAPI_ATTID_trustAuthOutgoing: 130 case DRSUAPI_ATTID_trustAuthIncoming: 131 case DRSUAPI_ATTID_initialAuthOutgoing: 132 case DRSUAPI_ATTID_initialAuthIncoming: 156 133 /*set value to null*/ 157 134 attr->value_ctr.num_values = 0; … … 163 140 return; 164 141 } 165 return; 166 } 142 } 143 144 145 /* 146 check security on a DN, with logging of errors 147 */ 148 static WERROR drs_security_access_check_log(struct ldb_context *sam_ctx, 149 TALLOC_CTX *mem_ctx, 150 struct security_token *token, 151 struct ldb_dn *dn, 152 const char *ext_right) 153 { 154 int ret; 155 if (!dn) { 156 DEBUG(3,("drs_security_access_check: Null dn provided, access is denied for %s\n", 157 ext_right)); 158 return WERR_DS_DRA_ACCESS_DENIED; 159 } 160 ret = dsdb_check_access_on_dn(sam_ctx, 161 mem_ctx, 162 dn, 163 token, 164 SEC_ADS_CONTROL_ACCESS, 165 ext_right); 166 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { 167 DEBUG(3,("%s refused for security token on %s\n", 168 ext_right, ldb_dn_get_linearized(dn))); 169 security_token_debug(2, 0, token); 170 return WERR_DS_DRA_ACCESS_DENIED; 171 } else if (ret != LDB_SUCCESS) { 172 DEBUG(1,("Failed to perform access check on %s\n", ldb_dn_get_linearized(dn))); 173 return WERR_DS_DRA_INTERNAL_ERROR; 174 } 175 return WERR_OK; 176 } 177 178 179 /* 180 check security on a object identifier 181 */ 182 WERROR drs_security_access_check(struct ldb_context *sam_ctx, 183 TALLOC_CTX *mem_ctx, 184 struct security_token *token, 185 struct drsuapi_DsReplicaObjectIdentifier *nc, 186 const char *ext_right) 187 { 188 struct ldb_dn *dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, nc); 189 WERROR werr; 190 werr = drs_security_access_check_log(sam_ctx, mem_ctx, token, dn, ext_right); 191 talloc_free(dn); 192 return werr; 193 } 194 195 /* 196 check security on the NC root of a object identifier 197 */ 198 WERROR drs_security_access_check_nc_root(struct ldb_context *sam_ctx, 199 TALLOC_CTX *mem_ctx, 200 struct security_token *token, 201 struct drsuapi_DsReplicaObjectIdentifier *nc, 202 const char *ext_right) 203 { 204 struct ldb_dn *dn, *nc_root; 205 WERROR werr; 206 int ret; 207 208 dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, nc); 209 W_ERROR_HAVE_NO_MEMORY(dn); 210 ret = dsdb_find_nc_root(sam_ctx, dn, dn, &nc_root); 211 if (ret != LDB_SUCCESS) { 212 return WERR_DS_CANT_FIND_EXPECTED_NC; 213 } 214 werr = drs_security_access_check_log(sam_ctx, mem_ctx, token, nc_root, ext_right); 215 talloc_free(dn); 216 return werr; 217 } -
trunk/server/source4/rpc_server/drsuapi/getncchanges.c
r414 r745 2 2 Unix SMB/CIFS implementation. 3 3 4 implement the D RSUpdateRefs call4 implement the DSGetNCChanges call 5 5 6 6 Copyright (C) Anatoliy Atanasov 2009 … … 22 22 23 23 #include "includes.h" 24 #include "librpc/gen_ndr/ndr_drsuapi.h"25 24 #include "rpc_server/dcerpc_server.h" 26 25 #include "dsdb/samdb/samdb.h" 27 26 #include "param/param.h" 28 27 #include "librpc/gen_ndr/ndr_drsblobs.h" 29 #include "auth/auth.h" 28 #include "librpc/gen_ndr/ndr_drsuapi.h" 29 #include "librpc/gen_ndr/ndr_security.h" 30 #include "libcli/security/security.h" 31 #include "libcli/security/session.h" 30 32 #include "rpc_server/drsuapi/dcesrv_drsuapi.h" 31 33 #include "rpc_server/dcerpc_server_proto.h" 32 34 #include "../libcli/drsuapi/drsuapi.h" 33 #include "libcli/security/security.h" 35 #include "lib/util/binsearch.h" 36 #include "lib/util/tsort.h" 37 #include "auth/session.h" 38 #include "dsdb/common/util.h" 39 40 /* 41 build a DsReplicaObjectIdentifier from a ldb msg 42 */ 43 static struct drsuapi_DsReplicaObjectIdentifier *get_object_identifier(TALLOC_CTX *mem_ctx, 44 struct ldb_message *msg) 45 { 46 struct drsuapi_DsReplicaObjectIdentifier *identifier; 47 struct dom_sid *sid; 48 49 identifier = talloc(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier); 50 if (identifier == NULL) { 51 return NULL; 52 } 53 54 identifier->dn = ldb_dn_alloc_linearized(identifier, msg->dn); 55 identifier->guid = samdb_result_guid(msg, "objectGUID"); 56 57 sid = samdb_result_dom_sid(identifier, msg, "objectSid"); 58 if (sid) { 59 identifier->sid = *sid; 60 } else { 61 ZERO_STRUCT(identifier->sid); 62 } 63 return identifier; 64 } 65 66 static int udv_compare(const struct GUID *guid1, struct GUID guid2) 67 { 68 return GUID_compare(guid1, &guid2); 69 } 70 71 /* 72 see if we can filter an attribute using the uptodateness_vector 73 */ 74 static bool udv_filter(const struct drsuapi_DsReplicaCursorCtrEx *udv, 75 const struct GUID *originating_invocation_id, 76 uint64_t originating_usn) 77 { 78 const struct drsuapi_DsReplicaCursor *c; 79 if (udv == NULL) return false; 80 BINARY_ARRAY_SEARCH(udv->cursors, udv->count, source_dsa_invocation_id, 81 originating_invocation_id, udv_compare, c); 82 if (c && originating_usn <= c->highest_usn) { 83 return true; 84 } 85 return false; 86 87 } 88 89 static int attid_cmp(enum drsuapi_DsAttributeId a1, enum drsuapi_DsAttributeId a2) 90 { 91 if (a1 == a2) return 0; 92 return ((uint32_t)a1) > ((uint32_t)a2) ? 1 : -1; 93 } 94 95 /* 96 check if an attribute is in a partial_attribute_set 97 */ 98 static bool check_partial_attribute_set(const struct dsdb_attribute *sa, 99 struct drsuapi_DsPartialAttributeSet *pas) 100 { 101 enum drsuapi_DsAttributeId *result; 102 BINARY_ARRAY_SEARCH_V(pas->attids, pas->num_attids, (enum drsuapi_DsAttributeId)sa->attributeID_id, 103 attid_cmp, result); 104 return result != NULL; 105 } 106 34 107 35 108 /* … … 40 113 struct ldb_context *sam_ctx, 41 114 struct ldb_dn *ncRoot_dn, 115 bool is_schema_nc, 42 116 struct dsdb_schema *schema, 43 117 DATA_BLOB *session_key, 44 118 uint64_t highest_usn, 45 uint32_t replica_flags) 119 uint32_t replica_flags, 120 struct drsuapi_DsPartialAttributeSet *partial_attribute_set, 121 struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector, 122 enum drsuapi_DsExtendedOperation extended_op) 46 123 { 47 124 const struct ldb_val *md_value; 48 int i, n; 49 struct ldb_dn *obj_dn; 125 uint32_t i, n; 50 126 struct replPropertyMetaDataBlob md; 51 struct dom_sid *sid;52 127 uint32_t rid = 0; 53 128 enum ndr_err_code ndr_err; … … 55 130 const char *rdn; 56 131 const struct dsdb_attribute *rdn_sa; 57 58 if (ldb_dn_compare(ncRoot_dn, msg->dn) == 0) { 132 unsigned int instanceType; 133 struct dsdb_syntax_ctx syntax_ctx; 134 135 /* make dsdb sytanx context for conversions */ 136 dsdb_syntax_ctx_init(&syntax_ctx, sam_ctx, schema); 137 syntax_ctx.is_schema_nc = is_schema_nc; 138 139 instanceType = ldb_msg_find_attr_as_uint(msg, "instanceType", 0); 140 if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) { 59 141 obj->is_nc_prefix = true; 60 142 obj->parent_object_guid = NULL; 61 143 } else { 62 struct ldb_dn *parent_dn;63 uint32_t instance_type;64 65 instance_type = ldb_msg_find_attr_as_uint(msg, "instanceType", 0);66 if (instance_type & INSTANCE_TYPE_IS_NC_HEAD) {67 struct ldb_result *res;68 int ret;69 char *dnstr = ldb_dn_get_linearized(msg->dn);70 msg->dn = ldb_dn_new(msg, sam_ctx, dnstr);71 /* we need to re-search the msg, to avoid the72 * broken dual message problems with our73 * partitions implementation */74 DEBUG(6,(__location__ ": Re-fetching subref %s\n",75 ldb_dn_get_linearized(msg->dn)));76 ret = drsuapi_search_with_extended_dn(sam_ctx, msg, &res,77 msg->dn, LDB_SCOPE_BASE, NULL,78 NULL, NULL);79 if (ret != LDB_SUCCESS || res->count < 1) {80 DEBUG(0,(__location__ ": Failed to reload subref head %s in %s\n",81 ldb_dn_get_linearized(msg->dn), ldb_dn_get_linearized(ncRoot_dn)));82 return WERR_DS_DRA_INTERNAL_ERROR;83 }84 msg = res->msgs[0];85 }86 87 parent_dn = ldb_dn_copy(msg, msg->dn);88 144 obj->is_nc_prefix = false; 89 145 obj->parent_object_guid = talloc(obj, struct GUID); 90 if ( parent_dn== NULL) {146 if (obj->parent_object_guid == NULL) { 91 147 return WERR_DS_DRA_INTERNAL_ERROR; 92 148 } 93 if (ldb_dn_remove_child_components(parent_dn, 1) != true) { 94 DEBUG(0,(__location__ ": Unable to remove DN component\n")); 149 *obj->parent_object_guid = samdb_result_guid(msg, "parentGUID"); 150 if (GUID_all_zero(obj->parent_object_guid)) { 151 DEBUG(0,(__location__ ": missing parentGUID for %s\n", 152 ldb_dn_get_linearized(msg->dn))); 95 153 return WERR_DS_DRA_INTERNAL_ERROR; 96 154 } 97 if (dsdb_find_guid_by_dn(sam_ctx, parent_dn, obj->parent_object_guid) != LDB_SUCCESS) {98 DEBUG(0,(__location__ ": Unable to find parent DN %s %s\n",99 ldb_dn_get_linearized(msg->dn), ldb_dn_get_linearized(parent_dn)));100 }101 talloc_free(parent_dn);102 155 } 103 156 obj->next_object = NULL; … … 109 162 } 110 163 111 ndr_err = ndr_pull_struct_blob(md_value, obj, 112 lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")), &md, 164 if (instanceType & INSTANCE_TYPE_UNINSTANT) { 165 /* don't send uninstantiated objects */ 166 return WERR_OK; 167 } 168 169 ndr_err = ndr_pull_struct_blob(md_value, obj, &md, 113 170 (ndr_pull_flags_fn_t)ndr_pull_replPropertyMetaDataBlob); 114 171 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 135 192 obj->meta_data_ctr = talloc(obj, struct drsuapi_DsReplicaMetaDataCtr); 136 193 attids = talloc_array(obj, uint32_t, md.ctr.ctr1.count); 194 195 obj->object.identifier = get_object_identifier(obj, msg); 196 if (obj->object.identifier == NULL) { 197 return WERR_NOMEM; 198 } 199 dom_sid_split_rid(NULL, &obj->object.identifier->sid, NULL, &rid); 137 200 138 201 obj->meta_data_ctr->meta_data = talloc_array(obj, struct drsuapi_DsReplicaMetaData, md.ctr.ctr1.count); 139 202 for (n=i=0; i<md.ctr.ctr1.count; i++) { 203 const struct dsdb_attribute *sa; 204 bool force_attribute = false; 205 140 206 /* if the attribute has not changed, and it is not the 141 207 instanceType then don't include it */ 142 208 if (md.ctr.ctr1.array[i].local_usn < highest_usn && 143 md.ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType) continue; 209 extended_op != DRSUAPI_EXOP_REPL_SECRET && 210 md.ctr.ctr1.array[i].attid != DRSUAPI_ATTID_instanceType) continue; 211 144 212 /* don't include the rDN */ 145 213 if (md.ctr.ctr1.array[i].attid == rdn_sa->attributeID_id) continue; 214 215 sa = dsdb_attribute_by_attributeID_id(schema, md.ctr.ctr1.array[i].attid); 216 if (!sa) { 217 DEBUG(0,(__location__ ": Failed to find attribute in schema for attrid %u mentioned in replPropertyMetaData of %s\n", 218 (unsigned int)md.ctr.ctr1.array[i].attid, 219 ldb_dn_get_linearized(msg->dn))); 220 return WERR_DS_DRA_INTERNAL_ERROR; 221 } 222 223 if (sa->linkID) { 224 struct ldb_message_element *el; 225 el = ldb_msg_find_element(msg, sa->lDAPDisplayName); 226 if (el && el->num_values && dsdb_dn_is_upgraded_link_val(&el->values[0])) { 227 /* don't send upgraded links inline */ 228 continue; 229 } 230 } 231 232 if (extended_op == DRSUAPI_EXOP_REPL_SECRET && 233 !dsdb_attr_in_rodc_fas(sa)) { 234 force_attribute = true; 235 DEBUG(4,("Forcing attribute %s in %s\n", 236 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); 237 } 238 239 /* filter by uptodateness_vector */ 240 if (md.ctr.ctr1.array[i].attid != DRSUAPI_ATTID_instanceType && 241 !force_attribute && 242 udv_filter(uptodateness_vector, 243 &md.ctr.ctr1.array[i].originating_invocation_id, 244 md.ctr.ctr1.array[i].originating_usn)) { 245 continue; 246 } 247 248 /* filter by partial_attribute_set */ 249 if (partial_attribute_set && !check_partial_attribute_set(sa, partial_attribute_set)) { 250 continue; 251 } 252 146 253 obj->meta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time; 147 254 obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version; … … 152 259 } 153 260 154 /* 155 note that if n==0 we still need to send the change, as it 156 could be a rename, which changes the uSNChanged, but not any 157 of the replicated attributes 158 */ 261 /* ignore it if its an empty change. Note that renames always 262 * change the 'name' attribute, so they won't be ignored by 263 * this */ 264 if (n == 0 || 265 (n == 1 && attids[0] == DRSUAPI_ATTID_instanceType)) { 266 talloc_free(obj->meta_data_ctr); 267 obj->meta_data_ctr = NULL; 268 return WERR_OK; 269 } 159 270 160 271 obj->meta_data_ctr->count = n; 161 162 obj->object.identifier = talloc(obj, struct drsuapi_DsReplicaObjectIdentifier);163 obj_dn = ldb_msg_find_attr_as_dn(sam_ctx, obj, msg, "distinguishedName");164 obj->object.identifier->dn = ldb_dn_get_linearized(obj_dn);165 obj->object.identifier->guid = samdb_result_guid(msg, "objectGUID");166 sid = samdb_result_dom_sid(obj, msg, "objectSid");167 if (sid) {168 dom_sid_split_rid(NULL, sid, NULL, &rid);169 obj->object.identifier->sid = *sid;170 } else {171 ZERO_STRUCT(obj->object.identifier->sid);172 }173 272 174 273 obj->object.flags = DRSUAPI_DS_REPLICA_OBJECT_FROM_MASTER; … … 194 293 el = ldb_msg_find_element(msg, sa->lDAPDisplayName); 195 294 if (el == NULL) { 196 DEBUG(0,("No element '%s' for attributeID %u in message\n", 295 /* this happens for attributes that have been removed */ 296 DEBUG(5,("No element '%s' for attributeID %u in message\n", 197 297 sa->lDAPDisplayName, attids[i])); 198 298 ZERO_STRUCT(obj->object.attribute_ctr.attributes[i]); 199 obj->object.attribute_ctr.attributes[i].attid = attids[i]; 299 obj->object.attribute_ctr.attributes[i].attid = 300 dsdb_attribute_get_attid(sa, syntax_ctx.is_schema_nc); 200 301 } else { 201 werr = dsdb_attribute_ldb_to_drsuapi(sam_ctx, schema, el, obj,202 302 werr = sa->syntax->ldb_to_drsuapi(&syntax_ctx, sa, el, obj, 303 &obj->object.attribute_ctr.attributes[i]); 203 304 if (!W_ERROR_IS_OK(werr)) { 204 305 DEBUG(0,("Unable to convert %s to DRS object - %s\n", … … 206 307 return werr; 207 308 } 208 /* if DRSUAPI_D S_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING is set309 /* if DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING is set 209 310 * check if attribute is secret and send a null value 210 * TODO: check if we can make this in the database layer211 311 */ 212 if ((replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) 213 == DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) { 312 if (replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) { 214 313 drsuapi_process_secret_attribute(&obj->object.attribute_ctr.attributes[i], 215 314 &obj->meta_data_ctr->meta_data[i]); … … 230 329 } 231 330 331 232 332 /* 233 load replUpToDateVector from a DN 333 add one linked attribute from an object to the list of linked 334 attributes in a getncchanges request 234 335 */ 235 static WERROR load_udv(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, 236 struct ldb_dn *dn, struct replUpToDateVectorBlob *ouv) 237 { 238 const char *attrs[] = { "replUpToDateVector", NULL }; 239 struct ldb_result *res = NULL; 336 static WERROR get_nc_changes_add_la(TALLOC_CTX *mem_ctx, 337 struct ldb_context *sam_ctx, 338 const struct dsdb_schema *schema, 339 const struct dsdb_attribute *sa, 340 struct ldb_message *msg, 341 struct dsdb_dn *dsdb_dn, 342 struct drsuapi_DsReplicaLinkedAttribute **la_list, 343 uint32_t *la_count) 344 { 345 struct drsuapi_DsReplicaLinkedAttribute *la; 346 bool active; 347 NTSTATUS status; 348 WERROR werr; 349 350 (*la_list) = talloc_realloc(mem_ctx, *la_list, struct drsuapi_DsReplicaLinkedAttribute, (*la_count)+1); 351 W_ERROR_HAVE_NO_MEMORY(*la_list); 352 353 la = &(*la_list)[*la_count]; 354 355 la->identifier = get_object_identifier(*la_list, msg); 356 W_ERROR_HAVE_NO_MEMORY(la->identifier); 357 358 active = (dsdb_dn_rmd_flags(dsdb_dn->dn) & DSDB_RMD_FLAG_DELETED) == 0; 359 360 la->attid = sa->attributeID_id; 361 la->flags = active?DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE:0; 362 363 status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME"); 364 if (!NT_STATUS_IS_OK(status)) { 365 return ntstatus_to_werror(status); 366 } 367 status = dsdb_get_extended_dn_uint32(dsdb_dn->dn, &la->meta_data.version, "RMD_VERSION"); 368 if (!NT_STATUS_IS_OK(status)) { 369 return ntstatus_to_werror(status); 370 } 371 status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->meta_data.originating_change_time, "RMD_CHANGETIME"); 372 if (!NT_STATUS_IS_OK(status)) { 373 return ntstatus_to_werror(status); 374 } 375 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &la->meta_data.originating_invocation_id, "RMD_INVOCID"); 376 if (!NT_STATUS_IS_OK(status)) { 377 return ntstatus_to_werror(status); 378 } 379 status = dsdb_get_extended_dn_uint64(dsdb_dn->dn, &la->meta_data.originating_usn, "RMD_ORIGINATING_USN"); 380 if (!NT_STATUS_IS_OK(status)) { 381 return ntstatus_to_werror(status); 382 } 383 384 werr = dsdb_dn_la_to_blob(sam_ctx, sa, schema, *la_list, dsdb_dn, &la->value.blob); 385 W_ERROR_NOT_OK_RETURN(werr); 386 387 (*la_count)++; 388 return WERR_OK; 389 } 390 391 392 /* 393 add linked attributes from an object to the list of linked 394 attributes in a getncchanges request 395 */ 396 static WERROR get_nc_changes_add_links(struct ldb_context *sam_ctx, 397 TALLOC_CTX *mem_ctx, 398 struct ldb_dn *ncRoot_dn, 399 struct dsdb_schema *schema, 400 uint64_t highest_usn, 401 uint32_t replica_flags, 402 struct ldb_message *msg, 403 struct drsuapi_DsReplicaLinkedAttribute **la_list, 404 uint32_t *la_count, 405 struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector) 406 { 407 unsigned int i; 240 408 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 241 struct ldb_message_element *el; 242 enum ndr_err_code ndr_err; 243 244 ZERO_STRUCTP(ouv); 245 246 if (ldb_search(sam_ctx, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL) != LDB_SUCCESS || 247 res->count < 1) { 248 DEBUG(0,("load_udv: failed to read partition object\n")); 249 talloc_free(tmp_ctx); 250 return WERR_DS_DRA_INTERNAL_ERROR; 251 } 252 253 el = ldb_msg_find_element(res->msgs[0], "replUpToDateVector"); 254 if (el == NULL || el->num_values < 1) { 255 talloc_free(tmp_ctx); 256 ouv->version = 2; 257 return WERR_OK; 258 } 259 260 ndr_err = ndr_pull_struct_blob(&el->values[0], 261 mem_ctx, lp_iconv_convenience(ldb_get_opaque(sam_ctx, "loadparm")), 262 ouv, 263 (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); 409 uint64_t uSNChanged = ldb_msg_find_attr_as_int(msg, "uSNChanged", -1); 410 411 for (i=0; i<msg->num_elements; i++) { 412 struct ldb_message_element *el = &msg->elements[i]; 413 const struct dsdb_attribute *sa; 414 unsigned int j; 415 416 sa = dsdb_attribute_by_lDAPDisplayName(schema, el->name); 417 418 if (!sa || sa->linkID == 0 || (sa->linkID & 1)) { 419 /* we only want forward links */ 420 continue; 421 } 422 423 if (el->num_values && !dsdb_dn_is_upgraded_link_val(&el->values[0])) { 424 /* its an old style link, it will have been 425 * sent in the main replication data */ 426 continue; 427 } 428 429 for (j=0; j<el->num_values; j++) { 430 struct dsdb_dn *dsdb_dn; 431 uint64_t local_usn; 432 NTSTATUS status; 433 WERROR werr; 434 435 dsdb_dn = dsdb_dn_parse(tmp_ctx, sam_ctx, &el->values[j], sa->syntax->ldap_oid); 436 if (dsdb_dn == NULL) { 437 DEBUG(1,(__location__ ": Failed to parse DN for %s in %s\n", 438 el->name, ldb_dn_get_linearized(msg->dn))); 439 talloc_free(tmp_ctx); 440 return WERR_DS_DRA_INTERNAL_ERROR; 441 } 442 443 status = dsdb_get_extended_dn_uint64(dsdb_dn->dn, &local_usn, "RMD_LOCAL_USN"); 444 if (!NT_STATUS_IS_OK(status)) { 445 /* this can happen for attributes 446 given to us with old style meta 447 data */ 448 continue; 449 } 450 451 if (local_usn > uSNChanged) { 452 DEBUG(1,(__location__ ": uSNChanged less than RMD_LOCAL_USN for %s on %s\n", 453 el->name, ldb_dn_get_linearized(msg->dn))); 454 talloc_free(tmp_ctx); 455 return WERR_DS_DRA_INTERNAL_ERROR; 456 } 457 458 if (local_usn < highest_usn) { 459 continue; 460 } 461 462 werr = get_nc_changes_add_la(mem_ctx, sam_ctx, schema, sa, msg, 463 dsdb_dn, la_list, la_count); 464 if (!W_ERROR_IS_OK(werr)) { 465 talloc_free(tmp_ctx); 466 return werr; 467 } 468 } 469 } 470 264 471 talloc_free(tmp_ctx); 265 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {266 DEBUG(0,(__location__ ": Failed to parse replUpToDateVector for %s\n",267 ldb_dn_get_linearized(dn)));268 return WERR_DS_DRA_INTERNAL_ERROR;269 }270 271 472 return WERR_OK; 272 273 473 } 274 474 … … 280 480 struct drsuapi_DsReplicaCursor2CtrEx *udv) 281 481 { 482 int ret; 483 484 udv->version = 2; 485 udv->reserved1 = 0; 486 udv->reserved2 = 0; 487 488 ret = dsdb_load_udv_v2(sam_ctx, ncRoot_dn, udv, &udv->cursors, &udv->count); 489 if (ret != LDB_SUCCESS) { 490 DEBUG(0,(__location__ ": Failed to load UDV for %s - %s\n", 491 ldb_dn_get_linearized(ncRoot_dn), ldb_errstring(sam_ctx))); 492 return WERR_DS_DRA_INTERNAL_ERROR; 493 } 494 495 return WERR_OK; 496 } 497 498 499 /* comparison function for linked attributes - see CompareLinks() in 500 * MS-DRSR section 4.1.10.5.17 */ 501 static int linked_attribute_compare(const struct drsuapi_DsReplicaLinkedAttribute *la1, 502 const struct drsuapi_DsReplicaLinkedAttribute *la2, 503 struct ldb_context *sam_ctx) 504 { 505 int c; 282 506 WERROR werr; 283 struct drsuapi_DsReplicaCursor2 *tmp_cursor; 284 uint64_t highest_commited_usn; 285 NTTIME now; 286 time_t t = time(NULL); 507 TALLOC_CTX *tmp_ctx; 508 const struct dsdb_schema *schema; 509 const struct dsdb_attribute *schema_attrib; 510 struct dsdb_dn *dn1, *dn2; 511 struct GUID guid1, guid2; 512 NTSTATUS status; 513 514 c = GUID_compare(&la1->identifier->guid, 515 &la2->identifier->guid); 516 if (c != 0) return c; 517 518 if (la1->attid != la2->attid) { 519 return la1->attid < la2->attid? -1:1; 520 } 521 522 if ((la1->flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE) != 523 (la2->flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)) { 524 return (la1->flags & DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE)? 1:-1; 525 } 526 527 /* we need to get the target GUIDs to compare */ 528 tmp_ctx = talloc_new(sam_ctx); 529 530 schema = dsdb_get_schema(sam_ctx, tmp_ctx); 531 schema_attrib = dsdb_attribute_by_attributeID_id(schema, la1->attid); 532 533 werr = dsdb_dn_la_from_blob(sam_ctx, schema_attrib, schema, tmp_ctx, la1->value.blob, &dn1); 534 if (!W_ERROR_IS_OK(werr)) { 535 DEBUG(0,(__location__ ": Bad la1 blob in sort\n")); 536 talloc_free(tmp_ctx); 537 return 0; 538 } 539 540 werr = dsdb_dn_la_from_blob(sam_ctx, schema_attrib, schema, tmp_ctx, la2->value.blob, &dn2); 541 if (!W_ERROR_IS_OK(werr)) { 542 DEBUG(0,(__location__ ": Bad la2 blob in sort\n")); 543 talloc_free(tmp_ctx); 544 return 0; 545 } 546 547 status = dsdb_get_extended_dn_guid(dn1->dn, &guid1, "GUID"); 548 if (!NT_STATUS_IS_OK(status)) { 549 DEBUG(0,(__location__ ": Bad la1 guid in sort\n")); 550 talloc_free(tmp_ctx); 551 return 0; 552 } 553 status = dsdb_get_extended_dn_guid(dn2->dn, &guid2, "GUID"); 554 if (!NT_STATUS_IS_OK(status)) { 555 DEBUG(0,(__location__ ": Bad la2 guid in sort\n")); 556 talloc_free(tmp_ctx); 557 return 0; 558 } 559 560 talloc_free(tmp_ctx); 561 562 return GUID_compare(&guid1, &guid2); 563 } 564 565 566 /* 567 sort the objects we send by tree order 568 */ 569 static int site_res_cmp_parent_order(struct ldb_message **m1, struct ldb_message **m2) 570 { 571 return ldb_dn_compare((*m2)->dn, (*m1)->dn); 572 } 573 574 /* 575 sort the objects we send first by uSNChanged 576 */ 577 static int site_res_cmp_usn_order(struct ldb_message **m1, struct ldb_message **m2) 578 { 579 unsigned usnchanged1, usnchanged2; 580 unsigned cn1, cn2; 581 cn1 = ldb_dn_get_comp_num((*m1)->dn); 582 cn2 = ldb_dn_get_comp_num((*m2)->dn); 583 if (cn1 != cn2) { 584 return cn1 > cn2 ? 1 : -1; 585 } 586 usnchanged1 = ldb_msg_find_attr_as_uint(*m1, "uSNChanged", 0); 587 usnchanged2 = ldb_msg_find_attr_as_uint(*m2, "uSNChanged", 0); 588 if (usnchanged1 == usnchanged2) { 589 return 0; 590 } 591 return usnchanged1 > usnchanged2 ? 1 : -1; 592 } 593 594 595 /* 596 handle a DRSUAPI_EXOP_FSMO_RID_ALLOC call 597 */ 598 static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state, 599 TALLOC_CTX *mem_ctx, 600 struct drsuapi_DsGetNCChangesRequest10 *req10, 601 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 602 { 603 struct ldb_dn *rid_manager_dn, *fsmo_role_dn, *req_dn; 287 604 int ret; 288 struct replUpToDateVectorBlob ouv; 289 290 werr = load_udv(sam_ctx, udv, ncRoot_dn, &ouv); 605 struct ldb_context *ldb = b_state->sam_ctx; 606 struct ldb_result *ext_res; 607 struct ldb_dn *base_dn; 608 struct dsdb_fsmo_extended_op *exop; 609 610 /* 611 steps: 612 - verify that the DN being asked for is the RID Manager DN 613 - verify that we are the RID Manager 614 */ 615 616 /* work out who is the RID Manager */ 617 ret = samdb_rid_manager_dn(ldb, mem_ctx, &rid_manager_dn); 618 if (ret != LDB_SUCCESS) { 619 DEBUG(0, (__location__ ": Failed to find RID Manager object - %s\n", ldb_errstring(ldb))); 620 return WERR_DS_DRA_INTERNAL_ERROR; 621 } 622 623 req_dn = drs_ObjectIdentifier_to_dn(mem_ctx, ldb, req10->naming_context); 624 if (!ldb_dn_validate(req_dn) || 625 ldb_dn_compare(req_dn, rid_manager_dn) != 0) { 626 /* that isn't the RID Manager DN */ 627 DEBUG(0,(__location__ ": RID Alloc request for wrong DN %s\n", 628 drs_ObjectIdentifier_to_string(mem_ctx, req10->naming_context))); 629 ctr6->extended_ret = DRSUAPI_EXOP_ERR_MISMATCH; 630 return WERR_OK; 631 } 632 633 /* find the DN of the RID Manager */ 634 ret = samdb_reference_dn(ldb, mem_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn); 635 if (ret != LDB_SUCCESS) { 636 DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in RID Manager object - %s\n", 637 ldb_errstring(ldb))); 638 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 639 return WERR_DS_DRA_INTERNAL_ERROR; 640 } 641 642 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { 643 /* we're not the RID Manager - go away */ 644 DEBUG(0,(__location__ ": RID Alloc request when not RID Manager\n")); 645 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 646 return WERR_OK; 647 } 648 649 exop = talloc(mem_ctx, struct dsdb_fsmo_extended_op); 650 W_ERROR_HAVE_NO_MEMORY(exop); 651 652 exop->fsmo_info = req10->fsmo_info; 653 exop->destination_dsa_guid = req10->destination_dsa_guid; 654 655 ret = ldb_transaction_start(ldb); 656 if (ret != LDB_SUCCESS) { 657 DEBUG(0,(__location__ ": Failed transaction start - %s\n", 658 ldb_errstring(ldb))); 659 return WERR_DS_DRA_INTERNAL_ERROR; 660 } 661 662 /* 663 * FIXME (kim): this is a temp hack to return just few object, 664 * but not the whole domain NC. 665 * We should remove this hack and implement a 'scope' 666 * building function to return just the set of object 667 * documented for DRSUAPI_EXOP_FSMO_RID_ALLOC extended_op 668 */ 669 ldb_sequence_number(ldb, LDB_SEQ_HIGHEST_SEQ, &req10->highwatermark.highest_usn); 670 671 ret = ldb_extended(ldb, DSDB_EXTENDED_ALLOCATE_RID_POOL, exop, &ext_res); 672 if (ret != LDB_SUCCESS) { 673 DEBUG(0,(__location__ ": Failed extended allocation RID pool operation - %s\n", 674 ldb_errstring(ldb))); 675 ldb_transaction_cancel(ldb); 676 return WERR_DS_DRA_INTERNAL_ERROR; 677 } 678 679 ret = ldb_transaction_commit(ldb); 680 if (ret != LDB_SUCCESS) { 681 DEBUG(0,(__location__ ": Failed transaction commit - %s\n", 682 ldb_errstring(ldb))); 683 return WERR_DS_DRA_INTERNAL_ERROR; 684 } 685 686 talloc_free(ext_res); 687 688 base_dn = ldb_get_default_basedn(ldb); 689 690 DEBUG(2,("Allocated RID pool for server %s\n", 691 GUID_string(mem_ctx, &req10->destination_dsa_guid))); 692 693 ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 694 695 return WERR_OK; 696 } 697 698 /* 699 return an array of SIDs from a ldb_message given an attribute name 700 assumes the SIDs are in extended DN format 701 */ 702 static WERROR samdb_result_sid_array_dn(struct ldb_context *sam_ctx, 703 struct ldb_message *msg, 704 TALLOC_CTX *mem_ctx, 705 const char *attr, 706 const struct dom_sid ***sids) 707 { 708 struct ldb_message_element *el; 709 unsigned int i; 710 711 el = ldb_msg_find_element(msg, attr); 712 if (!el) { 713 *sids = NULL; 714 return WERR_OK; 715 } 716 717 (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); 718 W_ERROR_HAVE_NO_MEMORY(*sids); 719 720 for (i=0; i<el->num_values; i++) { 721 struct ldb_dn *dn = ldb_dn_from_ldb_val(mem_ctx, sam_ctx, &el->values[i]); 722 NTSTATUS status; 723 struct dom_sid *sid; 724 725 sid = talloc(*sids, struct dom_sid); 726 W_ERROR_HAVE_NO_MEMORY(sid); 727 status = dsdb_get_extended_dn_sid(dn, sid, "SID"); 728 if (!NT_STATUS_IS_OK(status)) { 729 return WERR_INTERNAL_DB_CORRUPTION; 730 } 731 (*sids)[i] = sid; 732 } 733 (*sids)[i] = NULL; 734 735 return WERR_OK; 736 } 737 738 739 /* 740 return an array of SIDs from a ldb_message given an attribute name 741 assumes the SIDs are in NDR form 742 */ 743 static WERROR samdb_result_sid_array_ndr(struct ldb_context *sam_ctx, 744 struct ldb_message *msg, 745 TALLOC_CTX *mem_ctx, 746 const char *attr, 747 const struct dom_sid ***sids) 748 { 749 struct ldb_message_element *el; 750 unsigned int i; 751 752 el = ldb_msg_find_element(msg, attr); 753 if (!el) { 754 *sids = NULL; 755 return WERR_OK; 756 } 757 758 (*sids) = talloc_array(mem_ctx, const struct dom_sid *, el->num_values + 1); 759 W_ERROR_HAVE_NO_MEMORY(*sids); 760 761 for (i=0; i<el->num_values; i++) { 762 enum ndr_err_code ndr_err; 763 struct dom_sid *sid; 764 765 sid = talloc(*sids, struct dom_sid); 766 W_ERROR_HAVE_NO_MEMORY(sid); 767 768 ndr_err = ndr_pull_struct_blob(&el->values[i], sid, sid, 769 (ndr_pull_flags_fn_t)ndr_pull_dom_sid); 770 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 771 return WERR_INTERNAL_DB_CORRUPTION; 772 } 773 (*sids)[i] = sid; 774 } 775 (*sids)[i] = NULL; 776 777 return WERR_OK; 778 } 779 780 /* 781 see if any SIDs in list1 are in list2 782 */ 783 static bool sid_list_match(const struct dom_sid **list1, const struct dom_sid **list2) 784 { 785 unsigned int i, j; 786 /* do we ever have enough SIDs here to worry about O(n^2) ? */ 787 for (i=0; list1[i]; i++) { 788 for (j=0; list2[j]; j++) { 789 if (dom_sid_equal(list1[i], list2[j])) { 790 return true; 791 } 792 } 793 } 794 return false; 795 } 796 797 /* 798 handle a DRSUAPI_EXOP_REPL_SECRET call 799 */ 800 static WERROR getncchanges_repl_secret(struct drsuapi_bind_state *b_state, 801 TALLOC_CTX *mem_ctx, 802 struct drsuapi_DsGetNCChangesRequest10 *req10, 803 struct dom_sid *user_sid, 804 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 805 { 806 struct drsuapi_DsReplicaObjectIdentifier *ncRoot = req10->naming_context; 807 struct ldb_dn *obj_dn, *rodc_dn, *krbtgt_link_dn; 808 int ret; 809 const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", NULL }; 810 const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL }; 811 struct ldb_result *rodc_res, *obj_res; 812 const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids; 813 WERROR werr; 814 815 DEBUG(3,(__location__ ": DRSUAPI_EXOP_REPL_SECRET extended op on %s\n", 816 drs_ObjectIdentifier_to_string(mem_ctx, ncRoot))); 817 818 /* 819 * we need to work out if we will allow this RODC to 820 * replicate the secrets for this object 821 * 822 * see 4.1.10.5.14 GetRevealSecretsPolicyForUser for details 823 * of this function 824 */ 825 826 if (b_state->sam_ctx_system == NULL) { 827 /* this operation needs system level access */ 828 ctr6->extended_ret = DRSUAPI_EXOP_ERR_ACCESS_DENIED; 829 return WERR_DS_DRA_SOURCE_DISABLED; 830 } 831 832 obj_dn = drs_ObjectIdentifier_to_dn(mem_ctx, b_state->sam_ctx_system, ncRoot); 833 if (!ldb_dn_validate(obj_dn)) goto failed; 834 835 rodc_dn = ldb_dn_new_fmt(mem_ctx, b_state->sam_ctx_system, "<SID=%s>", 836 dom_sid_string(mem_ctx, user_sid)); 837 if (!ldb_dn_validate(rodc_dn)) goto failed; 838 839 /* do the two searches we need */ 840 ret = dsdb_search_dn(b_state->sam_ctx_system, mem_ctx, &rodc_res, rodc_dn, rodc_attrs, 841 DSDB_SEARCH_SHOW_EXTENDED_DN); 842 if (ret != LDB_SUCCESS || rodc_res->count != 1) goto failed; 843 844 ret = dsdb_search_dn(b_state->sam_ctx_system, mem_ctx, &obj_res, obj_dn, obj_attrs, 0); 845 if (ret != LDB_SUCCESS || obj_res->count != 1) goto failed; 846 847 /* if the object SID is equal to the user_sid, allow */ 848 if (dom_sid_equal(user_sid, 849 samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid"))) { 850 goto allowed; 851 } 852 853 /* an RODC is allowed to get its own krbtgt account secrets */ 854 krbtgt_link_dn = samdb_result_dn(b_state->sam_ctx_system, mem_ctx, 855 rodc_res->msgs[0], "msDS-KrbTgtLink", NULL); 856 if (krbtgt_link_dn != NULL && 857 ldb_dn_compare(obj_dn, krbtgt_link_dn) == 0) { 858 goto allowed; 859 } 860 861 /* but it isn't allowed to get anyone elses krbtgt secrets */ 862 if (samdb_result_dn(b_state->sam_ctx_system, mem_ctx, 863 obj_res->msgs[0], "msDS-KrbTgtLinkBL", NULL)) { 864 goto denied; 865 } 866 867 if (ldb_msg_find_attr_as_uint(obj_res->msgs[0], 868 "userAccountControl", 0) & 869 UF_INTERDOMAIN_TRUST_ACCOUNT) { 870 goto denied; 871 } 872 873 werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0], 874 mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids); 291 875 if (!W_ERROR_IS_OK(werr)) { 292 return werr; 293 } 294 295 ret = ldb_sequence_number(sam_ctx, LDB_SEQ_HIGHEST_SEQ, &highest_commited_usn); 876 goto denied; 877 } 878 879 werr = samdb_result_sid_array_dn(b_state->sam_ctx_system, rodc_res->msgs[0], 880 mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids); 881 if (!W_ERROR_IS_OK(werr)) { 882 goto denied; 883 } 884 885 werr = samdb_result_sid_array_ndr(b_state->sam_ctx_system, obj_res->msgs[0], 886 mem_ctx, "tokenGroups", &token_sids); 887 if (!W_ERROR_IS_OK(werr) || token_sids==NULL) { 888 goto denied; 889 } 890 891 if (never_reveal_sids && 892 sid_list_match(token_sids, never_reveal_sids)) { 893 goto denied; 894 } 895 896 if (reveal_sids && 897 sid_list_match(token_sids, reveal_sids)) { 898 goto allowed; 899 } 900 901 /* default deny */ 902 denied: 903 DEBUG(2,(__location__ ": Denied RODC secret replication for %s by RODC %s\n", 904 ldb_dn_get_linearized(obj_dn), ldb_dn_get_linearized(rodc_res->msgs[0]->dn))); 905 ctr6->extended_ret = DRSUAPI_EXOP_ERR_NONE; 906 return WERR_DS_DRA_ACCESS_DENIED; 907 908 allowed: 909 DEBUG(2,(__location__ ": Allowed RODC secret replication for %s by RODC %s\n", 910 ldb_dn_get_linearized(obj_dn), ldb_dn_get_linearized(rodc_res->msgs[0]->dn))); 911 ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 912 req10->highwatermark.highest_usn = 0; 913 return WERR_OK; 914 915 failed: 916 DEBUG(2,(__location__ ": Failed RODC secret replication for %s by RODC %s\n", 917 ldb_dn_get_linearized(obj_dn), dom_sid_string(mem_ctx, user_sid))); 918 ctr6->extended_ret = DRSUAPI_EXOP_ERR_NONE; 919 return WERR_DS_DRA_BAD_DN; 920 } 921 922 923 /* 924 handle a DRSUAPI_EXOP_REPL_OBJ call 925 */ 926 static WERROR getncchanges_repl_obj(struct drsuapi_bind_state *b_state, 927 TALLOC_CTX *mem_ctx, 928 struct drsuapi_DsGetNCChangesRequest10 *req10, 929 struct dom_sid *user_sid, 930 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 931 { 932 struct drsuapi_DsReplicaObjectIdentifier *ncRoot = req10->naming_context; 933 934 DEBUG(3,(__location__ ": DRSUAPI_EXOP_REPL_OBJ extended op on %s\n", 935 drs_ObjectIdentifier_to_string(mem_ctx, ncRoot))); 936 937 ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 938 req10->highwatermark.highest_usn = 0; 939 return WERR_OK; 940 } 941 942 943 /* 944 handle DRSUAPI_EXOP_FSMO_REQ_ROLE, 945 DRSUAPI_EXOP_FSMO_RID_REQ_ROLE, 946 and DRSUAPI_EXOP_FSMO_REQ_PDC calls 947 */ 948 static WERROR getncchanges_change_master(struct drsuapi_bind_state *b_state, 949 TALLOC_CTX *mem_ctx, 950 struct drsuapi_DsGetNCChangesRequest10 *req10, 951 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 952 { 953 struct ldb_dn *fsmo_role_dn, *req_dn, *ntds_dn; 954 int ret; 955 unsigned int i; 956 struct ldb_context *ldb = b_state->sam_ctx; 957 struct ldb_message *msg; 958 959 /* 960 steps: 961 - verify that the client dn exists 962 - verify that we are the current master 963 */ 964 965 req_dn = drs_ObjectIdentifier_to_dn(mem_ctx, ldb, req10->naming_context); 966 if (!ldb_dn_validate(req_dn)) { 967 /* that is not a valid dn */ 968 DEBUG(0,(__location__ ": FSMO role transfer request for invalid DN %s\n", 969 drs_ObjectIdentifier_to_string(mem_ctx, req10->naming_context))); 970 ctr6->extended_ret = DRSUAPI_EXOP_ERR_MISMATCH; 971 return WERR_OK; 972 } 973 974 /* retrieve the current role owner */ 975 ret = samdb_reference_dn(ldb, mem_ctx, req_dn, "fSMORoleOwner", &fsmo_role_dn); 296 976 if (ret != LDB_SUCCESS) { 297 return WERR_DS_DRA_INTERNAL_ERROR; 298 } 299 300 tmp_cursor = talloc(udv, struct drsuapi_DsReplicaCursor2); 301 tmp_cursor->source_dsa_invocation_id = *(samdb_ntds_invocation_id(sam_ctx)); 302 tmp_cursor->highest_usn = highest_commited_usn; 303 unix_to_nt_time(&now, t); 304 tmp_cursor->last_sync_success = now; 305 306 udv->count = ouv.ctr.ctr2.count + 1; 307 udv->cursors = talloc_steal(udv, ouv.ctr.ctr2.cursors); 308 udv->cursors = talloc_realloc(udv, udv->cursors, struct drsuapi_DsReplicaCursor2, udv->count); 309 if (!udv->cursors) { 310 return WERR_DS_DRA_INTERNAL_ERROR; 311 } 312 udv->cursors[udv->count - 1] = *tmp_cursor; 313 314 qsort(udv->cursors, udv->count, 315 sizeof(struct drsuapi_DsReplicaCursor2), 316 (comparison_fn_t)drsuapi_DsReplicaCursor2_compare); 977 DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in context - %s\n", 978 ldb_errstring(ldb))); 979 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 980 return WERR_DS_DRA_INTERNAL_ERROR; 981 } 982 983 if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) { 984 /* we're not the current owner - go away */ 985 DEBUG(0,(__location__ ": FSMO transfer request when not owner\n")); 986 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 987 return WERR_OK; 988 } 989 990 /* change the current master */ 991 msg = ldb_msg_new(ldb); 992 W_ERROR_HAVE_NO_MEMORY(msg); 993 msg->dn = drs_ObjectIdentifier_to_dn(msg, ldb, req10->naming_context); 994 W_ERROR_HAVE_NO_MEMORY(msg->dn); 995 996 ret = dsdb_find_dn_by_guid(ldb, msg, &req10->destination_dsa_guid, &ntds_dn); 997 if (ret != LDB_SUCCESS) { 998 DEBUG(0, (__location__ ": Unable to find NTDS object for guid %s - %s\n", 999 GUID_string(mem_ctx, &req10->destination_dsa_guid), ldb_errstring(ldb))); 1000 talloc_free(msg); 1001 return WERR_DS_DRA_INTERNAL_ERROR; 1002 } 1003 1004 ret = ldb_msg_add_string(msg, "fSMORoleOwner", ldb_dn_get_linearized(ntds_dn)); 1005 if (ret != 0) { 1006 talloc_free(msg); 1007 return WERR_DS_DRA_INTERNAL_ERROR; 1008 } 1009 1010 for (i=0;i<msg->num_elements;i++) { 1011 msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; 1012 } 1013 1014 ret = ldb_transaction_start(ldb); 1015 if (ret != LDB_SUCCESS) { 1016 DEBUG(0,(__location__ ": Failed transaction start - %s\n", 1017 ldb_errstring(ldb))); 1018 return WERR_DS_DRA_INTERNAL_ERROR; 1019 } 1020 1021 ret = ldb_modify(ldb, msg); 1022 if (ret != LDB_SUCCESS) { 1023 DEBUG(0,(__location__ ": Failed to change current owner - %s\n", 1024 ldb_errstring(ldb))); 1025 ldb_transaction_cancel(ldb); 1026 return WERR_DS_DRA_INTERNAL_ERROR; 1027 } 1028 1029 ret = ldb_transaction_commit(ldb); 1030 if (ret != LDB_SUCCESS) { 1031 DEBUG(0,(__location__ ": Failed transaction commit - %s\n", 1032 ldb_errstring(ldb))); 1033 return WERR_DS_DRA_INTERNAL_ERROR; 1034 } 1035 1036 ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 317 1037 318 1038 return WERR_OK; … … 321 1041 /* state of a partially completed getncchanges call */ 322 1042 struct drsuapi_getncchanges_state { 323 struct ldb_result *site_res;324 uint32_t num_ sent;325 struct ldb_context *sam_ctx;1043 struct GUID *guids; 1044 uint32_t num_records; 1045 uint32_t num_processed; 326 1046 struct ldb_dn *ncRoot_dn; 327 uint32_t min_usn; 1047 bool is_schema_nc; 1048 uint64_t min_usn; 1049 uint64_t highest_usn; 1050 struct ldb_dn *last_dn; 1051 struct drsuapi_DsReplicaLinkedAttribute *la_list; 1052 uint32_t la_count; 1053 bool la_sorted; 1054 uint32_t la_idx; 1055 struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector; 328 1056 }; 1057 1058 /* 1059 see if this getncchanges request includes a request to reveal secret information 1060 */ 1061 static WERROR dcesrv_drsuapi_is_reveal_secrets_request(struct drsuapi_bind_state *b_state, 1062 struct drsuapi_DsGetNCChangesRequest10 *req10, 1063 bool *is_secret_request) 1064 { 1065 enum drsuapi_DsExtendedOperation exop; 1066 uint32_t i; 1067 struct dsdb_schema *schema; 1068 1069 *is_secret_request = true; 1070 1071 exop = req10->extended_op; 1072 1073 switch (exop) { 1074 case DRSUAPI_EXOP_FSMO_REQ_ROLE: 1075 case DRSUAPI_EXOP_FSMO_RID_ALLOC: 1076 case DRSUAPI_EXOP_FSMO_RID_REQ_ROLE: 1077 case DRSUAPI_EXOP_FSMO_REQ_PDC: 1078 case DRSUAPI_EXOP_FSMO_ABANDON_ROLE: 1079 /* FSMO exops can reveal secrets */ 1080 *is_secret_request = true; 1081 return WERR_OK; 1082 case DRSUAPI_EXOP_REPL_SECRET: 1083 case DRSUAPI_EXOP_REPL_OBJ: 1084 case DRSUAPI_EXOP_NONE: 1085 break; 1086 } 1087 1088 if (req10->replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) { 1089 *is_secret_request = false; 1090 return WERR_OK; 1091 } 1092 1093 if (exop == DRSUAPI_EXOP_REPL_SECRET || 1094 req10->partial_attribute_set == NULL) { 1095 /* they want secrets */ 1096 *is_secret_request = true; 1097 return WERR_OK; 1098 } 1099 1100 schema = dsdb_get_schema(b_state->sam_ctx, NULL); 1101 1102 /* check the attributes they asked for */ 1103 for (i=0; i<req10->partial_attribute_set->num_attids; i++) { 1104 const struct dsdb_attribute *sa; 1105 sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set->attids[i]); 1106 if (sa == NULL) { 1107 return WERR_DS_DRA_SCHEMA_MISMATCH; 1108 } 1109 if (!dsdb_attr_in_rodc_fas(sa)) { 1110 *is_secret_request = true; 1111 return WERR_OK; 1112 } 1113 } 1114 1115 /* check the attributes they asked for */ 1116 for (i=0; i<req10->partial_attribute_set_ex->num_attids; i++) { 1117 const struct dsdb_attribute *sa; 1118 sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set_ex->attids[i]); 1119 if (sa == NULL) { 1120 return WERR_DS_DRA_SCHEMA_MISMATCH; 1121 } 1122 if (!dsdb_attr_in_rodc_fas(sa)) { 1123 *is_secret_request = true; 1124 return WERR_OK; 1125 } 1126 } 1127 1128 *is_secret_request = false; 1129 return WERR_OK; 1130 } 1131 1132 1133 /* 1134 map from req8 to req10 1135 */ 1136 static struct drsuapi_DsGetNCChangesRequest10 * 1137 getncchanges_map_req8(TALLOC_CTX *mem_ctx, 1138 struct drsuapi_DsGetNCChangesRequest8 *req8) 1139 { 1140 struct drsuapi_DsGetNCChangesRequest10 *req10 = talloc_zero(mem_ctx, 1141 struct drsuapi_DsGetNCChangesRequest10); 1142 if (req10 == NULL) { 1143 return NULL; 1144 } 1145 1146 req10->destination_dsa_guid = req8->destination_dsa_guid; 1147 req10->source_dsa_invocation_id = req8->source_dsa_invocation_id; 1148 req10->naming_context = req8->naming_context; 1149 req10->highwatermark = req8->highwatermark; 1150 req10->uptodateness_vector = req8->uptodateness_vector; 1151 req10->replica_flags = req8->replica_flags; 1152 req10->max_object_count = req8->max_object_count; 1153 req10->max_ndr_size = req8->max_ndr_size; 1154 req10->extended_op = req8->extended_op; 1155 req10->fsmo_info = req8->fsmo_info; 1156 req10->partial_attribute_set = req8->partial_attribute_set; 1157 req10->partial_attribute_set_ex = req8->partial_attribute_set_ex; 1158 req10->mapping_ctr = req8->mapping_ctr; 1159 1160 return req10; 1161 } 1162 329 1163 330 1164 /* 331 1165 drsuapi_DsGetNCChanges 1166 1167 see MS-DRSR 4.1.10.5.2 for basic logic of this function 332 1168 */ 333 1169 WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 336 1172 struct drsuapi_DsReplicaObjectIdentifier *ncRoot; 337 1173 int ret; 338 int i;1174 uint32_t i; 339 1175 struct dsdb_schema *schema; 340 1176 struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; … … 342 1178 NTSTATUS status; 343 1179 DATA_BLOB session_key; 344 const char *attrs[] = { "*", "distinguishedName", NULL }; 1180 const char *attrs[] = { "uSNChanged", 1181 "objectGUID" , 1182 NULL }; 345 1183 WERROR werr; 346 1184 struct dcesrv_handle *h; 347 1185 struct drsuapi_bind_state *b_state; 348 1186 struct drsuapi_getncchanges_state *getnc_state; 1187 struct drsuapi_DsGetNCChangesRequest10 *req10; 1188 uint32_t options; 1189 uint32_t max_objects; 1190 uint32_t max_links; 1191 uint32_t link_count = 0; 1192 uint32_t link_total = 0; 1193 uint32_t link_given = 0; 1194 struct ldb_dn *search_dn = NULL; 1195 bool am_rodc, null_scope=false; 1196 enum security_user_level security_level; 1197 struct ldb_context *sam_ctx; 1198 struct dom_sid *user_sid; 1199 bool is_secret_request; 349 1200 350 1201 DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); 351 1202 b_state = h->data; 1203 1204 sam_ctx = b_state->sam_ctx_system?b_state->sam_ctx_system:b_state->sam_ctx; 352 1205 353 1206 *r->out.level_out = 6; … … 361 1214 r->out.ctr->ctr6.uptodateness_vector = NULL; 362 1215 363 /* Check request revision. */ 364 if (r->in.level != 8) { 1216 /* a RODC doesn't allow for any replication */ 1217 ret = samdb_rodc(sam_ctx, &am_rodc); 1218 if (ret == LDB_SUCCESS && am_rodc) { 1219 DEBUG(0,(__location__ ": DsGetNCChanges attempt on RODC\n")); 1220 return WERR_DS_DRA_SOURCE_DISABLED; 1221 } 1222 1223 /* Check request revision. 1224 */ 1225 switch (r->in.level) { 1226 case 8: 1227 req10 = getncchanges_map_req8(mem_ctx, &r->in.req->req8); 1228 if (req10 == NULL) { 1229 return WERR_NOMEM; 1230 } 1231 break; 1232 case 10: 1233 req10 = &r->in.req->req10; 1234 break; 1235 default: 1236 DEBUG(0,(__location__ ": Request for DsGetNCChanges with unsupported level %u\n", 1237 r->in.level)); 365 1238 return WERR_REVISION_MISMATCH; 366 1239 } 367 1240 1241 368 1242 /* Perform access checks. */ 369 if (r->in.req->req8.naming_context == NULL) { 1243 /* TODO: we need to support a sync on a specific non-root 1244 * DN. We'll need to find the real partition root here */ 1245 ncRoot = req10->naming_context; 1246 if (ncRoot == NULL) { 1247 DEBUG(0,(__location__ ": Request for DsGetNCChanges with no NC\n")); 370 1248 return WERR_DS_DRA_INVALID_PARAMETER; 371 1249 } 372 1250 373 ncRoot = r->in.req->req8.naming_context; 374 if (ncRoot == NULL) { 375 return WERR_DS_DRA_BAD_NC; 376 } 377 378 if ((r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) 379 == DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) { 380 /* Ignore the _in_ uptpdateness vector*/ 381 r->in.req->req8.uptodateness_vector = NULL; 382 } 383 384 werr = drs_security_level_check(dce_call, "DsGetNCChanges"); 1251 if (samdb_ntds_options(sam_ctx, &options) != LDB_SUCCESS) { 1252 return WERR_DS_DRA_INTERNAL_ERROR; 1253 } 1254 1255 if ((options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) && 1256 !(req10->replica_flags & DRSUAPI_DRS_SYNC_FORCED)) { 1257 return WERR_DS_DRA_SOURCE_DISABLED; 1258 } 1259 1260 user_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 1261 1262 werr = drs_security_access_check_nc_root(b_state->sam_ctx, 1263 mem_ctx, 1264 dce_call->conn->auth_state.session_info->security_token, 1265 req10->naming_context, 1266 GUID_DRS_GET_CHANGES); 385 1267 if (!W_ERROR_IS_OK(werr)) { 386 1268 return werr; 387 1269 } 388 1270 1271 werr = dcesrv_drsuapi_is_reveal_secrets_request(b_state, req10, &is_secret_request); 1272 if (!W_ERROR_IS_OK(werr)) { 1273 return werr; 1274 } 1275 if (is_secret_request && req10->extended_op != DRSUAPI_EXOP_REPL_SECRET) { 1276 werr = drs_security_access_check_nc_root(b_state->sam_ctx, 1277 mem_ctx, 1278 dce_call->conn->auth_state.session_info->security_token, 1279 req10->naming_context, 1280 GUID_DRS_GET_ALL_CHANGES); 1281 if (!W_ERROR_IS_OK(werr)) { 1282 return werr; 1283 } 1284 } 1285 1286 /* for non-administrator replications, check that they have 1287 given the correct source_dsa_invocation_id */ 1288 security_level = security_session_user_level(dce_call->conn->auth_state.session_info, 1289 samdb_domain_sid(sam_ctx)); 1290 if (security_level == SECURITY_RO_DOMAIN_CONTROLLER) { 1291 if (req10->replica_flags & DRSUAPI_DRS_WRIT_REP) { 1292 /* we rely on this flag being unset for RODC requests */ 1293 req10->replica_flags &= ~DRSUAPI_DRS_WRIT_REP; 1294 } 1295 } 1296 1297 if (req10->replica_flags & DRSUAPI_DRS_FULL_SYNC_PACKET) { 1298 /* Ignore the _in_ uptpdateness vector*/ 1299 req10->uptodateness_vector = NULL; 1300 } 1301 389 1302 getnc_state = b_state->getncchanges_state; 1303 1304 /* see if a previous replication has been abandoned */ 1305 if (getnc_state) { 1306 struct ldb_dn *new_dn = drs_ObjectIdentifier_to_dn(getnc_state, sam_ctx, ncRoot); 1307 if (ldb_dn_compare(new_dn, getnc_state->ncRoot_dn) != 0) { 1308 DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication on different DN %s %s (last_dn %s)\n", 1309 ldb_dn_get_linearized(new_dn), 1310 ldb_dn_get_linearized(getnc_state->ncRoot_dn), 1311 ldb_dn_get_linearized(getnc_state->last_dn))); 1312 talloc_free(getnc_state); 1313 getnc_state = NULL; 1314 } 1315 } 1316 390 1317 if (getnc_state == NULL) { 391 1318 getnc_state = talloc_zero(b_state, struct drsuapi_getncchanges_state); … … 394 1321 } 395 1322 b_state->getncchanges_state = getnc_state; 396 1323 getnc_state->ncRoot_dn = drs_ObjectIdentifier_to_dn(getnc_state, sam_ctx, ncRoot); 1324 1325 /* find out if we are to replicate Schema NC */ 1326 ret = ldb_dn_compare(getnc_state->ncRoot_dn, 1327 ldb_get_schema_basedn(b_state->sam_ctx)); 1328 getnc_state->is_schema_nc = (0 == ret); 397 1329 398 1330 /* 399 * connect to the samdb. TODO: We need to check that the caller 400 * has the rights to do this. This exposes all attributes, 401 * including all passwords. 1331 * This is the first replication cycle and it is 1332 * a good place to handle extended operations 1333 * 1334 * FIXME: we don't fully support extended operations yet 402 1335 */ 403 getnc_state->sam_ctx = samdb_connect(getnc_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 404 system_session(getnc_state, dce_call->conn->dce_ctx->lp_ctx)); 405 if (!getnc_state->sam_ctx) { 406 return WERR_FOOBAR; 407 } 1336 switch (req10->extended_op) { 1337 case DRSUAPI_EXOP_NONE: 1338 break; 1339 case DRSUAPI_EXOP_FSMO_RID_ALLOC: 1340 werr = getncchanges_rid_alloc(b_state, mem_ctx, req10, &r->out.ctr->ctr6); 1341 W_ERROR_NOT_OK_RETURN(werr); 1342 search_dn = ldb_get_default_basedn(sam_ctx); 1343 break; 1344 case DRSUAPI_EXOP_REPL_SECRET: 1345 werr = getncchanges_repl_secret(b_state, mem_ctx, req10, user_sid, &r->out.ctr->ctr6); 1346 r->out.result = werr; 1347 W_ERROR_NOT_OK_RETURN(werr); 1348 break; 1349 case DRSUAPI_EXOP_FSMO_REQ_ROLE: 1350 werr = getncchanges_change_master(b_state, mem_ctx, req10, &r->out.ctr->ctr6); 1351 W_ERROR_NOT_OK_RETURN(werr); 1352 break; 1353 case DRSUAPI_EXOP_FSMO_RID_REQ_ROLE: 1354 werr = getncchanges_change_master(b_state, mem_ctx, req10, &r->out.ctr->ctr6); 1355 W_ERROR_NOT_OK_RETURN(werr); 1356 break; 1357 case DRSUAPI_EXOP_FSMO_REQ_PDC: 1358 werr = getncchanges_change_master(b_state, mem_ctx, req10, &r->out.ctr->ctr6); 1359 W_ERROR_NOT_OK_RETURN(werr); 1360 break; 1361 case DRSUAPI_EXOP_REPL_OBJ: 1362 werr = getncchanges_repl_obj(b_state, mem_ctx, req10, user_sid, &r->out.ctr->ctr6); 1363 r->out.result = werr; 1364 W_ERROR_NOT_OK_RETURN(werr); 1365 break; 1366 1367 case DRSUAPI_EXOP_FSMO_ABANDON_ROLE: 1368 1369 DEBUG(0,(__location__ ": Request for DsGetNCChanges unsupported extended op 0x%x\n", 1370 (unsigned)req10->extended_op)); 1371 return WERR_DS_DRA_NOT_SUPPORTED; 1372 } 1373 } 1374 1375 if (!ldb_dn_validate(getnc_state->ncRoot_dn) || 1376 ldb_dn_is_null(getnc_state->ncRoot_dn)) { 1377 DEBUG(0,(__location__ ": Bad DN '%s'\n", 1378 drs_ObjectIdentifier_to_string(mem_ctx, ncRoot))); 1379 return WERR_DS_DRA_INVALID_PARAMETER; 408 1380 } 409 1381 … … 415 1387 } 416 1388 417 if (getnc_state->site_res == NULL) { 1389 /* 1390 TODO: MS-DRSR section 4.1.10.1.1 1391 Work out if this is the start of a new cycle */ 1392 1393 if (getnc_state->guids == NULL) { 418 1394 char* search_filter; 419 1395 enum ldb_scope scope = LDB_SCOPE_SUBTREE; 420 421 getnc_state->min_usn = r->in.req->req8.highwatermark.highest_usn; 1396 const char *extra_filter; 1397 struct ldb_result *search_res; 1398 1399 if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || 1400 req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { 1401 scope = LDB_SCOPE_BASE; 1402 } 1403 1404 extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); 1405 1406 getnc_state->min_usn = req10->highwatermark.highest_usn; 422 1407 423 1408 /* Construct response. */ … … 425 1410 "(uSNChanged>=%llu)", 426 1411 (unsigned long long)(getnc_state->min_usn+1)); 427 428 if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) { 1412 1413 if (extra_filter) { 1414 search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); 1415 } 1416 1417 if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { 429 1418 search_filter = talloc_asprintf(mem_ctx, 430 1419 "(&%s(isCriticalSystemObject=TRUE))", … … 432 1421 } 433 1422 434 getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, getnc_state->sam_ctx, ncRoot->dn); 435 if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) { 1423 if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { 436 1424 scope = LDB_SCOPE_BASE; 437 1425 } 438 1426 439 DEBUG(6,(__location__ ": getncchanges on %s using filter %s\n", 1427 if (!search_dn) { 1428 search_dn = getnc_state->ncRoot_dn; 1429 } 1430 1431 DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", 440 1432 ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); 441 ret = drsuapi_search_with_extended_dn(getnc_state->sam_ctx, getnc_state, &getnc_state->site_res, 442 getnc_state->ncRoot_dn, scope, attrs, 443 "distinguishedName", 1433 ret = drsuapi_search_with_extended_dn(sam_ctx, getnc_state, &search_res, 1434 search_dn, scope, attrs, 444 1435 search_filter); 445 1436 if (ret != LDB_SUCCESS) { 446 1437 return WERR_DS_DRA_INTERNAL_ERROR; 447 1438 } 1439 1440 if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { 1441 TYPESAFE_QSORT(search_res->msgs, 1442 search_res->count, 1443 site_res_cmp_parent_order); 1444 } else { 1445 TYPESAFE_QSORT(search_res->msgs, 1446 search_res->count, 1447 site_res_cmp_usn_order); 1448 } 1449 1450 /* extract out the GUIDs list */ 1451 getnc_state->num_records = search_res->count; 1452 getnc_state->guids = talloc_array(getnc_state, struct GUID, getnc_state->num_records); 1453 W_ERROR_HAVE_NO_MEMORY(getnc_state->guids); 1454 1455 for (i=0; i<getnc_state->num_records; i++) { 1456 getnc_state->guids[i] = samdb_result_guid(search_res->msgs[i], "objectGUID"); 1457 if (GUID_all_zero(&getnc_state->guids[i])) { 1458 DEBUG(2,("getncchanges: bad objectGUID from %s\n", ldb_dn_get_linearized(search_res->msgs[i]->dn))); 1459 return WERR_DS_DRA_INTERNAL_ERROR; 1460 } 1461 } 1462 1463 1464 talloc_free(search_res); 1465 1466 getnc_state->uptodateness_vector = talloc_steal(getnc_state, req10->uptodateness_vector); 1467 if (getnc_state->uptodateness_vector) { 1468 /* make sure its sorted */ 1469 TYPESAFE_QSORT(getnc_state->uptodateness_vector->cursors, 1470 getnc_state->uptodateness_vector->count, 1471 drsuapi_DsReplicaCursor_compare); 1472 } 448 1473 } 449 1474 450 1475 /* Prefix mapping */ 451 schema = dsdb_get_schema( getnc_state->sam_ctx);1476 schema = dsdb_get_schema(sam_ctx, mem_ctx); 452 1477 if (!schema) { 453 1478 DEBUG(0,("No schema in sam_ctx\n")); … … 458 1483 *r->out.ctr->ctr6.naming_context = *ncRoot; 459 1484 460 if (dsdb_find_guid_by_dn( getnc_state->sam_ctx, getnc_state->ncRoot_dn,1485 if (dsdb_find_guid_by_dn(sam_ctx, getnc_state->ncRoot_dn, 461 1486 &r->out.ctr->ctr6.naming_context->guid) != LDB_SUCCESS) { 462 1487 DEBUG(0,(__location__ ": Failed to find GUID of ncRoot_dn %s\n", … … 466 1491 467 1492 /* find the SID if there is one */ 468 dsdb_find_sid_by_dn( getnc_state->sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid);1493 dsdb_find_sid_by_dn(sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid); 469 1494 470 1495 dsdb_get_oid_mappings_drsuapi(schema, true, mem_ctx, &ctr); 471 1496 r->out.ctr->ctr6.mapping_ctr = *ctr; 472 1497 473 r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID( getnc_state->sam_ctx));474 r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id( getnc_state->sam_ctx));475 476 r->out.ctr->ctr6.old_highwatermark = r ->in.req->req8.highwatermark;477 r->out.ctr->ctr6.new_highwatermark = r ->in.req->req8.highwatermark;1498 r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(sam_ctx)); 1499 r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(sam_ctx)); 1500 1501 r->out.ctr->ctr6.old_highwatermark = req10->highwatermark; 1502 r->out.ctr->ctr6.new_highwatermark = req10->highwatermark; 478 1503 479 1504 r->out.ctr->ctr6.first_object = NULL; 480 1505 currentObject = &r->out.ctr->ctr6.first_object; 481 1506 482 for(i=getnc_state->num_sent; 483 i<getnc_state->site_res->count && 484 (r->out.ctr->ctr6.object_count < r->in.req->req8.max_object_count); 1507 /* use this to force single objects at a time, which is useful 1508 * for working out what object is giving problems 1509 */ 1510 max_objects = lpcfg_parm_int(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "max object sync", 1000); 1511 if (req10->max_object_count < max_objects) { 1512 max_objects = req10->max_object_count; 1513 } 1514 /* 1515 * TODO: work out how the maximum should be calculated 1516 */ 1517 max_links = lpcfg_parm_int(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "max link sync", 1500); 1518 1519 for (i=getnc_state->num_processed; 1520 i<getnc_state->num_records && 1521 !null_scope && 1522 (r->out.ctr->ctr6.object_count < max_objects); 485 1523 i++) { 486 1524 int uSN; 487 1525 struct drsuapi_DsReplicaObjectListItemEx *obj; 1526 struct ldb_message *msg; 1527 static const char * const msg_attrs[] = { 1528 "*", 1529 "nTSecurityDescriptor", 1530 "parentGUID", 1531 "replPropertyMetaData", 1532 DSDB_SECRET_ATTRIBUTES, 1533 NULL }; 1534 struct ldb_result *msg_res; 1535 struct ldb_dn *msg_dn; 1536 488 1537 obj = talloc_zero(mem_ctx, struct drsuapi_DsReplicaObjectListItemEx); 489 490 uSN = ldb_msg_find_attr_as_int(getnc_state->site_res->msgs[i], "uSNChanged", -1); 1538 W_ERROR_HAVE_NO_MEMORY(obj); 1539 1540 msg_dn = ldb_dn_new_fmt(obj, sam_ctx, "<GUID=%s>", GUID_string(obj, &getnc_state->guids[i])); 1541 W_ERROR_HAVE_NO_MEMORY(msg_dn); 1542 1543 1544 /* by re-searching here we avoid having a lot of full 1545 * records in memory between calls to getncchanges 1546 */ 1547 ret = drsuapi_search_with_extended_dn(sam_ctx, obj, &msg_res, 1548 msg_dn, 1549 LDB_SCOPE_BASE, msg_attrs, NULL); 1550 if (ret != LDB_SUCCESS) { 1551 if (ret != LDB_ERR_NO_SUCH_OBJECT) { 1552 DEBUG(1,("getncchanges: failed to fetch DN %s - %s\n", 1553 ldb_dn_get_extended_linearized(obj, msg_dn, 1), ldb_errstring(sam_ctx))); 1554 } 1555 talloc_free(obj); 1556 continue; 1557 } 1558 1559 msg = msg_res->msgs[0]; 1560 1561 werr = get_nc_changes_build_object(obj, msg, 1562 sam_ctx, getnc_state->ncRoot_dn, 1563 getnc_state->is_schema_nc, 1564 schema, &session_key, getnc_state->min_usn, 1565 req10->replica_flags, 1566 req10->partial_attribute_set, 1567 getnc_state->uptodateness_vector, 1568 req10->extended_op); 1569 if (!W_ERROR_IS_OK(werr)) { 1570 return werr; 1571 } 1572 1573 werr = get_nc_changes_add_links(sam_ctx, getnc_state, 1574 getnc_state->ncRoot_dn, 1575 schema, getnc_state->min_usn, 1576 req10->replica_flags, 1577 msg, 1578 &getnc_state->la_list, 1579 &getnc_state->la_count, 1580 getnc_state->uptodateness_vector); 1581 if (!W_ERROR_IS_OK(werr)) { 1582 return werr; 1583 } 1584 1585 uSN = ldb_msg_find_attr_as_int(msg, "uSNChanged", -1); 491 1586 if (uSN > r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn) { 492 1587 r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn = uSN; 493 1588 } 494 495 werr = get_nc_changes_build_object(obj, getnc_state->site_res->msgs[i], 496 getnc_state->sam_ctx, getnc_state->ncRoot_dn, 497 schema, &session_key, getnc_state->min_usn, 498 r->in.req->req8.replica_flags); 499 if (!W_ERROR_IS_OK(werr)) { 500 return werr; 1589 if (uSN > getnc_state->highest_usn) { 1590 getnc_state->highest_usn = uSN; 501 1591 } 502 1592 503 1593 if (obj->meta_data_ctr == NULL) { 504 DEBUG( 0,(__location__ ": getncchanges skipping send of object %s\n",505 ldb_dn_get_linearized( getnc_state->site_res->msgs[i]->dn)));1594 DEBUG(8,(__location__ ": getncchanges skipping send of object %s\n", 1595 ldb_dn_get_linearized(msg->dn))); 506 1596 /* no attributes to send */ 507 1597 talloc_free(obj); … … 513 1603 *currentObject = obj; 514 1604 currentObject = &obj->next_object; 515 } 516 517 getnc_state->num_sent += r->out.ctr->ctr6.object_count; 518 519 r->out.ctr->ctr6.nc_object_count = getnc_state->site_res->count; 520 521 if (i < getnc_state->site_res->count) { 1605 1606 talloc_free(getnc_state->last_dn); 1607 getnc_state->last_dn = ldb_dn_copy(getnc_state, msg->dn); 1608 1609 DEBUG(8,(__location__ ": replicating object %s\n", ldb_dn_get_linearized(msg->dn))); 1610 1611 talloc_free(msg_res); 1612 talloc_free(msg_dn); 1613 } 1614 1615 getnc_state->num_processed = i; 1616 1617 r->out.ctr->ctr6.nc_object_count = getnc_state->num_records; 1618 1619 /* the client can us to call UpdateRefs on its behalf to 1620 re-establish monitoring of the NC */ 1621 if ((req10->replica_flags & (DRSUAPI_DRS_ADD_REF | DRSUAPI_DRS_REF_GCSPN)) && 1622 !GUID_all_zero(&req10->destination_dsa_guid)) { 1623 struct drsuapi_DsReplicaUpdateRefsRequest1 ureq; 1624 DEBUG(3,("UpdateRefs on getncchanges for %s\n", 1625 GUID_string(mem_ctx, &req10->destination_dsa_guid))); 1626 ureq.naming_context = ncRoot; 1627 ureq.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "%s._msdcs.%s", 1628 GUID_string(mem_ctx, &req10->destination_dsa_guid), 1629 lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx)); 1630 if (!ureq.dest_dsa_dns_name) { 1631 return WERR_NOMEM; 1632 } 1633 ureq.dest_dsa_guid = req10->destination_dsa_guid; 1634 ureq.options = DRSUAPI_DRS_ADD_REF | 1635 DRSUAPI_DRS_ASYNC_OP | 1636 DRSUAPI_DRS_GETCHG_CHECK; 1637 1638 /* we also need to pass through the 1639 DRSUAPI_DRS_REF_GCSPN bit so that repsTo gets flagged 1640 to send notifies using the GC SPN */ 1641 ureq.options |= (req10->replica_flags & DRSUAPI_DRS_REF_GCSPN); 1642 1643 werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq); 1644 if (!W_ERROR_IS_OK(werr)) { 1645 DEBUG(0,(__location__ ": Failed UpdateRefs in DsGetNCChanges - %s\n", 1646 win_errstr(werr))); 1647 } 1648 } 1649 1650 /* 1651 * TODO: 1652 * This is just a guess, how to calculate the 1653 * number of linked attributes to send, we need to 1654 * find out how to do this right. 1655 */ 1656 if (r->out.ctr->ctr6.object_count >= max_links) { 1657 max_links = 0; 1658 } else { 1659 max_links -= r->out.ctr->ctr6.object_count; 1660 } 1661 1662 link_total = getnc_state->la_count; 1663 1664 if (i < getnc_state->num_records) { 522 1665 r->out.ctr->ctr6.more_data = true; 523 1666 } else { 1667 /* sort the whole array the first time */ 1668 if (!getnc_state->la_sorted) { 1669 LDB_TYPESAFE_QSORT(getnc_state->la_list, getnc_state->la_count, 1670 sam_ctx, linked_attribute_compare); 1671 getnc_state->la_sorted = true; 1672 } 1673 1674 link_count = getnc_state->la_count - getnc_state->la_idx; 1675 link_count = MIN(max_links, link_count); 1676 1677 r->out.ctr->ctr6.linked_attributes_count = link_count; 1678 r->out.ctr->ctr6.linked_attributes = getnc_state->la_list + getnc_state->la_idx; 1679 1680 getnc_state->la_idx += link_count; 1681 link_given = getnc_state->la_idx; 1682 1683 if (getnc_state->la_idx < getnc_state->la_count) { 1684 r->out.ctr->ctr6.more_data = true; 1685 } 1686 } 1687 1688 if (!r->out.ctr->ctr6.more_data) { 1689 talloc_steal(mem_ctx, getnc_state->la_list); 1690 524 1691 r->out.ctr->ctr6.uptodateness_vector = talloc(mem_ctx, struct drsuapi_DsReplicaCursor2CtrEx); 525 r->out.ctr->ctr6.uptodateness_vector->version = 2;526 r->out.ctr->ctr6.uptodateness_vector->reserved1 = 0;527 r->out.ctr->ctr6.uptodateness_vector->reserved2 = 0;528 529 1692 r->out.ctr->ctr6.new_highwatermark.highest_usn = r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn; 530 1693 531 werr = get_nc_changes_udv( getnc_state->sam_ctx, getnc_state->ncRoot_dn,1694 werr = get_nc_changes_udv(sam_ctx, getnc_state->ncRoot_dn, 532 1695 r->out.ctr->ctr6.uptodateness_vector); 533 1696 if (!W_ERROR_IS_OK(werr)) { … … 539 1702 } 540 1703 541 DEBUG(3,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", 542 (unsigned long long)(r->in.req->req8.highwatermark.highest_usn+1), 543 ncRoot->dn, r->out.ctr->ctr6.object_count)); 1704 if (req10->extended_op != DRSUAPI_EXOP_NONE) { 1705 r->out.ctr->ctr6.uptodateness_vector = NULL; 1706 r->out.ctr->ctr6.nc_object_count = 0; 1707 ZERO_STRUCT(r->out.ctr->ctr6.new_highwatermark); 1708 r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 1709 } 1710 1711 DEBUG(r->out.ctr->ctr6.more_data?4:2, 1712 ("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects (done %u/%u) %u links (done %u/%u (as %s))\n", 1713 (unsigned long long)(req10->highwatermark.highest_usn+1), 1714 req10->replica_flags, drs_ObjectIdentifier_to_string(mem_ctx, ncRoot), 1715 r->out.ctr->ctr6.object_count, 1716 i, r->out.ctr->ctr6.more_data?getnc_state->num_records:i, 1717 r->out.ctr->ctr6.linked_attributes_count, 1718 link_given, link_total, 1719 dom_sid_string(mem_ctx, user_sid))); 1720 1721 #if 0 1722 if (!r->out.ctr->ctr6.more_data && req10->extended_op != DRSUAPI_EXOP_NONE) { 1723 NDR_PRINT_FUNCTION_DEBUG(drsuapi_DsGetNCChanges, NDR_BOTH, r); 1724 } 1725 #endif 544 1726 545 1727 return WERR_OK; -
trunk/server/source4/rpc_server/drsuapi/updaterefs.c
r414 r745 23 23 #include "rpc_server/dcerpc_server.h" 24 24 #include "dsdb/samdb/samdb.h" 25 #include "auth/auth.h" 25 #include "libcli/security/security.h" 26 #include "libcli/security/session.h" 26 27 #include "rpc_server/drsuapi/dcesrv_drsuapi.h" 27 #include "libcli/security/security.h" 28 #include "auth/session.h" 29 #include "librpc/gen_ndr/ndr_drsuapi.h" 28 30 29 31 struct repsTo { … … 36 38 */ 37 39 static WERROR uref_add_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, 38 struct ldb_dn *dn, struct repsFromTo1 *dest) 40 struct ldb_dn *dn, struct repsFromTo1 *dest, 41 uint32_t options) 39 42 { 40 43 struct repsTo reps; 41 44 WERROR werr; 45 unsigned int i; 42 46 43 47 werr = dsdb_loadreps(sam_ctx, mem_ctx, dn, "repsTo", &reps.r, &reps.count); 44 48 if (!W_ERROR_IS_OK(werr)) { 45 49 return werr; 50 } 51 52 for (i=0; i<reps.count; i++) { 53 if (GUID_compare(&dest->source_dsa_obj_guid, 54 &reps.r[i].ctr.ctr1.source_dsa_obj_guid) == 0) { 55 if (options & DRSUAPI_DRS_GETCHG_CHECK) { 56 return WERR_OK; 57 } else { 58 return WERR_DS_DRA_REF_ALREADY_EXISTS; 59 } 60 } 46 61 } 47 62 … … 53 68 reps.r[reps.count].version = 1; 54 69 reps.r[reps.count].ctr.ctr1 = *dest; 70 /* add the GCSPN flag if the client asked for it */ 71 reps.r[reps.count].ctr.ctr1.replica_flags |= (options & DRSUAPI_DRS_REF_GCSPN); 55 72 reps.count++; 56 73 … … 67 84 */ 68 85 static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, 69 struct ldb_dn *dn, struct GUID *dest_guid) 86 struct ldb_dn *dn, struct GUID *dest_guid, 87 uint32_t options) 70 88 { 71 89 struct repsTo reps; 72 90 WERROR werr; 73 int i; 91 unsigned int i; 92 bool found = false; 74 93 75 94 werr = dsdb_loadreps(sam_ctx, mem_ctx, dn, "repsTo", &reps.r, &reps.count); … … 84 103 } 85 104 reps.count--; 105 found = true; 86 106 } 87 107 } … … 92 112 } 93 113 114 if (!found && 115 !(options & DRSUAPI_DRS_GETCHG_CHECK) && 116 !(options & DRSUAPI_DRS_ADD_REF)) { 117 return WERR_DS_DRA_REF_NOT_FOUND; 118 } 119 94 120 return WERR_OK; 121 } 122 123 /* 124 drsuapi_DsReplicaUpdateRefs - a non RPC version callable from getncchanges 125 */ 126 WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, 127 struct drsuapi_DsReplicaUpdateRefsRequest1 *req) 128 { 129 WERROR werr; 130 struct ldb_dn *dn; 131 struct ldb_context *sam_ctx = b_state->sam_ctx_system?b_state->sam_ctx_system:b_state->sam_ctx; 132 133 DEBUG(4,("DsReplicaUpdateRefs for host '%s' with GUID %s options 0x%08x nc=%s\n", 134 req->dest_dsa_dns_name, GUID_string(mem_ctx, &req->dest_dsa_guid), 135 req->options, 136 drs_ObjectIdentifier_to_string(mem_ctx, req->naming_context))); 137 138 dn = ldb_dn_new(mem_ctx, sam_ctx, req->naming_context->dn); 139 if (dn == NULL) { 140 return WERR_DS_INVALID_DN_SYNTAX; 141 } 142 143 if (ldb_transaction_start(sam_ctx) != LDB_SUCCESS) { 144 DEBUG(0,(__location__ ": Failed to start transaction on samdb: %s\n", 145 ldb_errstring(sam_ctx))); 146 return WERR_DS_DRA_INTERNAL_ERROR; 147 } 148 149 if (req->options & DRSUAPI_DRS_DEL_REF) { 150 werr = uref_del_dest(sam_ctx, mem_ctx, dn, &req->dest_dsa_guid, req->options); 151 if (!W_ERROR_IS_OK(werr)) { 152 DEBUG(0,("Failed to delete repsTo for %s: %s\n", 153 GUID_string(mem_ctx, &req->dest_dsa_guid), 154 win_errstr(werr))); 155 goto failed; 156 } 157 } 158 159 if (req->options & DRSUAPI_DRS_ADD_REF) { 160 struct repsFromTo1 dest; 161 struct repsFromTo1OtherInfo oi; 162 163 ZERO_STRUCT(dest); 164 ZERO_STRUCT(oi); 165 166 oi.dns_name = req->dest_dsa_dns_name; 167 dest.other_info = &oi; 168 dest.source_dsa_obj_guid = req->dest_dsa_guid; 169 dest.replica_flags = req->options; 170 171 werr = uref_add_dest(sam_ctx, mem_ctx, dn, &dest, req->options); 172 if (!W_ERROR_IS_OK(werr)) { 173 DEBUG(0,("Failed to add repsTo for %s: %s\n", 174 GUID_string(mem_ctx, &dest.source_dsa_obj_guid), 175 win_errstr(werr))); 176 goto failed; 177 } 178 } 179 180 if (ldb_transaction_commit(sam_ctx) != LDB_SUCCESS) { 181 DEBUG(0,(__location__ ": Failed to commit transaction on samdb: %s\n", 182 ldb_errstring(sam_ctx))); 183 return WERR_DS_DRA_INTERNAL_ERROR; 184 } 185 186 return WERR_OK; 187 188 failed: 189 ldb_transaction_cancel(sam_ctx); 190 return werr; 95 191 } 96 192 … … 101 197 struct drsuapi_DsReplicaUpdateRefs *r) 102 198 { 199 struct dcesrv_handle *h; 200 struct drsuapi_bind_state *b_state; 103 201 struct drsuapi_DsReplicaUpdateRefsRequest1 *req; 104 struct ldb_context *sam_ctx; 105 WERROR werr; 106 struct ldb_dn *dn; 107 108 werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs"); 109 if (!W_ERROR_IS_OK(werr)) { 110 return werr; 111 } 202 WERROR werr; 203 int ret; 204 enum security_user_level security_level; 205 206 DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); 207 b_state = h->data; 112 208 113 209 if (r->in.level != 1) { … … 115 211 return WERR_DS_DRA_INVALID_PARAMETER; 116 212 } 117 118 213 req = &r->in.req.req1; 119 DEBUG(4,("DsReplicaUpdateRefs for host '%s' with GUID %s options 0x%08x nc=%s\n", 120 req->dest_dsa_dns_name, GUID_string(mem_ctx, &req->dest_dsa_guid), 121 req->options, 122 drs_ObjectIdentifier_to_string(mem_ctx, req->naming_context))); 123 124 /* TODO: We need to authenticate this operation pretty carefully */ 125 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 126 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 127 if (!sam_ctx) { 128 return WERR_DS_DRA_INTERNAL_ERROR; 129 } 130 131 dn = ldb_dn_new(mem_ctx, sam_ctx, req->naming_context->dn); 132 if (dn == NULL) { 133 talloc_free(sam_ctx); 134 return WERR_DS_INVALID_DN_SYNTAX; 135 } 136 137 if (ldb_transaction_start(sam_ctx) != LDB_SUCCESS) { 138 DEBUG(0,(__location__ ": Failed to start transaction on samdb\n")); 139 talloc_free(sam_ctx); 140 return WERR_DS_DRA_INTERNAL_ERROR; 141 } 142 143 if (req->options & DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE) { 144 werr = uref_del_dest(sam_ctx, mem_ctx, dn, &req->dest_dsa_guid); 145 if (!W_ERROR_IS_OK(werr)) { 146 DEBUG(0,("Failed to delete repsTo for %s\n", 147 GUID_string(dce_call, &req->dest_dsa_guid))); 148 goto failed; 149 } 150 } 151 152 if (req->options & DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE) { 153 struct repsFromTo1 dest; 154 struct repsFromTo1OtherInfo oi; 155 156 ZERO_STRUCT(dest); 157 ZERO_STRUCT(oi); 158 159 oi.dns_name = req->dest_dsa_dns_name; 160 dest.other_info = &oi; 161 dest.source_dsa_obj_guid = req->dest_dsa_guid; 162 dest.replica_flags = req->options; 163 164 werr = uref_add_dest(sam_ctx, mem_ctx, dn, &dest); 165 if (!W_ERROR_IS_OK(werr)) { 166 DEBUG(0,("Failed to delete repsTo for %s\n", 167 GUID_string(dce_call, &dest.source_dsa_obj_guid))); 168 goto failed; 169 } 170 } 171 172 if (ldb_transaction_commit(sam_ctx) != LDB_SUCCESS) { 173 DEBUG(0,(__location__ ": Failed to commit transaction on samdb\n")); 174 return WERR_DS_DRA_INTERNAL_ERROR; 175 } 176 177 talloc_free(sam_ctx); 178 return WERR_OK; 179 180 failed: 181 ldb_transaction_cancel(sam_ctx); 182 talloc_free(sam_ctx); 214 werr = drs_security_access_check(b_state->sam_ctx, 215 mem_ctx, 216 dce_call->conn->auth_state.session_info->security_token, 217 req->naming_context, 218 GUID_DRS_MANAGE_TOPOLOGY); 219 220 if (!W_ERROR_IS_OK(werr)) { 221 return werr; 222 } 223 224 security_level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL); 225 if (security_level < SECURITY_ADMINISTRATOR) { 226 /* check that they are using an DSA objectGUID that they own */ 227 ret = dsdb_validate_dsa_guid(b_state->sam_ctx, 228 &req->dest_dsa_guid, 229 &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]); 230 if (ret != LDB_SUCCESS) { 231 DEBUG(0,(__location__ ": Refusing DsReplicaUpdateRefs for sid %s with GUID %s\n", 232 dom_sid_string(mem_ctx, 233 &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]), 234 GUID_string(mem_ctx, &req->dest_dsa_guid))); 235 return WERR_DS_DRA_ACCESS_DENIED; 236 } 237 } 238 239 werr = drsuapi_UpdateRefs(b_state, mem_ctx, req); 240 241 #if 0 242 NDR_PRINT_FUNCTION_DEBUG(drsuapi_DsReplicaUpdateRefs, NDR_BOTH, r); 243 #endif 244 183 245 return werr; 184 246 } -
trunk/server/source4/rpc_server/echo/rpc_echo.c
r414 r745 40 40 } 41 41 42 r->out.out_data = talloc_memdup(mem_ctx, r->in.in_data, r->in.len);42 r->out.out_data = (uint8_t *)talloc_memdup(mem_ctx, r->in.in_data, r->in.len); 43 43 if (!r->out.out_data) { 44 44 return NT_STATUS_NO_MEMORY; … … 55 55 static NTSTATUS dcesrv_echo_SourceData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_SourceData *r) 56 56 { 57 int i;57 unsigned int i; 58 58 59 59 r->out.data = talloc_array(mem_ctx, uint8_t, r->in.len); -
trunk/server/source4/rpc_server/epmapper/rpc_epmapper.c
r414 r745 66 66 description->object = iface->iface.syntax_id; 67 67 68 status = dcerpc_binding_build_tower( mem_ctx, description, &(*eps)[total].ep);68 status = dcerpc_binding_build_tower(*eps, description, &(*eps)[total].ep); 69 69 if (NT_STATUS_IS_ERR(status)) { 70 70 DEBUG(1, ("Unable to build tower for %s\n", iface->iface.name)); … … 104 104 } *eps; 105 105 uint32_t num_ents; 106 int i;106 unsigned int i; 107 107 108 108 DCESRV_PULL_HANDLE_FAULT(h, r->in.entry_handle, HTYPE_LOOKUP); … … 169 169 { 170 170 uint32_t count; 171 int i;171 unsigned int i; 172 172 struct dcesrv_ep_iface *eps; 173 173 struct epm_floor *floors; -
trunk/server/source4/rpc_server/handles.c
r414 r745 23 23 #include "../lib/util/dlinklist.h" 24 24 #include "rpc_server/dcerpc_server.h" 25 #include "libcli/security/ dom_sid.h"25 #include "libcli/security/security.h" 26 26 #include "auth/session.h" 27 27 … … 45 45 struct dom_sid *sid; 46 46 47 sid = context->conn->auth_state.session_info->security_token->user_sid;47 sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 48 48 49 49 h = talloc(context->assoc_group, struct dcesrv_handle); … … 81 81 struct dom_sid *sid; 82 82 83 sid = context->conn->auth_state.session_info->security_token->user_sid;83 sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 84 84 85 85 if (policy_handle_empty(p)) { -
trunk/server/source4/rpc_server/lsa/dcesrv_lsa.c
r414 r745 29 29 #include "librpc/gen_ndr/ndr_lsa.h" 30 30 #include "../lib/crypto/crypto.h" 31 #include "lib/util/tsort.h" 32 #include "dsdb/common/util.h" 33 #include "libcli/security/session.h" 34 #include "kdc/kdc-policy.h" 31 35 32 36 /* … … 81 85 82 86 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid); 83 NT_STATUS_NOT_OK_RETURN (status);87 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx); 84 88 85 89 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS); … … 180 184 181 185 /* Ensure user is permitted to delete this... */ 182 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))186 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 183 187 { 184 188 case SECURITY_SYSTEM: … … 186 190 break; 187 191 default: 188 /* Users and an nonymous are not alloweddelete things */192 /* Users and anonymous are not allowed to delete things */ 189 193 return NT_STATUS_ACCESS_DENIED; 190 194 } … … 192 196 ret = ldb_delete(secret_state->sam_ldb, 193 197 secret_state->secret_dn); 194 talloc_free(h); 195 if (ret != 0) { 198 if (ret != LDB_SUCCESS) { 196 199 return NT_STATUS_INVALID_HANDLE; 197 200 } … … 200 203 201 204 return NT_STATUS_OK; 205 202 206 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) { 203 207 struct lsa_trusted_domain_state *trusted_domain_state = 204 208 talloc_get_type(h->data, struct lsa_trusted_domain_state); 205 209 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb); 206 if (ret != 0) {210 if (ret != LDB_SUCCESS) { 207 211 return NT_STATUS_INTERNAL_DB_CORRUPTION; 208 212 } … … 210 214 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 211 215 trusted_domain_state->trusted_domain_dn); 212 if (ret != 0) {216 if (ret != LDB_SUCCESS) { 213 217 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb); 214 218 return NT_STATUS_INVALID_HANDLE; … … 218 222 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 219 223 trusted_domain_state->trusted_domain_user_dn); 220 if (ret != 0) {224 if (ret != LDB_SUCCESS) { 221 225 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb); 222 226 return NT_STATUS_INVALID_HANDLE; … … 225 229 226 230 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb); 227 if (ret != 0) {231 if (ret != LDB_SUCCESS) { 228 232 return NT_STATUS_INTERNAL_DB_CORRUPTION; 229 233 } 230 talloc_free(h); 234 231 235 ZERO_STRUCTP(r->out.handle); 232 236 233 237 return NT_STATUS_OK; 238 234 239 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) { 235 240 struct lsa_RightSet *rights; … … 272 277 273 278 ZERO_STRUCTP(r->out.handle); 279 280 return NT_STATUS_OK; 274 281 } 275 282 … … 286 293 struct dcesrv_handle *h; 287 294 struct lsa_policy_state *state; 288 int i; 295 uint32_t i; 296 enum sec_privilege priv; 289 297 const char *privname; 290 298 … … 294 302 295 303 i = *r->in.resume_handle; 296 if (i == 0) i = 1; 297 298 while ((privname = sec_privilege_name(i)) && 304 305 while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) && 299 306 r->out.privs->count < r->in.max_count) { 300 307 struct lsa_PrivEntry *e; 301 308 privname = sec_privilege_name(priv); 302 309 r->out.privs->privs = talloc_realloc(r->out.privs, 303 310 r->out.privs->privs, … … 308 315 } 309 316 e = &r->out.privs->privs[r->out.privs->count]; 310 e->luid.low = i;317 e->luid.low = priv; 311 318 e->luid.high = 0; 312 319 e->name.string = privname; … … 334 341 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY); 335 342 336 sid = dce_call->conn->auth_state.session_info->security_token->user_sid;343 sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 337 344 338 345 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) { … … 386 393 union dssetup_DsRoleInfo *info; 387 394 388 info = talloc (mem_ctx, union dssetup_DsRoleInfo);395 info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo); 389 396 W_ERROR_HAVE_NO_MEMORY(info); 390 397 … … 407 414 ZERO_STRUCT(domain_guid); 408 415 409 switch (lp _server_role(dce_call->conn->dce_ctx->lp_ctx)) {416 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) { 410 417 case ROLE_STANDALONE: 411 418 role = DS_ROLE_STANDALONE_SERVER; … … 423 430 } 424 431 425 switch (lp _server_role(dce_call->conn->dce_ctx->lp_ctx)) {432 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) { 426 433 case ROLE_STANDALONE: 427 domain = talloc_strdup(mem_ctx, lp _workgroup(dce_call->conn->dce_ctx->lp_ctx));434 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx)); 428 435 W_ERROR_HAVE_NO_MEMORY(domain); 429 436 break; 430 437 case ROLE_DOMAIN_MEMBER: 431 domain = talloc_strdup(mem_ctx, lp _workgroup(dce_call->conn->dce_ctx->lp_ctx));438 domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx)); 432 439 W_ERROR_HAVE_NO_MEMORY(domain); 433 440 /* TODO: what is with dns_domain and forest and guid? */ … … 477 484 return WERR_INVALID_PARAM; 478 485 } 479 480 return WERR_INVALID_PARAM;481 486 } 482 487 … … 551 556 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain); 552 557 553 554 558 case LSA_POLICY_INFO_ROLE: 555 559 info->role.role = LSA_ROLE_PRIMARY; … … 683 687 struct dcesrv_handle *h; 684 688 struct lsa_policy_state *state; 685 int ret , i;689 int ret; 686 690 struct ldb_message **res; 687 691 const char * const attrs[] = { "objectSid", NULL}; 688 uint32_t count ;692 uint32_t count, i; 689 693 690 694 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); … … 695 699 one privilege set 696 700 */ 697 ret = gendb_search(state-> sam_ldb, mem_ctx, NULL, &res, attrs,701 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 698 702 "(&(objectSid=*)(privilege=*))"); 699 703 if (ret < 0) { 700 return NT_STATUS_ NO_SUCH_USER;704 return NT_STATUS_INTERNAL_DB_CORRUPTION; 701 705 } 702 706 … … 734 738 } 735 739 740 /* This decrypts and returns Trusted Domain Auth Information Internal data */ 741 static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, 742 TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob, 743 struct trustDomainPasswords *auth_struct) 744 { 745 DATA_BLOB session_key = data_blob(NULL, 0); 746 enum ndr_err_code ndr_err; 747 NTSTATUS nt_status; 748 749 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 750 if (!NT_STATUS_IS_OK(nt_status)) { 751 return nt_status; 752 } 753 754 arcfour_crypt_blob(auth_blob->data, auth_blob->length, &session_key); 755 ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx, 756 auth_struct, 757 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords); 758 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 759 return NT_STATUS_INVALID_PARAMETER; 760 } 761 762 return NT_STATUS_OK; 763 } 764 765 static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call, 766 TALLOC_CTX *mem_ctx, 767 struct trustAuthInOutBlob *iopw, 768 DATA_BLOB *trustauth_blob) 769 { 770 enum ndr_err_code ndr_err; 771 772 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx, 773 iopw, 774 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); 775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 776 return NT_STATUS_INVALID_PARAMETER; 777 } 778 779 return NT_STATUS_OK; 780 } 781 782 static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx, 783 struct ldb_context *sam_ldb, 784 struct ldb_dn *base_dn, 785 const char *netbios_name, 786 struct trustAuthInOutBlob *in, 787 struct ldb_dn **user_dn) 788 { 789 struct ldb_message *msg; 790 struct ldb_dn *dn; 791 uint32_t i; 792 int ret; 793 794 dn = ldb_dn_copy(mem_ctx, base_dn); 795 if (!dn) { 796 return NT_STATUS_NO_MEMORY; 797 } 798 if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) { 799 return NT_STATUS_NO_MEMORY; 800 } 801 802 msg = ldb_msg_new(mem_ctx); 803 if (!msg) { 804 return NT_STATUS_NO_MEMORY; 805 } 806 msg->dn = dn; 807 808 ret = ldb_msg_add_string(msg, "objectClass", "user"); 809 if (ret != LDB_SUCCESS) { 810 return NT_STATUS_NO_MEMORY; 811 } 812 813 ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name); 814 if (ret != LDB_SUCCESS) { 815 return NT_STATUS_NO_MEMORY; 816 } 817 818 ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl", 819 UF_INTERDOMAIN_TRUST_ACCOUNT); 820 if (ret != LDB_SUCCESS) { 821 return NT_STATUS_NO_MEMORY; 822 } 823 824 for (i = 0; i < in->count; i++) { 825 const char *attribute; 826 struct ldb_val v; 827 switch (in->current.array[i].AuthType) { 828 case TRUST_AUTH_TYPE_NT4OWF: 829 attribute = "unicodePwd"; 830 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password; 831 v.length = 16; 832 break; 833 case TRUST_AUTH_TYPE_CLEAR: 834 attribute = "clearTextPassword"; 835 v.data = in->current.array[i].AuthInfo.clear.password; 836 v.length = in->current.array[i].AuthInfo.clear.size; 837 break; 838 default: 839 continue; 840 } 841 842 ret = ldb_msg_add_value(msg, attribute, &v, NULL); 843 if (ret != LDB_SUCCESS) { 844 return NT_STATUS_NO_MEMORY; 845 } 846 } 847 848 /* create the trusted_domain user account */ 849 ret = ldb_add(sam_ldb, msg); 850 if (ret != LDB_SUCCESS) { 851 DEBUG(0,("Failed to create user record %s: %s\n", 852 ldb_dn_get_linearized(msg->dn), 853 ldb_errstring(sam_ldb))); 854 855 switch (ret) { 856 case LDB_ERR_ENTRY_ALREADY_EXISTS: 857 return NT_STATUS_DOMAIN_EXISTS; 858 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 859 return NT_STATUS_ACCESS_DENIED; 860 default: 861 return NT_STATUS_INTERNAL_DB_CORRUPTION; 862 } 863 } 864 865 if (user_dn) { 866 *user_dn = dn; 867 } 868 return NT_STATUS_OK; 869 } 736 870 737 871 /* … … 747 881 struct lsa_trusted_domain_state *trusted_domain_state; 748 882 struct dcesrv_handle *handle; 749 struct ldb_message **msgs, *msg , *msg_user;883 struct ldb_message **msgs, *msg; 750 884 const char *attrs[] = { 751 885 NULL … … 754 888 const char *dns_name; 755 889 const char *name; 756 DATA_BLOB session_key = data_blob(NULL, 0);757 890 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; 758 891 struct trustDomainPasswords auth_struct; 759 892 int ret; 760 893 NTSTATUS nt_status; 761 enum ndr_err_code ndr_err;762 894 struct ldb_context *sam_ldb; 895 763 896 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY); 764 897 ZERO_STRUCTP(r->out.trustdom_handle); 765 898 766 899 policy_state = policy_handle->data; 767 768 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 769 if (!NT_STATUS_IS_OK(nt_status)) { 770 return nt_status; 771 } 900 sam_ldb = policy_state->sam_ldb; 772 901 773 902 netbios_name = r->in.info->netbios_name.string; … … 775 904 return NT_STATUS_INVALID_PARAMETER; 776 905 } 777 906 778 907 dns_name = r->in.info->domain_name.string; 779 908 780 909 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); 781 910 if (!trusted_domain_state) { … … 785 914 786 915 if (strcasecmp(netbios_name, "BUILTIN") == 0 787 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0) 916 || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0) 788 917 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) { 789 return NT_STATUS_INVALID_PARAMETER; ;918 return NT_STATUS_INVALID_PARAMETER; 790 919 } 791 920 792 921 if (strcasecmp(netbios_name, policy_state->domain_name) == 0 793 922 || strcasecmp(netbios_name, policy_state->domain_dns) == 0 794 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0) 923 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0) 795 924 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0) 796 925 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) { … … 804 933 auth_struct.incoming.count = 0; 805 934 } else { 806 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, r->in.auth_info->auth_blob.size); 807 arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key); 808 ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx, 809 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 810 &auth_struct, 811 (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords); 812 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 813 return NT_STATUS_INVALID_PARAMETER; 814 } 935 auth_blob = data_blob_const(r->in.auth_info->auth_blob.data, 936 r->in.auth_info->auth_blob.size); 937 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx, 938 &auth_blob, &auth_struct); 939 if (!NT_STATUS_IS_OK(nt_status)) { 940 return nt_status; 941 } 815 942 816 943 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) { … … 822 949 823 950 if (auth_struct.incoming.count) { 824 int i; 825 struct trustAuthInOutBlob incoming; 826 827 incoming.count = auth_struct.incoming.count; 828 incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray); 829 if (!incoming.current) { 830 return NT_STATUS_NO_MEMORY; 831 } 832 833 incoming.current->array = *auth_struct.incoming.current; 834 if (!incoming.current->array) { 835 return NT_STATUS_NO_MEMORY; 836 } 837 838 incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray); 839 if (!incoming.previous) { 840 return NT_STATUS_NO_MEMORY; 841 } 842 incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count); 843 if (!incoming.previous->array) { 844 return NT_STATUS_NO_MEMORY; 845 } 846 847 for (i = 0; i < incoming.count; i++) { 848 incoming.previous->array[i].LastUpdateTime = 0; 849 incoming.previous->array[i].AuthType = 0; 850 } 851 ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx, 852 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 853 &incoming, 854 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); 855 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 856 return NT_STATUS_INVALID_PARAMETER; 951 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, 952 &auth_struct.incoming, 953 &trustAuthIncoming); 954 if (!NT_STATUS_IS_OK(nt_status)) { 955 return nt_status; 857 956 } 858 957 } else { 859 958 trustAuthIncoming = data_blob(NULL, 0); 860 959 } 861 960 862 961 if (auth_struct.outgoing.count) { 863 int i; 864 struct trustAuthInOutBlob outgoing; 865 866 outgoing.count = auth_struct.outgoing.count; 867 outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray); 868 if (!outgoing.current) { 869 return NT_STATUS_NO_MEMORY; 870 } 871 872 outgoing.current->array = *auth_struct.outgoing.current; 873 if (!outgoing.current->array) { 874 return NT_STATUS_NO_MEMORY; 875 } 876 877 outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray); 878 if (!outgoing.previous) { 879 return NT_STATUS_NO_MEMORY; 880 } 881 outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count); 882 if (!outgoing.previous->array) { 883 return NT_STATUS_NO_MEMORY; 884 } 885 886 for (i = 0; i < outgoing.count; i++) { 887 outgoing.previous->array[i].LastUpdateTime = 0; 888 outgoing.previous->array[i].AuthType = 0; 889 } 890 ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx, 891 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 892 &outgoing, 893 (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); 894 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 895 return NT_STATUS_INVALID_PARAMETER; 962 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, 963 &auth_struct.outgoing, 964 &trustAuthOutgoing); 965 if (!NT_STATUS_IS_OK(nt_status)) { 966 return nt_status; 896 967 } 897 968 } else { … … 899 970 } 900 971 901 ret = ldb_transaction_start( policy_state->sam_ldb);972 ret = ldb_transaction_start(sam_ldb); 902 973 if (ret != LDB_SUCCESS) { 903 974 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 908 979 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); 909 980 /* search for the trusted_domain record */ 910 ret = gendb_search( policy_state->sam_ldb,981 ret = gendb_search(sam_ldb, 911 982 mem_ctx, policy_state->system_dn, &msgs, attrs, 912 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 983 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 913 984 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded); 914 985 if (ret > 0) { 915 ldb_transaction_cancel( policy_state->sam_ldb);986 ldb_transaction_cancel(sam_ldb); 916 987 return NT_STATUS_OBJECT_NAME_COLLISION; 917 988 } … … 919 990 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); 920 991 /* search for the trusted_domain record */ 921 ret = gendb_search( policy_state->sam_ldb,992 ret = gendb_search(sam_ldb, 922 993 mem_ctx, policy_state->system_dn, &msgs, attrs, 923 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 994 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 924 995 netbios_encoded, netbios_encoded, netbios_encoded); 925 996 if (ret > 0) { 926 ldb_transaction_cancel( policy_state->sam_ldb);997 ldb_transaction_cancel(sam_ldb); 927 998 return NT_STATUS_OBJECT_NAME_COLLISION; 928 999 } 929 1000 } 930 1001 931 1002 if (ret < 0 ) { 932 ldb_transaction_cancel( policy_state->sam_ldb);1003 ldb_transaction_cancel(sam_ldb); 933 1004 return NT_STATUS_INTERNAL_DB_CORRUPTION; 934 1005 } 935 1006 936 1007 name = dns_name ? dns_name : netbios_name; 937 1008 … … 943 1014 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn); 944 1015 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) { 945 ldb_transaction_cancel( policy_state->sam_ldb);946 return NT_STATUS_NO_MEMORY; 947 } 948 949 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx,msg, "flatname", netbios_name);1016 ldb_transaction_cancel(sam_ldb); 1017 return NT_STATUS_NO_MEMORY; 1018 } 1019 1020 ldb_msg_add_string(msg, "flatname", netbios_name); 950 1021 951 1022 if (r->in.info->sid) { 952 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid); 953 if (!sid_string) { 954 ldb_transaction_cancel(policy_state->sam_ldb); 955 return NT_STATUS_NO_MEMORY; 956 } 957 958 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string); 959 } 960 961 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain"); 962 963 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type); 964 965 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes); 966 967 samdb_msg_add_int(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction); 968 1023 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid); 1024 if (ret != LDB_SUCCESS) { 1025 ldb_transaction_cancel(sam_ldb); 1026 return NT_STATUS_INVALID_PARAMETER; 1027 } 1028 } 1029 1030 ldb_msg_add_string(msg, "objectClass", "trustedDomain"); 1031 1032 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type); 1033 1034 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes); 1035 1036 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction); 1037 969 1038 if (dns_name) { 970 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx,msg, "trustPartner", dns_name);1039 ldb_msg_add_string(msg, "trustPartner", dns_name); 971 1040 } 972 1041 … … 974 1043 ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL); 975 1044 if (ret != LDB_SUCCESS) { 976 ldb_transaction_cancel( policy_state->sam_ldb);1045 ldb_transaction_cancel(sam_ldb); 977 1046 return NT_STATUS_NO_MEMORY; 978 1047 } … … 981 1050 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL); 982 1051 if (ret != LDB_SUCCESS) { 983 ldb_transaction_cancel( policy_state->sam_ldb);1052 ldb_transaction_cancel(sam_ldb); 984 1053 return NT_STATUS_NO_MEMORY; 985 1054 } … … 989 1058 990 1059 /* create the trusted_domain */ 991 ret = ldb_add( trusted_domain_state->policy->sam_ldb, msg);1060 ret = ldb_add(sam_ldb, msg); 992 1061 switch (ret) { 993 1062 case LDB_SUCCESS: 994 1063 break; 995 1064 case LDB_ERR_ENTRY_ALREADY_EXISTS: 996 ldb_transaction_cancel( trusted_domain_state->policy->sam_ldb);1065 ldb_transaction_cancel(sam_ldb); 997 1066 DEBUG(0,("Failed to create trusted domain record %s: %s\n", 998 1067 ldb_dn_get_linearized(msg->dn), 999 ldb_errstring( trusted_domain_state->policy->sam_ldb)));1068 ldb_errstring(sam_ldb))); 1000 1069 return NT_STATUS_DOMAIN_EXISTS; 1001 1070 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1002 ldb_transaction_cancel( trusted_domain_state->policy->sam_ldb);1071 ldb_transaction_cancel(sam_ldb); 1003 1072 DEBUG(0,("Failed to create trusted domain record %s: %s\n", 1004 1073 ldb_dn_get_linearized(msg->dn), 1005 ldb_errstring( trusted_domain_state->policy->sam_ldb)));1074 ldb_errstring(sam_ldb))); 1006 1075 return NT_STATUS_ACCESS_DENIED; 1007 1076 default: 1008 ldb_transaction_cancel( trusted_domain_state->policy->sam_ldb);1077 ldb_transaction_cancel(sam_ldb); 1009 1078 DEBUG(0,("Failed to create user record %s: %s\n", 1010 1079 ldb_dn_get_linearized(msg->dn), 1011 ldb_errstring( trusted_domain_state->policy->sam_ldb)));1080 ldb_errstring(sam_ldb))); 1012 1081 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1013 1082 } 1014 1083 1015 1084 if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) { 1016 msg_user = ldb_msg_new(mem_ctx); 1017 if (msg_user == NULL) { 1018 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb); 1019 return NT_STATUS_NO_MEMORY; 1020 } 1021 1085 struct ldb_dn *user_dn; 1022 1086 /* Inbound trusts must also create a cn=users object to match */ 1023 1024 trusted_domain_state->trusted_domain_user_dn = msg_user->dn 1025 = ldb_dn_copy(trusted_domain_state, policy_state->domain_dn); 1026 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=users")) { 1027 ldb_transaction_cancel(policy_state->sam_ldb); 1028 return NT_STATUS_NO_MEMORY; 1029 } 1030 1031 if ( ! ldb_dn_add_child_fmt(msg_user->dn, "cn=%s", netbios_name)) { 1032 ldb_transaction_cancel(policy_state->sam_ldb); 1033 return NT_STATUS_NO_MEMORY; 1034 } 1035 1036 ldb_msg_add_string(msg_user, "objectClass", "user"); 1037 1038 ldb_msg_add_steal_string(msg_user, "samAccountName", 1039 talloc_asprintf(mem_ctx, "%s$", netbios_name)); 1040 1041 if (samdb_msg_add_uint(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user, 1042 "userAccountControl", 1043 UF_INTERDOMAIN_TRUST_ACCOUNT) != 0) { 1044 ldb_transaction_cancel(policy_state->sam_ldb); 1045 return NT_STATUS_NO_MEMORY; 1046 } 1047 1048 if (auth_struct.incoming.count) { 1049 int i; 1050 for (i=0; i < auth_struct.incoming.count; i++ ) { 1051 if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) { 1052 samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb, 1053 mem_ctx, msg_user, "unicodePwd", 1054 &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password); 1055 } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) { 1056 DATA_BLOB new_password = data_blob_const(auth_struct.incoming.current[i]->AuthInfo.clear.password, 1057 auth_struct.incoming.current[i]->AuthInfo.clear.size); 1058 ret = ldb_msg_add_value(msg_user, "clearTextPassword", &new_password, NULL); 1059 if (ret != LDB_SUCCESS) { 1060 ldb_transaction_cancel(policy_state->sam_ldb); 1061 return NT_STATUS_NO_MEMORY; 1062 } 1063 } 1064 } 1065 } 1066 1067 /* create the cn=users trusted_domain account */ 1068 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg_user); 1069 switch (ret) { 1070 case LDB_SUCCESS: 1071 break; 1072 case LDB_ERR_ENTRY_ALREADY_EXISTS: 1073 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb); 1074 DEBUG(0,("Failed to create trusted domain record %s: %s\n", 1075 ldb_dn_get_linearized(msg_user->dn), 1076 ldb_errstring(trusted_domain_state->policy->sam_ldb))); 1077 return NT_STATUS_DOMAIN_EXISTS; 1078 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1079 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb); 1080 DEBUG(0,("Failed to create trusted domain record %s: %s\n", 1081 ldb_dn_get_linearized(msg_user->dn), 1082 ldb_errstring(trusted_domain_state->policy->sam_ldb))); 1083 return NT_STATUS_ACCESS_DENIED; 1084 default: 1085 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb); 1086 DEBUG(0,("Failed to create user record %s: %s\n", 1087 ldb_dn_get_linearized(msg_user->dn), 1088 ldb_errstring(trusted_domain_state->policy->sam_ldb))); 1089 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1090 } 1091 } 1092 1093 ret = ldb_transaction_commit(policy_state->sam_ldb); 1087 nt_status = add_trust_user(mem_ctx, sam_ldb, 1088 policy_state->domain_dn, 1089 netbios_name, 1090 &auth_struct.incoming, 1091 &user_dn); 1092 if (!NT_STATUS_IS_OK(nt_status)) { 1093 ldb_transaction_cancel(sam_ldb); 1094 return nt_status; 1095 } 1096 1097 /* save the trust user dn */ 1098 trusted_domain_state->trusted_domain_user_dn 1099 = talloc_steal(trusted_domain_state, user_dn); 1100 } 1101 1102 ret = ldb_transaction_commit(sam_ldb); 1094 1103 if (ret != LDB_SUCCESS) { 1095 1104 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 1100 1109 return NT_STATUS_NO_MEMORY; 1101 1110 } 1102 1111 1103 1112 handle->data = talloc_steal(handle, trusted_domain_state); 1104 1113 1105 1114 trusted_domain_state->access_mask = r->in.access_mask; 1106 1115 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state); 1107 1116 1108 1117 *r->out.trustdom_handle = handle->wire_handle; 1109 1118 1110 1119 return NT_STATUS_OK; 1111 1120 } … … 1224 1233 ret = gendb_search(trusted_domain_state->policy->sam_ldb, 1225 1234 mem_ctx, policy_state->domain_dn, &msgs, attrs, 1226 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=% d))",1235 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%u))", 1227 1236 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT); 1228 1237 if (ret == 1) { … … 1254 1263 { 1255 1264 struct dcesrv_handle *policy_handle; 1256 1265 1257 1266 struct lsa_policy_state *policy_state; 1258 1267 struct lsa_trusted_domain_state *trusted_domain_state; … … 1262 1271 NULL 1263 1272 }; 1264 1273 char *td_name; 1265 1274 int ret; 1266 1275 … … 1272 1281 return NT_STATUS_INVALID_PARAMETER; 1273 1282 } 1274 1283 1275 1284 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); 1276 1285 if (!trusted_domain_state) { … … 1280 1289 1281 1290 /* search for the trusted_domain record */ 1291 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string); 1282 1292 ret = gendb_search(trusted_domain_state->policy->sam_ldb, 1283 1293 mem_ctx, policy_state->system_dn, &msgs, attrs, 1284 "(&(flatname=%s)(objectclass=trustedDomain))", 1285 ldb_binary_encode_string(mem_ctx, r->in.name.string)); 1294 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))" 1295 "(objectclass=trustedDomain))", 1296 td_name, td_name, td_name); 1286 1297 if (ret == 0) { 1287 1298 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1288 1299 } 1289 1300 1290 1301 if (ret != 1) { 1291 1302 DEBUG(0,("Found %d records matching DN %s\n", ret, … … 1294 1305 } 1295 1306 1307 /* TODO: perform access checks */ 1308 1296 1309 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn); 1297 1310 1298 1311 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); 1299 1312 if (!handle) { 1300 1313 return NT_STATUS_NO_MEMORY; 1301 1314 } 1302 1315 1303 1316 handle->data = talloc_steal(handle, trusted_domain_state); 1304 1317 1305 1318 trusted_domain_state->access_mask = r->in.access_mask; 1306 1319 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state); 1307 1320 1308 1321 *r->out.trustdom_handle = handle->wire_handle; 1309 1322 1310 1323 return NT_STATUS_OK; 1311 1324 } … … 1324 1337 1325 1338 1326 /* 1339 /* parameters 4 to 6 are optional if the dn is a dn of a TDO object, 1340 * otherwise at least one must be provided */ 1341 static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx, 1342 struct ldb_dn *basedn, const char *dns_domain, 1343 const char *netbios, struct dom_sid2 *sid, 1344 struct ldb_message ***msgs) 1345 { 1346 const char *attrs[] = { "flatname", "trustPartner", 1347 "securityIdentifier", "trustDirection", 1348 "trustType", "trustAttributes", 1349 "trustPosixOffset", 1350 "msDs-supportedEncryptionTypes", NULL }; 1351 char *dns = NULL; 1352 char *nbn = NULL; 1353 char *sidstr = NULL; 1354 char *filter; 1355 int ret; 1356 1357 1358 if (dns_domain || netbios || sid) { 1359 filter = talloc_strdup(mem_ctx, 1360 "(&(objectclass=trustedDomain)(|"); 1361 } else { 1362 filter = talloc_strdup(mem_ctx, 1363 "(objectclass=trustedDomain)"); 1364 } 1365 if (!filter) { 1366 return NT_STATUS_NO_MEMORY; 1367 } 1368 1369 if (dns_domain) { 1370 dns = ldb_binary_encode_string(mem_ctx, dns_domain); 1371 if (!dns) { 1372 return NT_STATUS_NO_MEMORY; 1373 } 1374 filter = talloc_asprintf_append(filter, 1375 "(trustPartner=%s)", dns); 1376 if (!filter) { 1377 return NT_STATUS_NO_MEMORY; 1378 } 1379 } 1380 if (netbios) { 1381 nbn = ldb_binary_encode_string(mem_ctx, netbios); 1382 if (!nbn) { 1383 return NT_STATUS_NO_MEMORY; 1384 } 1385 filter = talloc_asprintf_append(filter, 1386 "(flatname=%s)", nbn); 1387 if (!filter) { 1388 return NT_STATUS_NO_MEMORY; 1389 } 1390 } 1391 if (sid) { 1392 sidstr = dom_sid_string(mem_ctx, sid); 1393 if (!sidstr) { 1394 return NT_STATUS_INVALID_PARAMETER; 1395 } 1396 filter = talloc_asprintf_append(filter, 1397 "(securityIdentifier=%s)", 1398 sidstr); 1399 if (!filter) { 1400 return NT_STATUS_NO_MEMORY; 1401 } 1402 } 1403 if (dns_domain || netbios || sid) { 1404 filter = talloc_asprintf_append(filter, "))"); 1405 if (!filter) { 1406 return NT_STATUS_NO_MEMORY; 1407 } 1408 } 1409 1410 ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter); 1411 if (ret == 0) { 1412 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1413 } 1414 1415 if (ret != 1) { 1416 return NT_STATUS_OBJECT_NAME_COLLISION; 1417 } 1418 1419 return NT_STATUS_OK; 1420 } 1421 1422 static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx, 1423 struct ldb_context *sam_ldb, 1424 struct ldb_message *orig, 1425 struct ldb_message *dest, 1426 const char *attribute, 1427 uint32_t value, 1428 uint32_t *orig_value) 1429 { 1430 const struct ldb_val *orig_val; 1431 uint32_t orig_uint = 0; 1432 int flags = 0; 1433 int ret; 1434 1435 orig_val = ldb_msg_find_ldb_val(orig, attribute); 1436 if (!orig_val || !orig_val->data) { 1437 /* add new attribute */ 1438 flags = LDB_FLAG_MOD_ADD; 1439 1440 } else { 1441 errno = 0; 1442 orig_uint = strtoul((const char *)orig_val->data, NULL, 0); 1443 if (errno != 0 || orig_uint != value) { 1444 /* replace also if can't get value */ 1445 flags = LDB_FLAG_MOD_REPLACE; 1446 } 1447 } 1448 1449 if (flags == 0) { 1450 /* stored value is identical, nothing to change */ 1451 goto done; 1452 } 1453 1454 ret = ldb_msg_add_empty(dest, attribute, flags, NULL); 1455 if (ret != LDB_SUCCESS) { 1456 return NT_STATUS_NO_MEMORY; 1457 } 1458 1459 ret = samdb_msg_add_uint(sam_ldb, dest, dest, attribute, value); 1460 if (ret != LDB_SUCCESS) { 1461 return NT_STATUS_NO_MEMORY; 1462 } 1463 1464 done: 1465 if (orig_value) { 1466 *orig_value = orig_uint; 1467 } 1468 return NT_STATUS_OK; 1469 } 1470 1471 static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx, 1472 struct ldb_context *sam_ldb, 1473 struct ldb_dn *base_dn, 1474 bool delete_user, 1475 const char *netbios_name, 1476 struct trustAuthInOutBlob *in) 1477 { 1478 const char *attrs[] = { "userAccountControl", NULL }; 1479 struct ldb_message **msgs; 1480 struct ldb_message *msg; 1481 uint32_t uac; 1482 uint32_t i; 1483 int ret; 1484 1485 ret = gendb_search(sam_ldb, mem_ctx, 1486 base_dn, &msgs, attrs, 1487 "samAccountName=%s$", netbios_name); 1488 if (ret > 1) { 1489 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1490 } 1491 1492 if (ret == 0) { 1493 if (delete_user) { 1494 return NT_STATUS_OK; 1495 } 1496 1497 /* ok no existing user, add it from scratch */ 1498 return add_trust_user(mem_ctx, sam_ldb, base_dn, 1499 netbios_name, in, NULL); 1500 } 1501 1502 /* check user is what we are looking for */ 1503 uac = ldb_msg_find_attr_as_uint(msgs[0], 1504 "userAccountControl", 0); 1505 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) { 1506 return NT_STATUS_OBJECT_NAME_COLLISION; 1507 } 1508 1509 if (delete_user) { 1510 ret = ldb_delete(sam_ldb, msgs[0]->dn); 1511 switch (ret) { 1512 case LDB_SUCCESS: 1513 return NT_STATUS_OK; 1514 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1515 return NT_STATUS_ACCESS_DENIED; 1516 default: 1517 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1518 } 1519 } 1520 1521 /* entry exists, just modify secret if any */ 1522 if (in->count == 0) { 1523 return NT_STATUS_OK; 1524 } 1525 1526 msg = ldb_msg_new(mem_ctx); 1527 if (!msg) { 1528 return NT_STATUS_NO_MEMORY; 1529 } 1530 msg->dn = msgs[0]->dn; 1531 1532 for (i = 0; i < in->count; i++) { 1533 const char *attribute; 1534 struct ldb_val v; 1535 switch (in->current.array[i].AuthType) { 1536 case TRUST_AUTH_TYPE_NT4OWF: 1537 attribute = "unicodePwd"; 1538 v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password; 1539 v.length = 16; 1540 break; 1541 case TRUST_AUTH_TYPE_CLEAR: 1542 attribute = "clearTextPassword"; 1543 v.data = in->current.array[i].AuthInfo.clear.password; 1544 v.length = in->current.array[i].AuthInfo.clear.size; 1545 break; 1546 default: 1547 continue; 1548 } 1549 1550 ret = ldb_msg_add_empty(msg, attribute, 1551 LDB_FLAG_MOD_REPLACE, NULL); 1552 if (ret != LDB_SUCCESS) { 1553 return NT_STATUS_NO_MEMORY; 1554 } 1555 1556 ret = ldb_msg_add_value(msg, attribute, &v, NULL); 1557 if (ret != LDB_SUCCESS) { 1558 return NT_STATUS_NO_MEMORY; 1559 } 1560 } 1561 1562 /* create the trusted_domain user account */ 1563 ret = ldb_modify(sam_ldb, msg); 1564 if (ret != LDB_SUCCESS) { 1565 DEBUG(0,("Failed to create user record %s: %s\n", 1566 ldb_dn_get_linearized(msg->dn), 1567 ldb_errstring(sam_ldb))); 1568 1569 switch (ret) { 1570 case LDB_ERR_ENTRY_ALREADY_EXISTS: 1571 return NT_STATUS_DOMAIN_EXISTS; 1572 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1573 return NT_STATUS_ACCESS_DENIED; 1574 default: 1575 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1576 } 1577 } 1578 1579 return NT_STATUS_OK; 1580 } 1581 1582 1583 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, 1584 struct dcesrv_handle *p_handle, 1585 TALLOC_CTX *mem_ctx, 1586 struct ldb_message *dom_msg, 1587 enum lsa_TrustDomInfoEnum level, 1588 union lsa_TrustedDomainInfo *info) 1589 { 1590 struct lsa_policy_state *p_state = p_handle->data; 1591 uint32_t *posix_offset = NULL; 1592 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL; 1593 struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL; 1594 struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL; 1595 uint32_t *enc_types = NULL; 1596 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; 1597 struct trustDomainPasswords auth_struct; 1598 NTSTATUS nt_status; 1599 struct ldb_message **msgs; 1600 struct ldb_message *msg; 1601 bool add_outgoing = false; 1602 bool add_incoming = false; 1603 bool del_outgoing = false; 1604 bool del_incoming = false; 1605 bool in_transaction = false; 1606 int ret; 1607 bool am_rodc; 1608 1609 switch (level) { 1610 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET: 1611 posix_offset = &info->posix_offset.posix_offset; 1612 break; 1613 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX: 1614 info_ex = &info->info_ex; 1615 break; 1616 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO: 1617 auth_info = &info->auth_info; 1618 break; 1619 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO: 1620 posix_offset = &info->full_info.posix_offset.posix_offset; 1621 info_ex = &info->full_info.info_ex; 1622 auth_info = &info->full_info.auth_info; 1623 break; 1624 case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL: 1625 auth_info_int = &info->auth_info_internal; 1626 break; 1627 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL: 1628 posix_offset = &info->full_info_internal.posix_offset.posix_offset; 1629 info_ex = &info->full_info_internal.info_ex; 1630 auth_info_int = &info->full_info_internal.auth_info; 1631 break; 1632 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: 1633 enc_types = &info->enc_types.enc_types; 1634 break; 1635 default: 1636 return NT_STATUS_INVALID_PARAMETER; 1637 } 1638 1639 if (auth_info) { 1640 /* FIXME: not handled yet */ 1641 return NT_STATUS_INVALID_PARAMETER; 1642 } 1643 1644 /* decode auth_info_int if set */ 1645 if (auth_info_int) { 1646 1647 /* now decrypt blob */ 1648 auth_blob = data_blob_const(auth_info_int->auth_blob.data, 1649 auth_info_int->auth_blob.size); 1650 1651 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx, 1652 &auth_blob, &auth_struct); 1653 if (!NT_STATUS_IS_OK(nt_status)) { 1654 return nt_status; 1655 } 1656 } 1657 1658 if (info_ex) { 1659 /* verify data matches */ 1660 if (info_ex->trust_attributes & 1661 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { 1662 /* TODO: check what behavior level we have */ 1663 if (strcasecmp_m(p_state->domain_dns, 1664 p_state->forest_dns) != 0) { 1665 return NT_STATUS_INVALID_DOMAIN_STATE; 1666 } 1667 } 1668 1669 ret = samdb_rodc(p_state->sam_ldb, &am_rodc); 1670 if (ret == LDB_SUCCESS && am_rodc) { 1671 return NT_STATUS_NO_SUCH_DOMAIN; 1672 } 1673 1674 /* verify only one object matches the dns/netbios/sid 1675 * triplet and that this is the one we already have */ 1676 nt_status = get_tdo(p_state->sam_ldb, mem_ctx, 1677 p_state->system_dn, 1678 info_ex->domain_name.string, 1679 info_ex->netbios_name.string, 1680 info_ex->sid, &msgs); 1681 if (!NT_STATUS_IS_OK(nt_status)) { 1682 return nt_status; 1683 } 1684 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) { 1685 return NT_STATUS_OBJECT_NAME_COLLISION; 1686 } 1687 talloc_free(msgs); 1688 } 1689 1690 /* TODO: should we fetch previous values from the existing entry 1691 * and append them ? */ 1692 if (auth_struct.incoming.count) { 1693 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, 1694 &auth_struct.incoming, 1695 &trustAuthIncoming); 1696 if (!NT_STATUS_IS_OK(nt_status)) { 1697 return nt_status; 1698 } 1699 } else { 1700 trustAuthIncoming = data_blob(NULL, 0); 1701 } 1702 1703 if (auth_struct.outgoing.count) { 1704 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, 1705 &auth_struct.outgoing, 1706 &trustAuthOutgoing); 1707 if (!NT_STATUS_IS_OK(nt_status)) { 1708 return nt_status; 1709 } 1710 } else { 1711 trustAuthOutgoing = data_blob(NULL, 0); 1712 } 1713 1714 msg = ldb_msg_new(mem_ctx); 1715 if (msg == NULL) { 1716 return NT_STATUS_NO_MEMORY; 1717 } 1718 msg->dn = dom_msg->dn; 1719 1720 if (posix_offset) { 1721 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb, 1722 dom_msg, msg, 1723 "trustPosixOffset", 1724 *posix_offset, NULL); 1725 if (!NT_STATUS_IS_OK(nt_status)) { 1726 return nt_status; 1727 } 1728 } 1729 1730 if (info_ex) { 1731 uint32_t origattrs; 1732 uint32_t origdir; 1733 uint32_t tmp; 1734 int origtype; 1735 1736 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb, 1737 dom_msg, msg, 1738 "trustDirection", 1739 info_ex->trust_direction, 1740 &origdir); 1741 if (!NT_STATUS_IS_OK(nt_status)) { 1742 return nt_status; 1743 } 1744 1745 tmp = info_ex->trust_direction ^ origdir; 1746 if (tmp & LSA_TRUST_DIRECTION_INBOUND) { 1747 if (origdir & LSA_TRUST_DIRECTION_INBOUND) { 1748 del_incoming = true; 1749 } else { 1750 add_incoming = true; 1751 } 1752 } 1753 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) { 1754 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) { 1755 del_outgoing = true; 1756 } else { 1757 add_outgoing = true; 1758 } 1759 } 1760 1761 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1); 1762 if (origtype == -1 || origtype != info_ex->trust_type) { 1763 DEBUG(1, ("Attempted to change trust type! " 1764 "Operation not handled\n")); 1765 return NT_STATUS_INVALID_PARAMETER; 1766 } 1767 1768 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb, 1769 dom_msg, msg, 1770 "trustAttributes", 1771 info_ex->trust_attributes, 1772 &origattrs); 1773 if (!NT_STATUS_IS_OK(nt_status)) { 1774 return nt_status; 1775 } 1776 /* TODO: check forestFunctionality from ldb opaque */ 1777 /* TODO: check what is set makes sense */ 1778 /* for now refuse changes */ 1779 if (origattrs == -1 || 1780 origattrs != info_ex->trust_attributes) { 1781 DEBUG(1, ("Attempted to change trust attributes! " 1782 "Operation not handled\n")); 1783 return NT_STATUS_INVALID_PARAMETER; 1784 } 1785 } 1786 1787 if (enc_types) { 1788 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb, 1789 dom_msg, msg, 1790 "msDS-SupportedEncryptionTypes", 1791 *enc_types, NULL); 1792 if (!NT_STATUS_IS_OK(nt_status)) { 1793 return nt_status; 1794 } 1795 } 1796 1797 if (add_incoming && trustAuthIncoming.data) { 1798 ret = ldb_msg_add_empty(msg, "trustAuthIncoming", 1799 LDB_FLAG_MOD_REPLACE, NULL); 1800 if (ret != LDB_SUCCESS) { 1801 return NT_STATUS_NO_MEMORY; 1802 } 1803 ret = ldb_msg_add_value(msg, "trustAuthIncoming", 1804 &trustAuthIncoming, NULL); 1805 if (ret != LDB_SUCCESS) { 1806 return NT_STATUS_NO_MEMORY; 1807 } 1808 } 1809 if (add_outgoing && trustAuthOutgoing.data) { 1810 ret = ldb_msg_add_empty(msg, "trustAuthIncoming", 1811 LDB_FLAG_MOD_REPLACE, NULL); 1812 if (ret != LDB_SUCCESS) { 1813 return NT_STATUS_NO_MEMORY; 1814 } 1815 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", 1816 &trustAuthOutgoing, NULL); 1817 if (ret != LDB_SUCCESS) { 1818 return NT_STATUS_NO_MEMORY; 1819 } 1820 } 1821 1822 /* start transaction */ 1823 ret = ldb_transaction_start(p_state->sam_ldb); 1824 if (ret != LDB_SUCCESS) { 1825 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1826 } 1827 in_transaction = true; 1828 1829 ret = ldb_modify(p_state->sam_ldb, msg); 1830 if (ret != LDB_SUCCESS) { 1831 DEBUG(1,("Failed to modify trusted domain record %s: %s\n", 1832 ldb_dn_get_linearized(msg->dn), 1833 ldb_errstring(p_state->sam_ldb))); 1834 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { 1835 nt_status = NT_STATUS_ACCESS_DENIED; 1836 } else { 1837 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; 1838 } 1839 goto done; 1840 } 1841 1842 if (add_incoming || del_incoming) { 1843 const char *netbios_name; 1844 1845 netbios_name = ldb_msg_find_attr_as_string(dom_msg, 1846 "flatname", NULL); 1847 if (!netbios_name) { 1848 nt_status = NT_STATUS_INVALID_DOMAIN_STATE; 1849 goto done; 1850 } 1851 1852 nt_status = update_trust_user(mem_ctx, 1853 p_state->sam_ldb, 1854 p_state->domain_dn, 1855 del_incoming, 1856 netbios_name, 1857 &auth_struct.incoming); 1858 if (!NT_STATUS_IS_OK(nt_status)) { 1859 goto done; 1860 } 1861 } 1862 1863 /* ok, all fine, commit transaction and return */ 1864 ret = ldb_transaction_commit(p_state->sam_ldb); 1865 if (ret != LDB_SUCCESS) { 1866 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1867 } 1868 in_transaction = false; 1869 1870 nt_status = NT_STATUS_OK; 1871 1872 done: 1873 if (in_transaction) { 1874 ldb_transaction_cancel(p_state->sam_ldb); 1875 } 1876 return nt_status; 1877 } 1878 1879 /* 1327 1880 lsa_SetInfomrationTrustedDomain 1328 1881 */ 1329 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call, 1330 TALLOC_CTX *mem_ctx, 1331 struct lsa_SetInformationTrustedDomain *r) 1332 { 1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1882 static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain( 1883 struct dcesrv_call_state *dce_call, 1884 TALLOC_CTX *mem_ctx, 1885 struct lsa_SetInformationTrustedDomain *r) 1886 { 1887 struct dcesrv_handle *h; 1888 struct lsa_trusted_domain_state *td_state; 1889 struct ldb_message **msgs; 1890 NTSTATUS nt_status; 1891 1892 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, 1893 LSA_HANDLE_TRUSTED_DOMAIN); 1894 1895 td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state); 1896 1897 /* get the trusted domain object */ 1898 nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx, 1899 td_state->trusted_domain_dn, 1900 NULL, NULL, NULL, &msgs); 1901 if (!NT_STATUS_IS_OK(nt_status)) { 1902 if (NT_STATUS_EQUAL(nt_status, 1903 NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1904 return nt_status; 1905 } 1906 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1907 } 1908 1909 return setInfoTrustedDomain_base(dce_call, h, mem_ctx, 1910 msgs[0], r->in.level, r->in.info); 1334 1911 } 1335 1912 … … 1433 2010 case LSA_TRUSTED_DOMAIN_INFO_NAME: 1434 2011 info->name.netbios_name.string 1435 = samdb_result_string(msg, "flatname", NULL);2012 = ldb_msg_find_attr_as_string(msg, "flatname", NULL); 1436 2013 break; 1437 2014 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET: 1438 2015 info->posix_offset.posix_offset 1439 = samdb_result_uint(msg, "posixOffset", 0);2016 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0); 1440 2017 break; 1441 2018 #if 0 /* Win2k3 doesn't implement this */ … … 1453 2030 ZERO_STRUCT(info->full_info); 1454 2031 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex); 1455 1456 2032 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL: 1457 2033 ZERO_STRUCT(info->full_info2_internal); 1458 2034 info->full_info2_internal.posix_offset.posix_offset 1459 = samdb_result_uint(msg, "posixOffset", 0);2035 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0); 1460 2036 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex); 1461 2037 1462 2038 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: 1463 2039 info->enc_types.enc_types 1464 = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);2040 = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5); 1465 2041 break; 1466 2042 … … 1527 2103 struct lsa_SetTrustedDomainInfoByName *r) 1528 2104 { 1529 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2105 struct dcesrv_handle *policy_handle; 2106 struct lsa_policy_state *policy_state; 2107 struct ldb_message **msgs; 2108 NTSTATUS nt_status; 2109 2110 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); 2111 policy_state = policy_handle->data; 2112 2113 /* get the trusted domain object */ 2114 nt_status = get_tdo(policy_state->sam_ldb, mem_ctx, 2115 policy_state->domain_dn, 2116 r->in.trusted_domain->string, 2117 r->in.trusted_domain->string, 2118 NULL, &msgs); 2119 if (!NT_STATUS_IS_OK(nt_status)) { 2120 if (NT_STATUS_EQUAL(nt_status, 2121 NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 2122 return nt_status; 2123 } 2124 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2125 } 2126 2127 return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx, 2128 msgs[0], r->in.level, r->in.info); 1530 2129 } 1531 2130 … … 1623 2222 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 1624 2223 "objectclass=trustedDomain"); 1625 if (count == -1) {2224 if (count < 0) { 1626 2225 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1627 2226 } … … 1634 2233 for (i=0;i<count;i++) { 1635 2234 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier"); 1636 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);2235 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL); 1637 2236 } 1638 2237 1639 2238 /* sort the results by name */ 1640 qsort(entries, count, sizeof(*entries), 1641 (comparison_fn_t)compare_DomainInfo); 2239 TYPESAFE_QSORT(entries, count, compare_DomainInfo); 1642 2240 1643 2241 if (*r->in.resume_handle >= count) { … … 1717 2315 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 1718 2316 "objectclass=trustedDomain"); 1719 if (count == -1) {2317 if (count < 0) { 1720 2318 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1721 2319 } … … 1734 2332 1735 2333 /* sort the results by name */ 1736 qsort(entries, count, sizeof(*entries), 1737 (comparison_fn_t)compare_TrustDomainInfoInfoEx); 2334 TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx); 1738 2335 1739 2336 if (*r->in.resume_handle >= count) { … … 1814 2411 struct dcesrv_handle *h; 1815 2412 struct lsa_account_state *astate; 1816 int ret, i; 2413 int ret; 2414 unsigned int i, j; 1817 2415 struct ldb_message **res; 1818 2416 const char * const attrs[] = { "privilege", NULL}; … … 1840 2438 } 1841 2439 1842 ret = gendb_search(astate->policy-> sam_ldb, mem_ctx, NULL, &res, attrs,2440 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 1843 2441 "objectSid=%s", sidstr); 2442 if (ret < 0) { 2443 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2444 } 1844 2445 if (ret != 1) { 1845 2446 return NT_STATUS_OK; … … 1857 2458 } 1858 2459 2460 j = 0; 1859 2461 for (i=0;i<el->num_values;i++) { 1860 2462 int id = sec_privilege_id((const char *)el->values[i].data); 1861 if (id == -1) { 1862 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1863 } 1864 privs->set[i].attribute = 0; 1865 privs->set[i].luid.low = id; 1866 privs->set[i].luid.high = 0; 1867 } 1868 1869 privs->count = el->num_values; 2463 if (id == SEC_PRIV_INVALID) { 2464 /* Perhaps an account right, not a privilege */ 2465 continue; 2466 } 2467 privs->set[j].attribute = 0; 2468 privs->set[j].luid.low = id; 2469 privs->set[j].luid.high = 0; 2470 j++; 2471 } 2472 2473 privs->count = j; 1870 2474 1871 2475 return NT_STATUS_OK; … … 1881 2485 struct dcesrv_handle *h; 1882 2486 struct lsa_policy_state *state; 1883 int ret, i; 2487 int ret; 2488 unsigned int i; 1884 2489 struct ldb_message **res; 1885 2490 const char * const attrs[] = { "privilege", NULL}; … … 1896 2501 } 1897 2502 1898 ret = gendb_search(state-> sam_ldb, mem_ctx, NULL, &res, attrs,2503 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 1899 2504 "(&(objectSid=%s)(privilege=*))", sidstr); 1900 2505 if (ret == 0) { 1901 2506 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1902 2507 } 1903 if (ret > 1) { 1904 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1905 } 1906 if (ret == -1) { 2508 if (ret != 1) { 1907 2509 DEBUG(3, ("searching for account rights for SID: %s failed: %s", 1908 2510 dom_sid_string(mem_ctx, r->in.sid), 1909 ldb_errstring(state-> sam_ldb)));2511 ldb_errstring(state->pdb))); 1910 2512 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1911 2513 } … … 1942 2544 const struct lsa_RightSet *rights) 1943 2545 { 1944 const char *sidstr ;2546 const char *sidstr, *sidndrstr; 1945 2547 struct ldb_message *msg; 1946 2548 struct ldb_message_element *el; 1947 int i, ret; 2549 int ret; 2550 uint32_t i; 1948 2551 struct lsa_EnumAccountRights r2; 1949 1950 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid); 1951 if (sidstr == NULL) { 1952 return NT_STATUS_NO_MEMORY; 2552 char *dnstr; 2553 2554 if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) < 2555 SECURITY_ADMINISTRATOR) { 2556 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n")); 2557 return NT_STATUS_ACCESS_DENIED; 1953 2558 } 1954 2559 … … 1958 2563 } 1959 2564 1960 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, 1961 NULL, "objectSid=%s", sidstr); 1962 if (msg->dn == NULL) { 1963 NTSTATUS status; 1964 if (ldb_flag == LDB_FLAG_MOD_DELETE) { 1965 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1966 } 1967 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx, 1968 sid, &msg->dn); 1969 if (!NT_STATUS_IS_OK(status)) { 1970 return status; 1971 } 1972 return NT_STATUS_NO_SUCH_USER; 1973 } 1974 1975 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) { 1976 return NT_STATUS_NO_MEMORY; 1977 } 1978 1979 if (ldb_flag == LDB_FLAG_MOD_ADD) { 2565 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid); 2566 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg); 2567 2568 sidstr = dom_sid_string(msg, sid); 2569 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg); 2570 2571 dnstr = talloc_asprintf(msg, "sid=%s", sidstr); 2572 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg); 2573 2574 msg->dn = ldb_dn_new(msg, state->pdb, dnstr); 2575 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg); 2576 2577 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) { 1980 2578 NTSTATUS status; 1981 2579 … … 1991 2589 1992 2590 for (i=0;i<rights->count;i++) { 1993 if (sec_privilege_id(rights->names[i].string) == -1) { 2591 if (sec_privilege_id(rights->names[i].string) == SEC_PRIV_INVALID) { 2592 if (sec_right_bit(rights->names[i].string) == 0) { 2593 talloc_free(msg); 2594 return NT_STATUS_NO_SUCH_PRIVILEGE; 2595 } 2596 2597 talloc_free(msg); 1994 2598 return NT_STATUS_NO_SUCH_PRIVILEGE; 1995 2599 } 1996 2600 1997 if ( ldb_flag== LDB_FLAG_MOD_ADD) {1998 int j;2601 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) { 2602 uint32_t j; 1999 2603 for (j=0;j<r2.out.rights->count;j++) { 2000 2604 if (strcasecmp_m(r2.out.rights->names[j].string, … … 2008 2612 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string); 2009 2613 if (ret != LDB_SUCCESS) { 2614 talloc_free(msg); 2010 2615 return NT_STATUS_NO_MEMORY; 2011 2616 } … … 2014 2619 el = ldb_msg_find_element(msg, "privilege"); 2015 2620 if (!el) { 2621 talloc_free(msg); 2016 2622 return NT_STATUS_OK; 2017 2623 } 2018 2624 2019 ret = ldb_modify(state->sam_ldb, msg); 2020 if (ret != 0) { 2021 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { 2022 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 2625 el->flags = ldb_flag; 2626 2627 ret = ldb_modify(state->pdb, msg); 2628 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 2629 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) { 2630 talloc_free(msg); 2631 return NT_STATUS_NO_MEMORY; 2632 } 2633 ldb_msg_add_string(msg, "comment", "added via LSA"); 2634 ret = ldb_add(state->pdb, msg); 2635 } 2636 if (ret != LDB_SUCCESS) { 2637 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { 2638 talloc_free(msg); 2639 return NT_STATUS_OK; 2023 2640 } 2024 2641 DEBUG(3, ("Could not %s attributes from %s: %s", 2025 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add", 2026 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb))); 2642 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add", 2643 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb))); 2644 talloc_free(msg); 2027 2645 return NT_STATUS_UNEXPECTED_IO_ERROR; 2028 2646 } 2029 2647 2648 talloc_free(msg); 2030 2649 return NT_STATUS_OK; 2031 2650 } … … 2040 2659 struct dcesrv_handle *h; 2041 2660 struct lsa_account_state *astate; 2042 int i;2661 uint32_t i; 2043 2662 2044 2663 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT); … … 2077 2696 struct dcesrv_handle *h; 2078 2697 struct lsa_account_state *astate; 2079 int i;2698 uint32_t i; 2080 2699 2081 2700 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT); … … 2156 2775 struct lsa_GetSystemAccessAccount *r) 2157 2776 { 2158 int i; 2159 NTSTATUS status; 2160 struct lsa_EnumPrivsAccount enumPrivs; 2161 struct lsa_PrivilegeSet *privs; 2162 2163 privs = talloc(mem_ctx, struct lsa_PrivilegeSet); 2164 if (!privs) { 2165 return NT_STATUS_NO_MEMORY; 2166 } 2167 privs->count = 0; 2168 privs->unknown = 0; 2169 privs->set = NULL; 2170 2171 enumPrivs.in.handle = r->in.handle; 2172 enumPrivs.out.privs = &privs; 2173 2174 status = dcesrv_lsa_EnumPrivsAccount(dce_call, mem_ctx, &enumPrivs); 2175 if (!NT_STATUS_IS_OK(status)) { 2176 return status; 2177 } 2777 struct dcesrv_handle *h; 2778 struct lsa_account_state *astate; 2779 int ret; 2780 unsigned int i; 2781 struct ldb_message **res; 2782 const char * const attrs[] = { "privilege", NULL}; 2783 struct ldb_message_element *el; 2784 const char *sidstr; 2178 2785 2179 2786 *(r->out.access_mask) = 0x00000000; 2180 2787 2181 for (i = 0; i < privs->count; i++) { 2182 int priv = privs->set[i].luid.low; 2183 2184 switch (priv) { 2185 case SEC_PRIV_INTERACTIVE_LOGON: 2186 *(r->out.access_mask) |= LSA_POLICY_MODE_INTERACTIVE; 2187 break; 2188 case SEC_PRIV_NETWORK_LOGON: 2189 *(r->out.access_mask) |= LSA_POLICY_MODE_NETWORK; 2190 break; 2191 case SEC_PRIV_REMOTE_INTERACTIVE_LOGON: 2192 *(r->out.access_mask) |= LSA_POLICY_MODE_REMOTE_INTERACTIVE; 2193 break; 2194 } 2788 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT); 2789 2790 astate = h->data; 2791 2792 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid); 2793 if (sidstr == NULL) { 2794 return NT_STATUS_NO_MEMORY; 2795 } 2796 2797 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 2798 "objectSid=%s", sidstr); 2799 if (ret < 0) { 2800 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2801 } 2802 if (ret != 1) { 2803 return NT_STATUS_OK; 2804 } 2805 2806 el = ldb_msg_find_element(res[0], "privilege"); 2807 if (el == NULL || el->num_values == 0) { 2808 return NT_STATUS_OK; 2809 } 2810 2811 for (i=0;i<el->num_values;i++) { 2812 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data); 2813 if (right_bit == 0) { 2814 /* Perhaps an privilege, not a right */ 2815 continue; 2816 } 2817 *(r->out.access_mask) |= right_bit; 2195 2818 } 2196 2819 … … 2231 2854 ZERO_STRUCTP(r->out.sec_handle); 2232 2855 2233 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))2856 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 2234 2857 { 2235 2858 case SECURITY_SYSTEM: … … 2248 2871 2249 2872 secret_state = talloc(mem_ctx, struct lsa_secret_state); 2250 if (!secret_state) { 2251 return NT_STATUS_NO_MEMORY; 2252 } 2873 NT_STATUS_HAVE_NO_MEMORY(secret_state); 2253 2874 secret_state->policy = policy_state; 2254 2875 … … 2260 2881 if (strncmp("G$", r->in.name.string, 2) == 0) { 2261 2882 const char *name2; 2883 2884 secret_state->global = true; 2885 2262 2886 name = &r->in.name.string[2]; 2263 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */ 2264 secret_state->sam_ldb = talloc_reference(secret_state, 2265 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx))); 2266 secret_state->global = true; 2267 2268 if (strlen(name) < 1) { 2887 if (strlen(name) == 0) { 2269 2888 return NT_STATUS_INVALID_PARAMETER; 2270 2889 } 2271 2890 2272 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name)); 2891 name2 = talloc_asprintf(mem_ctx, "%s Secret", 2892 ldb_binary_encode_string(mem_ctx, name)); 2893 NT_STATUS_HAVE_NO_MEMORY(name2); 2894 2895 /* We need to connect to the database as system, as this is one 2896 * of the rare RPC calls that must read the secrets (and this 2897 * is denied otherwise) */ 2898 secret_state->sam_ldb = talloc_reference(secret_state, 2899 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0)); 2900 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb); 2901 2273 2902 /* search for the secret record */ 2274 2903 ret = gendb_search(secret_state->sam_ldb, … … 2280 2909 } 2281 2910 2282 if (ret == -1) {2911 if (ret < 0) { 2283 2912 DEBUG(0,("Failure searching for CN=%s: %s\n", 2284 2913 name2, ldb_errstring(secret_state->sam_ldb))); … … 2287 2916 2288 2917 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn); 2289 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) { 2918 NT_STATUS_HAVE_NO_MEMORY(msg->dn); 2919 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) { 2290 2920 return NT_STATUS_NO_MEMORY; 2291 2921 } 2292 2293 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx,msg, "cn", name2);2294 2922 2923 ret = ldb_msg_add_string(msg, "cn", name2); 2924 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY; 2295 2925 } else { 2296 2926 secret_state->global = false; 2297 2927 2298 2928 name = r->in.name.string; 2299 if (strlen(name) < 1) {2929 if (strlen(name) == 0) { 2300 2930 return NT_STATUS_INVALID_PARAMETER; 2301 2931 } 2302 2932 2303 2933 secret_state->sam_ldb = talloc_reference(secret_state, 2304 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx)); 2934 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 2935 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb); 2936 2305 2937 /* search for the secret record */ 2306 2938 ret = gendb_search(secret_state->sam_ldb, mem_ctx, … … 2313 2945 } 2314 2946 2315 if (ret == -1) {2947 if (ret < 0) { 2316 2948 DEBUG(0,("Failure searching for CN=%s: %s\n", 2317 2949 name, ldb_errstring(secret_state->sam_ldb))); … … 2319 2951 } 2320 2952 2321 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name); 2322 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name); 2953 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, 2954 "cn=%s,cn=LSA Secrets", name); 2955 NT_STATUS_HAVE_NO_MEMORY(msg->dn); 2956 ret = ldb_msg_add_string(msg, "cn", name); 2957 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY; 2323 2958 } 2324 2959 2325 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret"); 2960 ret = ldb_msg_add_string(msg, "objectClass", "secret"); 2961 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY; 2326 2962 2327 2963 secret_state->secret_dn = talloc_reference(secret_state, msg->dn); 2964 NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn); 2328 2965 2329 2966 /* create the secret */ 2330 2967 ret = ldb_add(secret_state->sam_ldb, msg); 2331 if (ret != 0) {2968 if (ret != LDB_SUCCESS) { 2332 2969 DEBUG(0,("Failed to create secret record %s: %s\n", 2333 2970 ldb_dn_get_linearized(msg->dn), … … 2336 2973 } 2337 2974 2975 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET); 2976 NT_STATUS_HAVE_NO_MEMORY(handle); 2977 2978 handle->data = talloc_steal(handle, secret_state); 2979 2980 secret_state->access_mask = r->in.access_mask; 2981 secret_state->policy = talloc_reference(secret_state, policy_state); 2982 NT_STATUS_HAVE_NO_MEMORY(secret_state->policy); 2983 2984 *r->out.sec_handle = handle->wire_handle; 2985 2986 return NT_STATUS_OK; 2987 } 2988 2989 2990 /* 2991 lsa_OpenSecret 2992 */ 2993 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2994 struct lsa_OpenSecret *r) 2995 { 2996 struct dcesrv_handle *policy_handle; 2997 2998 struct lsa_policy_state *policy_state; 2999 struct lsa_secret_state *secret_state; 3000 struct dcesrv_handle *handle; 3001 struct ldb_message **msgs; 3002 const char *attrs[] = { 3003 NULL 3004 }; 3005 3006 const char *name; 3007 3008 int ret; 3009 3010 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); 3011 ZERO_STRUCTP(r->out.sec_handle); 3012 policy_state = policy_handle->data; 3013 3014 if (!r->in.name.string) { 3015 return NT_STATUS_INVALID_PARAMETER; 3016 } 3017 3018 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 3019 { 3020 case SECURITY_SYSTEM: 3021 case SECURITY_ADMINISTRATOR: 3022 break; 3023 default: 3024 /* Users and annonymous are not allowed to access secrets */ 3025 return NT_STATUS_ACCESS_DENIED; 3026 } 3027 3028 secret_state = talloc(mem_ctx, struct lsa_secret_state); 3029 if (!secret_state) { 3030 return NT_STATUS_NO_MEMORY; 3031 } 3032 secret_state->policy = policy_state; 3033 3034 if (strncmp("G$", r->in.name.string, 2) == 0) { 3035 name = &r->in.name.string[2]; 3036 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */ 3037 secret_state->sam_ldb = talloc_reference(secret_state, 3038 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0)); 3039 secret_state->global = true; 3040 3041 if (strlen(name) < 1) { 3042 return NT_STATUS_INVALID_PARAMETER; 3043 } 3044 3045 /* search for the secret record */ 3046 ret = gendb_search(secret_state->sam_ldb, 3047 mem_ctx, policy_state->system_dn, &msgs, attrs, 3048 "(&(cn=%s Secret)(objectclass=secret))", 3049 ldb_binary_encode_string(mem_ctx, name)); 3050 if (ret == 0) { 3051 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3052 } 3053 3054 if (ret != 1) { 3055 DEBUG(0,("Found %d records matching DN %s\n", ret, 3056 ldb_dn_get_linearized(policy_state->system_dn))); 3057 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3058 } 3059 3060 } else { 3061 secret_state->global = false; 3062 secret_state->sam_ldb = talloc_reference(secret_state, 3063 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 3064 3065 name = r->in.name.string; 3066 if (strlen(name) < 1) { 3067 return NT_STATUS_INVALID_PARAMETER; 3068 } 3069 3070 /* search for the secret record */ 3071 ret = gendb_search(secret_state->sam_ldb, mem_ctx, 3072 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"), 3073 &msgs, attrs, 3074 "(&(cn=%s)(objectclass=secret))", 3075 ldb_binary_encode_string(mem_ctx, name)); 3076 if (ret == 0) { 3077 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3078 } 3079 3080 if (ret != 1) { 3081 DEBUG(0,("Found %d records matching CN=%s\n", 3082 ret, ldb_binary_encode_string(mem_ctx, name))); 3083 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3084 } 3085 } 3086 3087 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn); 3088 2338 3089 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET); 2339 3090 if (!handle) { … … 2353 3104 2354 3105 /* 2355 lsa_OpenSecret2356 */2357 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,2358 struct lsa_OpenSecret *r)2359 {2360 struct dcesrv_handle *policy_handle;2361 2362 struct lsa_policy_state *policy_state;2363 struct lsa_secret_state *secret_state;2364 struct dcesrv_handle *handle;2365 struct ldb_message **msgs;2366 const char *attrs[] = {2367 NULL2368 };2369 2370 const char *name;2371 2372 int ret;2373 2374 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);2375 ZERO_STRUCTP(r->out.sec_handle);2376 policy_state = policy_handle->data;2377 2378 if (!r->in.name.string) {2379 return NT_STATUS_INVALID_PARAMETER;2380 }2381 2382 switch (security_session_user_level(dce_call->conn->auth_state.session_info))2383 {2384 case SECURITY_SYSTEM:2385 case SECURITY_ADMINISTRATOR:2386 break;2387 default:2388 /* Users and annonymous are not allowed to access secrets */2389 return NT_STATUS_ACCESS_DENIED;2390 }2391 2392 secret_state = talloc(mem_ctx, struct lsa_secret_state);2393 if (!secret_state) {2394 return NT_STATUS_NO_MEMORY;2395 }2396 secret_state->policy = policy_state;2397 2398 if (strncmp("G$", r->in.name.string, 2) == 0) {2399 name = &r->in.name.string[2];2400 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */2401 secret_state->sam_ldb = talloc_reference(secret_state,2402 samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(secret_state, dce_call->conn->dce_ctx->lp_ctx)));2403 secret_state->global = true;2404 2405 if (strlen(name) < 1) {2406 return NT_STATUS_INVALID_PARAMETER;2407 }2408 2409 /* search for the secret record */2410 ret = gendb_search(secret_state->sam_ldb,2411 mem_ctx, policy_state->system_dn, &msgs, attrs,2412 "(&(cn=%s Secret)(objectclass=secret))",2413 ldb_binary_encode_string(mem_ctx, name));2414 if (ret == 0) {2415 return NT_STATUS_OBJECT_NAME_NOT_FOUND;2416 }2417 2418 if (ret != 1) {2419 DEBUG(0,("Found %d records matching DN %s\n", ret,2420 ldb_dn_get_linearized(policy_state->system_dn)));2421 return NT_STATUS_INTERNAL_DB_CORRUPTION;2422 }2423 2424 } else {2425 secret_state->global = false;2426 secret_state->sam_ldb = talloc_reference(secret_state,2427 secrets_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx));2428 2429 name = r->in.name.string;2430 if (strlen(name) < 1) {2431 return NT_STATUS_INVALID_PARAMETER;2432 }2433 2434 /* search for the secret record */2435 ret = gendb_search(secret_state->sam_ldb, mem_ctx,2436 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),2437 &msgs, attrs,2438 "(&(cn=%s)(objectclass=secret))",2439 ldb_binary_encode_string(mem_ctx, name));2440 if (ret == 0) {2441 return NT_STATUS_OBJECT_NAME_NOT_FOUND;2442 }2443 2444 if (ret != 1) {2445 DEBUG(0,("Found %d records matching CN=%s\n",2446 ret, ldb_binary_encode_string(mem_ctx, name)));2447 return NT_STATUS_INTERNAL_DB_CORRUPTION;2448 }2449 }2450 2451 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);2452 2453 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);2454 if (!handle) {2455 return NT_STATUS_NO_MEMORY;2456 }2457 2458 handle->data = talloc_steal(handle, secret_state);2459 2460 secret_state->access_mask = r->in.access_mask;2461 secret_state->policy = talloc_reference(secret_state, policy_state);2462 2463 *r->out.sec_handle = handle->wire_handle;2464 2465 return NT_STATUS_OK;2466 }2467 2468 2469 /*2470 3106 lsa_SetSecret 2471 3107 */ … … 2518 3154 2519 3155 /* set value */ 2520 if (samdb_msg_add_value(secret_state->sam_ldb, 2521 mem_ctx, msg, "priorValue", &val) != 0) { 3156 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) { 2522 3157 return NT_STATUS_NO_MEMORY; 2523 3158 } … … 2525 3160 /* set old value mtime */ 2526 3161 if (samdb_msg_add_uint64(secret_state->sam_ldb, 2527 mem_ctx, msg, "priorSetTime", nt_now) != 0) {3162 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) { 2528 3163 return NT_STATUS_NO_MEMORY; 2529 3164 } … … 2559 3194 if (old_val) { 2560 3195 /* set old value */ 2561 if (samdb_msg_add_value(secret_state->sam_ldb, 2562 mem_ctx, msg, "priorValue", 2563 old_val) != 0) { 3196 if (ldb_msg_add_value(msg, "priorValue", 3197 old_val, NULL) != LDB_SUCCESS) { 2564 3198 return NT_STATUS_NO_MEMORY; 2565 3199 } 2566 3200 } else { 2567 3201 if (samdb_msg_add_delete(secret_state->sam_ldb, 2568 mem_ctx, msg, "priorValue") ) {3202 mem_ctx, msg, "priorValue") != LDB_SUCCESS) { 2569 3203 return NT_STATUS_NO_MEMORY; 2570 3204 } … … 2575 3209 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) { 2576 3210 if (samdb_msg_add_uint64(secret_state->sam_ldb, 2577 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {3211 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) { 2578 3212 return NT_STATUS_NO_MEMORY; 2579 3213 } 2580 3214 } else { 2581 3215 if (samdb_msg_add_uint64(secret_state->sam_ldb, 2582 mem_ctx, msg, "priorSetTime", nt_now) != 0) {3216 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) { 2583 3217 return NT_STATUS_NO_MEMORY; 2584 3218 } … … 2600 3234 2601 3235 /* set value */ 2602 if (samdb_msg_add_value(secret_state->sam_ldb, 2603 mem_ctx, msg, "currentValue", &val) != 0) { 3236 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) { 2604 3237 return NT_STATUS_NO_MEMORY; 2605 3238 } … … 2607 3240 /* set new value mtime */ 2608 3241 if (samdb_msg_add_uint64(secret_state->sam_ldb, 2609 mem_ctx, msg, "lastSetTime", nt_now) != 0) {3242 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) { 2610 3243 return NT_STATUS_NO_MEMORY; 2611 3244 } … … 2614 3247 /* NULL out the NEW value */ 2615 3248 if (samdb_msg_add_uint64(secret_state->sam_ldb, 2616 mem_ctx, msg, "lastSetTime", nt_now) != 0) {3249 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) { 2617 3250 return NT_STATUS_NO_MEMORY; 2618 3251 } 2619 3252 if (samdb_msg_add_delete(secret_state->sam_ldb, 2620 mem_ctx, msg, "currentValue") ) {3253 mem_ctx, msg, "currentValue") != LDB_SUCCESS) { 2621 3254 return NT_STATUS_NO_MEMORY; 2622 3255 } … … 2624 3257 2625 3258 /* modify the samdb record */ 2626 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);2627 if (ret != 0) {3259 ret = dsdb_replace(secret_state->sam_ldb, msg, 0); 3260 if (ret != LDB_SUCCESS) { 2628 3261 /* we really need samdb.c to return NTSTATUS */ 2629 3262 return NT_STATUS_UNSUCCESSFUL; … … 2660 3293 2661 3294 /* Ensure user is permitted to read this... */ 2662 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))3295 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 2663 3296 { 2664 3297 case SECURITY_SYSTEM: … … 2776 3409 2777 3410 id = sec_privilege_id(r->in.name->string); 2778 if (id == -1) {3411 if (id == SEC_PRIV_INVALID) { 2779 3412 return NT_STATUS_NO_SUCH_PRIVILEGE; 2780 3413 } … … 2835 3468 struct lsa_policy_state *state; 2836 3469 struct lsa_StringLarge *disp_name = NULL; 2837 intid;3470 enum sec_privilege id; 2838 3471 2839 3472 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); … … 2842 3475 2843 3476 id = sec_privilege_id(r->in.name->string); 2844 if (id == -1) {3477 if (id == SEC_PRIV_INVALID) { 2845 3478 return NT_STATUS_NO_SUCH_PRIVILEGE; 2846 3479 } … … 2886 3519 2887 3520 privname = r->in.name->string; 2888 if (sec_privilege_id(privname) == -1) {3521 if (sec_privilege_id(privname) == SEC_PRIV_INVALID && sec_right_bit(privname) == 0) { 2889 3522 return NT_STATUS_NO_SUCH_PRIVILEGE; 2890 3523 } 2891 3524 2892 ret = gendb_search(state-> sam_ldb, mem_ctx, NULL, &res, attrs,3525 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 2893 3526 "privilege=%s", privname); 2894 if (ret == -1) {3527 if (ret < 0) { 2895 3528 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2896 3529 } … … 3004 3637 } 3005 3638 3006 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info-> server_info->account_name);3007 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info-> server_info->domain_name);3639 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->account_name); 3640 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->domain_name); 3008 3641 3009 3642 _account_name = talloc(mem_ctx, struct lsa_String); … … 3045 3678 union lsa_DomainInformationPolicy *info; 3046 3679 3047 info = talloc (r->out.info, union lsa_DomainInformationPolicy);3680 info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy); 3048 3681 if (!info) { 3049 3682 return NT_STATUS_NO_MEMORY; … … 3068 3701 return NT_STATUS_INTERNAL_ERROR; 3069 3702 } 3070 k->enforce_restrictions = 0; /* FIXME, details missing from MS-LSAD 2.2.53 */ 3071 k->service_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */ 3072 k->user_tkt_lifetime = 0; /* Need to find somewhere to store this, and query in KDC too */ 3073 k->user_tkt_renewaltime = 0; /* Need to find somewhere to store this, and query in KDC too */ 3074 k->clock_skew = krb5_get_max_time_skew(smb_krb5_context->krb5_context); 3703 kdc_get_policy(dce_call->conn->dce_ctx->lp_ctx, 3704 smb_krb5_context, 3705 k); 3075 3706 talloc_free(smb_krb5_context); 3076 3707 *r->out.info = info; … … 3233 3864 } 3234 3865 3235 3236 /* 3237 lsa_LSARSETFORESTTRUSTINFORMATION 3238 */ 3239 static NTSTATUS dcesrv_lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 3240 struct lsa_LSARSETFORESTTRUSTINFORMATION *r) 3241 { 3242 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 3243 } 3244 3866 #define DNS_CMP_MATCH 0 3867 #define DNS_CMP_FIRST_IS_CHILD 1 3868 #define DNS_CMP_SECOND_IS_CHILD 2 3869 #define DNS_CMP_NO_MATCH 3 3870 3871 /* this function assumes names are well formed DNS names. 3872 * it doesn't validate them */ 3873 static int dns_cmp(const char *s1, size_t l1, 3874 const char *s2, size_t l2) 3875 { 3876 const char *p1, *p2; 3877 size_t t1, t2; 3878 int cret; 3879 3880 if (l1 == l2) { 3881 if (strcasecmp_m(s1, s2) == 0) { 3882 return DNS_CMP_MATCH; 3883 } 3884 return DNS_CMP_NO_MATCH; 3885 } 3886 3887 if (l1 > l2) { 3888 p1 = s1; 3889 p2 = s2; 3890 t1 = l1; 3891 t2 = l2; 3892 cret = DNS_CMP_FIRST_IS_CHILD; 3893 } else { 3894 p1 = s2; 3895 p2 = s1; 3896 t1 = l2; 3897 t2 = l1; 3898 cret = DNS_CMP_SECOND_IS_CHILD; 3899 } 3900 3901 if (p1[t1 - t2 - 1] != '.') { 3902 return DNS_CMP_NO_MATCH; 3903 } 3904 3905 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) { 3906 return cret; 3907 } 3908 3909 return DNS_CMP_NO_MATCH; 3910 } 3911 3912 /* decode all TDOs forest trust info blobs */ 3913 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx, 3914 struct ldb_message *msg, 3915 struct ForestTrustInfo *info) 3916 { 3917 const struct ldb_val *ft_blob; 3918 enum ndr_err_code ndr_err; 3919 3920 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo"); 3921 if (!ft_blob || !ft_blob->data) { 3922 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3923 } 3924 /* ldb_val is equivalent to DATA_BLOB */ 3925 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info, 3926 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo); 3927 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 3928 return NT_STATUS_INVALID_DOMAIN_STATE; 3929 } 3930 3931 return NT_STATUS_OK; 3932 } 3933 3934 static NTSTATUS own_ft_info(struct lsa_policy_state *ps, 3935 struct ForestTrustInfo *fti) 3936 { 3937 struct ForestTrustDataDomainInfo *info; 3938 struct ForestTrustInfoRecord *rec; 3939 3940 fti->version = 1; 3941 fti->count = 2; 3942 fti->records = talloc_array(fti, 3943 struct ForestTrustInfoRecordArmor, 2); 3944 if (!fti->records) { 3945 return NT_STATUS_NO_MEMORY; 3946 } 3947 3948 /* TLN info */ 3949 rec = &fti->records[0].record; 3950 3951 rec->flags = 0; 3952 rec->timestamp = 0; 3953 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME; 3954 3955 rec->data.name.string = talloc_strdup(fti, ps->forest_dns); 3956 if (!rec->data.name.string) { 3957 return NT_STATUS_NO_MEMORY; 3958 } 3959 rec->data.name.size = strlen(rec->data.name.string); 3960 3961 /* DOMAIN info */ 3962 rec = &fti->records[1].record; 3963 3964 rec->flags = 0; 3965 rec->timestamp = 0; 3966 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO; 3967 3968 info = &rec->data.info; 3969 3970 info->sid = *ps->domain_sid; 3971 info->dns_name.string = talloc_strdup(fti, ps->domain_dns); 3972 if (!info->dns_name.string) { 3973 return NT_STATUS_NO_MEMORY; 3974 } 3975 info->dns_name.size = strlen(info->dns_name.string); 3976 info->netbios_name.string = talloc_strdup(fti, ps->domain_name); 3977 if (!info->netbios_name.string) { 3978 return NT_STATUS_NO_MEMORY; 3979 } 3980 info->netbios_name.size = strlen(info->netbios_name.string); 3981 3982 return NT_STATUS_OK; 3983 } 3984 3985 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx, 3986 struct lsa_ForestTrustInformation *lfti, 3987 struct ForestTrustInfo *fti) 3988 { 3989 struct lsa_ForestTrustRecord *lrec; 3990 struct ForestTrustInfoRecord *rec; 3991 struct lsa_StringLarge *tln; 3992 struct lsa_ForestTrustDomainInfo *info; 3993 uint32_t i; 3994 3995 fti->version = 1; 3996 fti->count = lfti->count; 3997 fti->records = talloc_array(mem_ctx, 3998 struct ForestTrustInfoRecordArmor, 3999 fti->count); 4000 if (!fti->records) { 4001 return NT_STATUS_NO_MEMORY; 4002 } 4003 for (i = 0; i < fti->count; i++) { 4004 lrec = lfti->entries[i]; 4005 rec = &fti->records[i].record; 4006 4007 rec->flags = lrec->flags; 4008 rec->timestamp = lrec->time; 4009 rec->type = lrec->type; 4010 4011 switch (lrec->type) { 4012 case LSA_FOREST_TRUST_TOP_LEVEL_NAME: 4013 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX: 4014 tln = &lrec->forest_trust_data.top_level_name; 4015 rec->data.name.string = 4016 talloc_strdup(mem_ctx, tln->string); 4017 if (!rec->data.name.string) { 4018 return NT_STATUS_NO_MEMORY; 4019 } 4020 rec->data.name.size = strlen(rec->data.name.string); 4021 break; 4022 case LSA_FOREST_TRUST_DOMAIN_INFO: 4023 info = &lrec->forest_trust_data.domain_info; 4024 rec->data.info.sid = *info->domain_sid; 4025 rec->data.info.dns_name.string = 4026 talloc_strdup(mem_ctx, 4027 info->dns_domain_name.string); 4028 if (!rec->data.info.dns_name.string) { 4029 return NT_STATUS_NO_MEMORY; 4030 } 4031 rec->data.info.dns_name.size = 4032 strlen(rec->data.info.dns_name.string); 4033 rec->data.info.netbios_name.string = 4034 talloc_strdup(mem_ctx, 4035 info->netbios_domain_name.string); 4036 if (!rec->data.info.netbios_name.string) { 4037 return NT_STATUS_NO_MEMORY; 4038 } 4039 rec->data.info.netbios_name.size = 4040 strlen(rec->data.info.netbios_name.string); 4041 break; 4042 default: 4043 return NT_STATUS_INVALID_DOMAIN_STATE; 4044 } 4045 } 4046 4047 return NT_STATUS_OK; 4048 } 4049 4050 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info, 4051 uint32_t idx, uint32_t collision_type, 4052 uint32_t conflict_type, const char *tdo_name); 4053 4054 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx, 4055 const char *tdo_name, 4056 struct ForestTrustInfo *tdo_fti, 4057 struct ForestTrustInfo *new_fti, 4058 struct lsa_ForestTrustCollisionInfo *c_info) 4059 { 4060 struct ForestTrustInfoRecord *nrec; 4061 struct ForestTrustInfoRecord *trec; 4062 const char *dns_name; 4063 const char *nb_name; 4064 struct dom_sid *sid; 4065 const char *tname; 4066 size_t dns_len; 4067 size_t nb_len; 4068 size_t tlen; 4069 NTSTATUS nt_status; 4070 uint32_t new_fti_idx; 4071 uint32_t i; 4072 /* use always TDO type, until we understand when Xref can be used */ 4073 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO; 4074 bool tln_conflict; 4075 bool sid_conflict; 4076 bool nb_conflict; 4077 bool exclusion; 4078 bool ex_rule; 4079 int ret; 4080 4081 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) { 4082 4083 nrec = &new_fti->records[new_fti_idx].record; 4084 dns_name = NULL; 4085 tln_conflict = false; 4086 sid_conflict = false; 4087 nb_conflict = false; 4088 exclusion = false; 4089 4090 switch (nrec->type) { 4091 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX: 4092 /* exclusions do not conflict by definition */ 4093 break; 4094 4095 case FOREST_TRUST_TOP_LEVEL_NAME: 4096 dns_name = nrec->data.name.string; 4097 dns_len = nrec->data.name.size; 4098 break; 4099 4100 case LSA_FOREST_TRUST_DOMAIN_INFO: 4101 dns_name = nrec->data.info.dns_name.string; 4102 dns_len = nrec->data.info.dns_name.size; 4103 nb_name = nrec->data.info.netbios_name.string; 4104 nb_len = nrec->data.info.netbios_name.size; 4105 sid = &nrec->data.info.sid; 4106 break; 4107 } 4108 4109 if (!dns_name) continue; 4110 4111 /* check if this is already taken and not excluded */ 4112 for (i = 0; i < tdo_fti->count; i++) { 4113 trec = &tdo_fti->records[i].record; 4114 4115 switch (trec->type) { 4116 case FOREST_TRUST_TOP_LEVEL_NAME: 4117 ex_rule = false; 4118 tname = trec->data.name.string; 4119 tlen = trec->data.name.size; 4120 break; 4121 case FOREST_TRUST_TOP_LEVEL_NAME_EX: 4122 ex_rule = true; 4123 tname = trec->data.name.string; 4124 tlen = trec->data.name.size; 4125 break; 4126 case FOREST_TRUST_DOMAIN_INFO: 4127 ex_rule = false; 4128 tname = trec->data.info.dns_name.string; 4129 tlen = trec->data.info.dns_name.size; 4130 } 4131 ret = dns_cmp(dns_name, dns_len, tname, tlen); 4132 switch (ret) { 4133 case DNS_CMP_MATCH: 4134 /* if it matches exclusion, 4135 * it doesn't conflict */ 4136 if (ex_rule) { 4137 exclusion = true; 4138 break; 4139 } 4140 /* fall through */ 4141 case DNS_CMP_FIRST_IS_CHILD: 4142 case DNS_CMP_SECOND_IS_CHILD: 4143 tln_conflict = true; 4144 /* fall through */ 4145 default: 4146 break; 4147 } 4148 4149 /* explicit exclusion, no dns name conflict here */ 4150 if (exclusion) { 4151 tln_conflict = false; 4152 } 4153 4154 if (trec->type != FOREST_TRUST_DOMAIN_INFO) { 4155 continue; 4156 } 4157 4158 /* also test for domain info */ 4159 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) && 4160 dom_sid_compare(&trec->data.info.sid, sid) == 0) { 4161 sid_conflict = true; 4162 } 4163 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) && 4164 strcasecmp_m(trec->data.info.netbios_name.string, 4165 nb_name) == 0) { 4166 nb_conflict = true; 4167 } 4168 } 4169 4170 if (tln_conflict) { 4171 nt_status = add_collision(c_info, new_fti_idx, 4172 collision_type, 4173 LSA_TLN_DISABLED_CONFLICT, 4174 tdo_name); 4175 } 4176 if (sid_conflict) { 4177 nt_status = add_collision(c_info, new_fti_idx, 4178 collision_type, 4179 LSA_SID_DISABLED_CONFLICT, 4180 tdo_name); 4181 } 4182 if (nb_conflict) { 4183 nt_status = add_collision(c_info, new_fti_idx, 4184 collision_type, 4185 LSA_NB_DISABLED_CONFLICT, 4186 tdo_name); 4187 } 4188 } 4189 4190 return NT_STATUS_OK; 4191 } 4192 4193 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info, 4194 uint32_t idx, uint32_t collision_type, 4195 uint32_t conflict_type, const char *tdo_name) 4196 { 4197 struct lsa_ForestTrustCollisionRecord **es; 4198 uint32_t i = c_info->count; 4199 4200 es = talloc_realloc(c_info, c_info->entries, 4201 struct lsa_ForestTrustCollisionRecord *, i + 1); 4202 if (!es) { 4203 return NT_STATUS_NO_MEMORY; 4204 } 4205 c_info->entries = es; 4206 c_info->count = i + 1; 4207 4208 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord); 4209 if (!es[i]) { 4210 return NT_STATUS_NO_MEMORY; 4211 } 4212 4213 es[i]->index = idx; 4214 es[i]->type = collision_type; 4215 es[i]->flags.flags = conflict_type; 4216 es[i]->name.string = talloc_strdup(es[i], tdo_name); 4217 if (!es[i]->name.string) { 4218 return NT_STATUS_NO_MEMORY; 4219 } 4220 es[i]->name.size = strlen(es[i]->name.string); 4221 4222 return NT_STATUS_OK; 4223 } 4224 4225 /* 4226 lsa_lsaRSetForestTrustInformation 4227 */ 4228 static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call, 4229 TALLOC_CTX *mem_ctx, 4230 struct lsa_lsaRSetForestTrustInformation *r) 4231 { 4232 struct dcesrv_handle *h; 4233 struct lsa_policy_state *p_state; 4234 const char *trust_attrs[] = { "trustPartner", "trustAttributes", 4235 "msDS-TrustForestTrustInfo", NULL }; 4236 struct ldb_message **dom_res = NULL; 4237 struct ldb_dn *tdo_dn; 4238 struct ldb_message *msg; 4239 int num_res, i; 4240 const char *td_name; 4241 uint32_t trust_attributes; 4242 struct lsa_ForestTrustCollisionInfo *c_info; 4243 struct ForestTrustInfo *nfti; 4244 struct ForestTrustInfo *fti; 4245 DATA_BLOB ft_blob; 4246 enum ndr_err_code ndr_err; 4247 NTSTATUS nt_status; 4248 bool am_rodc; 4249 int ret; 4250 4251 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 4252 4253 p_state = h->data; 4254 4255 if (strcmp(p_state->domain_dns, p_state->forest_dns)) { 4256 return NT_STATUS_INVALID_DOMAIN_STATE; 4257 } 4258 4259 /* abort if we are not a PDC */ 4260 if (!samdb_is_pdc(p_state->sam_ldb)) { 4261 return NT_STATUS_INVALID_DOMAIN_ROLE; 4262 } 4263 4264 ret = samdb_rodc(p_state->sam_ldb, &am_rodc); 4265 if (ret == LDB_SUCCESS && am_rodc) { 4266 return NT_STATUS_NO_SUCH_DOMAIN; 4267 } 4268 4269 /* check caller has TRUSTED_SET_AUTH */ 4270 4271 /* fetch all trusted domain objects */ 4272 num_res = gendb_search(p_state->sam_ldb, mem_ctx, 4273 p_state->system_dn, 4274 &dom_res, trust_attrs, 4275 "(objectclass=trustedDomain)"); 4276 if (num_res == 0) { 4277 return NT_STATUS_NO_SUCH_DOMAIN; 4278 } 4279 4280 for (i = 0; i < num_res; i++) { 4281 td_name = ldb_msg_find_attr_as_string(dom_res[i], 4282 "trustPartner", NULL); 4283 if (!td_name) { 4284 return NT_STATUS_INVALID_DOMAIN_STATE; 4285 } 4286 if (strcasecmp_m(td_name, 4287 r->in.trusted_domain_name->string) == 0) { 4288 break; 4289 } 4290 } 4291 if (i >= num_res) { 4292 return NT_STATUS_NO_SUCH_DOMAIN; 4293 } 4294 4295 tdo_dn = dom_res[i]->dn; 4296 4297 trust_attributes = ldb_msg_find_attr_as_uint(dom_res[i], 4298 "trustAttributes", 0); 4299 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { 4300 return NT_STATUS_INVALID_PARAMETER; 4301 } 4302 4303 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) { 4304 return NT_STATUS_INVALID_PARAMETER; 4305 } 4306 4307 nfti = talloc(mem_ctx, struct ForestTrustInfo); 4308 if (!nfti) { 4309 return NT_STATUS_NO_MEMORY; 4310 } 4311 4312 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti); 4313 if (!NT_STATUS_IS_OK(nt_status)) { 4314 return nt_status; 4315 } 4316 4317 c_info = talloc_zero(r->out.collision_info, 4318 struct lsa_ForestTrustCollisionInfo); 4319 if (!c_info) { 4320 return NT_STATUS_NO_MEMORY; 4321 } 4322 4323 /* first check own info, then other domains */ 4324 fti = talloc(mem_ctx, struct ForestTrustInfo); 4325 if (!fti) { 4326 return NT_STATUS_NO_MEMORY; 4327 } 4328 4329 nt_status = own_ft_info(p_state, fti); 4330 if (!NT_STATUS_IS_OK(nt_status)) { 4331 return nt_status; 4332 } 4333 4334 nt_status = check_ft_info(c_info, p_state->domain_dns, 4335 fti, nfti, c_info); 4336 if (!NT_STATUS_IS_OK(nt_status)) { 4337 return nt_status; 4338 } 4339 4340 for (i = 0; i < num_res; i++) { 4341 fti = talloc(mem_ctx, struct ForestTrustInfo); 4342 if (!fti) { 4343 return NT_STATUS_NO_MEMORY; 4344 } 4345 4346 nt_status = get_ft_info(mem_ctx, dom_res[i], fti); 4347 if (!NT_STATUS_IS_OK(nt_status)) { 4348 if (NT_STATUS_EQUAL(nt_status, 4349 NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 4350 continue; 4351 } 4352 return nt_status; 4353 } 4354 4355 td_name = ldb_msg_find_attr_as_string(dom_res[i], 4356 "trustPartner", NULL); 4357 if (!td_name) { 4358 return NT_STATUS_INVALID_DOMAIN_STATE; 4359 } 4360 4361 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info); 4362 if (!NT_STATUS_IS_OK(nt_status)) { 4363 return nt_status; 4364 } 4365 } 4366 4367 *r->out.collision_info = c_info; 4368 4369 if (r->in.check_only != 0) { 4370 return NT_STATUS_OK; 4371 } 4372 4373 /* not just a check, write info back */ 4374 4375 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti, 4376 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo); 4377 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 4378 return NT_STATUS_INVALID_PARAMETER; 4379 } 4380 4381 msg = ldb_msg_new(mem_ctx); 4382 if (msg == NULL) { 4383 return NT_STATUS_NO_MEMORY; 4384 } 4385 4386 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn); 4387 if (!msg->dn) { 4388 return NT_STATUS_NO_MEMORY; 4389 } 4390 4391 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo", 4392 LDB_FLAG_MOD_REPLACE, NULL); 4393 if (ret != LDB_SUCCESS) { 4394 return NT_STATUS_NO_MEMORY; 4395 } 4396 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo", 4397 &ft_blob, NULL); 4398 if (ret != LDB_SUCCESS) { 4399 return NT_STATUS_NO_MEMORY; 4400 } 4401 4402 ret = ldb_modify(p_state->sam_ldb, msg); 4403 if (ret != LDB_SUCCESS) { 4404 DEBUG(0, ("Failed to store Forest Trust Info: %s\n", 4405 ldb_errstring(p_state->sam_ldb))); 4406 4407 switch (ret) { 4408 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 4409 return NT_STATUS_ACCESS_DENIED; 4410 default: 4411 return NT_STATUS_INTERNAL_DB_CORRUPTION; 4412 } 4413 } 4414 4415 return NT_STATUS_OK; 4416 } 3245 4417 3246 4418 /* -
trunk/server/source4/rpc_server/lsa/lsa.h
r414 r745 27 27 #include "dsdb/samdb/samdb.h" 28 28 #include "libcli/ldap/ldap_ndr.h" 29 #include "lib/ldb/include/ldb_errors.h"29 #include <ldb_errors.h> 30 30 #include "libcli/security/security.h" 31 31 #include "libcli/auth/libcli_auth.h" … … 41 41 struct dcesrv_handle *handle; 42 42 struct ldb_context *sam_ldb; 43 struct ldb_context *pdb; 43 44 uint32_t access_mask; 44 45 struct ldb_dn *domain_dn; -
trunk/server/source4/rpc_server/lsa/lsa_init.c
r414 r745 44 44 45 45 /* make sure the sam database is accessible */ 46 state->sam_ldb = samdb_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info );46 state->sam_ldb = samdb_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info, 0); 47 47 if (state->sam_ldb == NULL) { 48 return NT_STATUS_INVALID_SYSTEM_SERVICE; 49 } 50 51 /* and the privilege database */ 52 state->pdb = privilege_connect(state, dce_call->conn->dce_ctx->lp_ctx); 53 if (state->pdb == NULL) { 48 54 return NT_STATUS_INVALID_SYSTEM_SERVICE; 49 55 } … … 58 64 /* work out the forest root_dn - useful for so many calls its worth 59 65 fetching here */ 60 state->forest_dn = samdb_root_dn(state->sam_ldb);66 state->forest_dn = ldb_get_root_basedn(state->sam_ldb); 61 67 if (!state->forest_dn) { 62 68 return NT_STATUS_NO_MEMORY; … … 83 89 talloc_free(dom_res); 84 90 85 state->domain_name = lp _sam_name(dce_call->conn->dce_ctx->lp_ctx);91 state->domain_name = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx); 86 92 87 93 state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn); -
trunk/server/source4/rpc_server/lsa/lsa_lookup.c
r414 r745 22 22 23 23 #include "rpc_server/lsa/lsa.h" 24 #include "libds/common/flag_mapping.h" 24 25 25 26 static const struct { … … 27 28 const char *name; 28 29 const char *sid; 29 intrtype;30 enum lsa_SidType rtype; 30 31 } well_known[] = { 31 32 { … … 194 195 static NTSTATUS lookup_well_known_names(TALLOC_CTX *mem_ctx, const char *domain, 195 196 const char *name, const char **authority_name, 196 struct dom_sid **sid, uint32_t *rtype)197 { 198 int i;197 struct dom_sid **sid, enum lsa_SidType *rtype) 198 { 199 unsigned int i; 199 200 for (i=0; well_known[i].sid; i++) { 200 201 if (domain) { … … 220 221 static NTSTATUS lookup_well_known_sids(TALLOC_CTX *mem_ctx, 221 222 const char *sid_str, const char **authority_name, 222 const char **name, uint32_t*rtype)223 { 224 int i;223 const char **name, enum lsa_SidType *rtype) 224 { 225 unsigned int i; 225 226 for (i=0; well_known[i].sid; i++) { 226 227 if (strcasecmp_m(sid_str, well_known[i].sid) == 0) { … … 240 241 struct loadparm_context *lp_ctx, 241 242 struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 242 const char *name, const char **authority_name, 243 struct dom_sid **sid, enum lsa_SidType *rtype) 244 { 245 int ret, atype, i; 243 const char *name, const char **authority_name, 244 struct dom_sid **sid, enum lsa_SidType *rtype, 245 uint32_t *rid) 246 { 247 int ret, i; 248 uint32_t atype; 246 249 struct ldb_message **res; 247 250 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL}; … … 275 278 status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype); 276 279 if (NT_STATUS_IS_OK(status)) { 280 dom_sid_split_rid(NULL, *sid, NULL, rid); 281 return NT_STATUS_OK; 282 } 283 284 if (username == NULL) { 285 *authority_name = NAME_BUILTIN; 286 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); 287 *rtype = SID_NAME_DOMAIN; 288 *rid = 0xFFFFFFFF; 277 289 return NT_STATUS_OK; 278 290 } … … 282 294 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); 283 295 *rtype = SID_NAME_DOMAIN; 296 dom_sid_split_rid(NULL, *sid, NULL, rid); 284 297 return NT_STATUS_OK; 285 298 } … … 288 301 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); 289 302 *rtype = SID_NAME_DOMAIN; 303 *rid = 0xFFFFFFFF; 290 304 return NT_STATUS_OK; 291 305 } … … 294 308 *sid = state->domain_sid; 295 309 *rtype = SID_NAME_DOMAIN; 310 *rid = 0xFFFFFFFF; 296 311 return NT_STATUS_OK; 297 312 } … … 300 315 *sid = state->domain_sid; 301 316 *rtype = SID_NAME_DOMAIN; 317 *rid = 0xFFFFFFFF; 302 318 return NT_STATUS_OK; 303 319 } … … 308 324 return NT_STATUS_NO_MEMORY; 309 325 } 310 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype );326 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid); 311 327 if (NT_STATUS_IS_OK(status)) { 312 328 return status; … … 318 334 return NT_STATUS_NO_MEMORY; 319 335 } 320 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype );336 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid); 321 337 if (NT_STATUS_IS_OK(status)) { 322 338 return status; … … 328 344 return NT_STATUS_NO_MEMORY; 329 345 } 330 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype );346 status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid); 331 347 if (NT_STATUS_IS_OK(status)) { 332 348 return status; … … 339 355 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); 340 356 *rtype = SID_NAME_DOMAIN; 357 dom_sid_split_rid(NULL, *sid, NULL, rid); 341 358 return NT_STATUS_OK; 342 359 } 343 360 344 361 /* Look up table of well known names */ 345 return lookup_well_known_names(mem_ctx, domain, username, authority_name, 346 sid, rtype); 362 status = lookup_well_known_names(mem_ctx, domain, username, authority_name, 363 sid, rtype); 364 if (NT_STATUS_IS_OK(status)) { 365 dom_sid_split_rid(NULL, *sid, NULL, rid); 366 } 367 return status; 347 368 } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) { 348 369 *authority_name = NAME_BUILTIN; … … 360 381 361 382 ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs); 362 if (ret == 1) { 363 domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); 364 if (domain_sid == NULL) { 365 return NT_STATUS_INVALID_SID; 366 } 367 } else { 383 if (ret != 1) { 384 return NT_STATUS_INTERNAL_DB_CORRUPTION; 385 } 386 domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); 387 if (domain_sid == NULL) { 368 388 return NT_STATUS_INVALID_SID; 369 389 } … … 372 392 *sid = domain_sid; 373 393 *rtype = SID_NAME_DOMAIN; 394 *rid = 0xFFFFFFFF; 374 395 return NT_STATUS_OK; 375 396 } … … 378 399 "(&(sAMAccountName=%s)(objectSid=*))", 379 400 ldb_binary_encode_string(mem_ctx, username)); 380 if (ret == -1) {381 return NT_STATUS_IN VALID_SID;401 if (ret < 0) { 402 return NT_STATUS_INTERNAL_DB_CORRUPTION; 382 403 } 383 404 … … 393 414 } 394 415 395 atype = samdb_result_uint(res[i], "sAMAccountType", 0);416 atype = ldb_msg_find_attr_as_uint(res[i], "sAMAccountType", 0); 396 417 397 418 *rtype = ds_atype_map(atype); … … 400 421 } 401 422 423 dom_sid_split_rid(NULL, *sid, NULL, rid); 402 424 return NT_STATUS_OK; 403 425 } … … 420 442 { 421 443 struct dom_sid *authority_sid; 422 int i;444 uint32_t i; 423 445 424 446 if (rtype != SID_NAME_DOMAIN) { … … 490 512 } 491 513 514 /* need to re-add a check for an allocated sid */ 515 492 516 ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, 493 517 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid)); 494 if (ret == 1) { 495 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL); 518 if ((ret < 0) || (ret > 1)) { 519 return NT_STATUS_INTERNAL_DB_CORRUPTION; 520 } 521 if (ret == 0) { 522 return NT_STATUS_NOT_FOUND; 523 } 524 525 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL); 526 if (!*name) { 527 *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL); 496 528 if (!*name) { 497 *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL); 498 if (!*name) { 499 *name = talloc_strdup(mem_ctx, sid_str); 500 NT_STATUS_HAVE_NO_MEMORY(*name); 501 } 502 } 503 504 atype = samdb_result_uint(res[0], "sAMAccountType", 0); 505 506 *rtype = ds_atype_map(atype); 507 508 return NT_STATUS_OK; 509 } 510 511 /* need to re-add a check for an allocated sid */ 512 513 return NT_STATUS_NOT_FOUND; 529 *name = talloc_strdup(mem_ctx, sid_str); 530 NT_STATUS_HAVE_NO_MEMORY(*name); 531 } 532 } 533 534 atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0); 535 *rtype = ds_atype_map(atype); 536 537 return NT_STATUS_OK; 514 538 } 515 539 … … 524 548 struct lsa_policy_state *state; 525 549 struct lsa_RefDomainList *domains = NULL; 526 int i;550 uint32_t i; 527 551 NTSTATUS status = NT_STATUS_OK; 528 552 … … 683 707 struct lsa_LookupSids2 r2; 684 708 NTSTATUS status; 685 int i;709 uint32_t i; 686 710 687 711 ZERO_STRUCT(r2); … … 737 761 struct lsa_policy_state *policy_state; 738 762 struct dcesrv_handle *policy_handle; 739 int i;763 uint32_t i; 740 764 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 741 765 struct lsa_RefDomainList *domains; … … 775 799 const char *authority_name; 776 800 struct dom_sid *sid; 777 uint32_t sid_index ;801 uint32_t sid_index, rid; 778 802 enum lsa_SidType rtype; 779 803 NTSTATUS status2; … … 786 810 r->out.sids->sids[i].flags = 0; 787 811 788 status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype); 812 status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name, 813 &authority_name, &sid, &rtype, &rid); 789 814 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) { 790 815 continue; … … 878 903 struct lsa_policy_state *state; 879 904 struct dcesrv_handle *h; 880 int i;905 uint32_t i; 881 906 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 882 907 struct lsa_RefDomainList *domains; … … 916 941 const char *authority_name; 917 942 struct dom_sid *sid; 918 uint32_t rtype, sid_index; 943 uint32_t sid_index, rid=0; 944 enum lsa_SidType rtype; 919 945 NTSTATUS status2; 920 946 … … 929 955 r->out.sids->sids[i].unknown = 0; 930 956 931 status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, state, mem_ctx, name, 932 &authority_name, &sid, &rtype );957 status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, state, mem_ctx, name, 958 &authority_name, &sid, &rtype, &rid); 933 959 if (!NT_STATUS_IS_OK(status2)) { 934 960 continue; … … 942 968 943 969 r->out.sids->sids[i].sid_type = rtype; 944 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];970 r->out.sids->sids[i].rid = rid; 945 971 r->out.sids->sids[i].sid_index = sid_index; 946 972 r->out.sids->sids[i].unknown = 0; … … 967 993 struct lsa_LookupNames2 r2; 968 994 NTSTATUS status; 969 int i;995 uint32_t i; 970 996 971 997 ZERO_STRUCT(r2); -
trunk/server/source4/rpc_server/netlogon/dcerpc_netlogon.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008 7 7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005 8 Copyright (C) Matthias Dieter Wallnöfer 2009 9 8 Copyright (C) Matthias Dieter Wallnöfer 2009-2010 9 10 10 This program is free software; you can redistribute it and/or modify 11 11 it under the terms of the GNU General Public License as published by 12 12 the Free Software Foundation; either version 3 of the License, or 13 13 (at your option) any later version. 14 14 15 15 This program is distributed in the hope that it will be useful, 16 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 18 GNU General Public License for more details. 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 29 29 #include "../lib/util/util_ldb.h" 30 30 #include "../libcli/auth/schannel.h" 31 #include "auth/gensec/schannel_state.h"32 31 #include "libcli/security/security.h" 33 32 #include "param/param.h" 34 33 #include "lib/messaging/irpc.h" 34 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 #include "../libcli/ldap/ldap_ndr.h" 36 #include "cldap_server/cldap_server.h" 37 #include "lib/tsocket/tsocket.h" 38 #include "librpc/gen_ndr/ndr_netlogon.h" 35 39 #include "librpc/gen_ndr/ndr_irpc.h" 36 40 … … 40 44 }; 41 45 42 43 46 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 44 47 struct netr_ServerReqChallenge *r) … … 55 58 dce_call->context->private_data = NULL; 56 59 } 57 60 58 61 pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state); 59 62 NT_STATUS_HAVE_NO_MEMORY(pipe_state); … … 61 64 pipe_state->client_challenge = *r->in.credentials; 62 65 63 generate_random_buffer(pipe_state->server_challenge.data, 66 generate_random_buffer(pipe_state->server_challenge.data, 64 67 sizeof(pipe_state->server_challenge.data)); 65 68 … … 77 80 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); 78 81 struct netlogon_creds_CredentialState *creds; 79 struct ldb_context *schannel_ldb;80 82 struct ldb_context *sam_ctx; 81 83 struct samr_Password *mach_pwd; … … 84 86 struct ldb_message **msgs; 85 87 NTSTATUS nt_status; 86 const char *attrs[] = {"unicodePwd", "userAccountControl", 88 const char *attrs[] = {"unicodePwd", "userAccountControl", 87 89 "objectSid", NULL}; 88 90 … … 124 126 NETLOGON_NEG_AUTHENTICATED_RPC; 125 127 126 if (!pipe_state) { 127 DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); 128 return NT_STATUS_ACCESS_DENIED; 129 } 130 131 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 132 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 128 switch (r->in.secure_channel_type) { 129 case SEC_CHAN_WKSTA: 130 case SEC_CHAN_DNS_DOMAIN: 131 case SEC_CHAN_DOMAIN: 132 case SEC_CHAN_BDC: 133 case SEC_CHAN_RODC: 134 break; 135 default: 136 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 137 r->in.secure_channel_type)); 138 return NT_STATUS_INVALID_PARAMETER; 139 } 140 141 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 142 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 133 143 if (sam_ctx == NULL) { 134 144 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 150 160 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, 151 161 trust_dom_attrs, 152 "(&(trustPartner=%s)(objectclass=trustedDomain))", 162 "(&(trustPartner=%s)(objectclass=trustedDomain))", 153 163 encoded_account); 154 164 155 165 if (num_records == 0) { 156 DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 166 DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 157 167 encoded_account)); 158 return NT_STATUS_ ACCESS_DENIED;159 } 160 168 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 169 } 170 161 171 if (num_records > 1) { 162 172 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name)); 163 173 return NT_STATUS_INTERNAL_DB_CORRUPTION; 164 174 } 165 175 166 176 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL); 167 177 if (!flatname) { 168 178 /* No flatname for this trust - we can't proceed */ 169 return NT_STATUS_ ACCESS_DENIED;179 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 170 180 } 171 181 account_name = talloc_asprintf(mem_ctx, "%s$", flatname); … … 174 184 return NT_STATUS_NO_MEMORY; 175 185 } 176 186 177 187 } else { 178 188 account_name = r->in.account_name; 179 189 } 180 190 181 191 /* pull the user attributes */ 182 192 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, 183 "(&(sAMAccountName=%s)(objectclass=user))", 193 "(&(sAMAccountName=%s)(objectclass=user))", 184 194 ldb_binary_encode_string(mem_ctx, account_name)); 185 195 186 196 if (num_records == 0) { 187 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 197 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 188 198 r->in.account_name)); 189 return NT_STATUS_ ACCESS_DENIED;199 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 190 200 } 191 201 … … 195 205 } 196 206 197 198 207 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0); 199 208 200 209 if (user_account_control & UF_ACCOUNTDISABLE) { 201 210 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name)); 202 return NT_STATUS_ ACCESS_DENIED;211 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 203 212 } 204 213 … … 206 215 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) { 207 216 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control)); 208 return NT_STATUS_ ACCESS_DENIED;209 } 210 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 217 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 218 } 219 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 211 220 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { 212 221 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { 213 222 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control)); 214 215 return NT_STATUS_ ACCESS_DENIED;223 224 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 216 225 } 217 226 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) { 218 227 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) { 219 228 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control)); 220 return NT_STATUS_ACCESS_DENIED; 229 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 230 } 231 } else if (r->in.secure_channel_type == SEC_CHAN_RODC) { 232 if (!(user_account_control & UF_PARTIAL_SECRETS_ACCOUNT)) { 233 DEBUG(1, ("Client asked for a RODC secure channel, but is not a RODC: acb flags: 0x%x\n", user_account_control)); 234 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 221 235 } 222 236 } else { 223 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 224 r->in.secure_channel_type)); 225 return NT_STATUS_ACCESS_DENIED; 226 } 227 228 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 237 /* we should never reach this */ 238 return NT_STATUS_INTERNAL_ERROR; 239 } 240 241 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 229 242 "objectSid", 0); 230 243 … … 234 247 } 235 248 236 creds = netlogon_creds_server_init(mem_ctx, 249 if (!pipe_state) { 250 DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); 251 return NT_STATUS_ACCESS_DENIED; 252 } 253 254 creds = netlogon_creds_server_init(mem_ctx, 237 255 r->in.account_name, 238 256 r->in.computer_name, 239 257 r->in.secure_channel_type, 240 &pipe_state->client_challenge, 241 &pipe_state->server_challenge, 258 &pipe_state->client_challenge, 259 &pipe_state->server_challenge, 242 260 mach_pwd, 243 261 r->in.credentials, 244 262 r->out.return_credentials, 245 263 *r->in.negotiate_flags); 246 264 247 265 if (!creds) { 248 266 return NT_STATUS_ACCESS_DENIED; … … 251 269 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid"); 252 270 253 schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); 254 if (!schannel_ldb) { 255 return NT_STATUS_ACCESS_DENIED; 256 } 257 258 nt_status = schannel_store_session_key_ldb(schannel_ldb, mem_ctx, creds); 259 talloc_free(schannel_ldb); 271 nt_status = schannel_save_creds_state(mem_ctx, 272 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx), 273 creds); 260 274 261 275 return nt_status; 262 276 } 263 277 264 278 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 265 279 struct netr_ServerAuthenticate *r) … … 267 281 struct netr_ServerAuthenticate3 a; 268 282 uint32_t rid; 269 /* TODO: 283 /* TODO: 270 284 * negotiate_flags is used as an [in] parameter 271 285 * so it need to be initialised. … … 305 319 r3.out.negotiate_flags = r->out.negotiate_flags; 306 320 r3.out.rid = &rid; 307 321 308 322 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3); 309 323 } 310 324 311 325 /* 312 Validate an incoming authenticator against the credentials for the remote machine. 313 314 The credentials are (re)read and from the schannel database, and 315 written back after the caclulations are performed. 316 317 The creds_out parameter (if not NULL) returns the credentials, if 318 the caller needs some of that information. 319 320 */ 326 * NOTE: The following functions are nearly identical to the ones available in 327 * source3/rpc_server/srv_nelog_nt.c 328 * The reason we keep 2 copies is that they use different structures to 329 * represent the auth_info and the decrpc pipes. 330 */ 331 332 /* 333 * If schannel is required for this call test that it actually is available. 334 */ 335 static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info, 336 const char *computer_name, 337 bool integrity, bool privacy) 338 { 339 340 if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { 341 if (!privacy && !integrity) { 342 return NT_STATUS_OK; 343 } 344 345 if ((!privacy && integrity) && 346 auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { 347 return NT_STATUS_OK; 348 } 349 350 if ((privacy || integrity) && 351 auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { 352 return NT_STATUS_OK; 353 } 354 } 355 356 /* test didn't pass */ 357 DEBUG(0, ("schannel_check_required: [%s] is not using schannel\n", 358 computer_name)); 359 360 return NT_STATUS_ACCESS_DENIED; 361 } 362 321 363 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call, 322 TALLOC_CTX *mem_ctx, 364 TALLOC_CTX *mem_ctx, 323 365 const char *computer_name, 324 366 struct netr_Authenticator *received_authenticator, 325 367 struct netr_Authenticator *return_authenticator, 326 struct netlogon_creds_CredentialState **creds_out) 368 struct netlogon_creds_CredentialState **creds_out) 327 369 { 328 370 NTSTATUS nt_status; 329 struct ldb_context *ldb;330 bool schannel_global_required = false; /* Should be lp _schannel_server() == true */331 bool schannel_in_use = dce_call->conn->auth_state.auth_info 332 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL333 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY334 || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);335 336 ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);337 if (!ldb) {338 return NT_STATUS_ACCESS_DENIED;339 } 340 nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx, 341 computer_name,342 schannel_global_required,343 schannel_in_use,344 345 return_authenticator, creds_out);346 talloc_free(ldb);371 struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; 372 bool schannel_global_required = false; /* Should be lpcfg_schannel_server() == true */ 373 374 if (schannel_global_required) { 375 nt_status = schannel_check_required(auth_info, 376 computer_name, 377 true, false); 378 if (!NT_STATUS_IS_OK(nt_status)) { 379 return nt_status; 380 } 381 } 382 383 nt_status = schannel_check_creds_state(mem_ctx, 384 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx), 385 computer_name, 386 received_authenticator, 387 return_authenticator, 388 creds_out); 347 389 return nt_status; 348 390 } 349 391 350 /* 392 /* 351 393 Change the machine account password for the currently connected 352 394 client. Supplies only the NT#. … … 358 400 struct netlogon_creds_CredentialState *creds; 359 401 struct ldb_context *sam_ctx; 402 const char * const attrs[] = { "unicodePwd", NULL }; 403 struct ldb_message **res; 404 struct samr_Password *oldNtHash; 360 405 NTSTATUS nt_status; 406 int ret; 361 407 362 408 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 363 mem_ctx, 364 r->in.computer_name, 409 mem_ctx, 410 r->in.computer_name, 365 411 r->in.credential, r->out.return_authenticator, 366 412 &creds); 367 413 NT_STATUS_NOT_OK_RETURN(nt_status); 368 414 369 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session( mem_ctx, dce_call->conn->dce_ctx->lp_ctx));415 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 370 416 if (sam_ctx == NULL) { 371 417 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 374 420 netlogon_creds_des_decrypt(creds, r->in.new_password); 375 421 422 /* fetch the old password hashes (the NT hash has to exist) */ 423 424 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, 425 "(&(objectClass=user)(objectSid=%s))", 426 ldap_encode_ndr_dom_sid(mem_ctx, creds->sid)); 427 if (ret != 1) { 428 return NT_STATUS_WRONG_PASSWORD; 429 } 430 431 nt_status = samdb_result_passwords(mem_ctx, 432 dce_call->conn->dce_ctx->lp_ctx, 433 res[0], NULL, &oldNtHash); 434 if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) { 435 return NT_STATUS_WRONG_PASSWORD; 436 } 437 376 438 /* Using the sid for the account as the key, set the password */ 377 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 439 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 378 440 creds->sid, 379 441 NULL, /* Don't have plaintext */ 380 442 NULL, r->in.new_password, 381 true, /* Password change */443 NULL, oldNtHash, /* Password change */ 382 444 NULL, NULL); 383 445 return nt_status; 384 446 } 385 447 386 /* 448 /* 387 449 Change the machine account password for the currently connected 388 450 client. Supplies new plaintext. … … 393 455 struct netlogon_creds_CredentialState *creds; 394 456 struct ldb_context *sam_ctx; 457 const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL }; 458 struct ldb_message **res; 459 struct samr_Password *oldLmHash, *oldNtHash; 395 460 NTSTATUS nt_status; 396 461 DATA_BLOB new_password; 462 int ret; 397 463 398 464 struct samr_CryptPassword password_buf; 399 465 400 466 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 401 mem_ctx, 402 r->in.computer_name, 467 mem_ctx, 468 r->in.computer_name, 403 469 r->in.credential, r->out.return_authenticator, 404 470 &creds); 405 471 NT_STATUS_NOT_OK_RETURN(nt_status); 406 472 407 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session( mem_ctx, dce_call->conn->dce_ctx->lp_ctx));473 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 408 474 if (sam_ctx == NULL) { 409 475 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 418 484 return NT_STATUS_WRONG_PASSWORD; 419 485 } 420 486 487 /* fetch the old password hashes (at least one of both has to exist) */ 488 489 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, 490 "(&(objectClass=user)(objectSid=%s))", 491 ldap_encode_ndr_dom_sid(mem_ctx, creds->sid)); 492 if (ret != 1) { 493 return NT_STATUS_WRONG_PASSWORD; 494 } 495 496 nt_status = samdb_result_passwords(mem_ctx, 497 dce_call->conn->dce_ctx->lp_ctx, 498 res[0], &oldLmHash, &oldNtHash); 499 if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) { 500 return NT_STATUS_WRONG_PASSWORD; 501 } 502 421 503 /* Using the sid for the account as the key, set the password */ 422 504 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, … … 424 506 &new_password, /* we have plaintext */ 425 507 NULL, NULL, 426 true, /* Password change */508 oldLmHash, oldNtHash, /* Password change */ 427 509 NULL, NULL); 428 510 return nt_status; … … 430 512 431 513 432 /* 433 netr_LogonUasLogon 514 /* 515 netr_LogonUasLogon 434 516 */ 435 517 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 440 522 441 523 442 /* 443 netr_LogonUasLogoff 524 /* 525 netr_LogonUasLogoff 444 526 */ 445 527 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 450 532 451 533 452 /* 534 static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r) 535 { 536 switch (r->in.logon_level) { 537 case NetlogonInteractiveInformation: 538 case NetlogonServiceInformation: 539 case NetlogonInteractiveTransitiveInformation: 540 case NetlogonServiceTransitiveInformation: 541 if (r->in.logon->password == NULL) { 542 return NT_STATUS_INVALID_PARAMETER; 543 } 544 545 switch (r->in.validation_level) { 546 case NetlogonValidationSamInfo: /* 2 */ 547 case NetlogonValidationSamInfo2: /* 3 */ 548 case NetlogonValidationSamInfo4: /* 6 */ 549 break; 550 default: 551 return NT_STATUS_INVALID_INFO_CLASS; 552 } 553 554 break; 555 case NetlogonNetworkInformation: 556 case NetlogonNetworkTransitiveInformation: 557 if (r->in.logon->network == NULL) { 558 return NT_STATUS_INVALID_PARAMETER; 559 } 560 561 switch (r->in.validation_level) { 562 case NetlogonValidationSamInfo: /* 2 */ 563 case NetlogonValidationSamInfo2: /* 3 */ 564 case NetlogonValidationSamInfo4: /* 6 */ 565 break; 566 default: 567 return NT_STATUS_INVALID_INFO_CLASS; 568 } 569 570 break; 571 572 case NetlogonGenericInformation: 573 if (r->in.logon->generic == NULL) { 574 return NT_STATUS_INVALID_PARAMETER; 575 } 576 577 switch (r->in.validation_level) { 578 /* TODO: case NetlogonValidationGenericInfo: 4 */ 579 case NetlogonValidationGenericInfo2: /* 5 */ 580 break; 581 default: 582 return NT_STATUS_INVALID_INFO_CLASS; 583 } 584 585 break; 586 default: 587 return NT_STATUS_INVALID_PARAMETER; 588 } 589 590 return NT_STATUS_OK; 591 } 592 593 /* 453 594 netr_LogonSamLogon_base 454 595 … … 462 603 struct auth_context *auth_context; 463 604 struct auth_usersupplied_info *user_info; 464 struct auth_ serversupplied_info *server_info;605 struct auth_user_info_dc *user_info_dc; 465 606 NTSTATUS nt_status; 466 607 static const char zeros[16]; … … 469 610 struct netr_SamInfo3 *sam3; 470 611 struct netr_SamInfo6 *sam6; 471 472 user_info = talloc(mem_ctx, struct auth_usersupplied_info); 612 613 *r->out.authoritative = 1; 614 615 user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info); 473 616 NT_STATUS_HAVE_NO_MEMORY(user_info); 474 475 user_info->flags = 0;476 user_info->mapped_state = false;477 user_info->remote_host = NULL;478 617 479 618 switch (r->in.logon_level) { … … 483 622 case NetlogonServiceTransitiveInformation: 484 623 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 485 netlogon_creds_arcfour_crypt(creds, 624 netlogon_creds_arcfour_crypt(creds, 486 625 r->in.logon->password->lmpassword.hash, 487 626 sizeof(r->in.logon->password->lmpassword.hash)); 488 netlogon_creds_arcfour_crypt(creds, 627 netlogon_creds_arcfour_crypt(creds, 489 628 r->in.logon->password->ntpassword.hash, 490 629 sizeof(r->in.logon->password->ntpassword.hash)); … … 495 634 496 635 /* TODO: we need to deny anonymous access here */ 497 nt_status = auth_context_create(mem_ctx, 636 nt_status = auth_context_create(mem_ctx, 498 637 dce_call->event_ctx, dce_call->msg_ctx, 499 638 dce_call->conn->dce_ctx->lp_ctx, … … 505 644 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string; 506 645 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string; 507 646 508 647 user_info->flags |= USER_INFO_INTERACTIVE_LOGON; 509 648 user_info->password_state = AUTH_PASSWORD_HASH; … … 522 661 523 662 /* TODO: we need to deny anonymous access here */ 524 nt_status = auth_context_create(mem_ctx, 663 nt_status = auth_context_create(mem_ctx, 525 664 dce_call->event_ctx, dce_call->msg_ctx, 526 665 dce_call->conn->dce_ctx->lp_ctx, … … 535 674 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string; 536 675 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string; 537 676 538 677 user_info->password_state = AUTH_PASSWORD_RESPONSE; 539 678 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length); 540 679 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length); 541 680 542 681 break; 543 682 544 683 545 684 case NetlogonGenericInformation: 546 685 { 547 686 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 548 netlogon_creds_arcfour_crypt(creds, 687 netlogon_creds_arcfour_crypt(creds, 549 688 r->in.logon->generic->data, r->in.logon->generic->length); 550 689 } else { … … 555 694 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) { 556 695 NTSTATUS status; 557 struct server_id *kdc;696 struct dcerpc_binding_handle *irpc_handle; 558 697 struct kdc_check_generic_kerberos check; 559 698 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2); 560 699 NT_STATUS_HAVE_NO_MEMORY(generic); 561 700 *r->out.authoritative = 1; 562 701 563 702 /* TODO: Describe and deal with these flags */ 564 703 *r->out.flags = 0; 565 704 566 705 r->out.validation->generic = generic; 567 568 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server"); 569 if ((kdc == NULL) || (kdc[0].id == 0)) { 706 707 irpc_handle = irpc_binding_handle_by_name(mem_ctx, 708 dce_call->msg_ctx, 709 "kdc_server", 710 &ndr_table_irpc); 711 if (irpc_handle == NULL) { 570 712 return NT_STATUS_NO_LOGON_SERVERS; 571 713 } 572 573 check.in.generic_request = 714 715 check.in.generic_request = 574 716 data_blob_const(r->in.logon->generic->data, 575 717 r->in.logon->generic->length); 576 577 status = irpc_call(dce_call->msg_ctx, kdc[0],578 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,579 &check, mem_ctx);718 719 status = dcerpc_kdc_check_generic_kerberos_r(irpc_handle, 720 mem_ctx, 721 &check); 580 722 if (!NT_STATUS_IS_OK(status)) { 581 723 return status; … … 592 734 return NT_STATUS_INVALID_PARAMETER; 593 735 } 594 595 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info); 736 737 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc); 738 /* TODO: set *r->out.authoritative = 0 on specific errors */ 596 739 NT_STATUS_NOT_OK_RETURN(nt_status); 597 740 598 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam); 599 NT_STATUS_NOT_OK_RETURN(nt_status); 741 switch (r->in.validation_level) { 742 case 2: 743 nt_status = auth_convert_user_info_dc_sambaseinfo(mem_ctx, user_info_dc, &sam); 744 NT_STATUS_NOT_OK_RETURN(nt_status); 745 746 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2); 747 NT_STATUS_HAVE_NO_MEMORY(sam2); 748 sam2->base = *sam; 749 750 /* And put into the talloc tree */ 751 talloc_steal(sam2, sam); 752 r->out.validation->sam2 = sam2; 753 754 sam = &sam2->base; 755 break; 756 757 case 3: 758 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, 759 user_info_dc, 760 &sam3); 761 NT_STATUS_NOT_OK_RETURN(nt_status); 762 763 r->out.validation->sam3 = sam3; 764 765 sam = &sam3->base; 766 break; 767 768 case 6: 769 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, 770 user_info_dc, 771 &sam3); 772 NT_STATUS_NOT_OK_RETURN(nt_status); 773 774 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6); 775 NT_STATUS_HAVE_NO_MEMORY(sam6); 776 sam6->base = sam3->base; 777 sam = &sam6->base; 778 sam6->sidcount = sam3->sidcount; 779 sam6->sids = sam3->sids; 780 781 sam6->dns_domainname.string = lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); 782 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", 783 sam->account_name.string, sam6->dns_domainname.string); 784 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string); 785 /* And put into the talloc tree */ 786 talloc_steal(sam6, sam3); 787 788 r->out.validation->sam6 = sam6; 789 break; 790 791 default: 792 return NT_STATUS_INVALID_INFO_CLASS; 793 } 600 794 601 795 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ … … 605 799 /* This key is sent unencrypted without the ARCFOUR flag set */ 606 800 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 607 netlogon_creds_arcfour_crypt(creds, 608 sam->key.key, 801 netlogon_creds_arcfour_crypt(creds, 802 sam->key.key, 609 803 sizeof(sam->key.key)); 610 804 } … … 616 810 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) { 617 811 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 618 netlogon_creds_arcfour_crypt(creds, 619 sam->LMSessKey.key, 812 netlogon_creds_arcfour_crypt(creds, 813 sam->LMSessKey.key, 620 814 sizeof(sam->LMSessKey.key)); 621 815 } else { 622 netlogon_creds_des_encrypt_LMKey(creds, 816 netlogon_creds_des_encrypt_LMKey(creds, 623 817 &sam->LMSessKey); 624 818 } 625 819 } 626 627 switch (r->in.validation_level) {628 case 2:629 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);630 NT_STATUS_HAVE_NO_MEMORY(sam2);631 sam2->base = *sam;632 r->out.validation->sam2 = sam2;633 break;634 635 case 3:636 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);637 NT_STATUS_HAVE_NO_MEMORY(sam3);638 sam3->base = *sam;639 r->out.validation->sam3 = sam3;640 break;641 642 case 6:643 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);644 NT_STATUS_HAVE_NO_MEMORY(sam6);645 sam6->base = *sam;646 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);647 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",648 sam->account_name.string, sam6->forest.string);649 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);650 r->out.validation->sam6 = sam6;651 break;652 653 default:654 break;655 }656 657 *r->out.authoritative = 1;658 820 659 821 /* TODO: Describe and deal with these flags */ … … 664 826 665 827 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 666 struct netr_LogonSamLogonEx *r) 828 struct netr_LogonSamLogonEx *r) 667 829 { 668 830 NTSTATUS nt_status; 669 831 struct netlogon_creds_CredentialState *creds; 670 struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); 671 if (!ldb) { 672 return NT_STATUS_ACCESS_DENIED; 673 } 674 675 nt_status = schannel_fetch_session_key_ldb(ldb, mem_ctx, r->in.computer_name, &creds); 832 833 *r->out.authoritative = 1; 834 835 nt_status = dcesrv_netr_LogonSamLogon_check(r); 836 if (!NT_STATUS_IS_OK(nt_status)) { 837 return nt_status; 838 } 839 840 nt_status = schannel_get_creds_state(mem_ctx, 841 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx), 842 r->in.computer_name, &creds); 676 843 if (!NT_STATUS_IS_OK(nt_status)) { 677 844 return nt_status; … … 685 852 } 686 853 687 /* 854 /* 688 855 netr_LogonSamLogonWithFlags 689 856 … … 697 864 698 865 struct netr_Authenticator *return_authenticator; 699 700 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);701 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);702 703 nt_status = dcesrv_netr_creds_server_step_check(dce_call,704 mem_ctx,705 r->in.computer_name,706 r->in.credential, return_authenticator,707 &creds);708 NT_STATUS_NOT_OK_RETURN(nt_status);709 866 710 867 ZERO_STRUCT(r2); … … 720 877 r2.out.flags = r->out.flags; 721 878 879 *r->out.authoritative = 1; 880 881 nt_status = dcesrv_netr_LogonSamLogon_check(&r2); 882 if (!NT_STATUS_IS_OK(nt_status)) { 883 return nt_status; 884 } 885 886 return_authenticator = talloc(mem_ctx, struct netr_Authenticator); 887 NT_STATUS_HAVE_NO_MEMORY(return_authenticator); 888 889 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 890 mem_ctx, 891 r->in.computer_name, 892 r->in.credential, return_authenticator, 893 &creds); 894 NT_STATUS_NOT_OK_RETURN(nt_status); 895 722 896 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds); 723 897 … … 727 901 } 728 902 729 /* 903 /* 730 904 netr_LogonSamLogon 731 905 */ … … 759 933 760 934 761 /* 762 netr_LogonSamLogoff 935 /* 936 netr_LogonSamLogoff 763 937 */ 764 938 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 770 944 771 945 772 /* 773 netr_DatabaseDeltas 946 /* 947 netr_DatabaseDeltas 774 948 */ 775 949 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 780 954 781 955 782 /* 783 netr_DatabaseSync2 956 /* 957 netr_DatabaseSync2 784 958 */ 785 959 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 791 965 792 966 793 /* 794 netr_DatabaseSync 967 /* 968 netr_DatabaseSync 795 969 */ 796 970 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 818 992 819 993 820 /* 821 netr_AccountDeltas 994 /* 995 netr_AccountDeltas 822 996 */ 823 997 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 829 1003 830 1004 831 /* 832 netr_AccountSync 1005 /* 1006 netr_AccountSync 833 1007 */ 834 1008 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 840 1014 841 1015 842 /* 843 netr_GetDcName 1016 /* 1017 netr_GetDcName 844 1018 */ 845 1019 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 853 1027 const char *dcname; 854 1028 1029 /* 1030 * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says 1031 * that the domainname needs to be a valid netbios domain 1032 * name, if it is not NULL. 1033 */ 1034 if (r->in.domainname) { 1035 const char *dot = strchr(r->in.domainname, '.'); 1036 size_t len = strlen(r->in.domainname); 1037 1038 if (dot || len > 15) { 1039 return WERR_DCNOTFOUND; 1040 } 1041 1042 /* 1043 * TODO: Should we also varify that only valid 1044 * netbios name characters are used? 1045 */ 1046 } 1047 855 1048 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 856 1049 dce_call->conn->dce_ctx->lp_ctx, 857 dce_call->conn->auth_state.session_info );1050 dce_call->conn->auth_state.session_info, 0); 858 1051 if (sam_ctx == NULL) { 859 1052 return WERR_DS_UNAVAILABLE; … … 876 1069 */ 877 1070 dcname = talloc_asprintf(mem_ctx, "\\\\%s", 878 lp _netbios_name(dce_call->conn->dce_ctx->lp_ctx));1071 lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx)); 879 1072 W_ERROR_HAVE_NO_MEMORY(dcname); 880 1073 … … 884 1077 885 1078 886 /* 887 netr_LogonControl2Ex 1079 /* 1080 netr_LogonControl2Ex 888 1081 */ 889 1082 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 894 1087 895 1088 896 /* 897 netr_LogonControl 1089 /* 1090 netr_LogonControl 898 1091 */ 899 1092 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 923 1116 924 1117 925 /* 926 netr_LogonControl2 1118 /* 1119 netr_LogonControl2 927 1120 */ 928 1121 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 945 1138 } 946 1139 947 948 /* 949 netr_GetAnyDCName 1140 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx, 1141 struct ldb_context *sam_ctx, 1142 struct netr_DomainTrustList *trusts, 1143 uint32_t trust_flags); 1144 1145 /* 1146 netr_GetAnyDCName 950 1147 */ 951 1148 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 952 1149 struct netr_GetAnyDCName *r) 953 1150 { 954 struct netr_GetDcName r2; 1151 struct netr_DomainTrustList *trusts; 1152 struct ldb_context *sam_ctx; 1153 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1154 uint32_t i; 955 1155 WERROR werr; 956 1156 957 ZERO_STRUCT(r2); 958 959 r2.in.logon_server = r->in.logon_server; 960 r2.in.domainname = r->in.domainname; 961 r2.out.dcname = r->out.dcname; 962 963 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2); 964 965 return werr; 966 } 967 968 969 /* 970 netr_DatabaseRedo 1157 *r->out.dcname = NULL; 1158 1159 if ((r->in.domainname == NULL) || (r->in.domainname[0] == '\0')) { 1160 /* if the domainname parameter wasn't set assume our domain */ 1161 r->in.domainname = lpcfg_workgroup(lp_ctx); 1162 } 1163 1164 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1165 dce_call->conn->auth_state.session_info, 0); 1166 if (sam_ctx == NULL) { 1167 return WERR_DS_UNAVAILABLE; 1168 } 1169 1170 if (strcasecmp(r->in.domainname, lpcfg_workgroup(lp_ctx)) == 0) { 1171 /* well we asked for a DC of our own domain */ 1172 if (samdb_is_pdc(sam_ctx)) { 1173 /* we are the PDC of the specified domain */ 1174 return WERR_NO_SUCH_DOMAIN; 1175 } 1176 1177 *r->out.dcname = talloc_asprintf(mem_ctx, "\\%s", 1178 lpcfg_netbios_name(lp_ctx)); 1179 W_ERROR_HAVE_NO_MEMORY(*r->out.dcname); 1180 1181 return WERR_OK; 1182 } 1183 1184 /* Okay, now we have to consider the trusted domains */ 1185 1186 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList); 1187 W_ERROR_HAVE_NO_MEMORY(trusts); 1188 1189 trusts->count = 0; 1190 1191 werr = fill_trusted_domains_array(mem_ctx, sam_ctx, trusts, 1192 NETR_TRUST_FLAG_INBOUND 1193 | NETR_TRUST_FLAG_OUTBOUND); 1194 W_ERROR_NOT_OK_RETURN(werr); 1195 1196 for (i = 0; i < trusts->count; i++) { 1197 if (strcasecmp(r->in.domainname, trusts->array[i].netbios_name) == 0) { 1198 /* FIXME: Here we need to find a DC for the specified 1199 * trusted domain. */ 1200 1201 /* return WERR_OK; */ 1202 return WERR_NO_SUCH_DOMAIN; 1203 } 1204 } 1205 1206 return WERR_NO_SUCH_DOMAIN; 1207 } 1208 1209 1210 /* 1211 netr_DatabaseRedo 971 1212 */ 972 1213 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 977 1218 978 1219 979 /* 980 netr_NetrEnumerateT urstedDomains981 */ 982 static WERRORdcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1220 /* 1221 netr_NetrEnumerateTrustedDomains 1222 */ 1223 static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 983 1224 struct netr_NetrEnumerateTrustedDomains *r) 984 1225 { … … 987 1228 988 1229 989 /* 1230 /* 990 1231 netr_LogonGetCapabilities 991 1232 */ … … 998 1239 999 1240 1000 /* 1001 netr_NETRLOGONSETSERVICEBITS 1241 /* 1242 netr_NETRLOGONSETSERVICEBITS 1002 1243 */ 1003 1244 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1018 1259 1019 1260 1020 /* 1021 netr_NETRLOGONCOMPUTESERVERDIGEST 1261 /* 1262 netr_NETRLOGONCOMPUTESERVERDIGEST 1022 1263 */ 1023 1264 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1028 1269 1029 1270 1030 /* 1031 netr_NETRLOGONCOMPUTECLIENTDIGEST 1271 /* 1272 netr_NETRLOGONCOMPUTECLIENTDIGEST 1032 1273 */ 1033 1274 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1039 1280 1040 1281 1041 /* 1282 /* 1042 1283 netr_DsRGetSiteName 1043 1284 */ … … 1045 1286 struct netr_DsRGetSiteName *r) 1046 1287 { 1047 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1288 struct ldb_context *sam_ctx; 1289 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1290 1291 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1292 dce_call->conn->auth_state.session_info, 0); 1293 if (sam_ctx == NULL) { 1294 return WERR_DS_UNAVAILABLE; 1295 } 1296 1297 *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx); 1298 W_ERROR_HAVE_NO_MEMORY(*r->out.site); 1299 1300 return WERR_OK; 1048 1301 } 1049 1302 … … 1065 1318 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension); 1066 1319 info->trust_extension.length = 16; 1067 info->trust_extension.info->flags = 1320 info->trust_extension.info->flags = 1068 1321 NETR_TRUST_FLAG_TREEROOT | 1069 NETR_TRUST_FLAG_IN_FOREST | 1322 NETR_TRUST_FLAG_IN_FOREST | 1070 1323 NETR_TRUST_FLAG_PRIMARY | 1071 1324 NETR_TRUST_FLAG_NATIVE; … … 1081 1334 info->dns_forestname.string = NULL; 1082 1335 } else { 1083 char *p; 1084 /* TODO: we need a common function for pulling the forest */ 1085 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx)); 1086 if (!info->dns_forestname.string) { 1087 return NT_STATUS_NO_SUCH_DOMAIN; 1088 } 1089 p = strchr(info->dns_forestname.string, '/'); 1090 if (p) { 1091 *p = '\0'; 1092 } 1336 info->dns_forestname.string = samdb_forest_name(sam_ctx, mem_ctx); 1337 NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string); 1093 1338 info->dns_forestname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_forestname.string); 1094 1339 NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string); 1095 1340 } 1096 1341 1097 1342 if (is_local) { 1098 info->domainname.string = lp _sam_name(lp_ctx);1099 info->dns_domainname.string = lp _realm(lp_ctx);1343 info->domainname.string = lpcfg_workgroup(lp_ctx); 1344 info->dns_domainname.string = lpcfg_dnsdomain(lp_ctx); 1100 1345 info->domain_guid = samdb_result_guid(res, "objectGUID"); 1101 1346 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid"); 1102 1347 } else { 1103 info->domainname.string = samdb_result_string(res, "flatName", NULL);1104 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);1348 info->domainname.string = ldb_msg_find_attr_as_string(res, "flatName", NULL); 1349 info->dns_domainname.string = ldb_msg_find_attr_as_string(res, "trustPartner", NULL); 1105 1350 info->domain_guid = samdb_result_guid(res, "objectGUID"); 1106 1351 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier"); … … 1113 1358 } 1114 1359 1115 /* 1360 /* 1116 1361 netr_LogonGetDomainInfo 1117 1362 this is called as part of the ADS domain logon procedure. … … 1126 1371 const char * const attrs[] = { "objectSid", "objectGUID", "flatName", 1127 1372 "securityIdentifier", "trustPartner", NULL }; 1128 const char *temp_str; 1129 const char *old_dns_hostname; 1373 const char * const attrs2[] = { "sAMAccountName", "dNSHostName", 1374 "msDS-SupportedEncryptionTypes", NULL }; 1375 const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2; 1130 1376 struct ldb_context *sam_ctx; 1131 struct ldb_message **res1, **res2, * new_msg;1377 struct ldb_message **res1, **res2, **res3, *new_msg; 1132 1378 struct ldb_dn *workstation_dn; 1133 1379 struct netr_DomainInformation *domain_info; 1134 1380 struct netr_LsaPolicyInformation *lsa_policy_info; 1135 struct netr_OsVersionInfoEx *os_version;1136 1381 uint32_t default_supported_enc_types = 0xFFFFFFFF; 1137 int ret1, ret2, i; 1382 bool update_dns_hostname = true; 1383 int ret, ret3, i; 1138 1384 NTSTATUS status; 1139 1385 1140 1386 status = dcesrv_netr_creds_server_step_check(dce_call, 1141 mem_ctx, 1142 r->in.computer_name, 1143 r->in.credential, 1387 mem_ctx, 1388 r->in.computer_name, 1389 r->in.credential, 1144 1390 r->out.return_authenticator, 1145 1391 &creds); … … 1150 1396 1151 1397 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 1152 dce_call->conn->dce_ctx->lp_ctx,1153 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));1398 dce_call->conn->dce_ctx->lp_ctx, 1399 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 1154 1400 if (sam_ctx == NULL) { 1155 1401 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 1159 1405 case 1: /* Domain information */ 1160 1406 1161 /* TODO: check NTSTATUS results - and fail also on SAMDB 1162 * errors (needs some testing against Windows Server 2008) */ 1407 if (r->in.query->workstation_info == NULL) { 1408 return NT_STATUS_INVALID_PARAMETER; 1409 } 1410 1411 /* Prepares the workstation DN */ 1412 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", 1413 dom_sid_string(mem_ctx, creds->sid)); 1414 NT_STATUS_HAVE_NO_MEMORY(workstation_dn); 1415 1416 /* Lookup for attributes in workstation object */ 1417 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1, 1418 attrs2); 1419 if (ret != 1) { 1420 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1421 } 1422 1423 /* Gets the sam account name which is checked against the DNS 1424 * hostname parameter. */ 1425 sam_account_name = ldb_msg_find_attr_as_string(res1[0], 1426 "sAMAccountName", 1427 NULL); 1428 if (sam_account_name == NULL) { 1429 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1430 } 1163 1431 1164 1432 /* 1165 * Check that the computer name parameter matches as prefix with 1166 * the DNS hostname in the workstation info structure. 1433 * Checks that the sam account name without a possible "$" 1434 * matches as prefix with the DNS hostname in the workstation 1435 * info structure. 1167 1436 */ 1168 temp_str = strndup(r->in.query->workstation_info->dns_hostname, 1169 strcspn(r->in.query->workstation_info->dns_hostname, 1170 ".")); 1171 if (strcasecmp(r->in.computer_name, temp_str) != 0) 1172 return NT_STATUS_INVALID_PARAMETER; 1173 1174 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", 1175 dom_sid_string(mem_ctx, creds->sid)); 1176 NT_STATUS_HAVE_NO_MEMORY(workstation_dn); 1437 prefix1 = talloc_strndup(mem_ctx, sam_account_name, 1438 strcspn(sam_account_name, "$")); 1439 NT_STATUS_HAVE_NO_MEMORY(prefix1); 1440 if (r->in.query->workstation_info->dns_hostname != NULL) { 1441 prefix2 = talloc_strndup(mem_ctx, 1442 r->in.query->workstation_info->dns_hostname, 1443 strcspn(r->in.query->workstation_info->dns_hostname, ".")); 1444 NT_STATUS_HAVE_NO_MEMORY(prefix2); 1445 1446 if (strcasecmp(prefix1, prefix2) != 0) { 1447 update_dns_hostname = false; 1448 } 1449 } else { 1450 update_dns_hostname = false; 1451 } 1177 1452 1178 1453 /* Gets the old DNS hostname */ 1179 old_dns_hostname = samdb_search_string(sam_ctx, mem_ctx, 1180 workstation_dn, 1181 "dNSHostName", 1182 NULL); 1183 1184 /* Gets host informations and put them in our directory */ 1454 old_dns_hostname = ldb_msg_find_attr_as_string(res1[0], 1455 "dNSHostName", 1456 NULL); 1457 1458 /* 1459 * Updates the DNS hostname when the client wishes that the 1460 * server should handle this for him 1461 * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). And this is 1462 * obviously only checked when we do already have a 1463 * "dNSHostName". 1464 * See MS-NRPC section 3.5.4.3.9 1465 */ 1466 if ((old_dns_hostname != NULL) && 1467 (r->in.query->workstation_info->workstation_flags 1468 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) { 1469 update_dns_hostname = false; 1470 } 1471 1472 /* Gets host information and put them into our directory */ 1473 1185 1474 new_msg = ldb_msg_new(mem_ctx); 1186 1475 NT_STATUS_HAVE_NO_MEMORY(new_msg); … … 1188 1477 new_msg->dn = workstation_dn; 1189 1478 1190 /* Deletes old OS version values */1191 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,1192 "operatingSystemServicePack");1193 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,1194 "operatingSystemVersion");1195 1196 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {1197 DEBUG(3,("Impossible to update samdb: %s\n",1198 ldb_errstring(sam_ctx)));1199 }1200 1201 talloc_free(new_msg);1202 1203 new_msg = ldb_msg_new(mem_ctx);1204 NT_STATUS_HAVE_NO_MEMORY(new_msg);1205 1206 new_msg->dn = workstation_dn;1207 1208 1479 /* Sets the OS name */ 1209 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg, 1210 "operatingSystem",1211 r ->in.query->workstation_info->os_name.string);1212 1213 if (r->in.query->workstation_info->dns_hostname) { 1214 /* TODO: should this always be done? */1215 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,1216 "dNSHostname",1217 r->in.query->workstation_info->dns_hostname);1480 1481 if (r->in.query->workstation_info->os_name.string == NULL) { 1482 return NT_STATUS_INVALID_PARAMETER; 1483 } 1484 1485 ret = ldb_msg_add_string(new_msg, "operatingSystem", 1486 r->in.query->workstation_info->os_name.string); 1487 if (ret != LDB_SUCCESS) { 1488 return NT_STATUS_NO_MEMORY; 1218 1489 } 1219 1490 1220 1491 /* 1221 * Sets information s from "os_version". On aempty structure1492 * Sets information from "os_version". On an empty structure 1222 1493 * the values are cleared. 1223 1494 */ 1224 1495 if (r->in.query->workstation_info->os_version.os != NULL) { 1496 struct netr_OsVersionInfoEx *os_version; 1497 const char *os_version_str; 1498 1225 1499 os_version = &r->in.query->workstation_info->os_version.os->os; 1226 1500 1227 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg, 1228 "operatingSystemServicePack", 1229 os_version->CSDVersion); 1230 1231 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg, 1232 "operatingSystemVersion", 1233 talloc_asprintf(mem_ctx, "%d.%d (%d)", 1234 os_version->MajorVersion, 1235 os_version->MinorVersion, 1236 os_version->BuildNumber 1237 ) 1238 ); 1501 if (os_version->CSDVersion == NULL) { 1502 return NT_STATUS_INVALID_PARAMETER; 1503 } 1504 1505 os_version_str = talloc_asprintf(new_msg, "%u.%u (%u)", 1506 os_version->MajorVersion, 1507 os_version->MinorVersion, 1508 os_version->BuildNumber); 1509 NT_STATUS_HAVE_NO_MEMORY(os_version_str); 1510 1511 ret = ldb_msg_add_string(new_msg, 1512 "operatingSystemServicePack", 1513 os_version->CSDVersion); 1514 if (ret != LDB_SUCCESS) { 1515 return NT_STATUS_NO_MEMORY; 1516 } 1517 1518 ret = ldb_msg_add_string(new_msg, 1519 "operatingSystemVersion", 1520 os_version_str); 1521 if (ret != LDB_SUCCESS) { 1522 return NT_STATUS_NO_MEMORY; 1523 } 1524 } else { 1525 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg, 1526 "operatingSystemServicePack"); 1527 if (ret != LDB_SUCCESS) { 1528 return NT_STATUS_NO_MEMORY; 1529 } 1530 1531 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg, 1532 "operatingSystemVersion"); 1533 if (ret != LDB_SUCCESS) { 1534 return NT_STATUS_NO_MEMORY; 1535 } 1239 1536 } 1240 1537 1241 1538 /* 1242 * Updates the "dNSHostname" and the "servicePrincipalName"s 1243 * since the client wishes that the server should handle this 1244 * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). 1245 * See MS-NRPC section 3.5.4.3.9 1539 * If the boolean "update_dns_hostname" remained true, then we 1540 * are fine to start the update. 1246 1541 */ 1247 if ((r->in.query->workstation_info->workstation_flags 1248 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) { 1249 1250 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg, 1251 "servicePrincipalName", 1252 talloc_asprintf(mem_ctx, "HOST/%s", 1253 r->in.computer_name) 1254 ); 1255 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg, 1256 "servicePrincipalName", 1257 talloc_asprintf(mem_ctx, "HOST/%s", 1258 r->in.query->workstation_info->dns_hostname) 1259 ); 1260 } 1261 1262 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) { 1542 if (update_dns_hostname) { 1543 ret = ldb_msg_add_string(new_msg, 1544 "dNSHostname", 1545 r->in.query->workstation_info->dns_hostname); 1546 if (ret != LDB_SUCCESS) { 1547 return NT_STATUS_NO_MEMORY; 1548 } 1549 1550 /* This manual "servicePrincipalName" generation is 1551 * still needed! Since the update in the samldb LDB 1552 * module does only work if the entries already exist 1553 * which isn't always the case. */ 1554 ret = ldb_msg_add_string(new_msg, 1555 "servicePrincipalName", 1556 talloc_asprintf(new_msg, "HOST/%s", 1557 r->in.computer_name)); 1558 if (ret != LDB_SUCCESS) { 1559 return NT_STATUS_NO_MEMORY; 1560 } 1561 1562 ret = ldb_msg_add_string(new_msg, 1563 "servicePrincipalName", 1564 talloc_asprintf(new_msg, "HOST/%s", 1565 r->in.query->workstation_info->dns_hostname)); 1566 if (ret != LDB_SUCCESS) { 1567 return NT_STATUS_NO_MEMORY; 1568 } 1569 } 1570 1571 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) { 1263 1572 DEBUG(3,("Impossible to update samdb: %s\n", 1264 1573 ldb_errstring(sam_ctx))); … … 1274 1583 put the primary domain into the lists of returned trusts as 1275 1584 well. */ 1276 ret 1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),1277 &res 1, attrs);1278 if (ret 1!= 1) {1585 ret = gendb_search_dn(sam_ctx, mem_ctx, ldb_get_default_basedn(sam_ctx), 1586 &res2, attrs); 1587 if (ret != 1) { 1279 1588 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1280 1589 } 1281 1590 1282 ret 2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs,1591 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs, 1283 1592 "(objectClass=trustedDomain)"); 1284 if (ret 2== -1) {1593 if (ret3 == -1) { 1285 1594 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1286 1595 } … … 1295 1604 status = fill_one_domain_info(mem_ctx, 1296 1605 dce_call->conn->dce_ctx->lp_ctx, 1297 sam_ctx, res 1[0], &domain_info->primary_domain,1606 sam_ctx, res2[0], &domain_info->primary_domain, 1298 1607 true, false); 1299 1608 NT_STATUS_NOT_OK_RETURN(status); 1300 1609 1301 domain_info->trusted_domain_count = ret 2+ 1;1610 domain_info->trusted_domain_count = ret3 + 1; 1302 1611 domain_info->trusted_domains = talloc_array(mem_ctx, 1303 1612 struct netr_OneDomainInfo, … … 1305 1614 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains); 1306 1615 1307 for (i=0;i<ret 2;i++) {1616 for (i=0;i<ret3;i++) { 1308 1617 status = fill_one_domain_info(mem_ctx, 1309 1618 dce_call->conn->dce_ctx->lp_ctx, 1310 sam_ctx, res 2[i],1619 sam_ctx, res3[i], 1311 1620 &domain_info->trusted_domains[i], 1312 1621 false, true); … … 1315 1624 1316 1625 status = fill_one_domain_info(mem_ctx, 1317 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res 1[0],1626 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0], 1318 1627 &domain_info->trusted_domains[i], true, true); 1319 1628 NT_STATUS_NOT_OK_RETURN(status); 1320 1629 1321 1630 /* Sets the supported encryption types */ 1322 domain_info->supported_enc_types = samdb_search_uint( 1323 sam_ctx, mem_ctx, 1324 default_supported_enc_types, workstation_dn, 1325 "msDS-SupportedEncryptionTypes", NULL); 1326 1327 /* Other host domain informations */ 1631 domain_info->supported_enc_types = ldb_msg_find_attr_as_uint(res1[0], 1632 "msDS-SupportedEncryptionTypes", 1633 default_supported_enc_types); 1634 1635 /* Other host domain information */ 1328 1636 1329 1637 lsa_policy_info = talloc(mem_ctx, … … 1334 1642 domain_info->lsa_policy = *lsa_policy_info; 1335 1643 1336 domain_info->dns_hostname.string = old_dns_hostname; 1644 /* The DNS hostname is only returned back when there is a chance 1645 * for a change. */ 1646 if ((r->in.query->workstation_info->workstation_flags 1647 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) { 1648 domain_info->dns_hostname.string = old_dns_hostname; 1649 } else { 1650 domain_info->dns_hostname.string = NULL; 1651 } 1652 1337 1653 domain_info->workstation_flags = 1338 1654 r->in.query->workstation_info->workstation_flags; … … 1357 1673 1358 1674 1359 1360 1675 /* 1361 1676 netr_ServerPasswordGet … … 1368 1683 1369 1684 1370 /* 1371 netr_NETRLOGONSENDTOSAM 1685 /* 1686 netr_NETRLOGONSENDTOSAM 1372 1687 */ 1373 1688 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1378 1693 1379 1694 1380 /* 1381 netr_DsRAddressToSitenamesW 1382 */ 1383 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1384 struct netr_DsRAddressToSitenamesW *r) 1385 { 1386 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1387 } 1388 1389 1390 /* 1695 /* 1391 1696 netr_DsRGetDCNameEx2 1392 1697 */ 1393 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1394 struct netr_DsRGetDCNameEx2 *r)1395 { 1396 const char * const attrs[] = { "objectGUID", NULL }; 1698 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, 1699 TALLOC_CTX *mem_ctx, 1700 struct netr_DsRGetDCNameEx2 *r) 1701 { 1397 1702 struct ldb_context *sam_ctx; 1398 struct ldb_message **res;1399 struct ldb_dn *domain_dn;1400 int ret;1401 1703 struct netr_DsRGetDCNameInfo *info; 1704 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1705 const struct tsocket_address *remote_address; 1706 char *addr = NULL; 1707 const char *server_site_name; 1708 char *guid_str; 1709 struct netlogon_samlogon_response response; 1710 NTSTATUS status; 1711 const char *dc_name = NULL; 1712 const char *domain_name = NULL; 1402 1713 1403 1714 ZERO_STRUCTP(r->out.info); 1404 1715 1405 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 1716 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1717 dce_call->conn->auth_state.session_info, 0); 1406 1718 if (sam_ctx == NULL) { 1407 1719 return WERR_DS_UNAVAILABLE; 1408 1720 } 1409 1721 1410 /* Win7-beta will send the domain name in the form the user typed, so we have to cope 1411 with both the short and long form here */ 1412 if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx, 1413 r->in.domain_name)) { 1722 remote_address = dcesrv_connection_get_remote_address(dce_call->conn); 1723 if (tsocket_address_is_inet(remote_address, "ip")) { 1724 addr = tsocket_address_inet_addr_string(remote_address, mem_ctx); 1725 W_ERROR_HAVE_NO_MEMORY(addr); 1726 } 1727 1728 /* "server_unc" is ignored by w2k3 */ 1729 1730 if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) { 1731 return WERR_INVALID_FLAGS; 1732 } 1733 1734 if (r->in.flags & DS_GC_SERVER_REQUIRED && 1735 r->in.flags & DS_PDC_REQUIRED && 1736 r->in.flags & DS_KDC_REQUIRED) { 1737 return WERR_INVALID_FLAGS; 1738 } 1739 if (r->in.flags & DS_IS_FLAT_NAME && 1740 r->in.flags & DS_IS_DNS_NAME) { 1741 return WERR_INVALID_FLAGS; 1742 } 1743 if (r->in.flags & DS_RETURN_DNS_NAME && 1744 r->in.flags & DS_RETURN_FLAT_NAME) { 1745 return WERR_INVALID_FLAGS; 1746 } 1747 if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED && 1748 r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) { 1749 return WERR_INVALID_FLAGS; 1750 } 1751 1752 if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED && 1753 r->in.flags & 1754 (DS_DIRECTORY_SERVICE_REQUIRED | 1755 DS_DIRECTORY_SERVICE_PREFERRED | 1756 DS_GC_SERVER_REQUIRED | 1757 DS_PDC_REQUIRED | 1758 DS_KDC_REQUIRED)) { 1759 return WERR_INVALID_FLAGS; 1760 } 1761 1762 if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE && 1763 r->in.site_name) { 1764 return WERR_INVALID_FLAGS; 1765 } 1766 1767 /* Proof server site parameter "site_name" if it was specified */ 1768 server_site_name = samdb_server_site_name(sam_ctx, mem_ctx); 1769 W_ERROR_HAVE_NO_MEMORY(server_site_name); 1770 if ((r->in.site_name != NULL) && (strcasecmp(r->in.site_name, 1771 server_site_name) != 0)) { 1414 1772 return WERR_NO_SUCH_DOMAIN; 1415 1773 } 1416 1774 1417 domain_dn = ldb_get_default_basedn(sam_ctx); 1418 if (domain_dn == NULL) { 1419 return WERR_DS_UNAVAILABLE; 1420 } 1421 1422 ret = gendb_search_dn(sam_ctx, mem_ctx, 1423 domain_dn, &res, attrs); 1424 if (ret != 1) { 1775 guid_str = r->in.domain_guid != NULL ? 1776 GUID_string(mem_ctx, r->in.domain_guid) : NULL; 1777 1778 status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx, 1779 r->in.domain_name, 1780 r->in.domain_name, 1781 NULL, guid_str, 1782 r->in.client_account, 1783 r->in.mask, addr, 1784 NETLOGON_NT_VERSION_5EX_WITH_IP, 1785 lp_ctx, &response, true); 1786 if (!NT_STATUS_IS_OK(status)) { 1787 return ntstatus_to_werror(status); 1788 } 1789 1790 if (r->in.flags & DS_RETURN_DNS_NAME) { 1791 dc_name = response.data.nt5_ex.pdc_dns_name; 1792 domain_name = response.data.nt5_ex.dns_domain; 1793 } else if (r->in.flags & DS_RETURN_FLAT_NAME) { 1794 dc_name = response.data.nt5_ex.pdc_name; 1795 domain_name = response.data.nt5_ex.domain_name; 1796 } else { 1797 1798 /* 1799 * TODO: autodetect what we need to return 1800 * based on the given arguments 1801 */ 1802 dc_name = response.data.nt5_ex.pdc_name; 1803 domain_name = response.data.nt5_ex.domain_name; 1804 } 1805 1806 if (!dc_name || !dc_name[0]) { 1807 return WERR_NO_SUCH_DOMAIN; 1808 } 1809 1810 if (!domain_name || !domain_name[0]) { 1811 return WERR_NO_SUCH_DOMAIN; 1425 1812 } 1426 1813 1427 1814 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo); 1428 1815 W_ERROR_HAVE_NO_MEMORY(info); 1429 1430 /* TODO: - return real IP address 1431 * - check all r->in.* parameters (server_unc is ignored by w2k3!) 1432 */ 1433 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", 1434 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 1435 lp_realm(dce_call->conn->dce_ctx->lp_ctx)); 1816 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", dc_name); 1436 1817 W_ERROR_HAVE_NO_MEMORY(info->dc_unc); 1437 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0"); 1818 info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", 1819 response.data.nt5_ex.sockaddr.pdc_ip); 1438 1820 W_ERROR_HAVE_NO_MEMORY(info->dc_address); 1439 info->dc_address_type = DS_ADDRESS_TYPE_INET; 1440 info->domain_guid = samdb_result_guid(res[0], "objectGUID"); 1441 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 1442 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 1443 info->dc_flags = DS_DNS_FOREST | 1444 DS_DNS_DOMAIN | 1445 DS_DNS_CONTROLLER | 1446 DS_SERVER_WRITABLE | 1447 DS_SERVER_CLOSEST | 1448 DS_SERVER_TIMESERV | 1449 DS_SERVER_KDC | 1450 DS_SERVER_DS | 1451 DS_SERVER_LDAP | 1452 DS_SERVER_GC | 1453 DS_SERVER_PDC; 1454 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name"); 1455 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name); 1456 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name"); 1457 W_ERROR_HAVE_NO_MEMORY(info->client_site_name); 1821 info->dc_address_type = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */ 1822 info->domain_guid = response.data.nt5_ex.domain_uuid; 1823 info->domain_name = domain_name; 1824 info->forest_name = response.data.nt5_ex.forest; 1825 info->dc_flags = response.data.nt5_ex.server_type; 1826 info->dc_site_name = response.data.nt5_ex.server_site; 1827 info->client_site_name = response.data.nt5_ex.client_site; 1458 1828 1459 1829 *r->out.info = info; … … 1462 1832 } 1463 1833 1464 /* 1834 /* 1465 1835 netr_DsRGetDCNameEx 1466 1836 */ … … 1487 1857 } 1488 1858 1489 /* 1859 /* 1490 1860 netr_DsRGetDCName 1491 1861 */ … … 1503 1873 r2.in.domain_name = r->in.domain_name; 1504 1874 r2.in.domain_guid = r->in.domain_guid; 1505 1506 r2.in.site_name = NULL; /* should fill in fromsite GUID */1875 1876 r2.in.site_name = NULL; /* this is correct, we should ignore site GUID */ 1507 1877 r2.in.flags = r->in.flags; 1508 1878 r2.out.info = r->out.info; … … 1512 1882 return werr; 1513 1883 } 1514 /* 1515 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 1884 /* 1885 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 1516 1886 */ 1517 1887 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1532 1902 1533 1903 1534 /* 1535 netr_DsRAddressToSitenamesExW 1904 /* 1905 netr_DsRAddressToSitenamesExW 1536 1906 */ 1537 1907 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1538 1908 struct netr_DsRAddressToSitenamesExW *r) 1539 1909 { 1910 struct ldb_context *sam_ctx; 1540 1911 struct netr_DsRAddressToSitenamesExWCtr *ctr; 1541 int i; 1542 1543 /* we should map the provided IPs to site names, once we have 1544 * sites support 1545 */ 1912 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1913 sa_family_t sin_family; 1914 struct sockaddr_in *addr; 1915 #ifdef HAVE_IPV6 1916 struct sockaddr_in6 *addr6; 1917 char addr_str[INET6_ADDRSTRLEN]; 1918 #else 1919 char addr_str[INET_ADDRSTRLEN]; 1920 #endif 1921 char *subnet_name; 1922 const char *res; 1923 uint32_t i; 1924 1925 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1926 dce_call->conn->auth_state.session_info, 0); 1927 if (sam_ctx == NULL) { 1928 return WERR_DS_UNAVAILABLE; 1929 } 1930 1546 1931 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr); 1547 1932 W_ERROR_HAVE_NO_MEMORY(ctr); … … 1556 1941 1557 1942 for (i=0; i<ctr->count; i++) { 1558 ctr->sitename[i].string = "Default-First-Site-Name";1943 ctr->sitename[i].string = NULL; 1559 1944 ctr->subnetname[i].string = NULL; 1945 1946 if (r->in.addresses[i].size < sizeof(sa_family_t)) { 1947 continue; 1948 } 1949 /* The first two byte of the buffer are reserved for the 1950 * "sin_family" but for now only the first one is used. */ 1951 sin_family = r->in.addresses[i].buffer[0]; 1952 1953 switch (sin_family) { 1954 case AF_INET: 1955 if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) { 1956 continue; 1957 } 1958 addr = (struct sockaddr_in *) r->in.addresses[i].buffer; 1959 res = inet_ntop(AF_INET, &addr->sin_addr, 1960 addr_str, sizeof(addr_str)); 1961 break; 1962 #ifdef HAVE_IPV6 1963 case AF_INET6: 1964 if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) { 1965 continue; 1966 } 1967 addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer; 1968 res = inet_ntop(AF_INET6, &addr6->sin6_addr, 1969 addr_str, sizeof(addr_str)); 1970 break; 1971 #endif 1972 default: 1973 continue; 1974 } 1975 1976 if (res == NULL) { 1977 continue; 1978 } 1979 1980 ctr->sitename[i].string = samdb_client_site_name(sam_ctx, 1981 mem_ctx, 1982 addr_str, 1983 &subnet_name); 1984 W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string); 1985 ctr->subnetname[i].string = subnet_name; 1560 1986 } 1561 1987 … … 1564 1990 1565 1991 1566 /* 1992 /* 1993 netr_DsRAddressToSitenamesW 1994 */ 1995 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1996 struct netr_DsRAddressToSitenamesW *r) 1997 { 1998 struct netr_DsRAddressToSitenamesExW r2; 1999 struct netr_DsRAddressToSitenamesWCtr *ctr; 2000 uint32_t i; 2001 WERROR werr; 2002 2003 ZERO_STRUCT(r2); 2004 2005 r2.in.server_name = r->in.server_name; 2006 r2.in.count = r->in.count; 2007 r2.in.addresses = r->in.addresses; 2008 2009 r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *); 2010 W_ERROR_HAVE_NO_MEMORY(r2.out.ctr); 2011 2012 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr); 2013 W_ERROR_HAVE_NO_MEMORY(ctr); 2014 2015 *r->out.ctr = ctr; 2016 2017 ctr->count = r->in.count; 2018 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count); 2019 W_ERROR_HAVE_NO_MEMORY(ctr->sitename); 2020 2021 werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2); 2022 2023 for (i=0; i<ctr->count; i++) { 2024 ctr->sitename[i].string = (*r2.out.ctr)->sitename[i].string; 2025 } 2026 2027 return werr; 2028 } 2029 2030 2031 /* 1567 2032 netr_DsrGetDcSiteCoverageW 1568 2033 */ … … 1570 2035 struct netr_DsrGetDcSiteCoverageW *r) 1571 2036 { 1572 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1573 } 1574 1575 1576 /* 1577 netr_DsrEnumerateDomainTrusts 1578 */ 1579 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1580 struct netr_DsrEnumerateDomainTrusts *r) 2037 struct ldb_context *sam_ctx; 2038 struct DcSitesCtr *ctr; 2039 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2040 2041 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2042 dce_call->conn->auth_state.session_info, 0); 2043 if (sam_ctx == NULL) { 2044 return WERR_DS_UNAVAILABLE; 2045 } 2046 2047 ctr = talloc(mem_ctx, struct DcSitesCtr); 2048 W_ERROR_HAVE_NO_MEMORY(ctr); 2049 2050 *r->out.ctr = ctr; 2051 2052 /* For now only return our default site */ 2053 ctr->num_sites = 1; 2054 ctr->sites = talloc_array(ctr, struct lsa_String, ctr->num_sites); 2055 W_ERROR_HAVE_NO_MEMORY(ctr->sites); 2056 ctr->sites[0].string = samdb_server_site_name(sam_ctx, mem_ctx); 2057 W_ERROR_HAVE_NO_MEMORY(ctr->sites[0].string); 2058 2059 return WERR_OK; 2060 } 2061 2062 2063 #define GET_CHECK_STR(dest, mem, msg, attr) \ 2064 do {\ 2065 const char *s; \ 2066 s = ldb_msg_find_attr_as_string(msg, attr, NULL); \ 2067 if (!s) { \ 2068 DEBUG(0, ("DB Error, TustedDomain entry (%s) " \ 2069 "without flatname\n", \ 2070 ldb_dn_get_linearized(msg->dn))); \ 2071 continue; \ 2072 } \ 2073 dest = talloc_strdup(mem, s); \ 2074 W_ERROR_HAVE_NO_MEMORY(dest); \ 2075 } while(0) 2076 2077 2078 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx, 2079 struct ldb_context *sam_ctx, 2080 struct netr_DomainTrustList *trusts, 2081 uint32_t trust_flags) 2082 { 2083 struct ldb_dn *system_dn; 2084 struct ldb_message **dom_res = NULL; 2085 const char *trust_attrs[] = { "flatname", "trustPartner", 2086 "securityIdentifier", "trustDirection", 2087 "trustType", "trustAttributes", NULL }; 2088 uint32_t n; 2089 int i; 2090 int ret; 2091 2092 if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND | 2093 NETR_TRUST_FLAG_OUTBOUND))) { 2094 return WERR_INVALID_FLAGS; 2095 } 2096 2097 system_dn = samdb_search_dn(sam_ctx, mem_ctx, 2098 ldb_get_default_basedn(sam_ctx), 2099 "(&(objectClass=container)(cn=System))"); 2100 if (!system_dn) { 2101 return WERR_GENERAL_FAILURE; 2102 } 2103 2104 ret = gendb_search(sam_ctx, mem_ctx, system_dn, 2105 &dom_res, trust_attrs, 2106 "(objectclass=trustedDomain)"); 2107 2108 for (i = 0; i < ret; i++) { 2109 unsigned int trust_dir; 2110 uint32_t flags = 0; 2111 2112 trust_dir = ldb_msg_find_attr_as_uint(dom_res[i], 2113 "trustDirection", 0); 2114 2115 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) { 2116 flags |= NETR_TRUST_FLAG_INBOUND; 2117 } 2118 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) { 2119 flags |= NETR_TRUST_FLAG_OUTBOUND; 2120 } 2121 2122 if (!(flags & trust_flags)) { 2123 /* this trust direction was not requested */ 2124 continue; 2125 } 2126 2127 n = trusts->count; 2128 trusts->array = talloc_realloc(trusts, trusts->array, 2129 struct netr_DomainTrust, 2130 n + 1); 2131 W_ERROR_HAVE_NO_MEMORY(trusts->array); 2132 2133 GET_CHECK_STR(trusts->array[n].netbios_name, trusts, 2134 dom_res[i], "flatname"); 2135 GET_CHECK_STR(trusts->array[n].dns_name, trusts, 2136 dom_res[i], "trustPartner"); 2137 2138 trusts->array[n].trust_flags = flags; 2139 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) && 2140 !(flags & NETR_TRUST_FLAG_TREEROOT)) { 2141 /* TODO: find if we have parent in the list */ 2142 trusts->array[n].parent_index = 0; 2143 } 2144 2145 trusts->array[n].trust_type = 2146 ldb_msg_find_attr_as_uint(dom_res[i], 2147 "trustType", 0); 2148 trusts->array[n].trust_attributes = 2149 ldb_msg_find_attr_as_uint(dom_res[i], 2150 "trustAttributes", 0); 2151 2152 if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) || 2153 (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) { 2154 struct dom_sid zero_sid; 2155 ZERO_STRUCT(zero_sid); 2156 trusts->array[n].sid = 2157 dom_sid_dup(trusts, &zero_sid); 2158 } else { 2159 trusts->array[n].sid = 2160 samdb_result_dom_sid(trusts, dom_res[i], 2161 "securityIdentifier"); 2162 } 2163 trusts->array[n].guid = GUID_zero(); 2164 2165 trusts->count = n + 1; 2166 } 2167 2168 talloc_free(dom_res); 2169 return WERR_OK; 2170 } 2171 2172 /* 2173 netr_DsrEnumerateDomainTrusts 2174 */ 2175 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, 2176 TALLOC_CTX *mem_ctx, 2177 struct netr_DsrEnumerateDomainTrusts *r) 1581 2178 { 1582 2179 struct netr_DomainTrustList *trusts; … … 1585 2182 struct ldb_message **dom_res; 1586 2183 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL }; 1587 1588 ZERO_STRUCT(r->out); 1589 1590 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 2184 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2185 const char *dnsdomain = lpcfg_dnsdomain(lp_ctx); 2186 const char *p; 2187 WERROR werr; 2188 2189 if (r->in.trust_flags & 0xFFFFFE00) { 2190 return WERR_INVALID_FLAGS; 2191 } 2192 2193 /* TODO: turn to hard check once we are sure this is 100% correct */ 2194 if (!r->in.server_name) { 2195 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. " 2196 "But received NULL!\n", dnsdomain)); 2197 } else { 2198 p = strchr(r->in.server_name, '.'); 2199 if (!p) { 2200 DEBUG(3, ("Invalid domain! Expected name in domain " 2201 "[%s]. But received [%s]!\n", 2202 dnsdomain, r->in.server_name)); 2203 p = r->in.server_name; 2204 } else { 2205 p++; 2206 } 2207 if (strcasecmp(p, dnsdomain)) { 2208 DEBUG(3, ("Invalid domain! Expected name in domain " 2209 "[%s]. But received [%s]!\n", 2210 dnsdomain, r->in.server_name)); 2211 } 2212 } 2213 2214 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList); 2215 W_ERROR_HAVE_NO_MEMORY(trusts); 2216 2217 trusts->count = 0; 2218 r->out.trusts = trusts; 2219 2220 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2221 dce_call->conn->auth_state.session_info, 0); 1591 2222 if (sam_ctx == NULL) { 1592 2223 return WERR_GENERAL_FAILURE; 1593 2224 } 1594 2225 1595 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, 1596 &dom_res, dom_attrs); 1597 if (ret == -1) { 1598 return WERR_GENERAL_FAILURE; 1599 } 2226 if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) || 2227 (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) { 2228 2229 werr = fill_trusted_domains_array(mem_ctx, sam_ctx, 2230 trusts, r->in.trust_flags); 2231 W_ERROR_NOT_OK_RETURN(werr); 2232 } 2233 2234 /* NOTE: we currently are always the root of the forest */ 2235 if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) { 2236 uint32_t n = trusts->count; 2237 2238 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, 2239 &dom_res, dom_attrs); 2240 if (ret != 1) { 2241 return WERR_GENERAL_FAILURE; 2242 } 2243 2244 trusts->count = n + 1; 2245 trusts->array = talloc_realloc(trusts, trusts->array, 2246 struct netr_DomainTrust, 2247 trusts->count); 2248 W_ERROR_HAVE_NO_MEMORY(trusts->array); 2249 2250 trusts->array[n].netbios_name = lpcfg_workgroup(lp_ctx); 2251 trusts->array[n].dns_name = lpcfg_dnsdomain(lp_ctx); 2252 trusts->array[n].trust_flags = 2253 NETR_TRUST_FLAG_NATIVE | 2254 NETR_TRUST_FLAG_TREEROOT | 2255 NETR_TRUST_FLAG_IN_FOREST | 2256 NETR_TRUST_FLAG_PRIMARY; 2257 /* we are always the root domain for now */ 2258 trusts->array[n].parent_index = 0; 2259 trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL; 2260 trusts->array[n].trust_attributes = 0; 2261 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx, 2262 dom_res[0], 2263 "objectSid"); 2264 trusts->array[n].guid = samdb_result_guid(dom_res[0], 2265 "objectGUID"); 2266 talloc_free(dom_res); 2267 } 2268 2269 return WERR_OK; 2270 } 2271 2272 2273 /* 2274 netr_DsrDeregisterDNSHostRecords 2275 */ 2276 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2277 struct netr_DsrDeregisterDNSHostRecords *r) 2278 { 2279 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2280 } 2281 2282 2283 /* 2284 netr_ServerTrustPasswordsGet 2285 */ 2286 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2287 struct netr_ServerTrustPasswordsGet *r) 2288 { 2289 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2290 } 2291 2292 2293 static WERROR fill_forest_trust_array(TALLOC_CTX *mem_ctx, 2294 struct ldb_context *sam_ctx, 2295 struct loadparm_context *lp_ctx, 2296 struct lsa_ForestTrustInformation *info) 2297 { 2298 struct lsa_ForestTrustDomainInfo *domain_info; 2299 struct lsa_ForestTrustRecord *e; 2300 struct ldb_message **dom_res; 2301 const char * const dom_attrs[] = { "objectSid", NULL }; 2302 int ret; 2303 2304 /* we need to provide 2 entries: 2305 * 1. the Root Forest name 2306 * 2. the Domain Information 2307 */ 2308 2309 info->count = 2; 2310 info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2); 2311 W_ERROR_HAVE_NO_MEMORY(info->entries); 2312 2313 /* Forest root info */ 2314 e = talloc(info, struct lsa_ForestTrustRecord); 2315 W_ERROR_HAVE_NO_MEMORY(e); 2316 2317 e->flags = 0; 2318 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME; 2319 e->time = 0; /* so far always 0 in trces. */ 2320 e->forest_trust_data.top_level_name.string = samdb_forest_name(sam_ctx, 2321 mem_ctx); 2322 W_ERROR_HAVE_NO_MEMORY(e->forest_trust_data.top_level_name.string); 2323 2324 info->entries[0] = e; 2325 2326 /* Domain info */ 2327 e = talloc(info, struct lsa_ForestTrustRecord); 2328 W_ERROR_HAVE_NO_MEMORY(e); 2329 2330 /* get our own domain info */ 2331 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs); 1600 2332 if (ret != 1) { 1601 2333 return WERR_GENERAL_FAILURE; 1602 2334 } 1603 2335 1604 trusts = talloc(mem_ctx, struct netr_DomainTrustList); 1605 W_ERROR_HAVE_NO_MEMORY(trusts); 1606 1607 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret); 1608 W_ERROR_HAVE_NO_MEMORY(trusts->array); 1609 1610 trusts->count = 1; /* ?? */ 1611 1612 r->out.trusts = trusts; 1613 1614 /* TODO: add filtering by trust_flags, and correct trust_type 1615 and attributes */ 1616 trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx); 1617 trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 1618 trusts->array[0].trust_flags = 1619 NETR_TRUST_FLAG_TREEROOT | 1620 NETR_TRUST_FLAG_IN_FOREST | 1621 NETR_TRUST_FLAG_PRIMARY; 1622 trusts->array[0].parent_index = 0; 1623 trusts->array[0].trust_type = 2; 1624 trusts->array[0].trust_attributes = 0; 1625 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid"); 1626 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID"); 2336 /* TODO: check if disabled and set flags accordingly */ 2337 e->flags = 0; 2338 e->type = LSA_FOREST_TRUST_DOMAIN_INFO; 2339 e->time = 0; /* so far always 0 in traces. */ 2340 2341 domain_info = &e->forest_trust_data.domain_info; 2342 domain_info->domain_sid = samdb_result_dom_sid(info, dom_res[0], 2343 "objectSid"); 2344 domain_info->dns_domain_name.string = lpcfg_dnsdomain(lp_ctx); 2345 domain_info->netbios_domain_name.string = lpcfg_workgroup(lp_ctx); 2346 2347 info->entries[1] = e; 2348 2349 talloc_free(dom_res); 1627 2350 1628 2351 return WERR_OK; 1629 2352 } 1630 2353 1631 1632 /* 1633 netr_DsrDeregisterDNSHostRecords 1634 */ 1635 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1636 struct netr_DsrDeregisterDNSHostRecords *r) 1637 { 1638 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1639 } 1640 1641 1642 /* 1643 netr_ServerTrustPasswordsGet 1644 */ 1645 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1646 struct netr_ServerTrustPasswordsGet *r) 1647 { 1648 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1649 } 1650 1651 1652 /* 1653 netr_DsRGetForestTrustInformation 1654 */ 1655 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1656 struct netr_DsRGetForestTrustInformation *r) 1657 { 1658 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2354 /* 2355 netr_DsRGetForestTrustInformation 2356 */ 2357 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, 2358 TALLOC_CTX *mem_ctx, 2359 struct netr_DsRGetForestTrustInformation *r) 2360 { 2361 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2362 struct lsa_ForestTrustInformation *info, **info_ptr; 2363 struct ldb_context *sam_ctx; 2364 WERROR werr; 2365 2366 if (r->in.flags & 0xFFFFFFFE) { 2367 return WERR_INVALID_FLAGS; 2368 } 2369 2370 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2371 dce_call->conn->auth_state.session_info, 0); 2372 if (sam_ctx == NULL) { 2373 return WERR_GENERAL_FAILURE; 2374 } 2375 2376 if (r->in.flags & DS_GFTI_UPDATE_TDO) { 2377 if (!samdb_is_pdc(sam_ctx)) { 2378 return WERR_NERR_NOTPRIMARY; 2379 } 2380 2381 if (r->in.trusted_domain_name == NULL) { 2382 return WERR_INVALID_FLAGS; 2383 } 2384 2385 /* TODO: establish an schannel connection with 2386 * r->in.trusted_domain_name and perform a 2387 * netr_GetForestTrustInformation call against it */ 2388 2389 /* for now return not implementd */ 2390 return WERR_CALL_NOT_IMPLEMENTED; 2391 } 2392 2393 /* TODO: check r->in.server_name is our name */ 2394 2395 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *); 2396 W_ERROR_HAVE_NO_MEMORY(info_ptr); 2397 2398 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation); 2399 W_ERROR_HAVE_NO_MEMORY(info); 2400 2401 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info); 2402 W_ERROR_NOT_OK_RETURN(werr); 2403 2404 *info_ptr = info; 2405 r->out.forest_trust_info = info_ptr; 2406 2407 return WERR_OK; 1659 2408 } 1660 2409 … … 1663 2412 netr_GetForestTrustInformation 1664 2413 */ 1665 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1666 struct netr_GetForestTrustInformation *r) 1667 { 1668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2414 static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, 2415 TALLOC_CTX *mem_ctx, 2416 struct netr_GetForestTrustInformation *r) 2417 { 2418 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2419 struct netlogon_creds_CredentialState *creds; 2420 struct lsa_ForestTrustInformation *info, **info_ptr; 2421 struct ldb_context *sam_ctx; 2422 NTSTATUS status; 2423 WERROR werr; 2424 2425 status = dcesrv_netr_creds_server_step_check(dce_call, 2426 mem_ctx, 2427 r->in.computer_name, 2428 r->in.credential, 2429 r->out.return_authenticator, 2430 &creds); 2431 if (!NT_STATUS_IS_OK(status)) { 2432 return status; 2433 } 2434 2435 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) && 2436 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) { 2437 return NT_STATUS_NOT_IMPLEMENTED; 2438 } 2439 2440 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2441 dce_call->conn->auth_state.session_info, 0); 2442 if (sam_ctx == NULL) { 2443 return NT_STATUS_UNSUCCESSFUL; 2444 } 2445 2446 /* TODO: check r->in.server_name is our name */ 2447 2448 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *); 2449 if (!info_ptr) { 2450 return NT_STATUS_NO_MEMORY; 2451 } 2452 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation); 2453 if (!info) { 2454 return NT_STATUS_NO_MEMORY; 2455 } 2456 2457 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info); 2458 if (!W_ERROR_IS_OK(werr)) { 2459 return werror_to_ntstatus(werr); 2460 } 2461 2462 *info_ptr = info; 2463 r->out.forest_trust_info = info_ptr; 2464 2465 return NT_STATUS_OK; 1669 2466 } 1670 2467 … … 1679 2476 } 1680 2477 2478 /* 2479 netr_Unused47 2480 */ 2481 static NTSTATUS dcesrv_netr_Unused47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2482 struct netr_Unused47 *r) 2483 { 2484 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2485 } 2486 2487 2488 struct netr_dnsupdate_RODC_state { 2489 struct dcesrv_call_state *dce_call; 2490 struct netr_DsrUpdateReadOnlyServerDnsRecords *r; 2491 struct dnsupdate_RODC *r2; 2492 }; 2493 2494 /* 2495 called when the forwarded RODC dns update request is finished 2496 */ 2497 static void netr_dnsupdate_RODC_callback(struct tevent_req *subreq) 2498 { 2499 struct netr_dnsupdate_RODC_state *st = 2500 tevent_req_callback_data(subreq, 2501 struct netr_dnsupdate_RODC_state); 2502 NTSTATUS status; 2503 2504 status = dcerpc_dnsupdate_RODC_r_recv(subreq, st->dce_call); 2505 TALLOC_FREE(subreq); 2506 if (!NT_STATUS_IS_OK(status)) { 2507 DEBUG(0,(__location__ ": IRPC callback failed %s\n", nt_errstr(status))); 2508 st->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 2509 } 2510 2511 st->r->out.dns_names = talloc_steal(st->dce_call, st->r2->out.dns_names); 2512 2513 status = dcesrv_reply(st->dce_call); 2514 if (!NT_STATUS_IS_OK(status)) { 2515 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status))); 2516 } 2517 } 2518 2519 /* 2520 netr_DsrUpdateReadOnlyServerDnsRecords 2521 */ 2522 static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call_state *dce_call, 2523 TALLOC_CTX *mem_ctx, 2524 struct netr_DsrUpdateReadOnlyServerDnsRecords *r) 2525 { 2526 struct netlogon_creds_CredentialState *creds; 2527 NTSTATUS nt_status; 2528 struct dcerpc_binding_handle *binding_handle; 2529 struct netr_dnsupdate_RODC_state *st; 2530 struct tevent_req *subreq; 2531 2532 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 2533 mem_ctx, 2534 r->in.computer_name, 2535 r->in.credential, 2536 r->out.return_authenticator, 2537 &creds); 2538 NT_STATUS_NOT_OK_RETURN(nt_status); 2539 2540 if (creds->secure_channel_type != SEC_CHAN_RODC) { 2541 return NT_STATUS_ACCESS_DENIED; 2542 } 2543 2544 st = talloc_zero(mem_ctx, struct netr_dnsupdate_RODC_state); 2545 NT_STATUS_HAVE_NO_MEMORY(st); 2546 2547 st->dce_call = dce_call; 2548 st->r = r; 2549 st->r2 = talloc_zero(st, struct dnsupdate_RODC); 2550 NT_STATUS_HAVE_NO_MEMORY(st->r2); 2551 2552 st->r2->in.dom_sid = creds->sid; 2553 st->r2->in.site_name = r->in.site_name; 2554 st->r2->in.dns_ttl = r->in.dns_ttl; 2555 st->r2->in.dns_names = r->in.dns_names; 2556 st->r2->out.dns_names = r->out.dns_names; 2557 2558 binding_handle = irpc_binding_handle_by_name(st, dce_call->msg_ctx, 2559 "dnsupdate", &ndr_table_irpc); 2560 if (binding_handle == NULL) { 2561 DEBUG(0,("Failed to get binding_handle for dnsupdate task\n")); 2562 dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 2563 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2564 } 2565 2566 /* forward the call */ 2567 subreq = dcerpc_dnsupdate_RODC_r_send(st, dce_call->event_ctx, 2568 binding_handle, st->r2); 2569 NT_STATUS_HAVE_NO_MEMORY(subreq); 2570 2571 dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; 2572 2573 /* setup the callback */ 2574 tevent_req_set_callback(subreq, netr_dnsupdate_RODC_callback, st); 2575 2576 return NT_STATUS_OK; 2577 } 2578 1681 2579 1682 2580 /* include the generated boilerplate */ -
trunk/server/source4/rpc_server/remote/dcesrv_remote.c
r414 r745 4 4 5 5 Copyright (C) Stefan (metze) Metzmacher 2004 6 6 Copyright (C) Julien Kerihuel 2008-2009 7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2010 8 7 9 This program is free software; you can redistribute it and/or modify 8 10 it under the terms of the GNU General Public License as published by … … 20 22 21 23 #include "includes.h" 24 #include <tevent.h> 22 25 #include "rpc_server/dcerpc_server.h" 23 26 #include "auth/auth.h" … … 36 39 } 37 40 38 static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface )41 static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) 39 42 { 40 43 NTSTATUS status; 41 44 const struct ndr_interface_table *table; 42 45 struct dcesrv_remote_private *priv; 43 const char *binding = lp _parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding");46 const char *binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding"); 44 47 const char *user, *pass, *domain; 45 48 struct cli_credentials *credentials; 49 bool must_free_credentials = true; 46 50 bool machine_account; 47 48 machine_account = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "use_machine_account", false); 51 struct dcerpc_binding *b; 52 struct composite_context *pipe_conn_req; 53 54 machine_account = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "use_machine_account", false); 49 55 50 56 priv = talloc(dce_call->conn, struct dcesrv_remote_private); … … 61 67 } 62 68 63 user = lp _parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "user");64 pass = lp _parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "password");65 domain = lp _parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain");69 user = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "user"); 70 pass = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "password"); 71 domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain"); 66 72 67 73 table = ndr_table_by_uuid(&iface->syntax_id.uuid); /* FIXME: What about if_version ? */ … … 97 103 DEBUG(5, ("dcerpc_remote: RPC Proxy: Using delegated credentials\n")); 98 104 credentials = dce_call->conn->auth_state.session_info->credentials; 105 must_free_credentials = false; 99 106 } else { 100 107 DEBUG(1,("dcerpc_remote: RPC Proxy: You must supply binding, user and password or have delegated credentials\n")); … … 102 109 } 103 110 104 status = dcerpc_pipe_connect(priv, 105 &(priv->c_pipe), binding, table, 106 credentials, dce_call->event_ctx, 107 dce_call->conn->dce_ctx->lp_ctx); 108 109 talloc_free(credentials); 111 /* parse binding string to the structure */ 112 status = dcerpc_parse_binding(dce_call->context, binding, &b); 113 if (!NT_STATUS_IS_OK(status)) { 114 DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding)); 115 return status; 116 } 117 118 DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b))); 119 120 /* If we already have a remote association group ID, then use that */ 121 if (dce_call->context->assoc_group->proxied_id != 0) { 122 b->assoc_group_id = dce_call->context->assoc_group->proxied_id; 123 } 124 125 b->object.if_version = if_version; 126 127 pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table, 128 credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); 129 status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(priv->c_pipe)); 130 131 if (must_free_credentials) { 132 talloc_free(credentials); 133 } 134 110 135 if (!NT_STATUS_IS_OK(status)) { 111 136 return status; 112 137 } 113 138 139 if (dce_call->context->assoc_group->proxied_id == 0) { 140 dce_call->context->assoc_group->proxied_id = priv->c_pipe->assoc_group_id; 141 } 142 143 if (!NT_STATUS_IS_OK(status)) { 144 return status; 145 } 146 114 147 return NT_STATUS_OK; 115 }116 117 static void remote_op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)118 {119 struct dcesrv_remote_private *priv = (struct dcesrv_remote_private *)context->private_data;120 121 talloc_free(priv->c_pipe);122 123 return;124 148 } 125 149 … … 155 179 } 156 180 181 static void remote_op_dispatch_done(struct tevent_req *subreq); 182 157 183 static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) 158 184 { 159 struct dcesrv_remote_private *priv = dce_call->context->private_data; 185 struct dcesrv_remote_private *priv = talloc_get_type_abort(dce_call->context->private_data, 186 struct dcesrv_remote_private); 160 187 uint16_t opnum = dce_call->pkt.u.request.opnum; 161 188 const struct ndr_interface_table *table = dce_call->context->iface->private_data; 162 189 const struct ndr_interface_call *call; 163 190 const char *name; 191 struct tevent_req *subreq; 164 192 165 193 name = table->calls[opnum].name; … … 173 201 174 202 /* we didn't use the return code of this function as we only check the last_fault_code */ 175 dcerpc_ndr_request(priv->c_pipe, NULL, table, opnum, mem_ctx,r); 203 subreq = dcerpc_binding_handle_call_send(dce_call, dce_call->event_ctx, 204 priv->c_pipe->binding_handle, 205 NULL, table, 206 opnum, mem_ctx, r); 207 if (subreq == NULL) { 208 DEBUG(0,("dcesrv_remote: call[%s] dcerpc_binding_handle_call_send() failed!\n", name)); 209 return NT_STATUS_NO_MEMORY; 210 } 211 tevent_req_set_callback(subreq, remote_op_dispatch_done, dce_call); 212 213 dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; 214 return NT_STATUS_OK; 215 } 216 217 static void remote_op_dispatch_done(struct tevent_req *subreq) 218 { 219 struct dcesrv_call_state *dce_call = tevent_req_callback_data(subreq, 220 struct dcesrv_call_state); 221 struct dcesrv_remote_private *priv = talloc_get_type_abort(dce_call->context->private_data, 222 struct dcesrv_remote_private); 223 uint16_t opnum = dce_call->pkt.u.request.opnum; 224 const struct ndr_interface_table *table = dce_call->context->iface->private_data; 225 const struct ndr_interface_call *call; 226 const char *name; 227 NTSTATUS status; 228 229 name = table->calls[opnum].name; 230 call = &table->calls[opnum]; 231 232 /* we didn't use the return code of this function as we only check the last_fault_code */ 233 status = dcerpc_binding_handle_call_recv(subreq); 234 TALLOC_FREE(subreq); 176 235 177 236 dce_call->fault_code = priv->c_pipe->last_fault_code; 178 237 if (dce_call->fault_code != 0) { 179 DEBUG(0,("dcesrv_remote: call[%s] failed with: %s!\n",name, dcerpc_errstr(mem_ctx, dce_call->fault_code))); 180 return NT_STATUS_NET_WRITE_FAULT; 181 } 182 183 if ((dce_call->fault_code == 0) && 238 DEBUG(0,("dcesrv_remote: call[%s] failed with: %s!\n", 239 name, dcerpc_errstr(dce_call, dce_call->fault_code))); 240 goto reply; 241 } 242 243 if (NT_STATUS_IS_OK(status) && 184 244 (priv->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_OUT)) { 185 ndr_print_function_debug(call->ndr_print, name, NDR_OUT, r); 186 } 187 188 return NT_STATUS_OK; 245 ndr_print_function_debug(call->ndr_print, name, NDR_OUT, dce_call->r); 246 } 247 248 reply: 249 status = dcesrv_reply(dce_call); 250 if (!NT_STATUS_IS_OK(status)) { 251 DEBUG(0,("dcesrv_remote: call[%s]: dcesrv_reply() failed - %s\n", 252 name, nt_errstr(status))); 253 } 189 254 } 190 255 … … 207 272 static NTSTATUS remote_register_one_iface(struct dcesrv_context *dce_ctx, const struct dcesrv_interface *iface) 208 273 { 209 int i;274 unsigned int i; 210 275 const struct ndr_interface_table *table = iface->private_data; 211 276 … … 226 291 static NTSTATUS remote_op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) 227 292 { 228 int i;229 const char **ifaces = (const char **)str_list_make(dce_ctx, lp _parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_remote", "interfaces"),NULL);293 unsigned int i; 294 const char **ifaces = (const char **)str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_remote", "interfaces"),NULL); 230 295 231 296 if (!ifaces) { … … 262 327 263 328 iface->bind = remote_op_bind; 264 iface->unbind = remote_op_unbind;329 iface->unbind = NULL; 265 330 266 331 iface->ndr_pull = remote_op_ndr_pull; -
trunk/server/source4/rpc_server/samr/dcesrv_samr.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 8 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 9 9 Copyright (C) Matthias Dieter Wallnöfer 2009 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 29 29 #include "rpc_server/samr/dcesrv_samr.h" 30 30 #include "system/time.h" 31 #include "lib/ldb/include/ldb.h"32 #include "lib/ldb/include/ldb_errors.h"31 #include <ldb.h> 32 #include <ldb_errors.h> 33 33 #include "../libds/common/flags.h" 34 34 #include "dsdb/samdb/samdb.h" 35 #include "dsdb/common/util.h" 35 36 #include "libcli/ldap/ldap_ndr.h" 36 37 #include "libcli/security/security.h" … … 38 39 #include "../lib/util/util_ldb.h" 39 40 #include "param/param.h" 41 #include "lib/util/tsort.h" 42 #include "libds/common/flag_mapping.h" 40 43 41 44 /* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */ 42 45 43 46 #define QUERY_STRING(msg, field, attr) \ 44 info->field.string = samdb_result_string(msg, attr, "");47 info->field.string = ldb_msg_find_attr_as_string(msg, attr, ""); 45 48 #define QUERY_UINT(msg, field, attr) \ 46 info->field = samdb_result_uint(msg, attr, 0);49 info->field = ldb_msg_find_attr_as_uint(msg, attr, 0); 47 50 #define QUERY_RID(msg, field, attr) \ 48 51 info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0); 49 52 #define QUERY_UINT64(msg, field, attr) \ 50 info->field = samdb_result_uint64(msg, attr, 0);53 info->field = ldb_msg_find_attr_as_uint64(msg, attr, 0); 51 54 #define QUERY_APASSC(msg, field, attr) \ 52 55 info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \ … … 69 72 if (r->in.info->field.string == NULL) return NT_STATUS_INVALID_PARAMETER; \ 70 73 if (r->in.info->field.string[0] == '\0') { \ 71 if (ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, NULL) ) { \74 if (ldb_msg_add_empty(msg, attr, LDB_FLAG_MOD_DELETE, NULL) != LDB_SUCCESS) { \ 72 75 return NT_STATUS_NO_MEMORY; \ 73 76 } \ 74 77 } \ 75 if (ldb_msg_add_string(msg, attr, r->in.info->field.string) != 0) { \78 if (ldb_msg_add_string(msg, attr, r->in.info->field.string) != LDB_SUCCESS) { \ 76 79 return NT_STATUS_NO_MEMORY; \ 77 80 } \ … … 82 85 #define SET_UINT(msg, field, attr) do { \ 83 86 struct ldb_message_element *set_el; \ 84 if (samdb_msg_add_uint(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \87 if (samdb_msg_add_uint(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != LDB_SUCCESS) { \ 85 88 return NT_STATUS_NO_MEMORY; \ 86 89 } \ 87 90 set_el = ldb_msg_find_element(msg, attr); \ 88 91 set_el->flags = LDB_FLAG_MOD_REPLACE; \ 89 } while (0) 90 92 } while (0) 93 91 94 #define SET_INT64(msg, field, attr) do { \ 92 95 struct ldb_message_element *set_el; \ 93 if (samdb_msg_add_int64(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \96 if (samdb_msg_add_int64(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != LDB_SUCCESS) { \ 94 97 return NT_STATUS_NO_MEMORY; \ 95 98 } \ 96 99 set_el = ldb_msg_find_element(msg, attr); \ 97 100 set_el->flags = LDB_FLAG_MOD_REPLACE; \ 98 } while (0) 99 101 } while (0) 102 100 103 #define SET_UINT64(msg, field, attr) do { \ 101 104 struct ldb_message_element *set_el; \ 102 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \105 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != LDB_SUCCESS) { \ 103 106 return NT_STATUS_NO_MEMORY; \ 104 107 } \ 105 108 set_el = ldb_msg_find_element(msg, attr); \ 106 109 set_el->flags = LDB_FLAG_MOD_REPLACE; \ 107 } while (0) 110 } while (0) 108 111 109 112 #define CHECK_FOR_MULTIPLES(value, flag, poss_flags) \ … … 113 116 } \ 114 117 } while (0) \ 115 116 /* Set account flags, discarding flags that cannot be set with SAMR */ 118 119 /* Set account flags, discarding flags that cannot be set with SAMR */ 117 120 #define SET_AFLAGS(msg, field, attr) do { \ 118 121 struct ldb_message_element *set_el; \ … … 129 132 set_el = ldb_msg_find_element(msg, attr); \ 130 133 set_el->flags = LDB_FLAG_MOD_REPLACE; \ 131 } while (0) 132 134 } while (0) 135 133 136 #define SET_LHOURS(msg, field, attr) do { \ 134 137 struct ldb_message_element *set_el; \ 135 if (samdb_msg_add_logon_hours(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \138 if (samdb_msg_add_logon_hours(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != LDB_SUCCESS) { \ 136 139 return NT_STATUS_NO_MEMORY; \ 137 140 } \ … … 143 146 struct ldb_message_element *set_el; \ 144 147 if (r->in.info->field.length != 0) { \ 145 if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \148 if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != LDB_SUCCESS) { \ 146 149 return NT_STATUS_NO_MEMORY; \ 147 150 } \ … … 153 156 154 157 155 /* 156 samr_Connect 158 /* 159 samr_Connect 157 160 158 161 create a connection to the SAM database … … 166 169 ZERO_STRUCTP(r->out.connect_handle); 167 170 168 c_state = talloc( dce_call->conn, struct samr_connect_state);171 c_state = talloc(mem_ctx, struct samr_connect_state); 169 172 if (!c_state) { 170 173 return NT_STATUS_NO_MEMORY; … … 172 175 173 176 /* make sure the sam database is accessible */ 174 c_state->sam_ctx = samdb_connect(c_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info );177 c_state->sam_ctx = samdb_connect(c_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info, 0); 175 178 if (c_state->sam_ctx == NULL) { 176 179 talloc_free(c_state); … … 194 197 195 198 196 /* 197 samr_Close 199 /* 200 samr_Close 198 201 */ 199 202 static NTSTATUS dcesrv_samr_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 214 217 215 218 216 /* 217 samr_SetSecurity 219 /* 220 samr_SetSecurity 218 221 */ 219 222 static NTSTATUS dcesrv_samr_SetSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 224 227 225 228 226 /* 227 samr_QuerySecurity 229 /* 230 samr_QuerySecurity 228 231 */ 229 232 static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 250 253 251 254 252 /* 253 samr_Shutdown 255 /* 256 samr_Shutdown 254 257 255 258 we refuse this operation completely. If a admin wants to shutdown samr … … 263 266 264 267 265 /* 266 samr_LookupDomain 268 /* 269 samr_LookupDomain 267 270 268 271 this maps from a domain name to a SID … … 292 295 mem_ctx, NULL, &dom_msgs, dom_attrs, 293 296 "(objectClass=builtinDomain)"); 294 } else if (strcasecmp_m(r->in.domain_name->string, lp _sam_name(dce_call->conn->dce_ctx->lp_ctx)) == 0) {297 } else if (strcasecmp_m(r->in.domain_name->string, lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx)) == 0) { 295 298 ret = gendb_search_dn(c_state->sam_ctx, 296 mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), 299 mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), 297 300 &dom_msgs, dom_attrs); 298 301 } else { … … 302 305 return NT_STATUS_NO_SUCH_DOMAIN; 303 306 } 304 307 305 308 sid = samdb_result_dom_sid(mem_ctx, dom_msgs[0], 306 309 "objectSid"); 307 310 308 311 if (sid == NULL) { 309 312 return NT_STATUS_NO_SUCH_DOMAIN; … … 316 319 317 320 318 /* 319 samr_EnumDomains 321 /* 322 samr_EnumDomains 320 323 321 324 list the domains in the SAM … … 327 330 struct dcesrv_handle *h; 328 331 struct samr_SamArray *array; 329 int i, start_i;332 uint32_t i, start_i; 330 333 331 334 *r->out.resume_handle = 0; … … 350 353 return NT_STATUS_NO_MEMORY; 351 354 } 352 355 353 356 array->count = 0; 354 357 array->entries = NULL; … … 362 365 array->entries[i].idx = start_i + i; 363 366 if (i == 0) { 364 array->entries[i].name.string = lp _sam_name(dce_call->conn->dce_ctx->lp_ctx);367 array->entries[i].name.string = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx); 365 368 } else { 366 369 array->entries[i].name.string = "BUILTIN"; … … 376 379 377 380 378 /* 379 samr_OpenDomain 381 /* 382 samr_OpenDomain 380 383 */ 381 384 static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 399 402 } 400 403 401 d_state = talloc( c_state, struct samr_domain_state);404 d_state = talloc(mem_ctx, struct samr_domain_state); 402 405 if (!d_state) { 403 406 return NT_STATUS_NO_MEMORY; … … 411 414 } else { 412 415 d_state->builtin = false; 413 d_state->domain_name = lp _sam_name(dce_call->conn->dce_ctx->lp_ctx);416 d_state->domain_name = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx); 414 417 } 415 418 416 419 ret = gendb_search(c_state->sam_ctx, 417 420 mem_ctx, ldb_get_default_basedn(c_state->sam_ctx), &dom_msgs, dom_attrs, 418 "(objectSid=%s)", 421 "(objectSid=%s)", 419 422 ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid)); 420 423 421 424 if (ret == 0) { 422 425 talloc_free(d_state); … … 432 435 433 436 d_state->domain_dn = talloc_steal(d_state, dom_msgs[0]->dn); 434 d_state->role = lp _server_role(dce_call->conn->dce_ctx->lp_ctx);437 d_state->role = lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx); 435 438 d_state->connect_state = talloc_reference(d_state, c_state); 436 439 d_state->sam_ctx = c_state->sam_ctx; … … 444 447 return NT_STATUS_NO_MEMORY; 445 448 } 446 449 447 450 h_domain->data = talloc_steal(h_domain, d_state); 448 451 … … 456 459 */ 457 460 static NTSTATUS dcesrv_samr_info_DomInfo1(struct samr_domain_state *state, 458 459 460 461 TALLOC_CTX *mem_ctx, 462 struct ldb_message **dom_msgs, 463 struct samr_DomInfo1 *info) 461 464 { 462 465 info->min_password_length = 463 samdb_result_uint(dom_msgs[0], "minPwdLength", 0);466 ldb_msg_find_attr_as_uint(dom_msgs[0], "minPwdLength", 0); 464 467 info->password_history_length = 465 samdb_result_uint(dom_msgs[0], "pwdHistoryLength", 0);466 info->password_properties = 467 samdb_result_uint(dom_msgs[0], "pwdProperties", 0);468 info->max_password_age = 469 samdb_result_int64(dom_msgs[0], "maxPwdAge", 0);470 info->min_password_age = 471 samdb_result_int64(dom_msgs[0], "minPwdAge", 0);468 ldb_msg_find_attr_as_uint(dom_msgs[0], "pwdHistoryLength", 0); 469 info->password_properties = 470 ldb_msg_find_attr_as_uint(dom_msgs[0], "pwdProperties", 0); 471 info->max_password_age = 472 ldb_msg_find_attr_as_int64(dom_msgs[0], "maxPwdAge", 0); 473 info->min_password_age = 474 ldb_msg_find_attr_as_int64(dom_msgs[0], "minPwdAge", 0); 472 475 473 476 return NT_STATUS_OK; … … 477 480 return DomInfo2 478 481 */ 479 static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state *state, 482 static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state *state, 480 483 TALLOC_CTX *mem_ctx, 481 484 struct ldb_message **dom_msgs, 482 485 struct samr_DomGeneralInformation *info) 483 486 { 484 /* This pulls the NetBIOS name from the 485 cn=NTDS Settings,cn=<NETBIOS name of PDC>,.... 486 string */ 487 info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, dom_msgs[0], "fSMORoleOwner"); 488 489 if (!info->primary.string) { 490 info->primary.string = lp_netbios_name(state->lp_ctx); 491 } 492 493 info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff", 487 /* MS-SAMR 2.2.4.1 - ReplicaSourceNodeName: "domainReplica" attribute */ 488 info->primary.string = ldb_msg_find_attr_as_string(dom_msgs[0], 489 "domainReplica", 490 ""); 491 492 info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff", 494 493 0x8000000000000000LL); 495 494 496 info->oem_information.string = samdb_result_string(dom_msgs[0], "oEMInformation", NULL); 495 info->oem_information.string = ldb_msg_find_attr_as_string(dom_msgs[0], 496 "oEMInformation", 497 ""); 497 498 info->domain_name.string = state->domain_name; 498 499 499 info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount", 500 info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount", 500 501 0); 501 502 switch (state->role) { 502 503 case ROLE_DOMAIN_CONTROLLER: 503 /* This pulls the NetBIOS name from the 504 /* This pulls the NetBIOS name from the 504 505 cn=NTDS Settings,cn=<NETBIOS name of PDC>,.... 505 506 string */ … … 518 519 } 519 520 520 /* No users in BUILTIN, and the LOCAL group types are only in builtin, and the global group type is never in BUILTIN */521 info->num_users = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn,521 info->num_users = samdb_search_count(state->sam_ctx, mem_ctx, 522 state->domain_dn, 522 523 "(objectClass=user)"); 523 info->num_groups = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn, 524 "(&(objectClass=group)(sAMAccountType=%u))", 525 ATYPE_GLOBAL_GROUP); 526 info->num_aliases = samdb_search_count(state->sam_ctx, mem_ctx, state->domain_dn, 527 "(&(objectClass=group)(sAMAccountType=%u))", 528 ATYPE_LOCAL_GROUP); 524 info->num_groups = samdb_search_count(state->sam_ctx, mem_ctx, 525 state->domain_dn, 526 "(&(objectClass=group)(|(groupType=%d)(groupType=%d)))", 527 GTYPE_SECURITY_UNIVERSAL_GROUP, 528 GTYPE_SECURITY_GLOBAL_GROUP); 529 info->num_aliases = samdb_search_count(state->sam_ctx, mem_ctx, 530 state->domain_dn, 531 "(&(objectClass=group)(|(groupType=%d)(groupType=%d)))", 532 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, 533 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); 529 534 530 535 return NT_STATUS_OK; … … 535 540 */ 536 541 static NTSTATUS dcesrv_samr_info_DomInfo3(struct samr_domain_state *state, 537 538 539 540 { 541 info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff", 542 TALLOC_CTX *mem_ctx, 543 struct ldb_message **dom_msgs, 544 struct samr_DomInfo3 *info) 545 { 546 info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff", 542 547 0x8000000000000000LL); 543 548 … … 553 558 struct samr_DomOEMInformation *info) 554 559 { 555 info->oem_information.string = samdb_result_string(dom_msgs[0], "oEMInformation", NULL); 560 info->oem_information.string = ldb_msg_find_attr_as_string(dom_msgs[0], 561 "oEMInformation", 562 ""); 556 563 557 564 return NT_STATUS_OK; … … 562 569 */ 563 570 static NTSTATUS dcesrv_samr_info_DomInfo5(struct samr_domain_state *state, 564 565 566 571 TALLOC_CTX *mem_ctx, 572 struct ldb_message **dom_msgs, 573 struct samr_DomInfo5 *info) 567 574 { 568 575 info->domain_name.string = state->domain_name; … … 575 582 */ 576 583 static NTSTATUS dcesrv_samr_info_DomInfo6(struct samr_domain_state *state, 577 TALLOC_CTX *mem_ctx, 578 struct ldb_message **dom_msgs, 579 struct samr_DomInfo6 *info) 580 { 581 /* This pulls the NetBIOS name from the 582 cn=NTDS Settings,cn=<NETBIOS name of PDC>,.... 583 string */ 584 info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, 585 dom_msgs[0], "fSMORoleOwner"); 586 587 if (!info->primary.string) { 588 info->primary.string = lp_netbios_name(state->lp_ctx); 589 } 584 TALLOC_CTX *mem_ctx, 585 struct ldb_message **dom_msgs, 586 struct samr_DomInfo6 *info) 587 { 588 /* MS-SAMR 2.2.4.1 - ReplicaSourceNodeName: "domainReplica" attribute */ 589 info->primary.string = ldb_msg_find_attr_as_string(dom_msgs[0], 590 "domainReplica", 591 ""); 590 592 591 593 return NT_STATUS_OK; … … 596 598 */ 597 599 static NTSTATUS dcesrv_samr_info_DomInfo7(struct samr_domain_state *state, 598 599 600 600 TALLOC_CTX *mem_ctx, 601 struct ldb_message **dom_msgs, 602 struct samr_DomInfo7 *info) 601 603 { 602 604 603 605 switch (state->role) { 604 606 case ROLE_DOMAIN_CONTROLLER: 605 /* This pulls the NetBIOS name from the 607 /* This pulls the NetBIOS name from the 606 608 cn=NTDS Settings,cn=<NETBIOS name of PDC>,.... 607 609 string */ … … 627 629 */ 628 630 static NTSTATUS dcesrv_samr_info_DomInfo8(struct samr_domain_state *state, 629 630 631 632 { 633 info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount", 631 TALLOC_CTX *mem_ctx, 632 struct ldb_message **dom_msgs, 633 struct samr_DomInfo8 *info) 634 { 635 info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount", 634 636 time(NULL)); 635 637 … … 644 646 */ 645 647 static NTSTATUS dcesrv_samr_info_DomInfo9(struct samr_domain_state *state, 646 647 648 648 TALLOC_CTX *mem_ctx, 649 struct ldb_message **dom_msgs, 650 struct samr_DomInfo9 *info) 649 651 { 650 652 info->domain_server_state = DOMAIN_SERVER_ENABLED; … … 657 659 */ 658 660 static NTSTATUS dcesrv_samr_info_DomGeneralInformation2(struct samr_domain_state *state, 659 660 661 661 TALLOC_CTX *mem_ctx, 662 struct ldb_message **dom_msgs, 663 struct samr_DomGeneralInformation2 *info) 662 664 { 663 665 NTSTATUS status; … … 666 668 return status; 667 669 } 668 669 info->lockout_duration = ldb_msg_find_attr_as_int64(dom_msgs[0], "lockoutDuration", 670 671 info->lockout_duration = ldb_msg_find_attr_as_int64(dom_msgs[0], "lockoutDuration", 670 672 -18000000000LL); 671 673 info->lockout_window = ldb_msg_find_attr_as_int64(dom_msgs[0], "lockOutObservationWindow", … … 680 682 */ 681 683 static NTSTATUS dcesrv_samr_info_DomInfo12(struct samr_domain_state *state, 682 TALLOC_CTX *mem_ctx,683 684 struct samr_DomInfo12 *info)685 { 686 info->lockout_duration = ldb_msg_find_attr_as_int64(dom_msgs[0], "lockoutDuration", 684 TALLOC_CTX *mem_ctx, 685 struct ldb_message **dom_msgs, 686 struct samr_DomInfo12 *info) 687 { 688 info->lockout_duration = ldb_msg_find_attr_as_int64(dom_msgs[0], "lockoutDuration", 687 689 -18000000000LL); 688 690 info->lockout_window = ldb_msg_find_attr_as_int64(dom_msgs[0], "lockOutObservationWindow", … … 697 699 */ 698 700 static NTSTATUS dcesrv_samr_info_DomInfo13(struct samr_domain_state *state, 699 700 701 702 { 703 info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount", 701 TALLOC_CTX *mem_ctx, 702 struct ldb_message **dom_msgs, 703 struct samr_DomInfo13 *info) 704 { 705 info->sequence_num = ldb_msg_find_attr_as_uint64(dom_msgs[0], "modifiedCount", 704 706 time(NULL)); 705 707 … … 712 714 } 713 715 714 /* 715 samr_QueryDomainInfo 716 */ 717 static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 718 struct samr_QueryDomainInfo *r) 716 /* 717 samr_QueryDomainInfo 718 */ 719 static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, 720 TALLOC_CTX *mem_ctx, 721 struct samr_QueryDomainInfo *r) 719 722 { 720 723 struct dcesrv_handle *h; … … 724 727 struct ldb_message **dom_msgs; 725 728 const char * const *attrs = NULL; 726 729 727 730 *r->out.info = NULL; 728 731 … … 731 734 d_state = h->data; 732 735 733 info = talloc(mem_ctx, union samr_DomainInfo);734 if (!info) {735 return NT_STATUS_NO_MEMORY;736 }737 738 736 switch (r->in.level) { 739 case 1: 737 case 1: 740 738 { 741 739 static const char * const attrs2[] = { "minPwdLength", … … 751 749 { 752 750 static const char * const attrs2[] = {"forceLogoff", 753 "oEMInformation", 754 "modifiedCount", 755 " fSMORoleOwner",751 "oEMInformation", 752 "modifiedCount", 753 "domainReplica", 756 754 NULL}; 757 755 attrs = attrs2; … … 760 758 case 3: 761 759 { 762 static const char * const attrs2[] = {"forceLogoff", 760 static const char * const attrs2[] = {"forceLogoff", 763 761 NULL}; 764 762 attrs = attrs2; … … 767 765 case 4: 768 766 { 769 static const char * const attrs2[] = {"oEMInformation", 767 static const char * const attrs2[] = {"oEMInformation", 770 768 NULL}; 771 769 attrs = attrs2; … … 779 777 case 6: 780 778 { 781 static const char * const attrs2[] = { "fSMORoleOwner",782 NULL};779 static const char * const attrs2[] = { "domainReplica", 780 NULL }; 783 781 attrs = attrs2; 784 782 break; … … 791 789 case 8: 792 790 { 793 static const char * const attrs2[] = { "modifiedCount", 794 "creationTime", 791 static const char * const attrs2[] = { "modifiedCount", 792 "creationTime", 795 793 NULL }; 796 794 attrs = attrs2; … … 798 796 } 799 797 case 9: 798 { 800 799 attrs = NULL; 801 break; 800 break; 801 } 802 802 case 11: 803 803 { 804 804 static const char * const attrs2[] = { "oEMInformation", 805 805 "forceLogoff", 806 "modifiedCount", 807 "lockoutDuration", 808 "lockOutObservationWindow", 809 "lockoutThreshold", 806 "modifiedCount", 807 "lockoutDuration", 808 "lockOutObservationWindow", 809 "lockoutThreshold", 810 810 NULL}; 811 811 attrs = attrs2; … … 814 814 case 12: 815 815 { 816 static const char * const attrs2[] = { "lockoutDuration", 817 "lockOutObservationWindow", 818 "lockoutThreshold", 816 static const char * const attrs2[] = { "lockoutDuration", 817 "lockOutObservationWindow", 818 "lockoutThreshold", 819 819 NULL}; 820 820 attrs = attrs2; … … 823 823 case 13: 824 824 { 825 static const char * const attrs2[] = { "modifiedCount", 826 "creationTime", 825 static const char * const attrs2[] = { "modifiedCount", 826 "creationTime", 827 827 NULL }; 828 828 attrs = attrs2; 829 829 break; 830 } 831 default: 832 { 833 return NT_STATUS_INVALID_INFO_CLASS; 830 834 } 831 835 } … … 836 840 ret = gendb_search_dn(d_state->sam_ctx, mem_ctx, 837 841 d_state->domain_dn, &dom_msgs, attrs); 842 if (ret == 0) { 843 return NT_STATUS_NO_SUCH_DOMAIN; 844 } 838 845 if (ret != 1) { 839 846 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 841 848 } 842 849 850 /* allocate the info structure */ 851 info = talloc_zero(mem_ctx, union samr_DomainInfo); 852 if (info == NULL) { 853 return NT_STATUS_NO_MEMORY; 854 } 855 843 856 *r->out.info = info; 844 845 ZERO_STRUCTP(info);846 857 847 858 switch (r->in.level) { 848 859 case 1: 849 return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs, 860 return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs, 850 861 &info->info1); 851 862 case 2: 852 return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs, 863 return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs, 853 864 &info->general); 854 865 case 3: 855 return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs, 866 return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs, 856 867 &info->info3); 857 868 case 4: 858 return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs, 869 return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs, 859 870 &info->oem); 860 871 case 5: 861 return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs, 872 return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs, 862 873 &info->info5); 863 874 case 6: 864 return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs, 875 return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs, 865 876 &info->info6); 866 877 case 7: 867 return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs, 878 return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs, 868 879 &info->info7); 869 880 case 8: 870 return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs, 881 return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs, 871 882 &info->info8); 872 883 case 9: 873 return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs, 884 return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs, 874 885 &info->info9); 875 886 case 11: 876 return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs, 887 return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs, 877 888 &info->general2); 878 889 case 12: 879 return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs, 890 return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs, 880 891 &info->info12); 881 892 case 13: 882 return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs, 893 return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs, 883 894 &info->info13); 884 }885 886 return NT_STATUS_INVALID_INFO_CLASS;887 } 888 889 890 /* 891 samr_SetDomainInfo 895 default: 896 return NT_STATUS_INVALID_INFO_CLASS; 897 } 898 } 899 900 901 /* 902 samr_SetDomainInfo 892 903 */ 893 904 static NTSTATUS dcesrv_samr_SetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 937 948 938 949 case 12: 939 950 /* 951 * It is not possible to set lockout_duration < lockout_window. 952 * (The test is the other way around since the negative numbers 953 * are stored...) 954 * 955 * TODO: 956 * This check should be moved to the backend, i.e. to some 957 * ldb module under dsdb/samdb/ldb_modules/ . 958 * 959 * This constraint is documented here for the samr rpc service: 960 * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates 961 * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx 962 * 963 * And here for the ldap backend: 964 * MS-ADTS 3.1.1.5.3.2 Constraints 965 * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx 966 */ 967 if (r->in.info->info12.lockout_duration > 968 r->in.info->info12.lockout_window) 969 { 970 return NT_STATUS_INVALID_PARAMETER; 971 } 940 972 SET_INT64 (msg, info12.lockout_duration, "lockoutDuration"); 941 973 SET_INT64 (msg, info12.lockout_window, "lockOutObservationWindow"); … … 950 982 /* modify the samdb record */ 951 983 ret = ldb_modify(sam_ctx, msg); 952 if (ret != 0) {984 if (ret != LDB_SUCCESS) { 953 985 DEBUG(1,("Failed to modify record %s: %s\n", 954 986 ldb_dn_get_linearized(d_state->domain_dn), … … 962 994 } 963 995 964 /* 965 samr_CreateDomainGroup 996 /* 997 samr_CreateDomainGroup 966 998 */ 967 999 static NTSTATUS dcesrv_samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 968 1000 struct samr_CreateDomainGroup *r) 969 1001 { 1002 NTSTATUS status; 970 1003 struct samr_domain_state *d_state; 971 1004 struct samr_account_state *a_state; 972 1005 struct dcesrv_handle *h; 973 const char *name;974 struct ldb_message *msg;975 struct dom_sid *sid;976 1006 const char *groupname; 1007 struct dom_sid *group_sid; 1008 struct ldb_dn *group_dn; 977 1009 struct dcesrv_handle *g_handle; 978 int ret;979 1010 980 1011 ZERO_STRUCTP(r->out.group_handle); … … 996 1027 } 997 1028 998 /* check if the group already exists */ 999 name = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, 1000 "sAMAccountName", 1001 "(&(sAMAccountName=%s)(objectclass=group))", 1002 ldb_binary_encode_string(mem_ctx, groupname)); 1003 if (name != NULL) { 1004 return NT_STATUS_GROUP_EXISTS; 1005 } 1006 1007 msg = ldb_msg_new(mem_ctx); 1008 if (msg == NULL) { 1009 return NT_STATUS_NO_MEMORY; 1010 } 1011 1012 /* add core elements to the ldb_message for the user */ 1013 msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn); 1014 ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname); 1015 if (!msg->dn) { 1016 return NT_STATUS_NO_MEMORY; 1017 } 1018 samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", groupname); 1019 samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", "group"); 1020 1021 /* create the group */ 1022 ret = ldb_add(d_state->sam_ctx, msg); 1023 switch (ret) { 1024 case LDB_SUCCESS: 1025 break; 1026 case LDB_ERR_ENTRY_ALREADY_EXISTS: 1027 DEBUG(0,("Failed to create group record %s: %s\n", 1028 ldb_dn_get_linearized(msg->dn), 1029 ldb_errstring(d_state->sam_ctx))); 1030 return NT_STATUS_GROUP_EXISTS; 1031 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1032 DEBUG(0,("Failed to create group record %s: %s\n", 1033 ldb_dn_get_linearized(msg->dn), 1034 ldb_errstring(d_state->sam_ctx))); 1035 return NT_STATUS_ACCESS_DENIED; 1036 default: 1037 DEBUG(0,("Failed to create group record %s: %s\n", 1038 ldb_dn_get_linearized(msg->dn), 1039 ldb_errstring(d_state->sam_ctx))); 1040 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1041 } 1042 1043 a_state = talloc(d_state, struct samr_account_state); 1029 status = dsdb_add_domain_group(d_state->sam_ctx, mem_ctx, groupname, &group_sid, &group_dn); 1030 if (!NT_STATUS_IS_OK(status)) { 1031 return status; 1032 } 1033 1034 a_state = talloc(mem_ctx, struct samr_account_state); 1044 1035 if (!a_state) { 1045 1036 return NT_STATUS_NO_MEMORY; … … 1048 1039 a_state->access_mask = r->in.access_mask; 1049 1040 a_state->domain_state = talloc_reference(a_state, d_state); 1050 a_state->account_dn = talloc_steal(a_state, msg->dn); 1051 1052 /* retrieve the sid for the group just created */ 1053 sid = samdb_search_dom_sid(d_state->sam_ctx, a_state, 1054 msg->dn, "objectSid", NULL); 1055 if (sid == NULL) { 1056 return NT_STATUS_UNSUCCESSFUL; 1057 } 1058 1059 a_state->account_name = talloc_strdup(a_state, groupname); 1060 if (!a_state->account_name) { 1061 return NT_STATUS_NO_MEMORY; 1062 } 1041 a_state->account_dn = talloc_steal(a_state, group_dn); 1042 1043 a_state->account_name = talloc_steal(a_state, groupname); 1063 1044 1064 1045 /* create the policy handle */ … … 1071 1052 1072 1053 *r->out.group_handle = g_handle->wire_handle; 1073 *r->out.rid = sid->sub_auths[sid->num_auths-1];1054 *r->out.rid = group_sid->sub_auths[group_sid->num_auths-1]; 1074 1055 1075 1056 return NT_STATUS_OK; … … 1085 1066 } 1086 1067 1087 /* 1088 samr_EnumDomainGroups 1068 /* 1069 samr_EnumDomainGroups 1089 1070 */ 1090 1071 static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1094 1075 struct samr_domain_state *d_state; 1095 1076 struct ldb_message **res; 1096 int ldb_cnt, count, i, first; 1077 int i, ldb_cnt; 1078 uint32_t first, count; 1097 1079 struct samr_SamEntry *entries; 1098 const char * const attrs[ 3] = { "objectSid", "sAMAccountName", NULL };1080 const char * const attrs[] = { "objectSid", "sAMAccountName", NULL }; 1099 1081 struct samr_SamArray *sam; 1100 1082 … … 1112 1094 d_state->domain_dn, &res, attrs, 1113 1095 d_state->domain_sid, 1114 "(&(grouptype=%d)(objectclass=group))", 1096 "(&(|(groupType=%d)(groupType=%d))(objectClass=group))", 1097 GTYPE_SECURITY_UNIVERSAL_GROUP, 1115 1098 GTYPE_SECURITY_GLOBAL_GROUP); 1116 if (ldb_cnt == -1) {1099 if (ldb_cnt < 0) { 1117 1100 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1118 1101 } … … 1131 1114 group_sid = samdb_result_dom_sid(mem_ctx, res[i], 1132 1115 "objectSid"); 1133 if (group_sid == NULL) 1134 continue; 1116 if (group_sid == NULL) { 1117 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1118 } 1135 1119 1136 1120 entries[count].idx = 1137 1121 group_sid->sub_auths[group_sid->num_auths-1]; 1138 1122 entries[count].name.string = 1139 samdb_result_string(res[i], "sAMAccountName", "");1123 ldb_msg_find_attr_as_string(res[i], "sAMAccountName", ""); 1140 1124 count += 1; 1141 1125 } 1142 1126 1143 1127 /* sort the results by rid */ 1144 qsort(entries, count, sizeof(struct samr_SamEntry), 1145 (comparison_fn_t)compare_SamEntry); 1128 TYPESAFE_QSORT(entries, count, compare_SamEntry); 1146 1129 1147 1130 /* find the first entry to return */ … … 1150 1133 first++) ; 1151 1134 1152 /* return the rest, limit by max_size. Note that we 1135 /* return the rest, limit by max_size. Note that we 1153 1136 use the w2k3 element size value of 54 */ 1154 1137 *r->out.num_entries = count - first; … … 1166 1149 *r->out.sam = sam; 1167 1150 1151 if (first == count) { 1152 return NT_STATUS_OK; 1153 } 1154 1168 1155 if (*r->out.num_entries < count - first) { 1169 1156 *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx; … … 1175 1162 1176 1163 1177 /* 1178 samr_CreateUser2 1164 /* 1165 samr_CreateUser2 1179 1166 1180 1167 This call uses transactions to ensure we don't get a new conflicting … … 1185 1172 struct samr_CreateUser2 *r) 1186 1173 { 1174 NTSTATUS status; 1187 1175 struct samr_domain_state *d_state; 1188 1176 struct samr_account_state *a_state; 1189 1177 struct dcesrv_handle *h; 1190 const char *name; 1191 struct ldb_message *msg; 1178 struct ldb_dn *dn; 1192 1179 struct dom_sid *sid; 1180 struct dcesrv_handle *u_handle; 1193 1181 const char *account_name; 1194 struct dcesrv_handle *u_handle;1195 int ret;1196 const char *container, *obj_class=NULL;1197 char *cn_name;1198 int cn_name_len;1199 1200 const char *attrs[] = {1201 "objectSid",1202 "userAccountControl",1203 NULL1204 };1205 1206 uint32_t user_account_control;1207 1208 struct ldb_message **msgs;1209 1182 1210 1183 ZERO_STRUCTP(r->out.user_handle); … … 1229 1202 } 1230 1203 1231 /* 1232 * Start a transaction, so we can query and do a subsequent atomic 1233 * modify 1234 */ 1235 1236 ret = ldb_transaction_start(d_state->sam_ctx); 1237 if (ret != 0) { 1238 DEBUG(0,("Failed to start a transaction for user creation: %s\n", 1239 ldb_errstring(d_state->sam_ctx))); 1240 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1241 } 1242 1243 /* check if the user already exists */ 1244 name = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, 1245 "sAMAccountName", 1246 "(&(sAMAccountName=%s)(objectclass=user))", 1247 ldb_binary_encode_string(mem_ctx, account_name)); 1248 if (name != NULL) { 1249 ldb_transaction_cancel(d_state->sam_ctx); 1250 return NT_STATUS_USER_EXISTS; 1251 } 1252 1253 msg = ldb_msg_new(mem_ctx); 1254 if (msg == NULL) { 1255 ldb_transaction_cancel(d_state->sam_ctx); 1256 return NT_STATUS_NO_MEMORY; 1257 } 1258 1259 cn_name = talloc_strdup(mem_ctx, account_name); 1260 if (!cn_name) { 1261 ldb_transaction_cancel(d_state->sam_ctx); 1262 return NT_STATUS_NO_MEMORY; 1263 } 1264 1265 cn_name_len = strlen(cn_name); 1266 1267 /* This must be one of these values *only* */ 1268 if (r->in.acct_flags == ACB_NORMAL) { 1269 container = "CN=Users"; 1270 obj_class = "user"; 1271 1272 } else if (r->in.acct_flags == ACB_WSTRUST) { 1273 if (cn_name[cn_name_len - 1] != '$') { 1274 ldb_transaction_cancel(d_state->sam_ctx); 1275 return NT_STATUS_FOOBAR; 1276 } 1277 cn_name[cn_name_len - 1] = '\0'; 1278 container = "CN=Computers"; 1279 obj_class = "computer"; 1280 samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, 1281 "primaryGroupID", DOMAIN_RID_DOMAIN_MEMBERS); 1282 1283 } else if (r->in.acct_flags == ACB_SVRTRUST) { 1284 if (cn_name[cn_name_len - 1] != '$') { 1285 ldb_transaction_cancel(d_state->sam_ctx); 1286 return NT_STATUS_FOOBAR; 1287 } 1288 cn_name[cn_name_len - 1] = '\0'; 1289 container = "OU=Domain Controllers"; 1290 obj_class = "computer"; 1291 samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, 1292 "primaryGroupID", DOMAIN_RID_DCS); 1293 } else { 1294 ldb_transaction_cancel(d_state->sam_ctx); 1295 return NT_STATUS_INVALID_PARAMETER; 1296 } 1297 1298 /* add core elements to the ldb_message for the user */ 1299 msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn); 1300 if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) { 1301 ldb_transaction_cancel(d_state->sam_ctx); 1302 return NT_STATUS_FOOBAR; 1303 } 1304 1305 samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", 1306 account_name); 1307 samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", 1308 obj_class); 1309 1310 /* create the user */ 1311 ret = ldb_add(d_state->sam_ctx, msg); 1312 switch (ret) { 1313 case LDB_SUCCESS: 1314 break; 1315 case LDB_ERR_ENTRY_ALREADY_EXISTS: 1316 ldb_transaction_cancel(d_state->sam_ctx); 1317 DEBUG(0,("Failed to create user record %s: %s\n", 1318 ldb_dn_get_linearized(msg->dn), 1319 ldb_errstring(d_state->sam_ctx))); 1320 return NT_STATUS_USER_EXISTS; 1321 case LDB_ERR_UNWILLING_TO_PERFORM: 1322 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1323 ldb_transaction_cancel(d_state->sam_ctx); 1324 DEBUG(0,("Failed to create user record %s: %s\n", 1325 ldb_dn_get_linearized(msg->dn), 1326 ldb_errstring(d_state->sam_ctx))); 1327 return NT_STATUS_ACCESS_DENIED; 1328 default: 1329 ldb_transaction_cancel(d_state->sam_ctx); 1330 DEBUG(0,("Failed to create user record %s: %s\n", 1331 ldb_dn_get_linearized(msg->dn), 1332 ldb_errstring(d_state->sam_ctx))); 1333 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1334 } 1335 1336 a_state = talloc(d_state, struct samr_account_state); 1204 status = dsdb_add_user(d_state->sam_ctx, mem_ctx, account_name, r->in.acct_flags, &sid, &dn); 1205 if (!NT_STATUS_IS_OK(status)) { 1206 return status; 1207 } 1208 a_state = talloc(mem_ctx, struct samr_account_state); 1337 1209 if (!a_state) { 1338 1210 ldb_transaction_cancel(d_state->sam_ctx); … … 1342 1214 a_state->access_mask = r->in.access_mask; 1343 1215 a_state->domain_state = talloc_reference(a_state, d_state); 1344 a_state->account_dn = talloc_steal(a_state, msg->dn); 1345 1346 /* retrieve the sid and account control bits for the user just created */ 1347 ret = gendb_search_dn(d_state->sam_ctx, a_state, 1348 msg->dn, &msgs, attrs); 1349 1350 if (ret != 1) { 1351 ldb_transaction_cancel(d_state->sam_ctx); 1352 DEBUG(0,("Apparently we failed to create an account record, as %s now doesn't exist\n", 1353 ldb_dn_get_linearized(msg->dn))); 1354 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1355 } 1356 sid = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid"); 1357 if (sid == NULL) { 1358 ldb_transaction_cancel(d_state->sam_ctx); 1359 DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n", 1360 ldb_dn_get_linearized(msg->dn))); 1361 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1362 } 1363 1364 /* Change the account control to be the correct account type. 1365 * The default is for a workstation account */ 1366 user_account_control = samdb_result_uint(msgs[0], "userAccountControl", 0); 1367 user_account_control = (user_account_control & 1368 ~(UF_NORMAL_ACCOUNT | 1369 UF_INTERDOMAIN_TRUST_ACCOUNT | 1370 UF_WORKSTATION_TRUST_ACCOUNT | 1371 UF_SERVER_TRUST_ACCOUNT)); 1372 user_account_control |= ds_acb2uf(r->in.acct_flags); 1373 1374 talloc_free(msg); 1375 msg = ldb_msg_new(mem_ctx); 1376 if (msg == NULL) { 1377 ldb_transaction_cancel(d_state->sam_ctx); 1378 return NT_STATUS_NO_MEMORY; 1379 } 1380 1381 msg->dn = ldb_dn_copy(msg, a_state->account_dn); 1382 1383 if (samdb_msg_add_uint(a_state->sam_ctx, mem_ctx, msg, 1384 "userAccountControl", 1385 user_account_control) != 0) { 1386 ldb_transaction_cancel(d_state->sam_ctx); 1387 return NT_STATUS_NO_MEMORY; 1388 } 1389 1390 /* modify the samdb record */ 1391 ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg); 1392 if (ret != 0) { 1393 DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n", 1394 ldb_dn_get_linearized(msg->dn), 1395 ldb_errstring(d_state->sam_ctx))); 1396 ldb_transaction_cancel(d_state->sam_ctx); 1397 1398 /* we really need samdb.c to return NTSTATUS */ 1399 return NT_STATUS_UNSUCCESSFUL; 1400 } 1401 1402 ret = ldb_transaction_commit(d_state->sam_ctx); 1403 if (ret != 0) { 1404 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n", 1405 ldb_dn_get_linearized(msg->dn), 1406 ldb_errstring(d_state->sam_ctx))); 1407 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1408 } 1216 a_state->account_dn = talloc_steal(a_state, dn); 1409 1217 1410 1218 a_state->account_name = talloc_steal(a_state, account_name); … … 1430 1238 1431 1239 1432 /* 1433 samr_CreateUser 1240 /* 1241 samr_CreateUser 1434 1242 */ 1435 1243 static NTSTATUS dcesrv_samr_CreateUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1452 1260 } 1453 1261 1454 /* 1455 samr_EnumDomainUsers 1262 /* 1263 samr_EnumDomainUsers 1456 1264 */ 1457 1265 static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1460 1268 struct dcesrv_handle *h; 1461 1269 struct samr_domain_state *d_state; 1462 struct ldb_result *res; 1463 int ret, num_filtered_entries, i, first; 1270 struct ldb_message **res; 1271 int i, ldb_cnt; 1272 uint32_t first, count; 1464 1273 struct samr_SamEntry *entries; 1465 1274 const char * const attrs[] = { "objectSid", "sAMAccountName", … … 1474 1283 1475 1284 d_state = h->data; 1476 1477 /* don't have to worry about users in the builtin domain, as there are none */ 1478 ret = ldb_search(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=user"); 1479 1480 if (ret != LDB_SUCCESS) { 1481 DEBUG(3, ("Failed to search for Domain Users in %s: %s\n", 1482 ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(d_state->sam_ctx))); 1285 1286 /* search for all domain users in this domain. This could possibly be 1287 cached and resumed on resume_key */ 1288 ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx, 1289 d_state->domain_dn, 1290 &res, attrs, 1291 d_state->domain_sid, 1292 "(objectClass=user)"); 1293 if (ldb_cnt < 0) { 1483 1294 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1484 1295 } 1485 1296 1486 1297 /* convert to SamEntry format */ 1487 entries = talloc_array(mem_ctx, struct samr_SamEntry, res->count);1298 entries = talloc_array(mem_ctx, struct samr_SamEntry, ldb_cnt); 1488 1299 if (!entries) { 1489 1300 return NT_STATUS_NO_MEMORY; 1490 1301 } 1491 num_filtered_entries = 0; 1492 for (i=0;i<res->count;i++) { 1302 1303 count = 0; 1304 1305 for (i=0;i<ldb_cnt;i++) { 1493 1306 /* Check if a mask has been requested */ 1494 1307 if (r->in.acct_flags 1495 && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res->msgs[i],1496 d_state->domain_dn) & r->in.acct_flags) == 0)) {1308 && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, 1309 res[i], d_state->domain_dn) & r->in.acct_flags) == 0)) { 1497 1310 continue; 1498 1311 } 1499 entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res->msgs[i], "objectSid", 0); 1500 entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", ""); 1501 num_filtered_entries++; 1312 entries[count].idx = samdb_result_rid_from_sid(mem_ctx, res[i], 1313 "objectSid", 0); 1314 entries[count].name.string = ldb_msg_find_attr_as_string(res[i], 1315 "sAMAccountName", ""); 1316 count += 1; 1502 1317 } 1503 1318 1504 1319 /* sort the results by rid */ 1505 qsort(entries, num_filtered_entries, sizeof(struct samr_SamEntry), 1506 (comparison_fn_t)compare_SamEntry); 1320 TYPESAFE_QSORT(entries, count, compare_SamEntry); 1507 1321 1508 1322 /* find the first entry to return */ 1509 1323 for (first=0; 1510 first< num_filtered_entries&& entries[first].idx <= *r->in.resume_handle;1324 first<count && entries[first].idx <= *r->in.resume_handle; 1511 1325 first++) ; 1512 1326 1513 /* return the rest, limit by max_size. Note that we 1327 /* return the rest, limit by max_size. Note that we 1514 1328 use the w2k3 element size value of 54 */ 1515 *r->out.num_entries = num_filtered_entries- first;1329 *r->out.num_entries = count - first; 1516 1330 *r->out.num_entries = MIN(*r->out.num_entries, 1517 1331 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER)); … … 1527 1341 *r->out.sam = sam; 1528 1342 1529 if (first == num_filtered_entries) {1343 if (first == count) { 1530 1344 return NT_STATUS_OK; 1531 1345 } 1532 1346 1533 if (*r->out.num_entries < num_filtered_entries- first) {1347 if (*r->out.num_entries < count - first) { 1534 1348 *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx; 1535 1349 return STATUS_MORE_ENTRIES; … … 1540 1354 1541 1355 1542 /* 1543 samr_CreateDomAlias 1356 /* 1357 samr_CreateDomAlias 1544 1358 */ 1545 1359 static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1549 1363 struct samr_account_state *a_state; 1550 1364 struct dcesrv_handle *h; 1551 const char *alias_name, *name; 1552 struct ldb_message *msg; 1365 const char *alias_name; 1553 1366 struct dom_sid *sid; 1554 1367 struct dcesrv_handle *a_handle; 1555 int ret; 1368 struct ldb_dn *dn; 1369 NTSTATUS status; 1556 1370 1557 1371 ZERO_STRUCTP(r->out.alias_handle); … … 1573 1387 } 1574 1388 1575 /* Check if alias already exists */ 1576 name = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, 1577 "sAMAccountName", 1578 "(sAMAccountName=%s)(objectclass=group))", 1579 ldb_binary_encode_string(mem_ctx, alias_name)); 1580 1581 if (name != NULL) { 1582 return NT_STATUS_ALIAS_EXISTS; 1583 } 1584 1585 msg = ldb_msg_new(mem_ctx); 1586 if (msg == NULL) { 1587 return NT_STATUS_NO_MEMORY; 1588 } 1589 1590 /* add core elements to the ldb_message for the alias */ 1591 msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn); 1592 ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name); 1593 if (!msg->dn) { 1594 return NT_STATUS_NO_MEMORY; 1595 } 1596 1597 samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", alias_name); 1598 samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", "group"); 1599 samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); 1600 1601 /* create the alias */ 1602 ret = ldb_add(d_state->sam_ctx, msg); 1603 switch (ret) { 1604 case LDB_SUCCESS: 1605 break; 1606 case LDB_ERR_ENTRY_ALREADY_EXISTS: 1607 return NT_STATUS_ALIAS_EXISTS; 1608 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 1609 return NT_STATUS_ACCESS_DENIED; 1610 default: 1611 DEBUG(0,("Failed to create alias record %s: %s\n", 1612 ldb_dn_get_linearized(msg->dn), 1613 ldb_errstring(d_state->sam_ctx))); 1614 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1615 } 1616 1617 a_state = talloc(d_state, struct samr_account_state); 1389 status = dsdb_add_domain_alias(d_state->sam_ctx, mem_ctx, alias_name, &sid, &dn); 1390 if (!NT_STATUS_IS_OK(status)) { 1391 return status; 1392 } 1393 1394 a_state = talloc(mem_ctx, struct samr_account_state); 1618 1395 if (!a_state) { 1619 1396 return NT_STATUS_NO_MEMORY; … … 1623 1400 a_state->access_mask = r->in.access_mask; 1624 1401 a_state->domain_state = talloc_reference(a_state, d_state); 1625 a_state->account_dn = talloc_steal(a_state, msg->dn); 1626 1627 /* retrieve the sid for the alias just created */ 1628 sid = samdb_search_dom_sid(d_state->sam_ctx, a_state, 1629 msg->dn, "objectSid", NULL); 1630 1631 a_state->account_name = talloc_strdup(a_state, alias_name); 1632 if (!a_state->account_name) { 1633 return NT_STATUS_NO_MEMORY; 1634 } 1402 a_state->account_dn = talloc_steal(a_state, dn); 1403 1404 a_state->account_name = talloc_steal(a_state, alias_name); 1635 1405 1636 1406 /* create the policy handle */ … … 1649 1419 1650 1420 1651 /* 1652 samr_EnumDomainAliases 1421 /* 1422 samr_EnumDomainAliases 1653 1423 */ 1654 1424 static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1658 1428 struct samr_domain_state *d_state; 1659 1429 struct ldb_message **res; 1660 int ldb_cnt, count, i, first; 1430 int i, ldb_cnt; 1431 uint32_t first, count; 1661 1432 struct samr_SamEntry *entries; 1662 const char * const attrs[ 3] = { "objectSid", "sAMAccountName", NULL };1433 const char * const attrs[] = { "objectSid", "sAMAccountName", NULL }; 1663 1434 struct samr_SamArray *sam; 1664 1435 … … 1671 1442 d_state = h->data; 1672 1443 1673 /* search for all domain groups in this domain. This could possibly be1444 /* search for all domain aliases in this domain. This could possibly be 1674 1445 cached and resumed based on resume_key */ 1675 ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx, 1676 d_state->domain_dn, 1677 &res, attrs, 1446 ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx, NULL, 1447 &res, attrs, 1678 1448 d_state->domain_sid, 1679 1449 "(&(|(grouptype=%d)(grouptype=%d)))" … … 1681 1451 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, 1682 1452 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); 1683 if (ldb_cnt == -1) {1453 if (ldb_cnt < 0) { 1684 1454 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1685 }1686 if (ldb_cnt == 0) {1687 return NT_STATUS_OK;1688 1455 } 1689 1456 … … 1702 1469 "objectSid"); 1703 1470 1704 if (alias_sid == NULL) 1705 continue; 1471 if (alias_sid == NULL) { 1472 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1473 } 1706 1474 1707 1475 entries[count].idx = 1708 1476 alias_sid->sub_auths[alias_sid->num_auths-1]; 1709 1477 entries[count].name.string = 1710 samdb_result_string(res[i], "sAMAccountName", "");1478 ldb_msg_find_attr_as_string(res[i], "sAMAccountName", ""); 1711 1479 count += 1; 1712 1480 } 1713 1481 1714 1482 /* sort the results by rid */ 1715 qsort(entries, count, sizeof(struct samr_SamEntry), 1716 (comparison_fn_t)compare_SamEntry); 1483 TYPESAFE_QSORT(entries, count, compare_SamEntry); 1717 1484 1718 1485 /* find the first entry to return */ … … 1721 1488 first++) ; 1722 1489 1490 /* return the rest, limit by max_size. Note that we 1491 use the w2k3 element size value of 54 */ 1492 *r->out.num_entries = count - first; 1493 *r->out.num_entries = MIN(*r->out.num_entries, 1494 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER)); 1495 1496 sam = talloc(mem_ctx, struct samr_SamArray); 1497 if (!sam) { 1498 return NT_STATUS_NO_MEMORY; 1499 } 1500 1501 sam->entries = entries+first; 1502 sam->count = *r->out.num_entries; 1503 1504 *r->out.sam = sam; 1505 1723 1506 if (first == count) { 1724 1507 return NT_STATUS_OK; 1725 1508 } 1726 1727 *r->out.num_entries = count - first;1728 *r->out.num_entries = MIN(*r->out.num_entries, 1000);1729 1730 sam = talloc(mem_ctx, struct samr_SamArray);1731 if (!sam) {1732 return NT_STATUS_NO_MEMORY;1733 }1734 1735 sam->entries = entries+first;1736 sam->count = *r->out.num_entries;1737 1738 *r->out.sam = sam;1739 1509 1740 1510 if (*r->out.num_entries < count - first) { … … 1748 1518 1749 1519 1750 /* 1751 samr_GetAliasMembership 1520 /* 1521 samr_GetAliasMembership 1752 1522 */ 1753 1523 static NTSTATUS dcesrv_samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1756 1526 struct dcesrv_handle *h; 1757 1527 struct samr_domain_state *d_state; 1528 const char *filter; 1529 const char * const attrs[] = { "objectSid", NULL }; 1758 1530 struct ldb_message **res; 1759 int i, count = 0; 1531 uint32_t i; 1532 int count = 0; 1760 1533 1761 1534 DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); … … 1763 1536 d_state = h->data; 1764 1537 1765 if (r->in.sids->num_sids > 0) { 1766 const char *filter; 1767 const char * const attrs[2] = { "objectSid", NULL }; 1768 1769 filter = talloc_asprintf(mem_ctx, 1770 "(&(|(grouptype=%d)(grouptype=%d))" 1771 "(objectclass=group)(|", 1772 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, 1773 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); 1774 if (filter == NULL) 1538 filter = talloc_asprintf(mem_ctx, 1539 "(&(|(grouptype=%d)(grouptype=%d))" 1540 "(objectclass=group)(|", 1541 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, 1542 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); 1543 if (filter == NULL) { 1544 return NT_STATUS_NO_MEMORY; 1545 } 1546 1547 for (i=0; i<r->in.sids->num_sids; i++) { 1548 const char *memberdn; 1549 1550 memberdn = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, 1551 "distinguishedName", 1552 "(objectSid=%s)", 1553 ldap_encode_ndr_dom_sid(mem_ctx, 1554 r->in.sids->sids[i].sid)); 1555 if (memberdn == NULL) { 1556 continue; 1557 } 1558 1559 filter = talloc_asprintf(mem_ctx, "%s(member=%s)", filter, 1560 memberdn); 1561 if (filter == NULL) { 1775 1562 return NT_STATUS_NO_MEMORY; 1776 1777 for (i=0; i<r->in.sids->num_sids; i++) {1778 const char *memberdn;1779 1780 memberdn =1781 samdb_search_string(d_state->sam_ctx,1782 mem_ctx, NULL,1783 "distinguishedName",1784 "(objectSid=%s)",1785 ldap_encode_ndr_dom_sid(mem_ctx,1786 r->in.sids->sids[i].sid));1787 1788 if (memberdn == NULL)1789 continue;1790 1791 filter = talloc_asprintf(mem_ctx, "%s(member=%s)",1792 filter, memberdn);1793 if (filter == NULL)1794 return NT_STATUS_NO_MEMORY;1795 1563 } 1796 1797 count = samdb_search_domain(d_state->sam_ctx, mem_ctx, 1798 d_state->domain_dn, &res, attrs, 1799 d_state->domain_sid, "%s))", filter); 1800 if (count < 0) 1564 } 1565 1566 /* Find out if we had at least one valid member SID passed - otherwise 1567 * just skip the search. */ 1568 if (strstr(filter, "member") != NULL) { 1569 count = samdb_search_domain(d_state->sam_ctx, mem_ctx, NULL, 1570 &res, attrs, d_state->domain_sid, 1571 "%s))", filter); 1572 if (count < 0) { 1801 1573 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1574 } 1802 1575 } 1803 1576 … … 1811 1584 1812 1585 alias_sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid"); 1813 1814 1586 if (alias_sid == NULL) { 1815 DEBUG(0, ("Could not find objectSid\n")); 1816 continue; 1587 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1817 1588 } 1818 1589 … … 1826 1597 1827 1598 1828 /* 1829 samr_LookupNames 1599 /* 1600 samr_LookupNames 1830 1601 */ 1831 1602 static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1834 1605 struct dcesrv_handle *h; 1835 1606 struct samr_domain_state *d_state; 1836 int i, num_mapped;1607 uint32_t i, num_mapped; 1837 1608 NTSTATUS status = NT_STATUS_OK; 1838 1609 const char * const attrs[] = { "sAMAccountType", "objectSid", NULL }; … … 1868 1639 r->out.types->ids[i] = SID_NAME_UNKNOWN; 1869 1640 1870 count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, 1871 "sAMAccountName=%s", 1641 count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, 1642 "sAMAccountName=%s", 1872 1643 ldb_binary_encode_string(mem_ctx, r->in.names[i].string)); 1873 1644 if (count != 1) { … … 1881 1652 continue; 1882 1653 } 1883 1884 atype = samdb_result_uint(res[0], "sAMAccountType", 0);1654 1655 atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0); 1885 1656 if (atype == 0) { 1886 1657 status = STATUS_SOME_UNMAPPED; … … 1889 1660 1890 1661 rtype = ds_atype_map(atype); 1891 1662 1892 1663 if (rtype == SID_NAME_UNKNOWN) { 1893 1664 status = STATUS_SOME_UNMAPPED; … … 1899 1670 num_mapped++; 1900 1671 } 1901 1672 1902 1673 if (num_mapped == 0) { 1903 1674 return NT_STATUS_NONE_MAPPED; … … 1907 1678 1908 1679 1909 /* 1910 samr_LookupRids 1680 /* 1681 samr_LookupRids 1911 1682 */ 1912 1683 static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1913 1684 struct samr_LookupRids *r) 1914 1685 { 1686 NTSTATUS status; 1915 1687 struct dcesrv_handle *h; 1916 1688 struct samr_domain_state *d_state; 1917 int i, total; 1918 NTSTATUS status = NT_STATUS_OK; 1919 struct lsa_String *names; 1920 uint32_t *ids; 1689 const char **names; 1690 struct lsa_String *lsa_names; 1691 enum lsa_SidType *ids; 1921 1692 1922 1693 ZERO_STRUCTP(r->out.names); … … 1930 1701 return NT_STATUS_OK; 1931 1702 1932 names = talloc_array(mem_ctx, struct lsa_String, r->in.num_rids); 1933 ids = talloc_array(mem_ctx, uint32_t, r->in.num_rids); 1934 1935 if ((names == NULL) || (ids == NULL)) 1936 return NT_STATUS_NO_MEMORY; 1937 1938 total = 0; 1939 1940 for (i=0; i<r->in.num_rids; i++) { 1941 struct ldb_message **res; 1942 int count; 1943 const char * const attrs[] = { "sAMAccountType", 1944 "sAMAccountName", NULL }; 1945 uint32_t atype; 1946 struct dom_sid *sid; 1947 1948 ids[i] = SID_NAME_UNKNOWN; 1949 1950 sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, 1951 r->in.rids[i]); 1952 if (sid == NULL) { 1953 names[i].string = NULL; 1954 status = STATUS_SOME_UNMAPPED; 1955 continue; 1703 lsa_names = talloc_zero_array(mem_ctx, struct lsa_String, r->in.num_rids); 1704 names = talloc_zero_array(mem_ctx, const char *, r->in.num_rids); 1705 ids = talloc_zero_array(mem_ctx, enum lsa_SidType, r->in.num_rids); 1706 1707 if ((lsa_names == NULL) || (names == NULL) || (ids == NULL)) 1708 return NT_STATUS_NO_MEMORY; 1709 1710 r->out.names->names = lsa_names; 1711 r->out.names->count = r->in.num_rids; 1712 1713 r->out.types->ids = (uint32_t *) ids; 1714 r->out.types->count = r->in.num_rids; 1715 1716 status = dsdb_lookup_rids(d_state->sam_ctx, mem_ctx, d_state->domain_sid, 1717 r->in.num_rids, r->in.rids, names, ids); 1718 if (NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) || NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { 1719 uint32_t i; 1720 for (i = 0; i < r->in.num_rids; i++) { 1721 lsa_names[i].string = names[i]; 1956 1722 } 1957 1958 count = gendb_search(d_state->sam_ctx, mem_ctx, 1959 d_state->domain_dn, &res, attrs, 1960 "(objectSid=%s)", 1961 ldap_encode_ndr_dom_sid(mem_ctx, sid)); 1962 if (count != 1) { 1963 names[i].string = NULL; 1964 status = STATUS_SOME_UNMAPPED; 1965 continue; 1966 } 1967 1968 names[i].string = samdb_result_string(res[0], "sAMAccountName", 1969 NULL); 1970 1971 atype = samdb_result_uint(res[0], "sAMAccountType", 0); 1972 if (atype == 0) { 1973 status = STATUS_SOME_UNMAPPED; 1974 continue; 1975 } 1976 1977 ids[i] = ds_atype_map(atype); 1978 1979 if (ids[i] == SID_NAME_UNKNOWN) { 1980 status = STATUS_SOME_UNMAPPED; 1981 continue; 1982 } 1983 } 1984 1985 r->out.names->names = names; 1986 r->out.names->count = r->in.num_rids; 1987 1988 r->out.types->ids = ids; 1989 r->out.types->count = r->in.num_rids; 1990 1723 } 1991 1724 return status; 1992 1725 } 1993 1726 1994 1727 1995 /* 1996 samr_OpenGroup 1728 /* 1729 samr_OpenGroup 1997 1730 */ 1998 1731 static NTSTATUS dcesrv_samr_OpenGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2024 1757 ret = gendb_search(d_state->sam_ctx, 2025 1758 mem_ctx, d_state->domain_dn, &msgs, attrs, 2026 "(&(objectSid=%s)(object class=group)"2027 "( grouptype=%d))",1759 "(&(objectSid=%s)(objectClass=group)" 1760 "(|(groupType=%d)(groupType=%d)))", 2028 1761 ldap_encode_ndr_dom_sid(mem_ctx, sid), 1762 GTYPE_SECURITY_UNIVERSAL_GROUP, 2029 1763 GTYPE_SECURITY_GLOBAL_GROUP); 2030 1764 if (ret == 0) { … … 2032 1766 } 2033 1767 if (ret != 1) { 2034 DEBUG(0,("Found %d records matching sid %s\n", 1768 DEBUG(0,("Found %d records matching sid %s\n", 2035 1769 ret, dom_sid_string(mem_ctx, sid))); 2036 1770 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2037 1771 } 2038 1772 2039 groupname = samdb_result_string(msgs[0], "sAMAccountName", NULL);1773 groupname = ldb_msg_find_attr_as_string(msgs[0], "sAMAccountName", NULL); 2040 1774 if (groupname == NULL) { 2041 DEBUG(0,("sAMAccountName field missing for sid %s\n", 1775 DEBUG(0,("sAMAccountName field missing for sid %s\n", 2042 1776 dom_sid_string(mem_ctx, sid))); 2043 1777 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2044 1778 } 2045 1779 2046 a_state = talloc( d_state, struct samr_account_state);1780 a_state = talloc(mem_ctx, struct samr_account_state); 2047 1781 if (!a_state) { 2048 1782 return NT_STATUS_NO_MEMORY; … … 2071 1805 } 2072 1806 2073 /* 2074 samr_QueryGroupInfo 1807 /* 1808 samr_QueryGroupInfo 2075 1809 */ 2076 1810 static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2079 1813 struct dcesrv_handle *h; 2080 1814 struct samr_account_state *a_state; 2081 struct ldb_message *msg; 2082 struct ldb_result *res; 1815 struct ldb_message *msg, **res; 2083 1816 const char * const attrs[4] = { "sAMAccountName", "description", 2084 1817 "numMembers", NULL }; … … 2091 1824 2092 1825 a_state = h->data; 2093 2094 ret = ldb_search(a_state->sam_ctx, mem_ctx, &res, a_state->account_dn,2095 LDB_SCOPE_SUBTREE, attrs, "objectClass=*");2096 2097 if (ret == LDB_ERR_NO_SUCH_OBJECT) {1826 1827 /* pull all the group attributes */ 1828 ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, 1829 a_state->account_dn, &res, attrs); 1830 if (ret == 0) { 2098 1831 return NT_STATUS_NO_SUCH_GROUP; 2099 } else if (ret != LDB_SUCCESS) {2100 DEBUG(2, ("Error reading group info: %s\n", ldb_errstring(a_state->sam_ctx)));1832 } 1833 if (ret != 1) { 2101 1834 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2102 1835 } 2103 2104 if (res->count != 1) { 2105 DEBUG(2, ("Error finding group info, got %d entries\n", res->count)); 2106 2107 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2108 } 2109 msg = res->msgs[0]; 1836 msg = res[0]; 2110 1837 2111 1838 /* allocate the info structure */ … … 2149 1876 2150 1877 2151 /* 2152 samr_SetGroupInfo 1878 /* 1879 samr_SetGroupInfo 2153 1880 */ 2154 1881 static NTSTATUS dcesrv_samr_SetGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2169 1896 if (msg == NULL) { 2170 1897 return NT_STATUS_NO_MEMORY; 2171 } 1898 } 2172 1899 2173 1900 msg->dn = ldb_dn_copy(mem_ctx, g_state->account_dn); … … 2194 1921 /* modify the samdb record */ 2195 1922 ret = ldb_modify(g_state->sam_ctx, msg); 2196 if (ret != 0) {1923 if (ret != LDB_SUCCESS) { 2197 1924 /* we really need samdb.c to return NTSTATUS */ 2198 1925 return NT_STATUS_UNSUCCESSFUL; … … 2203 1930 2204 1931 2205 /* 2206 samr_AddGroupMember 1932 /* 1933 samr_AddGroupMember 2207 1934 */ 2208 1935 static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2225 1952 2226 1953 membersid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); 2227 if (membersid == NULL) 2228 return NT_STATUS_NO_MEMORY; 2229 2230 /* In native mode, AD can also nest domain groups. Not sure yet 2231 * whether this is also available via RPC.*/1954 if (membersid == NULL) { 1955 return NT_STATUS_NO_MEMORY; 1956 } 1957 1958 /* according to MS-SAMR 3.1.5.8.2 all type of accounts are accepted */ 2232 1959 ret = ldb_search(d_state->sam_ctx, mem_ctx, &res, 2233 2234 "(&(objectSid=%s)(objectclass=user))",2235 2236 2237 if (ret != 0) {1960 d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, 1961 "(objectSid=%s)", 1962 ldap_encode_ndr_dom_sid(mem_ctx, membersid)); 1963 1964 if (ret != LDB_SUCCESS) { 2238 1965 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2239 1966 } … … 2242 1969 return NT_STATUS_NO_SUCH_USER; 2243 1970 } 2244 1971 2245 1972 if (res->count > 1) { 2246 1973 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 2259 1986 mod->dn = talloc_reference(mem_ctx, a_state->account_dn); 2260 1987 2261 if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", 2262 memberdn) != 0) 1988 ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", 1989 memberdn); 1990 if (ret != LDB_SUCCESS) { 2263 1991 return NT_STATUS_UNSUCCESSFUL; 1992 } 2264 1993 2265 1994 ret = ldb_modify(a_state->sam_ctx, mod); … … 2267 1996 case LDB_SUCCESS: 2268 1997 return NT_STATUS_OK; 2269 case LDB_ERR_ ATTRIBUTE_OR_VALUE_EXISTS:1998 case LDB_ERR_ENTRY_ALREADY_EXISTS: 2270 1999 return NT_STATUS_MEMBER_IN_GROUP; 2271 2000 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: … … 2274 2003 return NT_STATUS_UNSUCCESSFUL; 2275 2004 } 2276 2277 } 2278 2279 2280 /* 2281 samr_DeleteDomainGroup 2005 } 2006 2007 2008 /* 2009 samr_DeleteDomainGroup 2282 2010 */ 2283 2011 static NTSTATUS dcesrv_samr_DeleteDomainGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2295 2023 2296 2024 ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); 2297 if (ret != 0) {2025 if (ret != LDB_SUCCESS) { 2298 2026 return NT_STATUS_UNSUCCESSFUL; 2299 2027 } 2300 2028 2029 talloc_free(h); 2301 2030 ZERO_STRUCTP(r->out.group_handle); 2302 2031 … … 2305 2034 2306 2035 2307 /* 2308 samr_DeleteGroupMember 2036 /* 2037 samr_DeleteGroupMember 2309 2038 */ 2310 2039 static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2327 2056 2328 2057 membersid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); 2329 if (membersid == NULL) 2330 return NT_STATUS_NO_MEMORY; 2331 2332 /* In native mode, AD can also nest domain groups. Not sure yet 2333 * whether this is also available via RPC.*/2058 if (membersid == NULL) { 2059 return NT_STATUS_NO_MEMORY; 2060 } 2061 2062 /* according to MS-SAMR 3.1.5.8.2 all type of accounts are accepted */ 2334 2063 ret = ldb_search(d_state->sam_ctx, mem_ctx, &res, 2335 2336 "(&(objectSid=%s)(objectclass=user))",2337 2338 2339 if (ret != 0) {2064 d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, 2065 "(objectSid=%s)", 2066 ldap_encode_ndr_dom_sid(mem_ctx, membersid)); 2067 2068 if (ret != LDB_SUCCESS) { 2340 2069 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2341 2070 } … … 2344 2073 return NT_STATUS_NO_SUCH_USER; 2345 2074 } 2346 2075 2347 2076 if (res->count > 1) { 2348 2077 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 2361 2090 mod->dn = talloc_reference(mem_ctx, a_state->account_dn); 2362 2091 2363 if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", 2364 memberdn) != 0) { 2092 ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", 2093 memberdn); 2094 if (ret != LDB_SUCCESS) { 2365 2095 return NT_STATUS_NO_MEMORY; 2366 2096 } … … 2370 2100 case LDB_SUCCESS: 2371 2101 return NT_STATUS_OK; 2372 case LDB_ERR_ NO_SUCH_ATTRIBUTE:2102 case LDB_ERR_UNWILLING_TO_PERFORM: 2373 2103 return NT_STATUS_MEMBER_NOT_IN_GROUP; 2374 2104 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: … … 2380 2110 2381 2111 2382 /* 2383 samr_QueryGroupMember 2112 /* 2113 samr_QueryGroupMember 2384 2114 */ 2385 2115 static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2388 2118 struct dcesrv_handle *h; 2389 2119 struct samr_account_state *a_state; 2390 struct ldb_message **res;2391 struct ldb_message_element *el;2392 struct samr_RidTypeArray *array;2393 const char * const attrs[2] = { "member", NULL };2394 int ret;2120 struct samr_domain_state *d_state; 2121 struct samr_RidAttrArray *array; 2122 unsigned int i, num_members; 2123 struct dom_sid *members; 2124 NTSTATUS status; 2395 2125 2396 2126 DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); 2397 2127 2398 2128 a_state = h->data; 2399 2400 /* pull the member attribute */ 2401 ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, 2402 a_state->account_dn, &res, attrs); 2403 2404 if (ret != 1) { 2405 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2406 } 2407 2408 array = talloc(mem_ctx, struct samr_RidTypeArray); 2409 2410 if (array == NULL) 2411 return NT_STATUS_NO_MEMORY; 2412 2413 ZERO_STRUCTP(array); 2414 2415 el = ldb_msg_find_element(res[0], "member"); 2416 2417 if (el != NULL) { 2418 int i; 2419 2420 array->count = el->num_values; 2421 2422 array->rids = talloc_array(mem_ctx, uint32_t, 2423 el->num_values); 2424 if (array->rids == NULL) 2425 return NT_STATUS_NO_MEMORY; 2426 2427 array->types = talloc_array(mem_ctx, uint32_t, 2428 el->num_values); 2429 if (array->types == NULL) 2430 return NT_STATUS_NO_MEMORY; 2431 2432 for (i=0; i<el->num_values; i++) { 2433 struct ldb_message **res2; 2434 const char * const attrs2[2] = { "objectSid", NULL }; 2435 ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, 2436 ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]), 2437 &res2, attrs2); 2438 if (ret != 1) 2439 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2440 2441 array->rids[i] = 2442 samdb_result_rid_from_sid(mem_ctx, res2[0], 2443 "objectSid", 0); 2444 2445 if (array->rids[i] == 0) 2446 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2447 2448 array->types[i] = 7; /* RID type of some kind, not sure what the value means. */ 2129 d_state = a_state->domain_state; 2130 2131 status = dsdb_enum_group_mem(d_state->sam_ctx, mem_ctx, 2132 a_state->account_dn, &members, 2133 &num_members); 2134 if (!NT_STATUS_IS_OK(status)) { 2135 return status; 2136 } 2137 2138 array = talloc_zero(mem_ctx, struct samr_RidAttrArray); 2139 if (array == NULL) { 2140 return NT_STATUS_NO_MEMORY; 2141 } 2142 2143 if (num_members == 0) { 2144 *r->out.rids = array; 2145 2146 return NT_STATUS_OK; 2147 } 2148 2149 array->rids = talloc_array(array, uint32_t, num_members); 2150 if (array->rids == NULL) { 2151 return NT_STATUS_NO_MEMORY; 2152 } 2153 2154 array->attributes = talloc_array(array, uint32_t, num_members); 2155 if (array->attributes == NULL) { 2156 return NT_STATUS_NO_MEMORY; 2157 } 2158 2159 array->count = 0; 2160 for (i=0; i<num_members; i++) { 2161 if (!dom_sid_in_domain(d_state->domain_sid, &members[i])) { 2162 continue; 2449 2163 } 2164 2165 status = dom_sid_split_rid(NULL, &members[i], NULL, 2166 &array->rids[array->count]); 2167 if (!NT_STATUS_IS_OK(status)) { 2168 return status; 2169 } 2170 2171 array->attributes[array->count] = SE_GROUP_MANDATORY | 2172 SE_GROUP_ENABLED_BY_DEFAULT | 2173 SE_GROUP_ENABLED; 2174 array->count++; 2450 2175 } 2451 2176 … … 2456 2181 2457 2182 2458 /* 2459 samr_SetMemberAttributesOfGroup 2183 /* 2184 samr_SetMemberAttributesOfGroup 2460 2185 */ 2461 2186 static NTSTATUS dcesrv_samr_SetMemberAttributesOfGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2466 2191 2467 2192 2468 /* 2469 samr_OpenAlias 2193 /* 2194 samr_OpenAlias 2470 2195 */ 2471 2196 static NTSTATUS dcesrv_samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2494 2219 2495 2220 /* search for the group record */ 2496 ret = gendb_search(d_state->sam_ctx, 2497 mem_ctx, d_state->domain_dn, &msgs, attrs, 2221 ret = gendb_search(d_state->sam_ctx, mem_ctx, NULL, &msgs, attrs, 2498 2222 "(&(objectSid=%s)(objectclass=group)" 2499 2223 "(|(grouptype=%d)(grouptype=%d)))", … … 2505 2229 } 2506 2230 if (ret != 1) { 2507 DEBUG(0,("Found %d records matching sid %s\n", 2231 DEBUG(0,("Found %d records matching sid %s\n", 2508 2232 ret, dom_sid_string(mem_ctx, sid))); 2509 2233 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2510 2234 } 2511 2235 2512 alias_name = samdb_result_string(msgs[0], "sAMAccountName", NULL);2236 alias_name = ldb_msg_find_attr_as_string(msgs[0], "sAMAccountName", NULL); 2513 2237 if (alias_name == NULL) { 2514 DEBUG(0,("sAMAccountName field missing for sid %s\n", 2238 DEBUG(0,("sAMAccountName field missing for sid %s\n", 2515 2239 dom_sid_string(mem_ctx, sid))); 2516 2240 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2517 2241 } 2518 2242 2519 a_state = talloc( d_state, struct samr_account_state);2243 a_state = talloc(mem_ctx, struct samr_account_state); 2520 2244 if (!a_state) { 2521 2245 return NT_STATUS_NO_MEMORY; … … 2545 2269 2546 2270 2547 /* 2548 samr_QueryAliasInfo 2271 /* 2272 samr_QueryAliasInfo 2549 2273 */ 2550 2274 static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2567 2291 /* pull all the alias attributes */ 2568 2292 ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, 2569 a_state->account_dn ,&res, attrs); 2293 a_state->account_dn, &res, attrs); 2294 if (ret == 0) { 2295 return NT_STATUS_NO_SUCH_ALIAS; 2296 } 2570 2297 if (ret != 1) { 2571 2298 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 2602 2329 2603 2330 2604 /* 2605 samr_SetAliasInfo 2331 /* 2332 samr_SetAliasInfo 2606 2333 */ 2607 2334 static NTSTATUS dcesrv_samr_SetAliasInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2644 2371 /* modify the samdb record */ 2645 2372 ret = ldb_modify(a_state->sam_ctx, msg); 2646 if (ret != 0) {2373 if (ret != LDB_SUCCESS) { 2647 2374 /* we really need samdb.c to return NTSTATUS */ 2648 2375 return NT_STATUS_UNSUCCESSFUL; … … 2653 2380 2654 2381 2655 /* 2656 samr_DeleteDomAlias 2382 /* 2383 samr_DeleteDomAlias 2657 2384 */ 2658 2385 static NTSTATUS dcesrv_samr_DeleteDomAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2670 2397 2671 2398 ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); 2672 if (ret != 0) {2399 if (ret != LDB_SUCCESS) { 2673 2400 return NT_STATUS_UNSUCCESSFUL; 2674 2401 } 2675 2402 2403 talloc_free(h); 2676 2404 ZERO_STRUCTP(r->out.alias_handle); 2677 2405 … … 2680 2408 2681 2409 2682 /* 2683 samr_AddAliasMember 2410 /* 2411 samr_AddAliasMember 2684 2412 */ 2685 2413 static NTSTATUS dcesrv_samr_AddAliasMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2702 2430 2703 2431 ret = gendb_search(d_state->sam_ctx, mem_ctx, NULL, 2704 &msgs, attrs, "(objectsid=%s)", 2432 &msgs, attrs, "(objectsid=%s)", 2705 2433 ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid)); 2706 2434 2707 2435 if (ret == 1) { 2708 2436 memberdn = msgs[0]->dn; 2709 } else if (ret > 1) {2710 DEBUG(0,("Found %d records matching sid %s\n",2711 ret, dom_sid_string(mem_ctx, r->in.sid)));2712 return NT_STATUS_INTERNAL_DB_CORRUPTION;2713 2437 } else if (ret == 0) { 2714 2438 status = samdb_create_foreign_security_principal( … … 2718 2442 } 2719 2443 } else { 2720 DEBUG(0, ("samdb_search returned %d: %s\n", ret, ldb_errstring(d_state->sam_ctx))); 2444 DEBUG(0,("Found %d records matching sid %s\n", 2445 ret, dom_sid_string(mem_ctx, r->in.sid))); 2446 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2721 2447 } 2722 2448 … … 2733 2459 mod->dn = talloc_reference(mem_ctx, a_state->account_dn); 2734 2460 2735 if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", 2736 ldb_dn_alloc_linearized(mem_ctx, memberdn)) != 0) 2461 ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", 2462 ldb_dn_alloc_linearized(mem_ctx, memberdn)); 2463 if (ret != LDB_SUCCESS) { 2737 2464 return NT_STATUS_UNSUCCESSFUL; 2738 2739 if (ldb_modify(a_state->sam_ctx, mod) != 0) 2465 } 2466 2467 ret = ldb_modify(a_state->sam_ctx, mod); 2468 switch (ret) { 2469 case LDB_SUCCESS: 2470 return NT_STATUS_OK; 2471 case LDB_ERR_ENTRY_ALREADY_EXISTS: 2472 return NT_STATUS_MEMBER_IN_GROUP; 2473 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 2474 return NT_STATUS_ACCESS_DENIED; 2475 default: 2740 2476 return NT_STATUS_UNSUCCESSFUL; 2741 2742 return NT_STATUS_OK; 2743 } 2744 2745 2746 /* 2747 samr_DeleteAliasMember 2477 } 2478 } 2479 2480 2481 /* 2482 samr_DeleteAliasMember 2748 2483 */ 2749 2484 static NTSTATUS dcesrv_samr_DeleteAliasMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2755 2490 struct ldb_message *mod; 2756 2491 const char *memberdn; 2492 int ret; 2757 2493 2758 2494 DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS); … … 2762 2498 2763 2499 memberdn = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, 2764 "distinguishedName", "(objectSid=%s)", 2500 "distinguishedName", "(objectSid=%s)", 2765 2501 ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid)); 2766 2767 if (memberdn == NULL) 2502 if (memberdn == NULL) { 2768 2503 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 2504 } 2769 2505 2770 2506 mod = ldb_msg_new(mem_ctx); … … 2775 2511 mod->dn = talloc_reference(mem_ctx, a_state->account_dn); 2776 2512 2777 if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", 2778 memberdn) != 0) 2513 ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", 2514 memberdn); 2515 if (ret != LDB_SUCCESS) { 2779 2516 return NT_STATUS_UNSUCCESSFUL; 2780 2781 if (ldb_modify(a_state->sam_ctx, mod) != 0) 2517 } 2518 2519 ret = ldb_modify(a_state->sam_ctx, mod); 2520 switch (ret) { 2521 case LDB_SUCCESS: 2522 return NT_STATUS_OK; 2523 case LDB_ERR_UNWILLING_TO_PERFORM: 2524 return NT_STATUS_MEMBER_NOT_IN_GROUP; 2525 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 2526 return NT_STATUS_ACCESS_DENIED; 2527 default: 2782 2528 return NT_STATUS_UNSUCCESSFUL; 2783 2784 return NT_STATUS_OK; 2785 } 2786 2787 2788 /* 2789 samr_GetMembersInAlias 2529 } 2530 } 2531 2532 2533 /* 2534 samr_GetMembersInAlias 2790 2535 */ 2791 2536 static NTSTATUS dcesrv_samr_GetMembersInAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2795 2540 struct samr_account_state *a_state; 2796 2541 struct samr_domain_state *d_state; 2797 struct ldb_message **msgs; 2798 struct lsa_SidPtr *sids; 2799 struct ldb_message_element *el; 2800 const char * const attrs[2] = { "member", NULL}; 2801 int ret; 2542 struct lsa_SidPtr *array; 2543 unsigned int i, num_members; 2544 struct dom_sid *members; 2545 NTSTATUS status; 2802 2546 2803 2547 DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS); … … 2806 2550 d_state = a_state->domain_state; 2807 2551 2808 ret = gendb_search_dn(d_state->sam_ctx, mem_ctx, 2809 a_state->account_dn, &msgs, attrs); 2810 2811 if (ret == -1) { 2812 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2813 } else if (ret == 0) { 2814 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 2815 } else if (ret != 1) { 2816 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2817 } 2818 2819 r->out.sids->num_sids = 0; 2820 r->out.sids->sids = NULL; 2821 2822 el = ldb_msg_find_element(msgs[0], "member"); 2823 2824 if (el != NULL) { 2825 int i; 2826 2827 sids = talloc_array(mem_ctx, struct lsa_SidPtr, 2828 el->num_values); 2829 2830 if (sids == NULL) 2831 return NT_STATUS_NO_MEMORY; 2832 2833 for (i=0; i<el->num_values; i++) { 2834 struct ldb_message **msgs2; 2835 const char * const attrs2[2] = { "objectSid", NULL }; 2836 ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, 2837 ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]), 2838 &msgs2, attrs2); 2839 if (ret != 1) 2840 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2841 2842 sids[i].sid = samdb_result_dom_sid(mem_ctx, msgs2[0], 2843 "objectSid"); 2844 2845 if (sids[i].sid == NULL) 2846 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2847 } 2848 r->out.sids->num_sids = el->num_values; 2849 r->out.sids->sids = sids; 2850 } 2851 2852 return NT_STATUS_OK; 2853 } 2854 2855 /* 2856 samr_OpenUser 2552 status = dsdb_enum_group_mem(d_state->sam_ctx, mem_ctx, 2553 a_state->account_dn, &members, 2554 &num_members); 2555 if (!NT_STATUS_IS_OK(status)) { 2556 return status; 2557 } 2558 2559 if (num_members == 0) { 2560 r->out.sids->sids = NULL; 2561 2562 return NT_STATUS_OK; 2563 } 2564 2565 array = talloc_array(mem_ctx, struct lsa_SidPtr, num_members); 2566 if (array == NULL) { 2567 return NT_STATUS_NO_MEMORY; 2568 } 2569 2570 for (i=0; i<num_members; i++) { 2571 array[i].sid = &members[i]; 2572 } 2573 2574 r->out.sids->num_sids = num_members; 2575 r->out.sids->sids = array; 2576 2577 return NT_STATUS_OK; 2578 } 2579 2580 /* 2581 samr_OpenUser 2857 2582 */ 2858 2583 static NTSTATUS dcesrv_samr_OpenUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2884 2609 ret = gendb_search(d_state->sam_ctx, 2885 2610 mem_ctx, d_state->domain_dn, &msgs, attrs, 2886 "(&(objectSid=%s)(objectclass=user))", 2611 "(&(objectSid=%s)(objectclass=user))", 2887 2612 ldap_encode_ndr_dom_sid(mem_ctx, sid)); 2888 2613 if (ret == 0) { … … 2890 2615 } 2891 2616 if (ret != 1) { 2892 DEBUG(0,("Found %d records matching sid %s\n", ret, 2617 DEBUG(0,("Found %d records matching sid %s\n", ret, 2893 2618 dom_sid_string(mem_ctx, sid))); 2894 2619 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2895 2620 } 2896 2621 2897 account_name = samdb_result_string(msgs[0], "sAMAccountName", NULL);2622 account_name = ldb_msg_find_attr_as_string(msgs[0], "sAMAccountName", NULL); 2898 2623 if (account_name == NULL) { 2899 DEBUG(0,("sAMAccountName field missing for sid %s\n", 2624 DEBUG(0,("sAMAccountName field missing for sid %s\n", 2900 2625 dom_sid_string(mem_ctx, sid))); 2901 2626 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 2931 2656 2932 2657 2933 /* 2934 samr_DeleteUser 2658 /* 2659 samr_DeleteUser 2935 2660 */ 2936 2661 static NTSTATUS dcesrv_samr_DeleteUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2948 2673 2949 2674 ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); 2950 if (ret != 0) {2951 DEBUG(1, ("Failed to delete user: %s: %s\n", 2952 ldb_dn_get_linearized(a_state->account_dn), 2675 if (ret != LDB_SUCCESS) { 2676 DEBUG(1, ("Failed to delete user: %s: %s\n", 2677 ldb_dn_get_linearized(a_state->account_dn), 2953 2678 ldb_errstring(a_state->sam_ctx))); 2954 2679 return NT_STATUS_UNSUCCESSFUL; 2955 2680 } 2956 2681 2682 talloc_free(h); 2957 2683 ZERO_STRUCTP(r->out.user_handle); 2958 2684 … … 2961 2687 2962 2688 2963 /* 2964 samr_QueryUserInfo 2689 /* 2690 samr_QueryUserInfo 2965 2691 */ 2966 2692 static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3036 2762 case 5: 3037 2763 { 3038 static const char * const attrs2[] = {"sAMAccountName", 2764 static const char * const attrs2[] = {"sAMAccountName", 3039 2765 "displayName", 3040 2766 "objectSid", … … 3042 2768 "homeDirectory", 3043 2769 "homeDrive", 3044 "scriptPath", 2770 "scriptPath", 3045 2771 "profilePath", 3046 2772 "description", … … 3137 2863 attrs = attrs2; 3138 2864 break; 2865 } 2866 case 18: 2867 { 2868 return NT_STATUS_NOT_SUPPORTED; 3139 2869 } 3140 2870 case 20: … … 3173 2903 break; 3174 2904 } 2905 case 23: 2906 case 24: 2907 case 25: 2908 case 26: 2909 { 2910 return NT_STATUS_NOT_SUPPORTED; 2911 } 2912 default: 2913 { 2914 return NT_STATUS_INVALID_INFO_CLASS; 2915 } 3175 2916 } 3176 2917 3177 2918 /* pull all the user attributes */ 3178 2919 ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, 3179 a_state->account_dn ,&res, attrs); 2920 a_state->account_dn, &res, attrs); 2921 if (ret == 0) { 2922 return NT_STATUS_NO_SUCH_USER; 2923 } 3180 2924 if (ret != 1) { 3181 2925 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 3321 3065 QUERY_UINT (msg, info21.primary_gid, "primaryGroupID"); 3322 3066 QUERY_AFLAGS(msg, info21.acct_flags, "userAccountControl"); 3323 info->info21.fields_present = 0x0 0FFFFFF;3067 info->info21.fields_present = 0x08FFFFFF; 3324 3068 QUERY_LHOURS(msg, info21.logon_hours, "logonHours"); 3325 3069 QUERY_UINT (msg, info21.bad_password_count, "badPwdCount"); 3326 3070 QUERY_UINT (msg, info21.logon_count, "logonCount"); 3071 if ((info->info21.acct_flags & ACB_PW_EXPIRED) != 0) { 3072 info->info21.password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON; 3073 } else { 3074 info->info21.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON; 3075 } 3327 3076 QUERY_UINT (msg, info21.country_code, "countryCode"); 3328 3077 QUERY_UINT (msg, info21.code_page, "codePage"); 3329 3078 break; 3330 3079 3331 3080 3332 3081 default: … … 3341 3090 3342 3091 3343 /* 3344 samr_SetUserInfo 3092 /* 3093 samr_SetUserInfo 3345 3094 */ 3346 3095 static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3426 3175 break; 3427 3176 3177 case 18: 3178 status = samr_set_password_buffers(dce_call, 3179 a_state->sam_ctx, 3180 a_state->account_dn, 3181 a_state->domain_state->domain_dn, 3182 mem_ctx, 3183 r->in.info->info18.lm_pwd_active ? r->in.info->info18.lm_pwd.hash : NULL, 3184 r->in.info->info18.nt_pwd_active ? r->in.info->info18.nt_pwd.hash : NULL); 3185 if (!NT_STATUS_IS_OK(status)) { 3186 return status; 3187 } 3188 3189 if (r->in.info->info18.password_expired > 0) { 3190 struct ldb_message_element *set_el; 3191 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, "pwdLastSet", 0) != LDB_SUCCESS) { 3192 return NT_STATUS_NO_MEMORY; 3193 } 3194 set_el = ldb_msg_find_element(msg, "pwdLastSet"); 3195 set_el->flags = LDB_FLAG_MOD_REPLACE; 3196 } 3197 break; 3198 3428 3199 case 20: 3429 3200 SET_PARAMETERS(msg, info20.parameters, "userParameters"); … … 3431 3202 3432 3203 case 21: 3204 if (r->in.info->info21.fields_present == 0) 3205 return NT_STATUS_INVALID_PARAMETER; 3206 3433 3207 #define IFSET(bit) if (bit & r->in.info->info21.fields_present) 3208 IFSET(SAMR_FIELD_LAST_LOGON) 3209 SET_UINT64(msg, info21.last_logon, "lastLogon"); 3210 IFSET(SAMR_FIELD_LAST_LOGOFF) 3211 SET_UINT64(msg, info21.last_logoff, "lastLogoff"); 3434 3212 IFSET(SAMR_FIELD_ACCT_EXPIRY) 3435 3213 SET_UINT64(msg, info21.acct_expiry, "accountExpires"); 3436 IFSET(SAMR_FIELD_ACCOUNT_NAME) 3214 IFSET(SAMR_FIELD_ACCOUNT_NAME) 3437 3215 SET_STRING(msg, info21.account_name, "samAccountName"); 3438 IFSET(SAMR_FIELD_FULL_NAME) 3216 IFSET(SAMR_FIELD_FULL_NAME) 3439 3217 SET_STRING(msg, info21.full_name, "displayName"); 3440 3218 IFSET(SAMR_FIELD_HOME_DIRECTORY) … … 3452 3230 IFSET(SAMR_FIELD_COMMENT) 3453 3231 SET_STRING(msg, info21.comment, "comment"); 3454 IFSET(SAMR_FIELD_PARAMETERS) 3232 IFSET(SAMR_FIELD_PARAMETERS) 3455 3233 SET_PARAMETERS(msg, info21.parameters, "userParameters"); 3456 3234 IFSET(SAMR_FIELD_PRIMARY_GID) … … 3460 3238 IFSET(SAMR_FIELD_LOGON_HOURS) 3461 3239 SET_LHOURS(msg, info21.logon_hours, "logonHours"); 3240 IFSET(SAMR_FIELD_BAD_PWD_COUNT) 3241 SET_UINT (msg, info21.bad_password_count, "badPwdCount"); 3242 IFSET(SAMR_FIELD_NUM_LOGONS) 3243 SET_UINT (msg, info21.logon_count, "logonCount"); 3462 3244 IFSET(SAMR_FIELD_COUNTRY_CODE) 3463 3245 SET_UINT (msg, info21.country_code, "countryCode"); 3464 3246 IFSET(SAMR_FIELD_CODE_PAGE) 3465 3247 SET_UINT (msg, info21.code_page, "codePage"); 3248 3249 /* password change fields */ 3250 IFSET(SAMR_FIELD_LAST_PWD_CHANGE) 3251 return NT_STATUS_ACCESS_DENIED; 3252 3253 IFSET((SAMR_FIELD_LM_PASSWORD_PRESENT 3254 | SAMR_FIELD_NT_PASSWORD_PRESENT)) { 3255 uint8_t *lm_pwd_hash = NULL, *nt_pwd_hash = NULL; 3256 3257 if (r->in.info->info21.lm_password_set) { 3258 if ((r->in.info->info21.lm_owf_password.length != 16) 3259 || (r->in.info->info21.lm_owf_password.size != 16)) { 3260 return NT_STATUS_INVALID_PARAMETER; 3261 } 3262 3263 lm_pwd_hash = (uint8_t *) r->in.info->info21.lm_owf_password.array; 3264 } 3265 if (r->in.info->info21.nt_password_set) { 3266 if ((r->in.info->info21.nt_owf_password.length != 16) 3267 || (r->in.info->info21.nt_owf_password.size != 16)) { 3268 return NT_STATUS_INVALID_PARAMETER; 3269 } 3270 3271 nt_pwd_hash = (uint8_t *) r->in.info->info21.nt_owf_password.array; 3272 } 3273 status = samr_set_password_buffers(dce_call, 3274 a_state->sam_ctx, 3275 a_state->account_dn, 3276 a_state->domain_state->domain_dn, 3277 mem_ctx, 3278 lm_pwd_hash, 3279 nt_pwd_hash); 3280 if (!NT_STATUS_IS_OK(status)) { 3281 return status; 3282 } 3283 } 3284 3285 3286 IFSET(SAMR_FIELD_EXPIRED_FLAG) { 3287 NTTIME t = 0; 3288 struct ldb_message_element *set_el; 3289 if (r->in.info->info21.password_expired 3290 == PASS_DONT_CHANGE_AT_NEXT_LOGON) { 3291 unix_to_nt_time(&t, time(NULL)); 3292 } 3293 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, 3294 "pwdLastSet", t) != LDB_SUCCESS) { 3295 return NT_STATUS_NO_MEMORY; 3296 } 3297 set_el = ldb_msg_find_element(msg, "pwdLastSet"); 3298 set_el->flags = LDB_FLAG_MOD_REPLACE; 3299 } 3466 3300 #undef IFSET 3467 3301 break; 3468 3302 3469 3303 case 23: 3304 if (r->in.info->info23.info.fields_present == 0) 3305 return NT_STATUS_INVALID_PARAMETER; 3306 3470 3307 #define IFSET(bit) if (bit & r->in.info->info23.info.fields_present) 3308 IFSET(SAMR_FIELD_LAST_LOGON) 3309 SET_UINT64(msg, info23.info.last_logon, "lastLogon"); 3310 IFSET(SAMR_FIELD_LAST_LOGOFF) 3311 SET_UINT64(msg, info23.info.last_logoff, "lastLogoff"); 3471 3312 IFSET(SAMR_FIELD_ACCT_EXPIRY) 3472 3313 SET_UINT64(msg, info23.info.acct_expiry, "accountExpires"); 3473 IFSET(SAMR_FIELD_ACCOUNT_NAME) 3314 IFSET(SAMR_FIELD_ACCOUNT_NAME) 3474 3315 SET_STRING(msg, info23.info.account_name, "samAccountName"); 3475 3316 IFSET(SAMR_FIELD_FULL_NAME) … … 3497 3338 IFSET(SAMR_FIELD_LOGON_HOURS) 3498 3339 SET_LHOURS(msg, info23.info.logon_hours, "logonHours"); 3340 IFSET(SAMR_FIELD_BAD_PWD_COUNT) 3341 SET_UINT (msg, info23.info.bad_password_count, "badPwdCount"); 3342 IFSET(SAMR_FIELD_NUM_LOGONS) 3343 SET_UINT (msg, info23.info.logon_count, "logonCount"); 3344 3499 3345 IFSET(SAMR_FIELD_COUNTRY_CODE) 3500 3346 SET_UINT (msg, info23.info.country_code, "countryCode"); 3501 3347 IFSET(SAMR_FIELD_CODE_PAGE) 3502 3348 SET_UINT (msg, info23.info.code_page, "codePage"); 3349 3350 /* password change fields */ 3351 IFSET(SAMR_FIELD_LAST_PWD_CHANGE) 3352 return NT_STATUS_ACCESS_DENIED; 3503 3353 3504 3354 IFSET(SAMR_FIELD_NT_PASSWORD_PRESENT) { … … 3507 3357 a_state->account_dn, 3508 3358 a_state->domain_state->domain_dn, 3509 mem_ctx, msg,3359 mem_ctx, 3510 3360 &r->in.info->info23.password); 3511 3361 } else IFSET(SAMR_FIELD_LM_PASSWORD_PRESENT) { … … 3514 3364 a_state->account_dn, 3515 3365 a_state->domain_state->domain_dn, 3516 mem_ctx, msg,3366 mem_ctx, 3517 3367 &r->in.info->info23.password); 3368 } 3369 if (!NT_STATUS_IS_OK(status)) { 3370 return status; 3371 } 3372 3373 IFSET(SAMR_FIELD_EXPIRED_FLAG) { 3374 NTTIME t = 0; 3375 struct ldb_message_element *set_el; 3376 if (r->in.info->info23.info.password_expired 3377 == PASS_DONT_CHANGE_AT_NEXT_LOGON) { 3378 unix_to_nt_time(&t, time(NULL)); 3379 } 3380 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, 3381 "pwdLastSet", t) != LDB_SUCCESS) { 3382 return NT_STATUS_NO_MEMORY; 3383 } 3384 set_el = ldb_msg_find_element(msg, "pwdLastSet"); 3385 set_el->flags = LDB_FLAG_MOD_REPLACE; 3518 3386 } 3519 3387 #undef IFSET … … 3526 3394 a_state->account_dn, 3527 3395 a_state->domain_state->domain_dn, 3528 mem_ctx, msg,3396 mem_ctx, 3529 3397 &r->in.info->info24.password); 3398 if (!NT_STATUS_IS_OK(status)) { 3399 return status; 3400 } 3401 3402 if (r->in.info->info24.password_expired > 0) { 3403 struct ldb_message_element *set_el; 3404 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, "pwdLastSet", 0) != LDB_SUCCESS) { 3405 return NT_STATUS_NO_MEMORY; 3406 } 3407 set_el = ldb_msg_find_element(msg, "pwdLastSet"); 3408 set_el->flags = LDB_FLAG_MOD_REPLACE; 3409 } 3530 3410 break; 3531 3411 3532 3412 case 25: 3413 if (r->in.info->info25.info.fields_present == 0) 3414 return NT_STATUS_INVALID_PARAMETER; 3415 3533 3416 #define IFSET(bit) if (bit & r->in.info->info25.info.fields_present) 3417 IFSET(SAMR_FIELD_LAST_LOGON) 3418 SET_UINT64(msg, info25.info.last_logon, "lastLogon"); 3419 IFSET(SAMR_FIELD_LAST_LOGOFF) 3420 SET_UINT64(msg, info25.info.last_logoff, "lastLogoff"); 3534 3421 IFSET(SAMR_FIELD_ACCT_EXPIRY) 3535 3422 SET_UINT64(msg, info25.info.acct_expiry, "accountExpires"); 3536 IFSET(SAMR_FIELD_ACCOUNT_NAME) 3423 IFSET(SAMR_FIELD_ACCOUNT_NAME) 3537 3424 SET_STRING(msg, info25.info.account_name, "samAccountName"); 3538 3425 IFSET(SAMR_FIELD_FULL_NAME) … … 3560 3447 IFSET(SAMR_FIELD_LOGON_HOURS) 3561 3448 SET_LHOURS(msg, info25.info.logon_hours, "logonHours"); 3449 IFSET(SAMR_FIELD_BAD_PWD_COUNT) 3450 SET_UINT (msg, info25.info.bad_password_count, "badPwdCount"); 3451 IFSET(SAMR_FIELD_NUM_LOGONS) 3452 SET_UINT (msg, info25.info.logon_count, "logonCount"); 3562 3453 IFSET(SAMR_FIELD_COUNTRY_CODE) 3563 3454 SET_UINT (msg, info25.info.country_code, "countryCode"); 3564 3455 IFSET(SAMR_FIELD_CODE_PAGE) 3565 3456 SET_UINT (msg, info25.info.code_page, "codePage"); 3457 3458 /* password change fields */ 3459 IFSET(SAMR_FIELD_LAST_PWD_CHANGE) 3460 return NT_STATUS_ACCESS_DENIED; 3566 3461 3567 3462 IFSET(SAMR_FIELD_NT_PASSWORD_PRESENT) { … … 3570 3465 a_state->account_dn, 3571 3466 a_state->domain_state->domain_dn, 3572 mem_ctx, msg,3467 mem_ctx, 3573 3468 &r->in.info->info25.password); 3574 3469 } else IFSET(SAMR_FIELD_LM_PASSWORD_PRESENT) { … … 3577 3472 a_state->account_dn, 3578 3473 a_state->domain_state->domain_dn, 3579 mem_ctx, msg,3474 mem_ctx, 3580 3475 &r->in.info->info25.password); 3476 } 3477 if (!NT_STATUS_IS_OK(status)) { 3478 return status; 3479 } 3480 3481 IFSET(SAMR_FIELD_EXPIRED_FLAG) { 3482 NTTIME t = 0; 3483 struct ldb_message_element *set_el; 3484 if (r->in.info->info25.info.password_expired 3485 == PASS_DONT_CHANGE_AT_NEXT_LOGON) { 3486 unix_to_nt_time(&t, time(NULL)); 3487 } 3488 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, 3489 "pwdLastSet", t) != LDB_SUCCESS) { 3490 return NT_STATUS_NO_MEMORY; 3491 } 3492 set_el = ldb_msg_find_element(msg, "pwdLastSet"); 3493 set_el->flags = LDB_FLAG_MOD_REPLACE; 3581 3494 } 3582 3495 #undef IFSET … … 3589 3502 a_state->account_dn, 3590 3503 a_state->domain_state->domain_dn, 3591 mem_ctx, msg,3504 mem_ctx, 3592 3505 &r->in.info->info26.password); 3593 break; 3594 3506 if (!NT_STATUS_IS_OK(status)) { 3507 return status; 3508 } 3509 3510 if (r->in.info->info26.password_expired > 0) { 3511 struct ldb_message_element *set_el; 3512 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, "pwdLastSet", 0) != LDB_SUCCESS) { 3513 return NT_STATUS_NO_MEMORY; 3514 } 3515 set_el = ldb_msg_find_element(msg, "pwdLastSet"); 3516 set_el->flags = LDB_FLAG_MOD_REPLACE; 3517 } 3518 break; 3595 3519 3596 3520 default: … … 3604 3528 3605 3529 /* modify the samdb record */ 3606 ret = ldb_modify(a_state->sam_ctx, msg); 3607 if (ret != 0) { 3608 DEBUG(1,("Failed to modify record %s: %s\n", 3609 ldb_dn_get_linearized(a_state->account_dn), 3610 ldb_errstring(a_state->sam_ctx))); 3611 3612 /* we really need samdb.c to return NTSTATUS */ 3613 return NT_STATUS_UNSUCCESSFUL; 3614 } 3615 3616 return NT_STATUS_OK; 3617 } 3618 3619 3620 /* 3621 samr_GetGroupsForUser 3530 if (msg->num_elements > 0) { 3531 ret = ldb_modify(a_state->sam_ctx, msg); 3532 if (ret != LDB_SUCCESS) { 3533 DEBUG(1,("Failed to modify record %s: %s\n", 3534 ldb_dn_get_linearized(a_state->account_dn), 3535 ldb_errstring(a_state->sam_ctx))); 3536 3537 /* we really need samdb.c to return NTSTATUS */ 3538 return NT_STATUS_UNSUCCESSFUL; 3539 } 3540 } 3541 3542 return NT_STATUS_OK; 3543 } 3544 3545 3546 /* 3547 samr_GetGroupsForUser 3622 3548 */ 3623 3549 static NTSTATUS dcesrv_samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3640 3566 d_state->domain_dn, &res, 3641 3567 attrs, d_state->domain_sid, 3642 "(&(member=%s)( grouptype=%d)(objectclass=group))",3568 "(&(member=%s)(|(grouptype=%d)(grouptype=%d))(objectclass=group))", 3643 3569 ldb_dn_get_linearized(a_state->account_dn), 3570 GTYPE_SECURITY_UNIVERSAL_GROUP, 3644 3571 GTYPE_SECURITY_GLOBAL_GROUP); 3645 3572 if (count < 0) … … 3672 3599 group_sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid"); 3673 3600 if (group_sid == NULL) { 3674 DEBUG(0, ("Couldn't find objectSid attrib\n")); 3675 continue; 3601 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3676 3602 } 3677 3603 … … 3689 3615 3690 3616 3691 /* 3692 samr_QueryDisplayInfo 3617 /* 3618 samr_QueryDisplayInfo 3693 3619 */ 3694 3620 static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3697 3623 struct dcesrv_handle *h; 3698 3624 struct samr_domain_state *d_state; 3699 struct ldb_message **res; 3700 int ldb_cnt, count, i; 3625 struct ldb_result *res; 3626 unsigned int i; 3627 uint32_t count; 3701 3628 const char * const attrs[] = { "objectSid", "sAMAccountName", 3702 3629 "displayName", "description", "userAccountControl", … … 3707 3634 struct samr_DispEntryGeneral *entriesGeneral = NULL; 3708 3635 const char *filter; 3636 int ret; 3709 3637 3710 3638 DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); … … 3716 3644 case 4: 3717 3645 filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)" 3718 "(sAMAccountType=% u))",3646 "(sAMAccountType=%d))", 3719 3647 ATYPE_NORMAL_ACCOUNT); 3720 3648 break; 3721 3649 case 2: 3722 3650 filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)" 3723 "(sAMAccountType=% u))",3651 "(sAMAccountType=%d))", 3724 3652 ATYPE_WORKSTATION_TRUST); 3725 3653 break; 3726 3654 case 3: 3727 3655 case 5: 3728 filter = talloc_asprintf(mem_ctx, "(&(grouptype=%d)" 3729 "(objectclass=group))", 3656 filter = talloc_asprintf(mem_ctx, 3657 "(&(|(groupType=%d)(groupType=%d))" 3658 "(objectClass=group))", 3659 GTYPE_SECURITY_UNIVERSAL_GROUP, 3730 3660 GTYPE_SECURITY_GLOBAL_GROUP); 3731 3661 break; … … 3734 3664 } 3735 3665 3736 /* search for all requested objects in this domain. This could3666 /* search for all requested objects in all domains. This could 3737 3667 possibly be cached and resumed based on resume_key */ 3738 ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx, 3739 d_state->domain_dn, &res, attrs, 3740 d_state->domain_sid, "%s", filter); 3741 if (ldb_cnt == -1) { 3668 ret = dsdb_search(d_state->sam_ctx, mem_ctx, &res, NULL, 3669 LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter); 3670 if (ret != LDB_SUCCESS) { 3742 3671 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3743 3672 } 3744 if ( ldb_cnt == 0 || r->in.max_entries == 0) {3673 if ((res->count == 0) || (r->in.max_entries == 0)) { 3745 3674 return NT_STATUS_OK; 3746 3675 } … … 3749 3678 case 1: 3750 3679 entriesGeneral = talloc_array(mem_ctx, 3751 struct samr_DispEntryGeneral,3752 ldb_cnt);3680 struct samr_DispEntryGeneral, 3681 res->count); 3753 3682 break; 3754 3683 case 2: 3755 3684 entriesFull = talloc_array(mem_ctx, 3756 3757 ldb_cnt);3685 struct samr_DispEntryFull, 3686 res->count); 3758 3687 break; 3759 3688 case 3: 3760 3689 entriesFullGroup = talloc_array(mem_ctx, 3761 3762 ldb_cnt);3690 struct samr_DispEntryFullGroup, 3691 res->count); 3763 3692 break; 3764 3693 case 4: 3765 3694 case 5: 3766 3695 entriesAscii = talloc_array(mem_ctx, 3767 3768 ldb_cnt);3696 struct samr_DispEntryAscii, 3697 res->count); 3769 3698 break; 3770 3699 } … … 3776 3705 count = 0; 3777 3706 3778 for (i =0; i<ldb_cnt; i++) {3707 for (i = 0; i < res->count; i++) { 3779 3708 struct dom_sid *objectsid; 3780 3709 3781 objectsid = samdb_result_dom_sid(mem_ctx, res [i],3710 objectsid = samdb_result_dom_sid(mem_ctx, res->msgs[i], 3782 3711 "objectSid"); 3783 3712 if (objectsid == NULL) … … 3787 3716 case 1: 3788 3717 entriesGeneral[count].idx = count + 1; 3789 entriesGeneral[count].rid = 3718 entriesGeneral[count].rid = 3790 3719 objectsid->sub_auths[objectsid->num_auths-1]; 3791 3720 entriesGeneral[count].acct_flags = 3792 samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, 3793 res[i], 3721 samdb_result_acct_flags(d_state->sam_ctx, 3722 mem_ctx, 3723 res->msgs[i], 3794 3724 d_state->domain_dn); 3795 3725 entriesGeneral[count].account_name.string = 3796 samdb_result_string(res[i],3797 "sAMAccountName", "");3726 ldb_msg_find_attr_as_string(res->msgs[i], 3727 "sAMAccountName", ""); 3798 3728 entriesGeneral[count].full_name.string = 3799 samdb_result_string(res[i], "displayName", ""); 3729 ldb_msg_find_attr_as_string(res->msgs[i], 3730 "displayName", ""); 3800 3731 entriesGeneral[count].description.string = 3801 samdb_result_string(res[i], "description", ""); 3732 ldb_msg_find_attr_as_string(res->msgs[i], 3733 "description", ""); 3802 3734 break; 3803 3735 case 2: … … 3808 3740 /* No idea why we need to or in ACB_NORMAL here, but this is what Win2k3 seems to do... */ 3809 3741 entriesFull[count].acct_flags = 3810 samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, 3811 res[i], 3742 samdb_result_acct_flags(d_state->sam_ctx, 3743 mem_ctx, 3744 res->msgs[i], 3812 3745 d_state->domain_dn) | ACB_NORMAL; 3813 3746 entriesFull[count].account_name.string = 3814 samdb_result_string(res[i], "sAMAccountName",3815 3747 ldb_msg_find_attr_as_string(res->msgs[i], 3748 "sAMAccountName", ""); 3816 3749 entriesFull[count].description.string = 3817 samdb_result_string(res[i], "description", ""); 3750 ldb_msg_find_attr_as_string(res->msgs[i], 3751 "description", ""); 3818 3752 break; 3819 3753 case 3: … … 3825 3759 = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; 3826 3760 entriesFullGroup[count].account_name.string = 3827 samdb_result_string(res[i], "sAMAccountName",3828 3761 ldb_msg_find_attr_as_string(res->msgs[i], 3762 "sAMAccountName", ""); 3829 3763 entriesFullGroup[count].description.string = 3830 samdb_result_string(res[i], "description", ""); 3764 ldb_msg_find_attr_as_string(res->msgs[i], 3765 "description", ""); 3831 3766 break; 3832 3767 case 4: … … 3834 3769 entriesAscii[count].idx = count + 1; 3835 3770 entriesAscii[count].account_name.string = 3836 samdb_result_string(res[i], "sAMAccountName",3837 3771 ldb_msg_find_attr_as_string(res->msgs[i], 3772 "sAMAccountName", ""); 3838 3773 break; 3839 3774 } … … 3905 3840 3906 3841 3907 /* 3908 samr_GetDisplayEnumerationIndex 3842 /* 3843 samr_GetDisplayEnumerationIndex 3909 3844 */ 3910 3845 static NTSTATUS dcesrv_samr_GetDisplayEnumerationIndex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3915 3850 3916 3851 3917 /* 3918 samr_TestPrivateFunctionsDomain 3852 /* 3853 samr_TestPrivateFunctionsDomain 3919 3854 */ 3920 3855 static NTSTATUS dcesrv_samr_TestPrivateFunctionsDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3925 3860 3926 3861 3927 /* 3928 samr_TestPrivateFunctionsUser 3862 /* 3863 samr_TestPrivateFunctionsUser 3929 3864 */ 3930 3865 static NTSTATUS dcesrv_samr_TestPrivateFunctionsUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3935 3870 3936 3871 3937 /* 3938 samr_GetUserPwInfo 3872 /* 3873 samr_GetUserPwInfo 3939 3874 */ 3940 3875 static NTSTATUS dcesrv_samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3960 3895 3961 3896 3962 /* 3963 samr_RemoveMemberFromForeignDomain 3964 */ 3965 static NTSTATUS dcesrv_samr_RemoveMemberFromForeignDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 3966 struct samr_RemoveMemberFromForeignDomain *r) 3897 /* 3898 samr_RemoveMemberFromForeignDomain 3899 */ 3900 static NTSTATUS dcesrv_samr_RemoveMemberFromForeignDomain(struct dcesrv_call_state *dce_call, 3901 TALLOC_CTX *mem_ctx, 3902 struct samr_RemoveMemberFromForeignDomain *r) 3967 3903 { 3968 3904 struct dcesrv_handle *h; … … 3970 3906 const char *memberdn; 3971 3907 struct ldb_message **res; 3972 const char * const attrs[3] = { "distinguishedName", "objectSid",NULL };3908 const char *no_attrs[] = { NULL }; 3973 3909 int i, count; 3974 3910 … … 3978 3914 3979 3915 memberdn = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, 3980 "distinguishedName", "(objectSid=%s)", 3916 "distinguishedName", "(objectSid=%s)", 3981 3917 ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid)); 3982 3918 /* Nothing to do */ … … 3985 3921 } 3986 3922 3987 /* TODO: Does this call only remove alias members, or does it do this3988 * for domain groups as well? */3989 3990 3923 count = samdb_search_domain(d_state->sam_ctx, mem_ctx, 3991 d_state->domain_dn, &res, attrs,3924 d_state->domain_dn, &res, no_attrs, 3992 3925 d_state->domain_sid, 3993 3926 "(&(member=%s)(objectClass=group)" … … 4008 3941 } 4009 3942 4010 mod->dn = samdb_result_dn(d_state->sam_ctx, mod, res[i], "distinguishedName", NULL); 4011 if (mod->dn == NULL) { 4012 talloc_free(mod); 4013 continue; 4014 } 3943 mod->dn = res[i]->dn; 4015 3944 4016 3945 if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, 4017 "member", memberdn) != 0)3946 "member", memberdn) != LDB_SUCCESS) 4018 3947 return NT_STATUS_NO_MEMORY; 4019 3948 4020 if (ldb_modify(d_state->sam_ctx, mod) != 0)3949 if (ldb_modify(d_state->sam_ctx, mod) != LDB_SUCCESS) 4021 3950 return NT_STATUS_UNSUCCESSFUL; 4022 3951 … … 4028 3957 4029 3958 4030 /* 4031 samr_QueryDomainInfo2 3959 /* 3960 samr_QueryDomainInfo2 4032 3961 4033 3962 just an alias for samr_QueryDomainInfo … … 4045 3974 4046 3975 status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1); 4047 3976 4048 3977 return status; 4049 3978 } 4050 3979 4051 3980 4052 /* 4053 samr_QueryUserInfo2 3981 /* 3982 samr_QueryUserInfo2 4054 3983 4055 3984 just an alias for samr_QueryUserInfo … … 4064 3993 r1.in.level = r->in.level; 4065 3994 r1.out.info = r->out.info; 4066 3995 4067 3996 status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1); 4068 3997 … … 4071 4000 4072 4001 4073 /* 4074 samr_QueryDisplayInfo2 4002 /* 4003 samr_QueryDisplayInfo2 4075 4004 */ 4076 4005 static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4095 4024 4096 4025 4097 /* 4098 samr_GetDisplayEnumerationIndex2 4026 /* 4027 samr_GetDisplayEnumerationIndex2 4099 4028 */ 4100 4029 static NTSTATUS dcesrv_samr_GetDisplayEnumerationIndex2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4105 4034 4106 4035 4107 /* 4108 samr_QueryDisplayInfo3 4036 /* 4037 samr_QueryDisplayInfo3 4109 4038 */ 4110 4039 static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4129 4058 4130 4059 4131 /* 4132 samr_AddMultipleMembersToAlias 4060 /* 4061 samr_AddMultipleMembersToAlias 4133 4062 */ 4134 4063 static NTSTATUS dcesrv_samr_AddMultipleMembersToAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4139 4068 4140 4069 4141 /* 4142 samr_RemoveMultipleMembersFromAlias 4070 /* 4071 samr_RemoveMultipleMembersFromAlias 4143 4072 */ 4144 4073 static NTSTATUS dcesrv_samr_RemoveMultipleMembersFromAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4149 4078 4150 4079 4151 /* 4152 samr_GetDomPwInfo 4080 /* 4081 samr_GetDomPwInfo 4153 4082 4154 4083 this fetches the default password properties for a domain 4155 4084 4156 note that w2k3 completely ignores the domain name in this call, and 4085 note that w2k3 completely ignores the domain name in this call, and 4157 4086 always returns the information for the servers primary domain 4158 4087 */ … … 4167 4096 ZERO_STRUCTP(r->out.info); 4168 4097 4169 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 4098 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 4099 dce_call->conn->dce_ctx->lp_ctx, 4100 dce_call->conn->auth_state.session_info, 0); 4170 4101 if (sam_ctx == NULL) { 4171 4102 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 4173 4104 4174 4105 /* The domain name in this call is ignored */ 4175 ret = gendb_search_dn(sam_ctx, 4106 ret = gendb_search_dn(sam_ctx, 4176 4107 mem_ctx, NULL, &msgs, attrs); 4177 4108 if (ret <= 0) { 4109 talloc_free(sam_ctx); 4110 4178 4111 return NT_STATUS_NO_SUCH_DOMAIN; 4179 4112 } 4180 4113 if (ret > 1) { 4181 4114 talloc_free(msgs); 4115 talloc_free(sam_ctx); 4116 4182 4117 return NT_STATUS_INTERNAL_DB_CORRUPTION; 4183 4118 } 4184 4119 4185 r->out.info->min_password_length = samdb_result_uint(msgs[0],4120 r->out.info->min_password_length = ldb_msg_find_attr_as_uint(msgs[0], 4186 4121 "minPwdLength", 0); 4187 r->out.info->password_properties = samdb_result_uint(msgs[0],4122 r->out.info->password_properties = ldb_msg_find_attr_as_uint(msgs[0], 4188 4123 "pwdProperties", 1); 4189 4124 4190 4125 talloc_free(msgs); 4191 4192 talloc_free(sam_ctx); 4193 return NT_STATUS_OK; 4194 } 4195 4196 4197 /* 4198 samr_Connect2 4126 talloc_unlink(mem_ctx, sam_ctx); 4127 4128 return NT_STATUS_OK; 4129 } 4130 4131 4132 /* 4133 samr_Connect2 4199 4134 */ 4200 4135 static NTSTATUS dcesrv_samr_Connect2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4211 4146 4212 4147 4213 /* 4214 samr_SetUserInfo2 4148 /* 4149 samr_SetUserInfo2 4215 4150 4216 4151 just an alias for samr_SetUserInfo … … 4229 4164 4230 4165 4231 /* 4232 samr_SetBootKeyInformation 4166 /* 4167 samr_SetBootKeyInformation 4233 4168 */ 4234 4169 static NTSTATUS dcesrv_samr_SetBootKeyInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4239 4174 4240 4175 4241 /* 4242 samr_GetBootKeyInformation 4176 /* 4177 samr_GetBootKeyInformation 4243 4178 */ 4244 4179 static NTSTATUS dcesrv_samr_GetBootKeyInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 4245 4180 struct samr_GetBootKeyInformation *r) 4246 4181 { 4247 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 4248 } 4249 4250 4251 /* 4252 samr_Connect3 4182 /* Windows Server 2008 returns this */ 4183 return NT_STATUS_NOT_SUPPORTED; 4184 } 4185 4186 4187 /* 4188 samr_Connect3 4253 4189 */ 4254 4190 static NTSTATUS dcesrv_samr_Connect3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4265 4201 4266 4202 4267 /* 4268 samr_Connect4 4203 /* 4204 samr_Connect4 4269 4205 */ 4270 4206 static NTSTATUS dcesrv_samr_Connect4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4281 4217 4282 4218 4283 /* 4284 samr_Connect5 4219 /* 4220 samr_Connect5 4285 4221 */ 4286 4222 static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4304 4240 4305 4241 4306 /* 4307 samr_RidToSid 4242 /* 4243 samr_RidToSid 4308 4244 */ 4309 4245 static NTSTATUS dcesrv_samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4327 4263 4328 4264 4329 /* 4330 samr_SetDsrmPassword 4265 /* 4266 samr_SetDsrmPassword 4331 4267 */ 4332 4268 static NTSTATUS dcesrv_samr_SetDsrmPassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4337 4273 4338 4274 4339 /* 4340 samr_ValidatePassword 4341 */ 4342 static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 4343 struct samr_ValidatePassword *r) 4344 { 4345 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 4275 /* 4276 samr_ValidatePassword 4277 4278 For now the call checks the password complexity (if active) and the minimum 4279 password length on level 2 and 3. Level 1 is ignored for now. 4280 */ 4281 static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, 4282 TALLOC_CTX *mem_ctx, 4283 struct samr_ValidatePassword *r) 4284 { 4285 struct samr_GetDomPwInfo r2; 4286 struct samr_PwInfo pwInfo; 4287 DATA_BLOB password; 4288 enum samr_ValidationStatus res; 4289 NTSTATUS status; 4290 4291 (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep); 4292 4293 r2.in.domain_name = NULL; 4294 r2.out.info = &pwInfo; 4295 status = dcesrv_samr_GetDomPwInfo(dce_call, mem_ctx, &r2); 4296 if (!NT_STATUS_IS_OK(status)) { 4297 return status; 4298 } 4299 4300 switch (r->in.level) { 4301 case NetValidateAuthentication: 4302 /* we don't support this yet */ 4303 return NT_STATUS_NOT_SUPPORTED; 4304 break; 4305 case NetValidatePasswordChange: 4306 password = data_blob_const(r->in.req->req2.password.string, 4307 r->in.req->req2.password.length); 4308 res = samdb_check_password(&password, 4309 pwInfo.password_properties, 4310 pwInfo.min_password_length); 4311 (*r->out.rep)->ctr2.status = res; 4312 break; 4313 case NetValidatePasswordReset: 4314 password = data_blob_const(r->in.req->req3.password.string, 4315 r->in.req->req3.password.length); 4316 res = samdb_check_password(&password, 4317 pwInfo.password_properties, 4318 pwInfo.min_password_length); 4319 (*r->out.rep)->ctr3.status = res; 4320 break; 4321 default: 4322 return NT_STATUS_INVALID_INFO_CLASS; 4323 break; 4324 } 4325 4326 return NT_STATUS_OK; 4346 4327 } 4347 4328 -
trunk/server/source4/rpc_server/samr/dcesrv_samr.h
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 5 5 6 6 Copyright (C) Andrew Tridgell 2004 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. -
trunk/server/source4/rpc_server/samr/samr_password.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 6 6 Copyright (C) Andrew Tridgell 2004 7 7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 8 8 9 9 This program is free software; you can redistribute it and/or modify 10 10 it under the terms of the GNU General Public License as published by 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 31 31 #include "../lib/util/util_ldb.h" 32 32 33 /* 34 samr_ChangePasswordUser 35 */ 36 NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, 33 /* 34 samr_ChangePasswordUser 35 */ 36 NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, 37 37 TALLOC_CTX *mem_ctx, 38 38 struct samr_ChangePasswordUser *r) … … 41 41 struct samr_account_state *a_state; 42 42 struct ldb_context *sam_ctx; 43 struct ldb_message **res , *msg;43 struct ldb_message **res; 44 44 int ret; 45 45 struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; … … 61 61 } 62 62 63 /* To change a password we need to open as system */ 64 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 63 /* Connect to a SAMDB with system privileges for fetching the old pw 64 * hashes. */ 65 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 66 dce_call->conn->dce_ctx->lp_ctx, 67 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 65 68 if (sam_ctx == NULL) { 66 69 return NT_STATUS_INVALID_SYSTEM_SERVICE; 67 }68 69 ret = ldb_transaction_start(sam_ctx);70 if (ret) {71 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx)));72 return NT_STATUS_TRANSACTION_ABORTED;73 70 } 74 71 … … 77 74 a_state->account_dn, &res, attrs); 78 75 if (ret != 1) { 79 ldb_transaction_cancel(sam_ctx); 80 return NT_STATUS_WRONG_PASSWORD; 81 } 82 msg = res[0]; 83 84 status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 85 msg, &lm_pwd, &nt_pwd); 76 return NT_STATUS_WRONG_PASSWORD; 77 } 78 79 status = samdb_result_passwords(mem_ctx, 80 dce_call->conn->dce_ctx->lp_ctx, 81 res[0], &lm_pwd, &nt_pwd); 86 82 if (!NT_STATUS_IS_OK(status) || !nt_pwd) { 87 ldb_transaction_cancel(sam_ctx);88 83 return NT_STATUS_WRONG_PASSWORD; 89 84 } … … 94 89 D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash); 95 90 if (memcmp(checkHash.hash, lm_pwd, 16) != 0) { 96 ldb_transaction_cancel(sam_ctx);97 91 return NT_STATUS_WRONG_PASSWORD; 98 92 } … … 103 97 D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash); 104 98 if (memcmp(checkHash.hash, nt_pwd, 16) != 0) { 105 ldb_transaction_cancel(sam_ctx); 106 return NT_STATUS_WRONG_PASSWORD; 107 } 108 99 return NT_STATUS_WRONG_PASSWORD; 100 } 101 109 102 /* The NT Cross is not required by Win2k3 R2, but if present 110 103 check the nt cross hash */ … … 112 105 D_P16(lm_pwd->hash, r->in.nt_cross->hash, checkHash.hash); 113 106 if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) { 114 ldb_transaction_cancel(sam_ctx);115 107 return NT_STATUS_WRONG_PASSWORD; 116 108 } … … 122 114 D_P16(nt_pwd->hash, r->in.lm_cross->hash, checkHash.hash); 123 115 if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) { 124 ldb_transaction_cancel(sam_ctx);125 116 return NT_STATUS_WRONG_PASSWORD; 126 117 } 127 118 } 128 119 129 msg = ldb_msg_new(mem_ctx); 130 if (msg == NULL) { 131 ldb_transaction_cancel(sam_ctx); 132 return NT_STATUS_NO_MEMORY; 133 } 134 135 msg->dn = ldb_dn_copy(msg, a_state->account_dn); 136 if (!msg->dn) { 137 ldb_transaction_cancel(sam_ctx); 138 return NT_STATUS_NO_MEMORY; 139 } 140 141 /* setup password modify mods on the user DN specified. This may fail 142 * due to password policies. */ 120 /* Start a SAM with user privileges for the password change */ 121 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 122 dce_call->conn->dce_ctx->lp_ctx, 123 dce_call->conn->auth_state.session_info, 0); 124 if (sam_ctx == NULL) { 125 return NT_STATUS_INVALID_SYSTEM_SERVICE; 126 } 127 128 /* Start transaction */ 129 ret = ldb_transaction_start(sam_ctx); 130 if (ret != LDB_SUCCESS) { 131 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx))); 132 return NT_STATUS_TRANSACTION_ABORTED; 133 } 134 135 /* Performs the password modification. We pass the old hashes read out 136 * from the database since they were already checked against the user- 137 * provided ones. */ 143 138 status = samdb_set_password(sam_ctx, mem_ctx, 144 a_state->account_dn, a_state->domain_state->domain_dn, 145 msg, NULL, &new_lmPwdHash, &new_ntPwdHash, 146 true, /* this is a user password change */ 139 a_state->account_dn, 140 a_state->domain_state->domain_dn, 141 NULL, &new_lmPwdHash, &new_ntPwdHash, 142 lm_pwd, nt_pwd, /* this is a user password change */ 147 143 NULL, 148 144 NULL); … … 152 148 } 153 149 154 /* The above call only setup the modifications, this actually155 * makes the write to the database. */156 ret = samdb_replace(sam_ctx, mem_ctx, msg);157 if (ret != 0) {158 DEBUG(2,("Failed to modify record to change password on %s: %s\n",159 ldb_dn_get_linearized(a_state->account_dn),160 ldb_errstring(sam_ctx)));161 ldb_transaction_cancel(sam_ctx);162 return NT_STATUS_INTERNAL_DB_CORRUPTION;163 }164 165 150 /* And this confirms it in a transaction commit */ 166 151 ret = ldb_transaction_commit(sam_ctx); 167 if (ret != 0) {152 if (ret != LDB_SUCCESS) { 168 153 DEBUG(1,("Failed to commit transaction to change password on %s: %s\n", 169 154 ldb_dn_get_linearized(a_state->account_dn), … … 175 160 } 176 161 177 /* 178 samr_OemChangePasswordUser2 179 */ 180 NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 181 struct samr_OemChangePasswordUser2 *r) 162 /* 163 samr_OemChangePasswordUser2 164 */ 165 NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, 166 TALLOC_CTX *mem_ctx, 167 struct samr_OemChangePasswordUser2 *r) 182 168 { 183 169 NTSTATUS status; … … 188 174 struct ldb_dn *user_dn; 189 175 int ret; 190 struct ldb_message **res , *mod;176 struct ldb_message **res; 191 177 const char * const attrs[] = { "objectSid", "dBCSPwd", NULL }; 192 178 struct samr_Password *lm_pwd; … … 205 191 206 192 /* this call can only work with lanman auth */ 207 if (!lp_lanman_auth(dce_call->conn->dce_ctx->lp_ctx)) { 208 return NT_STATUS_NOT_SUPPORTED; 209 } 210 211 /* To change a password we need to open as system */ 212 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 193 if (!lpcfg_lanman_auth(dce_call->conn->dce_ctx->lp_ctx)) { 194 return NT_STATUS_WRONG_PASSWORD; 195 } 196 197 /* Connect to a SAMDB with system privileges for fetching the old pw 198 * hashes. */ 199 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 200 dce_call->conn->dce_ctx->lp_ctx, 201 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 213 202 if (sam_ctx == NULL) { 214 203 return NT_STATUS_INVALID_SYSTEM_SERVICE; 215 }216 217 ret = ldb_transaction_start(sam_ctx);218 if (ret) {219 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx)));220 return NT_STATUS_TRANSACTION_ABORTED;221 204 } 222 205 … … 224 207 user SID). We also need the current lm password hash in 225 208 order to decrypt the incoming password */ 226 ret = gendb_search(sam_ctx, 209 ret = gendb_search(sam_ctx, 227 210 mem_ctx, NULL, &res, attrs, 228 211 "(&(sAMAccountName=%s)(objectclass=user))", 229 212 r->in.account->string); 230 213 if (ret != 1) { 231 ldb_transaction_cancel(sam_ctx);232 214 /* Don't give the game away: (don't allow anonymous users to prove the existance of usernames) */ 233 215 return NT_STATUS_WRONG_PASSWORD; … … 239 221 res[0], &lm_pwd, NULL); 240 222 if (!NT_STATUS_IS_OK(status) || !lm_pwd) { 241 ldb_transaction_cancel(sam_ctx);242 223 return NT_STATUS_WRONG_PASSWORD; 243 224 } 244 225 245 226 /* decrypt the password we have been given */ 246 lm_pwd_blob = data_blob(lm_pwd->hash, sizeof(lm_pwd->hash)); 227 lm_pwd_blob = data_blob(lm_pwd->hash, sizeof(lm_pwd->hash)); 247 228 arcfour_crypt_blob(pwbuf->data, 516, &lm_pwd_blob); 248 229 data_blob_free(&lm_pwd_blob); 249 230 250 231 if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) { 251 ldb_transaction_cancel(sam_ctx);252 232 DEBUG(3,("samr: failed to decode password buffer\n")); 253 233 return NT_STATUS_WRONG_PASSWORD; 254 234 } 255 256 if (!convert_string_talloc_convenience(mem_ctx, lp _iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),257 CH_DOS, CH_UNIX, 258 (const char *)new_password.data, 235 236 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 237 CH_DOS, CH_UNIX, 238 (const char *)new_password.data, 259 239 new_password.length, 260 240 (void **)&new_pass, NULL, false)) { 261 241 DEBUG(3,("samr: failed to convert incoming password buffer to unix charset\n")); 262 ldb_transaction_cancel(sam_ctx); 263 return NT_STATUS_WRONG_PASSWORD; 264 } 265 266 if (!convert_string_talloc_convenience(mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 267 CH_DOS, CH_UTF16, 268 (const char *)new_password.data, 242 return NT_STATUS_WRONG_PASSWORD; 243 } 244 245 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 246 CH_DOS, CH_UTF16, 247 (const char *)new_password.data, 269 248 new_password.length, 270 249 (void **)&new_unicode_password.data, &unicode_pw_len, false)) { 271 250 DEBUG(3,("samr: failed to convert incoming password buffer to UTF16 charset\n")); 272 ldb_transaction_cancel(sam_ctx);273 251 return NT_STATUS_WRONG_PASSWORD; 274 252 } … … 278 256 E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); 279 257 if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) { 280 ldb_transaction_cancel(sam_ctx); 281 return NT_STATUS_WRONG_PASSWORD; 282 } 283 284 mod = ldb_msg_new(mem_ctx); 285 if (mod == NULL) { 286 ldb_transaction_cancel(sam_ctx); 287 return NT_STATUS_NO_MEMORY; 288 } 289 290 mod->dn = ldb_dn_copy(mod, user_dn); 291 if (!mod->dn) { 292 ldb_transaction_cancel(sam_ctx); 293 return NT_STATUS_NO_MEMORY; 294 } 295 296 /* set the password on the user DN specified. This may fail 297 * due to password policies */ 258 return NT_STATUS_WRONG_PASSWORD; 259 } 260 261 /* Connect to a SAMDB with user privileges for the password change */ 262 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 263 dce_call->conn->dce_ctx->lp_ctx, 264 dce_call->conn->auth_state.session_info, 0); 265 if (sam_ctx == NULL) { 266 return NT_STATUS_INVALID_SYSTEM_SERVICE; 267 } 268 269 /* Start transaction */ 270 ret = ldb_transaction_start(sam_ctx); 271 if (ret != LDB_SUCCESS) { 272 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx))); 273 return NT_STATUS_TRANSACTION_ABORTED; 274 } 275 276 /* Performs the password modification. We pass the old hashes read out 277 * from the database since they were already checked against the user- 278 * provided ones. */ 298 279 status = samdb_set_password(sam_ctx, mem_ctx, 299 user_dn, NULL, 300 mod, &new_unicode_password,280 user_dn, NULL, 281 &new_unicode_password, 301 282 NULL, NULL, 302 true, /* this is a user password change */303 NULL, 283 lm_pwd, NULL, /* this is a user password change */ 284 NULL, 304 285 NULL); 305 286 if (!NT_STATUS_IS_OK(status)) { … … 308 289 } 309 290 310 /* The above call only setup the modifications, this actually311 * makes the write to the database. */312 ret = samdb_replace(sam_ctx, mem_ctx, mod);313 if (ret != 0) {314 DEBUG(2,("Failed to modify record to change password on %s: %s\n",315 ldb_dn_get_linearized(user_dn),316 ldb_errstring(sam_ctx)));317 ldb_transaction_cancel(sam_ctx);318 return NT_STATUS_INTERNAL_DB_CORRUPTION;319 }320 321 291 /* And this confirms it in a transaction commit */ 322 292 ret = ldb_transaction_commit(sam_ctx); 323 if (ret != 0) {293 if (ret != LDB_SUCCESS) { 324 294 DEBUG(1,("Failed to commit transaction to change password on %s: %s\n", 325 295 ldb_dn_get_linearized(user_dn), … … 332 302 333 303 334 /* 335 samr_ChangePasswordUser3 336 */ 337 NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, 338 339 340 { 304 /* 305 samr_ChangePasswordUser3 306 */ 307 NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, 308 TALLOC_CTX *mem_ctx, 309 struct samr_ChangePasswordUser3 *r) 310 { 341 311 NTSTATUS status; 342 312 DATA_BLOB new_password; … … 344 314 struct ldb_dn *user_dn; 345 315 int ret; 346 struct ldb_message **res , *mod;316 struct ldb_message **res; 347 317 const char * const attrs[] = { "unicodePwd", "dBCSPwd", NULL }; 348 318 struct samr_Password *nt_pwd, *lm_pwd; 349 319 DATA_BLOB nt_pwd_blob; 350 320 struct samr_DomInfo1 *dominfo = NULL; 351 struct samr_ChangeReject*reject = NULL;352 enum sam r_RejectReason reason = SAMR_REJECT_OTHER;321 struct userPwdChangeFailureInformation *reject = NULL; 322 enum samPwdChangeReason reason = SAM_PWD_CHANGE_NO_ERROR; 353 323 uint8_t new_nt_hash[16], new_lm_hash[16]; 354 324 struct samr_Password nt_verifier, lm_verifier; … … 362 332 } 363 333 364 /* To change a password we need to open as system */ 365 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 334 /* Connect to a SAMDB with system privileges for fetching the old pw 335 * hashes. */ 336 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 337 dce_call->conn->dce_ctx->lp_ctx, 338 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 366 339 if (sam_ctx == NULL) { 367 340 return NT_STATUS_INVALID_SYSTEM_SERVICE; 368 }369 370 ret = ldb_transaction_start(sam_ctx);371 if (ret) {372 talloc_free(sam_ctx);373 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx)));374 return NT_STATUS_TRANSACTION_ABORTED;375 341 } 376 342 … … 378 344 user SID). We also need the current lm and nt password hashes 379 345 in order to decrypt the incoming passwords */ 380 ret = gendb_search(sam_ctx, 346 ret = gendb_search(sam_ctx, 381 347 mem_ctx, NULL, &res, attrs, 382 348 "(&(sAMAccountName=%s)(objectclass=user))", … … 390 356 user_dn = res[0]->dn; 391 357 392 status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 358 status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 393 359 res[0], &lm_pwd, &nt_pwd); 394 360 if (!NT_STATUS_IS_OK(status) ) { … … 407 373 408 374 if (!extract_pw_from_buffer(mem_ctx, r->in.nt_password->data, &new_password)) { 409 ldb_transaction_cancel(sam_ctx);410 375 DEBUG(3,("samr: failed to decode password buffer\n")); 411 return NT_STATUS_WRONG_PASSWORD; 412 } 413 376 status = NT_STATUS_WRONG_PASSWORD; 377 goto failed; 378 } 379 414 380 if (r->in.nt_verifier == NULL) { 415 381 status = NT_STATUS_WRONG_PASSWORD; … … 431 397 if (lm_pwd && r->in.lm_verifier != NULL) { 432 398 char *new_pass; 433 if (!convert_string_talloc_convenience(mem_ctx, lp _iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),434 CH_UTF16, CH_UNIX, 435 (const char *)new_password.data, 399 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 400 CH_UTF16, CH_UNIX, 401 (const char *)new_password.data, 436 402 new_password.length, 437 403 (void **)&new_pass, NULL, false)) { … … 445 411 } 446 412 447 mod = ldb_msg_new(mem_ctx); 448 if (mod == NULL) { 449 status = NT_STATUS_NO_MEMORY; 450 goto failed; 451 } 452 453 mod->dn = ldb_dn_copy(mod, user_dn); 454 if (!mod->dn) { 455 status = NT_STATUS_NO_MEMORY; 456 goto failed; 457 } 458 459 /* set the password on the user DN specified. This may fail 460 * due to password policies */ 413 /* Connect to a SAMDB with user privileges for the password change */ 414 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 415 dce_call->conn->dce_ctx->lp_ctx, 416 dce_call->conn->auth_state.session_info, 0); 417 if (sam_ctx == NULL) { 418 return NT_STATUS_INVALID_SYSTEM_SERVICE; 419 } 420 421 ret = ldb_transaction_start(sam_ctx); 422 if (ret != LDB_SUCCESS) { 423 DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx))); 424 return NT_STATUS_TRANSACTION_ABORTED; 425 } 426 427 /* Performs the password modification. We pass the old hashes read out 428 * from the database since they were already checked against the user- 429 * provided ones. */ 461 430 status = samdb_set_password(sam_ctx, mem_ctx, 462 user_dn, NULL, 463 mod, &new_password,431 user_dn, NULL, 432 &new_password, 464 433 NULL, NULL, 465 true, /* this is a user password change */466 &reason, 434 lm_pwd, nt_pwd, /* this is a user password change */ 435 &reason, 467 436 &dominfo); 437 468 438 if (!NT_STATUS_IS_OK(status)) { 469 goto failed; 470 } 471 472 /* The above call only setup the modifications, this actually 473 * makes the write to the database. */ 474 ret = samdb_replace(sam_ctx, mem_ctx, mod); 475 if (ret != 0) { 476 DEBUG(2,("samdb_replace failed to change password for %s: %s\n", 477 ldb_dn_get_linearized(user_dn), 478 ldb_errstring(sam_ctx))); 479 status = NT_STATUS_UNSUCCESSFUL; 439 ldb_transaction_cancel(sam_ctx); 480 440 goto failed; 481 441 } … … 483 443 /* And this confirms it in a transaction commit */ 484 444 ret = ldb_transaction_commit(sam_ctx); 485 if (ret != 0) {445 if (ret != LDB_SUCCESS) { 486 446 DEBUG(1,("Failed to commit transaction to change password on %s: %s\n", 487 447 ldb_dn_get_linearized(user_dn), … … 494 454 495 455 failed: 496 ldb_transaction_cancel(sam_ctx); 497 talloc_free(sam_ctx); 498 499 reject = talloc(mem_ctx, struct samr_ChangeReject); 456 reject = talloc_zero(mem_ctx, struct userPwdChangeFailureInformation); 457 if (reject != NULL) { 458 reject->extendedFailureReason = reason; 459 460 *r->out.reject = reject; 461 } 462 500 463 *r->out.dominfo = dominfo; 501 *r->out.reject = reject;502 503 if (reject == NULL) {504 return status;505 }506 ZERO_STRUCTP(reject);507 508 reject->reason = reason;509 464 510 465 return status; … … 512 467 513 468 514 /* 515 samr_ChangePasswordUser2 469 /* 470 samr_ChangePasswordUser2 516 471 517 472 easy - just a subset of samr_ChangePasswordUser3 518 473 */ 519 NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 520 struct samr_ChangePasswordUser2 *r) 474 NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, 475 TALLOC_CTX *mem_ctx, 476 struct samr_ChangePasswordUser2 *r) 521 477 { 522 478 struct samr_ChangePasswordUser3 r2; 523 479 struct samr_DomInfo1 *dominfo = NULL; 524 struct samr_ChangeReject*reject = NULL;480 struct userPwdChangeFailureInformation *reject = NULL; 525 481 526 482 r2.in.server = r->in.server; … … 541 497 /* 542 498 set password via a samr_CryptPassword buffer 543 this will in the 'msg' with modify operations that will update the user544 password when applied545 499 */ 546 500 NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, 547 void*sam_ctx,501 struct ldb_context *sam_ctx, 548 502 struct ldb_dn *account_dn, struct ldb_dn *domain_dn, 549 503 TALLOC_CTX *mem_ctx, 550 struct ldb_message *msg,551 504 struct samr_CryptPassword *pwbuf) 552 505 { … … 566 519 return NT_STATUS_WRONG_PASSWORD; 567 520 } 568 521 569 522 /* set the password - samdb needs to know both the domain and user DNs, 570 523 so the domain password policy can be used */ 571 524 return samdb_set_password(sam_ctx, mem_ctx, 572 account_dn, domain_dn, 573 msg, &new_password,525 account_dn, domain_dn, 526 &new_password, 574 527 NULL, NULL, 575 false, /* This is a password set, not change */528 NULL, NULL, /* This is a password set, not change */ 576 529 NULL, NULL); 577 530 } … … 580 533 /* 581 534 set password via a samr_CryptPasswordEx buffer 582 this will in the 'msg' with modify operations that will update the user583 password when applied584 535 */ 585 536 NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, 586 537 struct ldb_context *sam_ctx, 587 struct ldb_dn *account_dn, struct ldb_dn *domain_dn, 538 struct ldb_dn *account_dn, 539 struct ldb_dn *domain_dn, 588 540 TALLOC_CTX *mem_ctx, 589 struct ldb_message *msg,590 541 struct samr_CryptPasswordEx *pwbuf) 591 542 { … … 610 561 MD5Update(&ctx, session_key.data, session_key.length); 611 562 MD5Final(co_session_key.data, &ctx); 612 563 613 564 arcfour_crypt_blob(pwbuf->data, 516, &co_session_key); 614 565 … … 617 568 return NT_STATUS_WRONG_PASSWORD; 618 569 } 619 570 620 571 /* set the password - samdb needs to know both the domain and user DNs, 621 572 so the domain password policy can be used */ 622 573 return samdb_set_password(sam_ctx, mem_ctx, 623 account_dn, domain_dn, 624 msg, &new_password,574 account_dn, domain_dn, 575 &new_password, 625 576 NULL, NULL, 626 false, /* This is a password set, not change */577 NULL, NULL, /* This is a password set, not change */ 627 578 NULL, NULL); 628 579 } 629 580 630 581 /* 582 set password via encrypted NT and LM hash buffers 583 */ 584 NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, 585 struct ldb_context *sam_ctx, 586 struct ldb_dn *account_dn, 587 struct ldb_dn *domain_dn, 588 TALLOC_CTX *mem_ctx, 589 const uint8_t *lm_pwd_hash, 590 const uint8_t *nt_pwd_hash) 591 { 592 struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL; 593 DATA_BLOB session_key = data_blob(NULL, 0); 594 DATA_BLOB in, out; 595 NTSTATUS nt_status = NT_STATUS_OK; 596 597 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 598 if (!NT_STATUS_IS_OK(nt_status)) { 599 return nt_status; 600 } 601 602 if (lm_pwd_hash != NULL) { 603 in = data_blob_const(lm_pwd_hash, 16); 604 out = data_blob_talloc_zero(mem_ctx, 16); 605 606 sess_crypt_blob(&out, &in, &session_key, false); 607 608 d_lm_pwd_hash = (struct samr_Password *) out.data; 609 } 610 if (nt_pwd_hash != NULL) { 611 in = data_blob_const(nt_pwd_hash, 16); 612 out = data_blob_talloc_zero(mem_ctx, 16); 613 614 sess_crypt_blob(&out, &in, &session_key, false); 615 616 d_nt_pwd_hash = (struct samr_Password *) out.data; 617 } 618 619 if ((d_lm_pwd_hash != NULL) || (d_nt_pwd_hash != NULL)) { 620 nt_status = samdb_set_password(sam_ctx, mem_ctx, account_dn, 621 domain_dn, NULL, 622 d_lm_pwd_hash, d_nt_pwd_hash, 623 NULL, NULL, /* this is a password set */ 624 NULL, NULL); 625 } 626 627 return nt_status; 628 } -
trunk/server/source4/rpc_server/service_rpc.c
r414 r745 28 28 #include "rpc_server/dcerpc_server.h" 29 29 #include "rpc_server/dcerpc_server_proto.h" 30 #include "smbd/service.h"31 30 #include "system/filesys.h" 32 #include "lib/socket/socket.h"33 31 #include "lib/messaging/irpc.h" 34 32 #include "system/network.h" … … 42 40 #include "smbd/process_model.h" 43 41 44 struct dcesrv_socket_context {45 const struct dcesrv_endpoint *endpoint;46 struct dcesrv_context *dcesrv_ctx;47 };48 49 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)50 {51 struct stream_connection *srv_conn;52 srv_conn = talloc_get_type(dce_conn->transport.private_data,53 struct stream_connection);54 55 stream_terminate_connection(srv_conn, reason);56 }57 58 static void dcesrv_sock_reply_done(struct tevent_req *subreq);59 60 struct dcesrv_sock_reply_state {61 struct dcesrv_connection *dce_conn;62 struct dcesrv_call_state *call;63 struct iovec iov;64 };65 66 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)67 {68 struct dcesrv_call_state *call;69 70 call = dce_conn->call_list;71 if (!call || !call->replies) {72 return;73 }74 75 while (call->replies) {76 struct data_blob_list_item *rep = call->replies;77 struct dcesrv_sock_reply_state *substate;78 struct tevent_req *subreq;79 80 substate = talloc(call, struct dcesrv_sock_reply_state);81 if (!substate) {82 dcesrv_terminate_connection(dce_conn, "no memory");83 return;84 }85 86 substate->dce_conn = dce_conn;87 substate->call = NULL;88 89 DLIST_REMOVE(call->replies, rep);90 91 if (call->replies == NULL) {92 substate->call = call;93 }94 95 substate->iov.iov_base = rep->blob.data;96 substate->iov.iov_len = rep->blob.length;97 98 subreq = tstream_writev_queue_send(substate,99 dce_conn->event_ctx,100 dce_conn->stream,101 dce_conn->send_queue,102 &substate->iov, 1);103 if (!subreq) {104 dcesrv_terminate_connection(dce_conn, "no memory");105 return;106 }107 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,108 substate);109 }110 111 DLIST_REMOVE(call->conn->call_list, call);112 call->list = DCESRV_LIST_NONE;113 }114 115 static void dcesrv_sock_reply_done(struct tevent_req *subreq)116 {117 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,118 struct dcesrv_sock_reply_state);119 int ret;120 int sys_errno;121 NTSTATUS status;122 struct dcesrv_call_state *call = substate->call;123 124 ret = tstream_writev_queue_recv(subreq, &sys_errno);125 TALLOC_FREE(subreq);126 if (ret == -1) {127 status = map_nt_error_from_unix(sys_errno);128 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));129 return;130 }131 132 talloc_free(substate);133 if (call) {134 talloc_free(call);135 }136 }137 138 static struct socket_address *dcesrv_sock_get_my_addr(struct dcesrv_connection *dcesrv_conn, TALLOC_CTX *mem_ctx)139 {140 struct stream_connection *srv_conn;141 srv_conn = talloc_get_type(dcesrv_conn->transport.private_data,142 struct stream_connection);143 144 return socket_get_my_addr(srv_conn->socket, mem_ctx);145 }146 147 static struct socket_address *dcesrv_sock_get_peer_addr(struct dcesrv_connection *dcesrv_conn, TALLOC_CTX *mem_ctx)148 {149 struct stream_connection *srv_conn;150 srv_conn = talloc_get_type(dcesrv_conn->transport.private_data,151 struct stream_connection);152 153 return socket_get_peer_addr(srv_conn->socket, mem_ctx);154 }155 156 struct dcerpc_read_ncacn_packet_state {157 struct {158 struct smb_iconv_convenience *smb_iconv_c;159 } caller;160 DATA_BLOB buffer;161 struct ncacn_packet *pkt;162 };163 164 static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context *stream,165 void *private_data,166 TALLOC_CTX *mem_ctx,167 struct iovec **_vector,168 size_t *_count);169 static void dcerpc_read_ncacn_packet_done(struct tevent_req *subreq);170 171 static struct tevent_req *dcerpc_read_ncacn_packet_send(TALLOC_CTX *mem_ctx,172 struct tevent_context *ev,173 struct tstream_context *stream,174 struct smb_iconv_convenience *ic)175 {176 struct tevent_req *req;177 struct dcerpc_read_ncacn_packet_state *state;178 struct tevent_req *subreq;179 180 req = tevent_req_create(mem_ctx, &state,181 struct dcerpc_read_ncacn_packet_state);182 if (req == NULL) {183 return NULL;184 }185 186 state->caller.smb_iconv_c = ic;187 state->buffer = data_blob_const(NULL, 0);188 state->pkt = talloc(state, struct ncacn_packet);189 if (tevent_req_nomem(state->pkt, req)) {190 goto post;191 }192 193 subreq = tstream_readv_pdu_send(state, ev,194 stream,195 dcerpc_read_ncacn_packet_next_vector,196 state);197 if (tevent_req_nomem(subreq, req)) {198 goto post;199 }200 tevent_req_set_callback(subreq, dcerpc_read_ncacn_packet_done, req);201 202 return req;203 post:204 tevent_req_post(req, ev);205 return req;206 }207 208 static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context *stream,209 void *private_data,210 TALLOC_CTX *mem_ctx,211 struct iovec **_vector,212 size_t *_count)213 {214 struct dcerpc_read_ncacn_packet_state *state =215 talloc_get_type_abort(private_data,216 struct dcerpc_read_ncacn_packet_state);217 struct iovec *vector;218 off_t ofs = 0;219 220 if (state->buffer.length == 0) {221 /* first get enough to read the fragment length */222 ofs = 0;223 state->buffer.length = DCERPC_FRAG_LEN_OFFSET + 2;224 state->buffer.data = talloc_array(state, uint8_t,225 state->buffer.length);226 if (!state->buffer.data) {227 return -1;228 }229 } else if (state->buffer.length == (DCERPC_FRAG_LEN_OFFSET + 2)) {230 /* now read the fragment length and allocate the full buffer */231 size_t frag_len = dcerpc_get_frag_length(&state->buffer);232 233 ofs = state->buffer.length;234 235 state->buffer.data = talloc_realloc(state,236 state->buffer.data,237 uint8_t, frag_len);238 if (!state->buffer.data) {239 return -1;240 }241 state->buffer.length = frag_len;242 } else {243 /* if we reach this we have a full fragment */244 *_vector = NULL;245 *_count = 0;246 return 0;247 }248 249 /* now create the vector that we want to be filled */250 vector = talloc_array(mem_ctx, struct iovec, 1);251 if (!vector) {252 return -1;253 }254 255 vector[0].iov_base = state->buffer.data + ofs;256 vector[0].iov_len = state->buffer.length - ofs;257 258 *_vector = vector;259 *_count = 1;260 return 0;261 }262 263 static void dcerpc_read_ncacn_packet_done(struct tevent_req *subreq)264 {265 struct tevent_req *req = tevent_req_callback_data(subreq,266 struct tevent_req);267 struct dcerpc_read_ncacn_packet_state *state = tevent_req_data(req,268 struct dcerpc_read_ncacn_packet_state);269 int ret;270 int sys_errno;271 struct ndr_pull *ndr;272 enum ndr_err_code ndr_err;273 NTSTATUS status;274 275 ret = tstream_readv_pdu_recv(subreq, &sys_errno);276 TALLOC_FREE(subreq);277 if (ret == -1) {278 status = map_nt_error_from_unix(sys_errno);279 tevent_req_nterror(req, status);280 return;281 }282 283 ndr = ndr_pull_init_blob(&state->buffer,284 state->pkt,285 state->caller.smb_iconv_c);286 if (tevent_req_nomem(ndr, req)) {287 return;288 }289 290 if (!(CVAL(ndr->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {291 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;292 }293 294 if (CVAL(ndr->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {295 ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;296 }297 298 ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, state->pkt);299 TALLOC_FREE(ndr);300 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {301 status = ndr_map_error2ntstatus(ndr_err);302 tevent_req_nterror(req, status);303 return;304 }305 306 tevent_req_done(req);307 }308 309 static NTSTATUS dcerpc_read_ncacn_packet_recv(struct tevent_req *req,310 TALLOC_CTX *mem_ctx,311 struct ncacn_packet **pkt,312 DATA_BLOB *buffer)313 {314 struct dcerpc_read_ncacn_packet_state *state = tevent_req_data(req,315 struct dcerpc_read_ncacn_packet_state);316 NTSTATUS status;317 318 if (tevent_req_is_nterror(req, &status)) {319 tevent_req_received(req);320 return status;321 }322 323 *pkt = talloc_move(mem_ctx, &state->pkt);324 if (buffer) {325 buffer->data = talloc_move(mem_ctx, &state->buffer.data);326 buffer->length = state->buffer.length;327 }328 329 tevent_req_received(req);330 return NT_STATUS_OK;331 }332 333 static void dcesrv_read_fragment_done(struct tevent_req *subreq);334 335 static void dcesrv_sock_accept(struct stream_connection *srv_conn)336 {337 NTSTATUS status;338 struct dcesrv_socket_context *dcesrv_sock =339 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);340 struct dcesrv_connection *dcesrv_conn = NULL;341 int ret;342 struct tevent_req *subreq;343 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;344 345 if (!srv_conn->session_info) {346 status = auth_anonymous_session_info(srv_conn,347 srv_conn->event.ctx,348 lp_ctx,349 &srv_conn->session_info);350 if (!NT_STATUS_IS_OK(status)) {351 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",352 nt_errstr(status)));353 stream_terminate_connection(srv_conn, nt_errstr(status));354 return;355 }356 }357 358 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,359 srv_conn,360 dcesrv_sock->endpoint,361 srv_conn->session_info,362 srv_conn->event.ctx,363 srv_conn->msg_ctx,364 srv_conn->server_id,365 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,366 &dcesrv_conn);367 if (!NT_STATUS_IS_OK(status)) {368 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",369 nt_errstr(status)));370 stream_terminate_connection(srv_conn, nt_errstr(status));371 return;372 }373 374 dcesrv_conn->transport.private_data = srv_conn;375 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;376 dcesrv_conn->transport.get_my_addr = dcesrv_sock_get_my_addr;377 dcesrv_conn->transport.get_peer_addr = dcesrv_sock_get_peer_addr;378 379 TALLOC_FREE(srv_conn->event.fde);380 381 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");382 if (!dcesrv_conn->send_queue) {383 status = NT_STATUS_NO_MEMORY;384 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",385 nt_errstr(status)));386 stream_terminate_connection(srv_conn, nt_errstr(status));387 return;388 }389 390 if (dcesrv_sock->endpoint->ep_description->transport == NCACN_NP) {391 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;392 ret = tstream_npa_existing_socket(dcesrv_conn,393 socket_get_fd(srv_conn->socket),394 FILE_TYPE_MESSAGE_MODE_PIPE,395 &dcesrv_conn->stream);396 } else {397 ret = tstream_bsd_existing_socket(dcesrv_conn,398 socket_get_fd(srv_conn->socket),399 &dcesrv_conn->stream);400 }401 if (ret == -1) {402 status = map_nt_error_from_unix(errno);403 DEBUG(0,("dcesrv_sock_accept: failed to setup tstream: %s\n",404 nt_errstr(status)));405 stream_terminate_connection(srv_conn, nt_errstr(status));406 return;407 }408 409 srv_conn->private_data = dcesrv_conn;410 411 irpc_add_name(srv_conn->msg_ctx, "rpc_server");412 413 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,414 dcesrv_conn->event_ctx,415 dcesrv_conn->stream,416 lp_iconv_convenience(lp_ctx));417 if (!subreq) {418 status = NT_STATUS_NO_MEMORY;419 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",420 nt_errstr(status)));421 stream_terminate_connection(srv_conn, nt_errstr(status));422 return;423 }424 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);425 426 return;427 }428 429 static void dcesrv_read_fragment_done(struct tevent_req *subreq)430 {431 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,432 struct dcesrv_connection);433 struct ncacn_packet *pkt;434 DATA_BLOB buffer;435 NTSTATUS status;436 struct loadparm_context *lp_ctx = dce_conn->dce_ctx->lp_ctx;437 438 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,439 &pkt, &buffer);440 TALLOC_FREE(subreq);441 if (!NT_STATUS_IS_OK(status)) {442 dcesrv_terminate_connection(dce_conn, nt_errstr(status));443 return;444 }445 446 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);447 if (!NT_STATUS_IS_OK(status)) {448 dcesrv_terminate_connection(dce_conn, nt_errstr(status));449 return;450 }451 452 subreq = dcerpc_read_ncacn_packet_send(dce_conn,453 dce_conn->event_ctx,454 dce_conn->stream,455 lp_iconv_convenience(lp_ctx));456 if (!subreq) {457 status = NT_STATUS_NO_MEMORY;458 dcesrv_terminate_connection(dce_conn, nt_errstr(status));459 return;460 }461 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);462 }463 464 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)465 {466 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,467 struct dcesrv_connection);468 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");469 }470 471 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)472 {473 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,474 struct dcesrv_connection);475 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");476 }477 478 479 static const struct stream_server_ops dcesrv_stream_ops = {480 .name = "rpc",481 .accept_connection = dcesrv_sock_accept,482 .recv_handler = dcesrv_sock_recv,483 .send_handler = dcesrv_sock_send,484 };485 486 487 488 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,489 struct loadparm_context *lp_ctx,490 struct dcesrv_endpoint *e,491 struct tevent_context *event_ctx, const struct model_ops *model_ops)492 {493 struct dcesrv_socket_context *dcesrv_sock;494 uint16_t port = 1;495 NTSTATUS status;496 497 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);498 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);499 500 /* remember the endpoint of this socket */501 dcesrv_sock->endpoint = e;502 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);503 504 status = stream_setup_socket(event_ctx, lp_ctx,505 model_ops, &dcesrv_stream_ops,506 "unix", e->ep_description->endpoint, &port,507 lp_socket_options(lp_ctx),508 dcesrv_sock);509 if (!NT_STATUS_IS_OK(status)) {510 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",511 e->ep_description->endpoint, nt_errstr(status)));512 }513 514 return status;515 }516 517 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,518 struct loadparm_context *lp_ctx,519 struct dcesrv_endpoint *e,520 struct tevent_context *event_ctx, const struct model_ops *model_ops)521 {522 struct dcesrv_socket_context *dcesrv_sock;523 uint16_t port = 1;524 char *full_path;525 NTSTATUS status;526 527 if (!e->ep_description->endpoint) {528 /* No identifier specified: use DEFAULT.529 * DO NOT hardcode this value anywhere else. Rather, specify530 * no endpoint and let the epmapper worry about it. */531 e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT");532 }533 534 full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(lp_ctx),535 e->ep_description->endpoint);536 537 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);538 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);539 540 /* remember the endpoint of this socket */541 dcesrv_sock->endpoint = e;542 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);543 544 status = stream_setup_socket(event_ctx, lp_ctx,545 model_ops, &dcesrv_stream_ops,546 "unix", full_path, &port,547 lp_socket_options(lp_ctx),548 dcesrv_sock);549 if (!NT_STATUS_IS_OK(status)) {550 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",551 e->ep_description->endpoint, full_path, nt_errstr(status)));552 }553 return status;554 }555 556 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,557 struct loadparm_context *lp_ctx,558 struct dcesrv_endpoint *e,559 struct tevent_context *event_ctx, const struct model_ops *model_ops)560 {561 struct dcesrv_socket_context *dcesrv_sock;562 NTSTATUS status;563 564 if (e->ep_description->endpoint == NULL) {565 DEBUG(0, ("Endpoint mandatory for named pipes\n"));566 return NT_STATUS_INVALID_PARAMETER;567 }568 569 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);570 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);571 572 /* remember the endpoint of this socket */573 dcesrv_sock->endpoint = e;574 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);575 576 status = stream_setup_named_pipe(event_ctx, lp_ctx,577 model_ops, &dcesrv_stream_ops,578 e->ep_description->endpoint, dcesrv_sock);579 if (!NT_STATUS_IS_OK(status)) {580 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",581 e->ep_description->endpoint, nt_errstr(status)));582 return status;583 }584 585 return NT_STATUS_OK;586 }587 588 /*589 add a socket address to the list of events, one event per dcerpc endpoint590 */591 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,592 struct tevent_context *event_ctx, const struct model_ops *model_ops,593 const char *address)594 {595 struct dcesrv_socket_context *dcesrv_sock;596 uint16_t port = 0;597 NTSTATUS status;598 599 if (e->ep_description->endpoint) {600 port = atoi(e->ep_description->endpoint);601 }602 603 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);604 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);605 606 /* remember the endpoint of this socket */607 dcesrv_sock->endpoint = e;608 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);609 610 status = stream_setup_socket(event_ctx, dce_ctx->lp_ctx,611 model_ops, &dcesrv_stream_ops,612 "ipv4", address, &port,613 lp_socket_options(dce_ctx->lp_ctx),614 dcesrv_sock);615 if (!NT_STATUS_IS_OK(status)) {616 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",617 address, port, nt_errstr(status)));618 }619 620 if (e->ep_description->endpoint == NULL) {621 e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port);622 }623 624 return status;625 }626 627 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,628 struct loadparm_context *lp_ctx,629 struct dcesrv_endpoint *e,630 struct tevent_context *event_ctx, const struct model_ops *model_ops)631 {632 NTSTATUS status;633 634 /* Add TCP/IP sockets */635 if (lp_interfaces(lp_ctx) && lp_bind_interfaces_only(lp_ctx)) {636 int num_interfaces;637 int i;638 struct interface *ifaces;639 640 load_interfaces(dce_ctx, lp_interfaces(lp_ctx), &ifaces);641 642 num_interfaces = iface_count(ifaces);643 for(i = 0; i < num_interfaces; i++) {644 const char *address = iface_n_ip(ifaces, i);645 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);646 NT_STATUS_NOT_OK_RETURN(status);647 }648 } else {649 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops,650 lp_socket_address(lp_ctx));651 NT_STATUS_NOT_OK_RETURN(status);652 }653 654 return NT_STATUS_OK;655 }656 657 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,658 struct loadparm_context *lp_ctx,659 struct dcesrv_endpoint *e,660 struct tevent_context *event_ctx,661 const struct model_ops *model_ops)662 {663 switch (e->ep_description->transport) {664 case NCACN_UNIX_STREAM:665 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);666 667 case NCALRPC:668 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);669 670 case NCACN_IP_TCP:671 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);672 673 case NCACN_NP:674 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);675 676 default:677 return NT_STATUS_NOT_SUPPORTED;678 }679 }680 42 681 43 /* … … 695 57 /* run the rpc server as a single process to allow for shard 696 58 * handles, and sharing of ldb contexts */ 697 model_ops = process_model_startup( task->event_ctx,"single");59 model_ops = process_model_startup("single"); 698 60 if (!model_ops) goto failed; 699 61 700 62 status = dcesrv_init_context(task->event_ctx, 701 63 task->lp_ctx, 702 lp _dcerpc_endpoint_servers(task->lp_ctx),64 lpcfg_dcerpc_endpoint_servers(task->lp_ctx), 703 65 &dce_ctx); 704 66 if (!NT_STATUS_IS_OK(status)) goto failed; 705 67 706 68 /* Make sure the directory for NCALRPC exists */ 707 if (!directory_exist(lp _ncalrpc_dir(task->lp_ctx))) {708 mkdir(lp _ncalrpc_dir(task->lp_ctx), 0755);69 if (!directory_exist(lpcfg_ncalrpc_dir(task->lp_ctx))) { 70 mkdir(lpcfg_ncalrpc_dir(task->lp_ctx), 0755); 709 71 } 710 72 … … 721 83 NTSTATUS server_service_rpc_init(void) 722 84 { 723 724 85 return register_server_service("rpc", dcesrv_task_init); 725 86 } -
trunk/server/source4/rpc_server/spoolss/dcesrv_spoolss.c
r429 r745 25 25 #include "librpc/gen_ndr/ndr_spoolss.h" 26 26 #include "ntptr/ntptr.h" 27 #include "lib/ socket/socket.h"27 #include "lib/tsocket/tsocket.h" 28 28 #include "librpc/gen_ndr/ndr_spoolss_c.h" 29 29 #include "auth/credentials/credentials.h" … … 34 34 }; 35 35 36 #define SPOOLSS_BUFFER_UNION(fn,i c,info,level) \37 ((info)?ndr_size_##fn(info, level, ic,0):0)38 39 #define SPOOLSS_BUFFER_UNION_ARRAY(fn,i c,info,level,count) \40 ((info)?ndr_size_##fn##_info(dce_call, ic,level, count, info):0)36 #define SPOOLSS_BUFFER_UNION(fn,info,level) \ 37 ((info)?ndr_size_##fn(info, level, 0):0) 38 39 #define SPOOLSS_BUFFER_UNION_ARRAY(fn,info,level,count) \ 40 ((info)?ndr_size_##fn##_info(dce_call, level, count, info):0) 41 41 42 42 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false) … … 149 149 { 150 150 bool ret; 151 struct socket_address *myaddr; 151 const struct tsocket_address *local_address; 152 char *myaddr; 152 153 const char **aliases; 153 int i; 154 const char *dnsdomain; 155 unsigned int i; 154 156 155 157 /* NULL is ok */ … … 173 175 174 176 /* NETBIOS NAME is ok */ 175 ret = strequal(lp _netbios_name(dce_call->conn->dce_ctx->lp_ctx), server_name);177 ret = strequal(lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx), server_name); 176 178 if (ret) return WERR_OK; 177 179 178 aliases = lp _netbios_aliases(dce_call->conn->dce_ctx->lp_ctx);180 aliases = lpcfg_netbios_aliases(dce_call->conn->dce_ctx->lp_ctx); 179 181 180 182 for (i=0; aliases && aliases[i]; i++) { … … 187 189 * TODO: we need to check if aliases are also ok 188 190 */ 189 if (lp_realm(dce_call->conn->dce_ctx->lp_ctx)) { 191 dnsdomain = lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); 192 if (dnsdomain != NULL) { 190 193 char *str; 191 194 192 195 str = talloc_asprintf(mem_ctx, "%s.%s", 193 lp _netbios_name(dce_call->conn->dce_ctx->lp_ctx),194 lp_realm(dce_call->conn->dce_ctx->lp_ctx));196 lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 197 dnsdomain); 195 198 W_ERROR_HAVE_NO_MEMORY(str); 196 199 … … 200 203 } 201 204 202 myaddr = dcesrv_connection_get_my_addr(dce_call->conn, mem_ctx); 205 local_address = dcesrv_connection_get_local_address(dce_call->conn); 206 207 myaddr = tsocket_address_inet_addr_string(local_address, mem_ctx); 203 208 W_ERROR_HAVE_NO_MEMORY(myaddr); 204 209 205 ret = strequal(myaddr ->addr, server_name);210 ret = strequal(myaddr, server_name); 206 211 talloc_free(myaddr); 207 212 if (ret) return WERR_OK; … … 216 221 217 222 status = ntptr_init_context(dce_call->context, dce_call->conn->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 218 lp _ntptr_providor(dce_call->conn->dce_ctx->lp_ctx), &ntptr);223 lpcfg_ntptr_providor(dce_call->conn->dce_ctx->lp_ctx), &ntptr); 219 224 NT_STATUS_NOT_OK_RETURN(status); 220 225 … … 234 239 struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); 235 240 WERROR status; 236 struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx);237 241 238 242 status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); … … 242 246 W_ERROR_NOT_OK_RETURN(status); 243 247 244 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, ic,*r->out.info, r->in.level, *r->out.count);248 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinters, *r->out.info, r->in.level, *r->out.count); 245 249 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); 246 250 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); … … 370 374 struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); 371 375 WERROR status; 372 struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx);373 376 374 377 status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); … … 378 381 W_ERROR_NOT_OK_RETURN(status); 379 382 380 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, ic,*r->out.info, r->in.level, *r->out.count);383 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPrinterDrivers, *r->out.info, r->in.level, *r->out.count); 381 384 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); 382 385 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); … … 403 406 struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); 404 407 WERROR status; 405 struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx);406 408 407 409 status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); … … 411 413 W_ERROR_NOT_OK_RETURN(status); 412 414 413 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, ic,r->out.info, r->in.level);415 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, r->out.info, r->in.level); 414 416 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); 415 417 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); … … 455 457 struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); 456 458 WERROR status; 457 struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx);458 459 459 460 status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); … … 463 464 W_ERROR_NOT_OK_RETURN(status); 464 465 465 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, ic,r->out.info, r->in.level);466 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, r->out.info, r->in.level); 466 467 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); 467 468 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); … … 572 573 struct dcesrv_handle *h; 573 574 WERROR status; 574 struct smb_iconv_convenience *ic = lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx);575 575 576 576 r->out.type = talloc_zero(mem_ctx, enum winreg_Type); … … 718 718 struct dcesrv_handle *h; 719 719 WERROR status; 720 struct smb_iconv_convenience *ic = lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx);721 720 722 721 DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); … … 739 738 } 740 739 741 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, ic,r->out.info, r->in.level);740 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, r->out.info, r->in.level); 742 741 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); 743 742 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); … … 786 785 struct dcesrv_handle *h; 787 786 WERROR status; 788 struct smb_iconv_convenience *ic = lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx);789 787 790 788 DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY); … … 806 804 } 807 805 808 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, ic,*r->out.info, r->in.level, *r->out.count);806 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumForms, *r->out.info, r->in.level, *r->out.count); 809 807 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); 810 808 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); … … 821 819 struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); 822 820 WERROR status; 823 struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx);824 821 825 822 status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.servername); … … 829 826 W_ERROR_NOT_OK_RETURN(status); 830 827 831 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, ic,*r->out.info, r->in.level, *r->out.count);828 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumPorts, *r->out.info, r->in.level, *r->out.count); 832 829 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); 833 830 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); … … 844 841 struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); 845 842 WERROR status; 846 struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx);847 843 848 844 status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.servername); … … 852 848 W_ERROR_NOT_OK_RETURN(status); 853 849 854 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, ic,*r->out.info, r->in.level, *r->out.count);850 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(spoolss_EnumMonitors, *r->out.info, r->in.level, *r->out.count); 855 851 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL); 856 852 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0); … … 1196 1192 1197 1193 ZERO_STRUCT(rop); 1198 rop.in.server_name = lp _netbios_name(dce_call->conn->dce_ctx->lp_ctx);1194 rop.in.server_name = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx); 1199 1195 W_ERROR_HAVE_NO_MEMORY(rop.in.server_name); 1200 1196 rop.in.printer_local = 0; … … 1204 1200 rop.out.handle = ¬ify_handle; 1205 1201 1206 status = dcerpc_spoolss_ReplyOpenPrinter (p, mem_ctx, &rop);1202 status = dcerpc_spoolss_ReplyOpenPrinter_r(p->binding_handle, mem_ctx, &rop); 1207 1203 if (NT_STATUS_IS_ERR(status)) { 1208 1204 DEBUG(0, ("unable to open remote printer %s\n", … … 1310 1306 1311 1307 /* 1312 spoolss_ 471313 */ 1314 static WERROR dcesrv_spoolss_ 47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1315 struct spoolss_ 47*r)1308 spoolss_SetPort 1309 */ 1310 static WERROR dcesrv_spoolss_SetPort(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1311 struct spoolss_SetPort *r) 1316 1312 { 1317 1313 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); … … 1450 1446 1451 1447 /* 1452 spoolss_ 551453 */ 1454 static WERROR dcesrv_spoolss_ 55(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1455 struct spoolss_ 55*r)1456 { 1457 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1458 } 1459 1460 1461 /* 1462 spoolss_ 561463 */ 1464 static WERROR dcesrv_spoolss_ 56(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1465 struct spoolss_ 56*r)1466 { 1467 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1468 } 1469 1470 1471 /* 1472 spoolss_ 571473 */ 1474 static WERROR dcesrv_spoolss_ 57(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1475 struct spoolss_ 57*r)1448 spoolss_AddPerMachineConnection 1449 */ 1450 static WERROR dcesrv_spoolss_AddPerMachineConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1451 struct spoolss_AddPerMachineConnection *r) 1452 { 1453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1454 } 1455 1456 1457 /* 1458 spoolss_DeletePerMachineConnection 1459 */ 1460 static WERROR dcesrv_spoolss_DeletePerMachineConnection(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1461 struct spoolss_DeletePerMachineConnection *r) 1462 { 1463 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1464 } 1465 1466 1467 /* 1468 spoolss_EnumPerMachineConnections 1469 */ 1470 static WERROR dcesrv_spoolss_EnumPerMachineConnections(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1471 struct spoolss_EnumPerMachineConnections *r) 1476 1472 { 1477 1473 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); -
trunk/server/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
r414 r745 25 25 #include "librpc/gen_ndr/ndr_srvsvc.h" 26 26 #include "rpc_server/common/common.h" 27 #include "rpc_server/common/share.h" 27 28 #include "auth/auth.h" 28 29 #include "libcli/security/security.h" … … 34 35 struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \ 35 36 if (!security_token_has_builtin_administrators(t) && \ 36 !security_token_has_sid _string(t, SID_BUILTIN_SERVER_OPERATORS)) { \37 !security_token_has_sid(t, &global_sid_Builtin_Server_Operators)) { \ 37 38 return WERR_ACCESS_DENIED; \ 38 39 } \ … … 69 70 return WERR_UNKNOWN_LEVEL; 70 71 } 71 72 return WERR_OK;73 72 } 74 73 … … 94 93 return WERR_UNKNOWN_LEVEL; 95 94 } 96 97 return WERR_UNKNOWN_LEVEL;98 95 } 99 96 … … 141 138 return WERR_UNKNOWN_LEVEL; 142 139 } 143 144 return WERR_UNKNOWN_LEVEL;145 140 } 146 141 … … 166 161 return WERR_UNKNOWN_LEVEL; 167 162 } 168 169 return WERR_UNKNOWN_LEVEL;170 163 } 171 164 … … 195 188 return WERR_UNKNOWN_LEVEL; 196 189 } 197 198 return WERR_UNKNOWN_LEVEL;199 190 } 200 191 … … 252 243 return WERR_UNKNOWN_LEVEL; 253 244 } 254 255 return WERR_UNKNOWN_LEVEL;256 245 } 257 246 … … 289 278 return WERR_UNKNOWN_LEVEL; 290 279 } 291 292 return WERR_UNKNOWN_LEVEL;293 280 } 294 281 … … 314 301 return WERR_UNKNOWN_LEVEL; 315 302 } 316 317 return WERR_UNKNOWN_LEVEL;318 303 } 319 304 … … 391 376 return WERR_UNKNOWN_LEVEL; 392 377 } 393 394 return WERR_UNKNOWN_LEVEL;395 378 } 396 379 … … 432 415 struct share_info *info; 433 416 struct share_context *sctx; 434 int count = 8;435 int i;436 437 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);417 unsigned int count = 8; 418 unsigned int i; 419 420 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 438 421 if (!NT_STATUS_IS_OK(nterr)) { 439 422 return ntstatus_to_werror(nterr); … … 449 432 info[i].type = SHARE_INFO_STRING; 450 433 switch (r->in.info->info2->type) { 451 case 0x00:434 case STYPE_DISKTREE: 452 435 info[i].value = talloc_strdup(info, "DISK"); 453 436 break; 454 case 0x01:437 case STYPE_PRINTQ: 455 438 info[i].value = talloc_strdup(info, "PRINTER"); 456 439 break; 457 case 0x03:440 case STYPE_IPC: 458 441 info[i].value = talloc_strdup(info, "IPC"); 459 442 break; … … 530 513 struct share_info *info; 531 514 struct share_context *sctx; 532 int count = 10;533 int i;534 535 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);515 unsigned int count = 10; 516 unsigned int i; 517 518 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 536 519 if (!NT_STATUS_IS_OK(nterr)) { 537 520 return ntstatus_to_werror(nterr); … … 619 602 return WERR_UNKNOWN_LEVEL; 620 603 } 621 622 return WERR_UNKNOWN_LEVEL;623 604 } 624 605 … … 700 681 return WERR_UNKNOWN_LEVEL; 701 682 } 702 703 return WERR_UNKNOWN_LEVEL;704 683 } 705 684 … … 721 700 */ 722 701 723 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);702 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 724 703 if (!NT_STATUS_IS_OK(nterr)) { 725 704 return ntstatus_to_werror(nterr); … … 734 713 case 0: 735 714 { 736 int i;715 unsigned int i; 737 716 struct srvsvc_NetShareCtr0 *ctr0; 738 717 … … 775 754 case 1: 776 755 { 777 int i;756 unsigned int i; 778 757 struct srvsvc_NetShareCtr1 *ctr1; 779 758 … … 817 796 case 2: 818 797 { 819 int i;798 unsigned int i; 820 799 struct srvsvc_NetShareCtr2 *ctr2; 821 800 … … 861 840 case 501: 862 841 { 863 int i;842 unsigned int i; 864 843 struct srvsvc_NetShareCtr501 *ctr501; 865 844 … … 905 884 case 502: 906 885 { 907 int i;886 unsigned int i; 908 887 struct srvsvc_NetShareCtr502 *ctr502; 909 888 … … 950 929 return WERR_UNKNOWN_LEVEL; 951 930 } 952 953 return WERR_UNKNOWN_LEVEL;954 931 } 955 932 … … 974 951 } 975 952 976 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);953 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 977 954 if (!NT_STATUS_IS_OK(nterr)) { 978 955 return ntstatus_to_werror(nterr); … … 1088 1065 return WERR_UNKNOWN_LEVEL; 1089 1066 } 1090 1091 return WERR_UNKNOWN_LEVEL;1092 1067 } 1093 1068 … … 1103 1078 struct security_descriptor *sd) 1104 1079 { 1105 int i = 0;1080 unsigned int i = 0; 1106 1081 1107 1082 if (level == 501) { … … 1222 1197 W_ERROR_HAVE_NO_MEMORY(info); 1223 1198 1224 ZERO_STRUCT(r->out);1225 1226 1199 if (strcmp("", r->in.share_name) == 0) { 1227 1200 return WERR_INVALID_PARAM; 1228 1201 } 1229 1202 1230 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);1203 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 1231 1204 if (!NT_STATUS_IS_OK(nterr)) { 1232 1205 return ntstatus_to_werror(nterr); … … 1384 1357 char *device; 1385 1358 const char **names; 1386 int count, i; 1359 int count; 1360 int i; 1387 1361 1388 1362 *r->out.type = 0; … … 1405 1379 all_string_sub(device, "\\", "/", 0); 1406 1380 1407 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);1381 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 1408 1382 if (!NT_STATUS_IS_OK(nterr)) { 1409 1383 return ntstatus_to_werror(nterr); … … 1458 1432 { 1459 1433 struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; 1460 struct dcerpc_server_info *server_info = lp _dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx);1434 struct dcerpc_server_info *server_info = lpcfg_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx); 1461 1435 1462 1436 ZERO_STRUCTP(r->out.info); … … 1491 1465 info101->version_minor = server_info->version_minor; 1492 1466 info101->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); 1493 info101->comment = talloc_strdup(mem_ctx, lp _serverstring(dce_ctx->lp_ctx));1467 info101->comment = talloc_strdup(mem_ctx, lpcfg_serverstring(dce_ctx->lp_ctx)); 1494 1468 W_ERROR_HAVE_NO_MEMORY(info101->comment); 1495 1469 … … 1511 1485 info102->version_minor = server_info->version_minor; 1512 1486 info102->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); 1513 info102->comment = talloc_strdup(mem_ctx, lp _serverstring(dce_ctx->lp_ctx));1487 info102->comment = talloc_strdup(mem_ctx, lpcfg_serverstring(dce_ctx->lp_ctx)); 1514 1488 W_ERROR_HAVE_NO_MEMORY(info102->comment); 1515 1489 … … 1529 1503 return WERR_UNKNOWN_LEVEL; 1530 1504 } 1531 1532 return WERR_UNKNOWN_LEVEL;1533 1505 } 1534 1506 … … 1577 1549 return WERR_UNKNOWN_LEVEL; 1578 1550 } 1579 1580 return WERR_UNKNOWN_LEVEL;1581 1551 } 1582 1552 … … 1658 1628 return WERR_UNKNOWN_LEVEL; 1659 1629 } 1660 1661 return WERR_UNKNOWN_LEVEL;1662 1630 } 1663 1631 … … 1788 1756 return WERR_INVALID_PARAM; 1789 1757 } 1790 1791 return WERR_INVALID_PARAM;1792 1758 } 1793 1759 … … 1821 1787 */ 1822 1788 1823 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);1789 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 1824 1790 if (!NT_STATUS_IS_OK(nterr)) { 1825 1791 return ntstatus_to_werror(nterr); … … 1834 1800 case 0: 1835 1801 { 1836 int i, y = 0;1837 int count;1802 unsigned int i, y = 0; 1803 unsigned int count; 1838 1804 struct srvsvc_NetShareCtr0 *ctr0; 1839 1805 … … 1886 1852 case 1: 1887 1853 { 1888 int i, y = 0;1889 int count;1854 unsigned int i, y = 0; 1855 unsigned int count; 1890 1856 struct srvsvc_NetShareCtr1 *ctr1; 1891 1857 … … 1938 1904 case 2: 1939 1905 { 1940 int i, y = 0;1941 int count;1906 unsigned int i, y = 0; 1907 unsigned int count; 1942 1908 struct srvsvc_NetShareCtr2 *ctr2; 1943 1909 … … 1992 1958 case 502: 1993 1959 { 1994 int i, y = 0;1995 int count;1960 unsigned int i, y = 0; 1961 unsigned int count; 1996 1962 struct srvsvc_NetShareCtr502 *ctr502; 1997 1963 … … 2047 2013 return WERR_UNKNOWN_LEVEL; 2048 2014 } 2049 2050 return WERR_UNKNOWN_LEVEL;2051 2015 } 2052 2016 … … 2288 2252 struct share_context *sctx; 2289 2253 2290 nterr = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);2254 nterr = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 2291 2255 if (!NT_STATUS_IS_OK(nterr)) { 2292 2256 return ntstatus_to_werror(nterr); -
trunk/server/source4/rpc_server/srvsvc/srvsvc_ntvfs.c
r414 r745 22 22 #include "ntvfs/ntvfs.h" 23 23 #include "rpc_server/dcerpc_server.h" 24 #include "librpc/gen_ndr/ndr_srvsvc.h"25 #include "rpc_server/common/common.h"26 #include "rpc_server/srvsvc/proto.h"27 #include "lib/socket/socket.h"28 24 #include "param/param.h" 29 30 struct socket_address *srvsvc_get_my_addr(void *p, TALLOC_CTX *mem_ctx)31 {32 struct dcesrv_connection *conn = talloc_get_type(p, struct dcesrv_connection);33 return dcesrv_connection_get_my_addr(conn, mem_ctx);34 }35 36 struct socket_address *srvsvc_get_peer_addr(void *p, TALLOC_CTX *mem_ctx)37 {38 struct dcesrv_connection *conn = talloc_get_type(p, struct dcesrv_connection);39 return dcesrv_connection_get_peer_addr(conn, mem_ctx);40 }41 25 42 26 struct srvsvc_ntvfs_ctx { … … 62 46 struct share_config *scfg; 63 47 const char *sharetype; 48 union smb_tcon tcon; 49 const struct tsocket_address *local_address; 50 const struct tsocket_address *remote_address; 64 51 65 status = share_get_context_by_name(mem_ctx, lp _share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx);52 status = share_get_context_by_name(mem_ctx, lpcfg_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 66 53 if (!NT_STATUS_IS_OK(status)) { 67 54 return status; … … 115 102 * NOTE: we only set the addr callbacks as we're not interesseted in oplocks or in getting file handles 116 103 */ 117 status = ntvfs_set_addr_callbacks(c->ntvfs, srvsvc_get_my_addr, srvsvc_get_peer_addr, dce_call->conn); 104 local_address = dcesrv_connection_get_local_address(dce_call->conn); 105 remote_address = dcesrv_connection_get_remote_address(dce_call->conn); 106 status = ntvfs_set_addresses(c->ntvfs, local_address, remote_address); 118 107 if (!NT_STATUS_IS_OK(status)) { 119 108 DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS failed to set the addr callbacks!\n")); … … 129 118 130 119 /* Invoke NTVFS connection hook */ 131 status = ntvfs_connect(ntvfs_req, scfg->name); 120 tcon.tcon.level = RAW_TCON_TCON; 121 ZERO_STRUCT(tcon.tcon.in); 122 tcon.tcon.in.service = scfg->name; 123 status = ntvfs_connect(ntvfs_req, &tcon); 132 124 if (!NT_STATUS_IS_OK(status)) { 133 125 DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS ntvfs_connect() failed!\n")); -
trunk/server/source4/rpc_server/unixinfo/dcesrv_unixinfo.c
r414 r745 50 50 dce_call->context->private_data, 51 51 struct wbc_context); 52 struct id_map ping*ids;52 struct id_map *ids; 53 53 struct composite_context *ctx; 54 54 55 55 DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n")); 56 56 57 ids = talloc(mem_ctx, struct id_mapping);57 ids = talloc(mem_ctx, struct id_map); 58 58 NT_STATUS_HAVE_NO_MEMORY(ids); 59 59 60 60 ids->sid = &r->in.sid; 61 ids->status = NT_STATUS_NONE_MAPPED;62 ids->unixid = NULL;61 ids->status = ID_UNKNOWN; 62 ZERO_STRUCT(ids->xid); 63 63 ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids); 64 64 NT_STATUS_HAVE_NO_MEMORY(ctx); … … 67 67 NT_STATUS_NOT_OK_RETURN(status); 68 68 69 if (ids-> unixid->type == ID_TYPE_BOTH ||70 ids-> unixid->type == ID_TYPE_UID) {71 *r->out.uid = ids-> unixid->id;69 if (ids->xid.type == ID_TYPE_BOTH || 70 ids->xid.type == ID_TYPE_UID) { 71 *r->out.uid = ids->xid.id; 72 72 return NT_STATUS_OK; 73 73 } else { … … 83 83 dce_call->context->private_data, 84 84 struct wbc_context); 85 struct id_map ping*ids;85 struct id_map *ids; 86 86 struct composite_context *ctx; 87 87 uint32_t uid; … … 96 96 } 97 97 98 ids = talloc(mem_ctx, struct id_map ping);98 ids = talloc(mem_ctx, struct id_map); 99 99 NT_STATUS_HAVE_NO_MEMORY(ids); 100 100 101 101 ids->sid = NULL; 102 ids->status = NT_STATUS_NONE_MAPPED; 103 ids->unixid = talloc(ids, struct unixid); 104 NT_STATUS_HAVE_NO_MEMORY(ids->unixid); 105 106 ids->unixid->id = uid; 107 ids->unixid->type = ID_TYPE_UID; 102 ids->status = ID_UNKNOWN; 103 104 ids->xid.id = uid; 105 ids->xid.type = ID_TYPE_UID; 108 106 109 107 ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids); … … 125 123 dce_call->context->private_data, 126 124 struct wbc_context); 127 struct id_map ping*ids;125 struct id_map *ids; 128 126 struct composite_context *ctx; 129 127 130 128 DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n")); 131 129 132 ids = talloc(mem_ctx, struct id_mapping);130 ids = talloc(mem_ctx, struct id_map); 133 131 NT_STATUS_HAVE_NO_MEMORY(ids); 134 132 135 133 ids->sid = &r->in.sid; 136 ids->status = NT_STATUS_NONE_MAPPED;137 ids->unixid = NULL;134 ids->status = ID_UNKNOWN; 135 ZERO_STRUCT(ids->xid); 138 136 ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids); 139 137 NT_STATUS_HAVE_NO_MEMORY(ctx); … … 142 140 NT_STATUS_NOT_OK_RETURN(status); 143 141 144 if (ids-> unixid->type == ID_TYPE_BOTH ||145 ids-> unixid->type == ID_TYPE_GID) {146 *r->out.gid = ids-> unixid->id;142 if (ids->xid.type == ID_TYPE_BOTH || 143 ids->xid.type == ID_TYPE_GID) { 144 *r->out.gid = ids->xid.id; 147 145 return NT_STATUS_OK; 148 146 } else { … … 158 156 dce_call->context->private_data, 159 157 struct wbc_context); 160 struct id_map ping*ids;158 struct id_map *ids; 161 159 struct composite_context *ctx; 162 160 uint32_t gid; … … 171 169 } 172 170 173 ids = talloc(mem_ctx, struct id_map ping);171 ids = talloc(mem_ctx, struct id_map); 174 172 NT_STATUS_HAVE_NO_MEMORY(ids); 175 173 176 174 ids->sid = NULL; 177 ids->status = NT_STATUS_NONE_MAPPED; 178 ids->unixid = talloc(ids, struct unixid); 179 NT_STATUS_HAVE_NO_MEMORY(ids->unixid); 180 181 ids->unixid->id = gid; 182 ids->unixid->type = ID_TYPE_GID; 175 ids->status = ID_UNKNOWN; 176 177 ids->xid.id = gid; 178 ids->xid.type = ID_TYPE_GID; 183 179 184 180 ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids); … … 196 192 struct unixinfo_GetPWUid *r) 197 193 { 198 int i;194 unsigned int i; 199 195 200 196 *r->out.count = 0; -
trunk/server/source4/rpc_server/winreg/rpc_winreg.c
r414 r745 26 26 #include "librpc/gen_ndr/ndr_winreg.h" 27 27 #include "librpc/gen_ndr/ndr_security.h" 28 #include "libcli/security/se curity.h"28 #include "libcli/security/session.h" 29 29 30 30 enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY }; … … 37 37 38 38 err = reg_open_samba(dce_call->context, 39 &ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info, 39 &ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 40 dce_call->conn->auth_state.session_info, 40 41 NULL); 41 42 … … 61 62 62 63 h = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); 64 W_ERROR_HAVE_NO_MEMORY(h); 63 65 64 66 result = reg_get_predefined_key(ctx, hkey, … … 98 100 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); 99 101 100 talloc_ free(h);102 talloc_unlink(dce_call->context, h); 101 103 102 104 ZERO_STRUCTP(r->out.handle); … … 122 124 newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); 123 125 124 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))126 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 125 127 { 126 128 case SECURITY_SYSTEM: 127 129 case SECURITY_ADMINISTRATOR: 130 /* we support only non volatile keys */ 131 if (r->in.options != REG_OPTION_NON_VOLATILE) { 132 return WERR_NOT_SUPPORTED; 133 } 134 128 135 /* the security descriptor is optional */ 129 136 if (r->in.secdesc != NULL) { … … 135 142 return WERR_INVALID_PARAM; 136 143 } 137 ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL,&sd,144 ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, &sd, 138 145 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); 139 146 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 144 151 result = reg_key_add_name(newh, key, r->in.name.name, NULL, 145 152 r->in.secdesc?&sd:NULL, (struct registry_key **)&newh->data); 153 154 r->out.action_taken = talloc(mem_ctx, enum winreg_CreateAction); 155 if (r->out.action_taken == NULL) { 156 talloc_free(newh); 157 return WERR_NOMEM; 158 } 159 *r->out.action_taken = REG_ACTION_NONE; 160 146 161 if (W_ERROR_IS_OK(result)) { 147 162 r->out.new_handle = &newh->wire_handle; 163 *r->out.action_taken = REG_CREATED_NEW_KEY; 148 164 } else { 149 165 talloc_free(newh); 150 166 } 151 167 152 168 return result; 153 169 default: … … 166 182 struct dcesrv_handle *h; 167 183 struct registry_key *key; 168 169 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); 170 key = h->data; 171 172 switch (security_session_user_level(dce_call->conn->auth_state.session_info)) 184 WERROR result; 185 186 DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); 187 key = h->data; 188 189 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 173 190 { 174 191 case SECURITY_SYSTEM: 175 192 case SECURITY_ADMINISTRATOR: 176 return reg_key_del(key, r->in.key.name); 193 result = reg_key_del(mem_ctx, key, r->in.key.name); 194 talloc_unlink(dce_call->context, h); 195 196 return result; 177 197 default: 178 198 return WERR_ACCESS_DENIED; … … 194 214 key = h->data; 195 215 196 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))216 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 197 217 { 198 218 case SECURITY_SYSTEM: 199 219 case SECURITY_ADMINISTRATOR: 200 return reg_del_value( key, r->in.value.name);220 return reg_del_value(mem_ctx, key, r->in.value.name); 201 221 default: 202 222 return WERR_ACCESS_DENIED; … … 282 302 } 283 303 284 /* check if there is enough room for the name */285 if (r->in.name->size < 2*strlen_m_term(data_name)) {286 return WERR_MORE_DATA;287 }288 289 304 /* "data_name" is NULL when we query the default attribute */ 290 305 if (data_name != NULL) { … … 297 312 r->out.name->size = r->in.name->size; 298 313 299 r->out.type = talloc(mem_ctx, uint32_t);314 r->out.type = talloc(mem_ctx, enum winreg_Type); 300 315 if (!r->out.type) { 301 316 return WERR_NOMEM; 302 317 } 303 *r->out.type = data_type;318 *r->out.type = (enum winreg_Type) data_type; 304 319 305 320 /* check the client has enough room for the value */ … … 337 352 key = h->data; 338 353 339 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))354 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 340 355 { 341 356 case SECURITY_SYSTEM: … … 399 414 key = h->data; 400 415 401 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))416 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 402 417 { 403 418 case SECURITY_SYSTEM: … … 422 437 return WERR_ACCESS_DENIED; 423 438 } 424 425 439 } 426 440 … … 441 455 key = h->data; 442 456 443 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))457 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 444 458 { 445 459 case SECURITY_SYSTEM: … … 451 465 r->out.max_valnamelen, r->out.max_valbufsize); 452 466 467 if (r->out.max_subkeylen != NULL) { 468 /* for UTF16 encoding */ 469 *r->out.max_subkeylen *= 2; 470 } 471 if (r->out.max_valnamelen != NULL) { 472 /* for UTF16 encoding */ 473 *r->out.max_valnamelen *= 2; 474 } 475 453 476 if (classname != NULL) { 454 477 r->out.classname->name = classname; … … 483 506 key = h->data; 484 507 485 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))508 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 486 509 { 487 510 case SECURITY_SYSTEM: 488 511 case SECURITY_ADMINISTRATOR: 489 512 case SECURITY_USER: 513 if ((r->in.type == NULL) || (r->in.data_length == NULL) || 514 (r->in.data_size == NULL)) { 515 return WERR_INVALID_PARAM; 516 } 517 490 518 result = reg_key_get_value_by_name(mem_ctx, key, 491 519 r->in.value_name->name, &value_type, &value_data); … … 496 524 value_data.data = r->in.data; 497 525 value_data.length = *r->in.data_length; 498 } 499 500 r->out.type = talloc(mem_ctx, uint32_t); 526 } else { 527 if ((r->in.data != NULL) 528 && (*r->in.data_size < value_data.length)) { 529 result = WERR_MORE_DATA; 530 } 531 } 532 533 r->out.type = talloc(mem_ctx, enum winreg_Type); 501 534 if (!r->out.type) { 502 535 return WERR_NOMEM; 503 536 } 504 *r->out.type = value_type;537 *r->out.type = (enum winreg_Type) value_type; 505 538 r->out.data_length = talloc(mem_ctx, uint32_t); 506 539 if (!r->out.data_length) { … … 581 614 key = h->data; 582 615 583 switch (security_session_user_level(dce_call->conn->auth_state.session_info ))616 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 584 617 { 585 618 case SECURITY_SYSTEM: … … 691 724 } 692 725 726 /* 727 winreg_DeleteKeyEx 728 */ 729 static WERROR dcesrv_winreg_DeleteKeyEx(struct dcesrv_call_state *dce_call, 730 TALLOC_CTX *mem_ctx, 731 struct winreg_DeleteKeyEx *r) 732 { 733 return WERR_NOT_SUPPORTED; 734 } 693 735 694 736 /* include the generated boilerplate */ -
trunk/server/source4/rpc_server/wkssvc/dcesrv_wkssvc.c
r414 r745 23 23 #include "rpc_server/dcerpc_server.h" 24 24 #include "librpc/gen_ndr/ndr_wkssvc.h" 25 #include "librpc/gen_ndr/ndr_srvsvc.h" 25 26 #include "rpc_server/common/common.h" 27 #include "rpc_server/common/share.h" 26 28 #include "param/param.h" 27 29 … … 33 35 { 34 36 struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; 35 struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx); 36 37 ZERO_STRUCT(r->out); 38 r->out.info = talloc_zero(mem_ctx, union wkssvc_NetWkstaInfo); 39 W_ERROR_HAVE_NO_MEMORY(r->out.info); 37 struct dcerpc_server_info *server_info = lpcfg_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx); 40 38 41 39 /* NOTE: win2k3 ignores r->in.server_name completly so we do --metze */ … … 52 50 info100->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, NULL); 53 51 W_ERROR_HAVE_NO_MEMORY(info100->server_name); 54 info100->domain_name = talloc_reference(mem_ctx, server_info->domain_name); 55 W_ERROR_HAVE_NO_MEMORY(info100->domain_name); 52 info100->domain_name = server_info->domain_name; 56 53 info100->version_major = server_info->version_major; 57 54 info100->version_minor = server_info->version_minor; … … 70 67 info101->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, NULL); 71 68 W_ERROR_HAVE_NO_MEMORY(info101->server_name); 72 info101->domain_name = talloc_reference(mem_ctx, server_info->domain_name); 73 W_ERROR_HAVE_NO_MEMORY(info101->domain_name); 69 info101->domain_name = server_info->domain_name; 74 70 info101->version_major = server_info->version_major; 75 71 info101->version_minor = server_info->version_minor; … … 90 86 return WERR_UNKNOWN_LEVEL; 91 87 } 92 93 return WERR_UNKNOWN_LEVEL;94 88 } 95 89 … … 141 135 struct wkssvc_NetWkstaTransportEnum *r) 142 136 { 143 r->out.total_entries = 0;144 r->out.resume_handle = NULL;145 146 137 switch (r->in.info->level) { 147 138 case 0: 148 r->out.info = talloc(mem_ctx, struct wkssvc_NetWkstaTransportInfo);149 W_ERROR_HAVE_NO_MEMORY(r->out.info);150 r->out.info->level = r->in.info->level;151 139 r->out.info->ctr.ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaTransportCtr0); 152 140 W_ERROR_HAVE_NO_MEMORY(r->out.info->ctr.ctr0); … … 160 148 return WERR_UNKNOWN_LEVEL; 161 149 } 162 163 return WERR_UNKNOWN_LEVEL;164 150 } 165 151
Note:
See TracChangeset
for help on using the changeset viewer.