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