Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/rpc_server/lsa/dcesrv_lsa.c

    r414 r745  
    2929#include "librpc/gen_ndr/ndr_lsa.h"
    3030#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"
    3135
    3236/*
     
    8185
    8286        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);
    8488
    8589        domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
     
    180184
    181185                /* 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))
    183187                {
    184188                case SECURITY_SYSTEM:
     
    186190                        break;
    187191                default:
    188                         /* Users and annonymous are not allowed delete things */
     192                        /* Users and anonymous are not allowed to delete things */
    189193                        return NT_STATUS_ACCESS_DENIED;
    190194                }
     
    192196                ret = ldb_delete(secret_state->sam_ldb,
    193197                                 secret_state->secret_dn);
    194                 talloc_free(h);
    195                 if (ret != 0) {
     198                if (ret != LDB_SUCCESS) {
    196199                        return NT_STATUS_INVALID_HANDLE;
    197200                }
     
    200203
    201204                return NT_STATUS_OK;
     205
    202206        } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
    203207                struct lsa_trusted_domain_state *trusted_domain_state =
    204208                        talloc_get_type(h->data, struct lsa_trusted_domain_state);
    205209                ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
    206                 if (ret != 0) {
     210                if (ret != LDB_SUCCESS) {
    207211                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    208212                }
     
    210214                ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
    211215                                 trusted_domain_state->trusted_domain_dn);
    212                 if (ret != 0) {
     216                if (ret != LDB_SUCCESS) {
    213217                        ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
    214218                        return NT_STATUS_INVALID_HANDLE;
     
    218222                        ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
    219223                                         trusted_domain_state->trusted_domain_user_dn);
    220                         if (ret != 0) {
     224                        if (ret != LDB_SUCCESS) {
    221225                                ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
    222226                                return NT_STATUS_INVALID_HANDLE;
     
    225229
    226230                ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
    227                 if (ret != 0) {
     231                if (ret != LDB_SUCCESS) {
    228232                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    229233                }
    230                 talloc_free(h);
     234
    231235                ZERO_STRUCTP(r->out.handle);
    232236
    233237                return NT_STATUS_OK;
     238
    234239        } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
    235240                struct lsa_RightSet *rights;
     
    272277
    273278                ZERO_STRUCTP(r->out.handle);
     279
     280                return NT_STATUS_OK;
    274281        }
    275282       
     
    286293        struct dcesrv_handle *h;
    287294        struct lsa_policy_state *state;
    288         int i;
     295        uint32_t i;
     296        enum sec_privilege priv;
    289297        const char *privname;
    290298
     
    294302
    295303        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) &&
    299306               r->out.privs->count < r->in.max_count) {
    300307                struct lsa_PrivEntry *e;
    301 
     308                privname = sec_privilege_name(priv);
    302309                r->out.privs->privs = talloc_realloc(r->out.privs,
    303310                                                       r->out.privs->privs,
     
    308315                }
    309316                e = &r->out.privs->privs[r->out.privs->count];
    310                 e->luid.low = i;
     317                e->luid.low = priv;
    311318                e->luid.high = 0;
    312319                e->name.string = privname;
     
    334341        DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
    335342
    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];
    337344
    338345        if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
     
    386393        union dssetup_DsRoleInfo *info;
    387394
    388         info = talloc(mem_ctx, union dssetup_DsRoleInfo);
     395        info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
    389396        W_ERROR_HAVE_NO_MEMORY(info);
    390397
     
    407414                ZERO_STRUCT(domain_guid);
    408415
    409                 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
     416                switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
    410417                case ROLE_STANDALONE:
    411418                        role            = DS_ROLE_STANDALONE_SERVER;
     
    423430                }
    424431
    425                 switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
     432                switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
    426433                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));
    428435                        W_ERROR_HAVE_NO_MEMORY(domain);
    429436                        break;
    430437                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));
    432439                        W_ERROR_HAVE_NO_MEMORY(domain);
    433440                        /* TODO: what is with dns_domain and forest and guid? */
     
    477484                return WERR_INVALID_PARAM;
    478485        }
    479 
    480         return WERR_INVALID_PARAM;
    481486}
    482487
     
    551556                return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
    552557
    553 
    554558        case LSA_POLICY_INFO_ROLE:
    555559                info->role.role = LSA_ROLE_PRIMARY;
     
    683687        struct dcesrv_handle *h;
    684688        struct lsa_policy_state *state;
    685         int ret, i;
     689        int ret;
    686690        struct ldb_message **res;
    687691        const char * const attrs[] = { "objectSid", NULL};
    688         uint32_t count;
     692        uint32_t count, i;
    689693
    690694        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     
    695699           one privilege set
    696700        */
    697         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
     701        ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    698702                           "(&(objectSid=*)(privilege=*))");
    699703        if (ret < 0) {
    700                 return NT_STATUS_NO_SUCH_USER;
     704                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    701705        }
    702706
     
    734738}
    735739
     740/* This decrypts and returns Trusted Domain Auth Information Internal data */
     741static 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
     765static 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
     782static 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}
    736870
    737871/*
     
    747881        struct lsa_trusted_domain_state *trusted_domain_state;
    748882        struct dcesrv_handle *handle;
    749         struct ldb_message **msgs, *msg, *msg_user;
     883        struct ldb_message **msgs, *msg;
    750884        const char *attrs[] = {
    751885                NULL
     
    754888        const char *dns_name;
    755889        const char *name;
    756         DATA_BLOB session_key = data_blob(NULL, 0);
    757890        DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
    758891        struct trustDomainPasswords auth_struct;
    759892        int ret;
    760893        NTSTATUS nt_status;
    761         enum ndr_err_code ndr_err;
    762        
     894        struct ldb_context *sam_ldb;
     895
    763896        DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
    764897        ZERO_STRUCTP(r->out.trustdom_handle);
    765        
     898
    766899        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;
    772901
    773902        netbios_name = r->in.info->netbios_name.string;
     
    775904                return NT_STATUS_INVALID_PARAMETER;
    776905        }
    777        
     906
    778907        dns_name = r->in.info->domain_name.string;
    779        
     908
    780909        trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
    781910        if (!trusted_domain_state) {
     
    785914
    786915        if (strcasecmp(netbios_name, "BUILTIN") == 0
    787             || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0) 
     916            || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
    788917            || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
    789                 return NT_STATUS_INVALID_PARAMETER;;
     918                return NT_STATUS_INVALID_PARAMETER;
    790919        }
    791920
    792921        if (strcasecmp(netbios_name, policy_state->domain_name) == 0
    793922            || 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)
    795924            || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)
    796925            || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
     
    804933                auth_struct.incoming.count = 0;
    805934        } 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                }
    815942
    816943                if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
     
    822949
    823950        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;
    857956                }
    858957        } else {
    859958                trustAuthIncoming = data_blob(NULL, 0);
    860959        }
    861        
     960
    862961        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;
    896967                }
    897968        } else {
     
    899970        }
    900971
    901         ret = ldb_transaction_start(policy_state->sam_ldb);
     972        ret = ldb_transaction_start(sam_ldb);
    902973        if (ret != LDB_SUCCESS) {
    903974                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     
    908979                char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
    909980                /* search for the trusted_domain record */
    910                 ret = gendb_search(policy_state->sam_ldb,
     981                ret = gendb_search(sam_ldb,
    911982                                   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))",
    913984                                   dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded);
    914985                if (ret > 0) {
    915                         ldb_transaction_cancel(policy_state->sam_ldb);
     986                        ldb_transaction_cancel(sam_ldb);
    916987                        return NT_STATUS_OBJECT_NAME_COLLISION;
    917988                }
     
    919990                char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
    920991                /* search for the trusted_domain record */
    921                 ret = gendb_search(policy_state->sam_ldb,
     992                ret = gendb_search(sam_ldb,
    922993                                   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))",
    924995                                   netbios_encoded, netbios_encoded, netbios_encoded);
    925996                if (ret > 0) {
    926                         ldb_transaction_cancel(policy_state->sam_ldb);
     997                        ldb_transaction_cancel(sam_ldb);
    927998                        return NT_STATUS_OBJECT_NAME_COLLISION;
    928999                }
    9291000        }
    930        
     1001
    9311002        if (ret < 0 ) {
    932                 ldb_transaction_cancel(policy_state->sam_ldb);
     1003                ldb_transaction_cancel(sam_ldb);
    9331004                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    9341005        }
    935        
     1006
    9361007        name = dns_name ? dns_name : netbios_name;
    9371008
     
    9431014        msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
    9441015        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);
    9501021
    9511022        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
    9691038        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);
    9711040        }
    9721041
     
    9741043                ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
    9751044                if (ret != LDB_SUCCESS) {
    976                         ldb_transaction_cancel(policy_state->sam_ldb);
     1045                        ldb_transaction_cancel(sam_ldb);
    9771046                        return NT_STATUS_NO_MEMORY;
    9781047                }
     
    9811050                ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
    9821051                if (ret != LDB_SUCCESS) {
    983                         ldb_transaction_cancel(policy_state->sam_ldb);
     1052                        ldb_transaction_cancel(sam_ldb);
    9841053                        return NT_STATUS_NO_MEMORY;
    9851054                }
     
    9891058
    9901059        /* create the trusted_domain */
    991         ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
     1060        ret = ldb_add(sam_ldb, msg);
    9921061        switch (ret) {
    9931062        case  LDB_SUCCESS:
    9941063                break;
    9951064        case  LDB_ERR_ENTRY_ALREADY_EXISTS:
    996                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
     1065                ldb_transaction_cancel(sam_ldb);
    9971066                DEBUG(0,("Failed to create trusted domain record %s: %s\n",
    9981067                         ldb_dn_get_linearized(msg->dn),
    999                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
     1068                         ldb_errstring(sam_ldb)));
    10001069                return NT_STATUS_DOMAIN_EXISTS;
    10011070        case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
    1002                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
     1071                ldb_transaction_cancel(sam_ldb);
    10031072                DEBUG(0,("Failed to create trusted domain record %s: %s\n",
    10041073                         ldb_dn_get_linearized(msg->dn),
    1005                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
     1074                         ldb_errstring(sam_ldb)));
    10061075                return NT_STATUS_ACCESS_DENIED;
    10071076        default:
    1008                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
     1077                ldb_transaction_cancel(sam_ldb);
    10091078                DEBUG(0,("Failed to create user record %s: %s\n",
    10101079                         ldb_dn_get_linearized(msg->dn),
    1011                          ldb_errstring(trusted_domain_state->policy->sam_ldb)));
     1080                         ldb_errstring(sam_ldb)));
    10121081                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    10131082        }
    10141083
    10151084        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;
    10221086                /* 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);
    10941103        if (ret != LDB_SUCCESS) {
    10951104                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     
    11001109                return NT_STATUS_NO_MEMORY;
    11011110        }
    1102        
     1111
    11031112        handle->data = talloc_steal(handle, trusted_domain_state);
    1104        
     1113
    11051114        trusted_domain_state->access_mask = r->in.access_mask;
    11061115        trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
    1107        
     1116
    11081117        *r->out.trustdom_handle = handle->wire_handle;
    1109        
     1118
    11101119        return NT_STATUS_OK;
    11111120}
     
    12241233                ret = gendb_search(trusted_domain_state->policy->sam_ldb,
    12251234                                   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))",
    12271236                                   flatname, UF_INTERDOMAIN_TRUST_ACCOUNT);
    12281237                if (ret == 1) {
     
    12541263{
    12551264        struct dcesrv_handle *policy_handle;
    1256        
     1265
    12571266        struct lsa_policy_state *policy_state;
    12581267        struct lsa_trusted_domain_state *trusted_domain_state;
     
    12621271                NULL
    12631272        };
    1264 
     1273        char *td_name;
    12651274        int ret;
    12661275
     
    12721281                return NT_STATUS_INVALID_PARAMETER;
    12731282        }
    1274        
     1283
    12751284        trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
    12761285        if (!trusted_domain_state) {
     
    12801289
    12811290        /* search for the trusted_domain record */
     1291        td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
    12821292        ret = gendb_search(trusted_domain_state->policy->sam_ldb,
    12831293                           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);
    12861297        if (ret == 0) {
    12871298                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    12881299        }
    1289        
     1300
    12901301        if (ret != 1) {
    12911302                DEBUG(0,("Found %d records matching DN %s\n", ret,
     
    12941305        }
    12951306
     1307        /* TODO: perform access checks */
     1308
    12961309        trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
    1297        
     1310
    12981311        handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
    12991312        if (!handle) {
    13001313                return NT_STATUS_NO_MEMORY;
    13011314        }
    1302        
     1315
    13031316        handle->data = talloc_steal(handle, trusted_domain_state);
    1304        
     1317
    13051318        trusted_domain_state->access_mask = r->in.access_mask;
    13061319        trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
    1307        
     1320
    13081321        *r->out.trustdom_handle = handle->wire_handle;
    1309        
     1322
    13101323        return NT_STATUS_OK;
    13111324}
     
    13241337
    13251338
    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 */
     1341static 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
     1422static 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
     1464done:
     1465        if (orig_value) {
     1466                *orig_value = orig_uint;
     1467        }
     1468        return NT_STATUS_OK;
     1469}
     1470
     1471static 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
     1583static 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
     1872done:
     1873        if (in_transaction) {
     1874                ldb_transaction_cancel(p_state->sam_ldb);
     1875        }
     1876        return nt_status;
     1877}
     1878
     1879/*
    13271880  lsa_SetInfomrationTrustedDomain
    13281881*/
    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);
     1882static 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);
    13341911}
    13351912
     
    14332010        case LSA_TRUSTED_DOMAIN_INFO_NAME:
    14342011                info->name.netbios_name.string
    1435                         = samdb_result_string(msg, "flatname", NULL);                                     
     2012                        = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
    14362013                break;
    14372014        case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    14382015                info->posix_offset.posix_offset
    1439                         = samdb_result_uint(msg, "posixOffset", 0);                                       
     2016                        = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
    14402017                break;
    14412018#if 0  /* Win2k3 doesn't implement this */
     
    14532030                ZERO_STRUCT(info->full_info);
    14542031                return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
    1455 
    14562032        case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
    14572033                ZERO_STRUCT(info->full_info2_internal);
    14582034                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);
    14602036                return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
    14612037               
    14622038        case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    14632039                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);
    14652041                break;
    14662042
     
    15272103                                               struct lsa_SetTrustedDomainInfoByName *r)
    15282104{
    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);
    15302129}
    15312130
     
    16232222        count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
    16242223                             "objectclass=trustedDomain");
    1625         if (count == -1) {
     2224        if (count < 0) {
    16262225                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    16272226        }
     
    16342233        for (i=0;i<count;i++) {
    16352234                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);
    16372236        }
    16382237
    16392238        /* sort the results by name */
    1640         qsort(entries, count, sizeof(*entries),
    1641               (comparison_fn_t)compare_DomainInfo);
     2239        TYPESAFE_QSORT(entries, count, compare_DomainInfo);
    16422240
    16432241        if (*r->in.resume_handle >= count) {
     
    17172315        count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
    17182316                             "objectclass=trustedDomain");
    1719         if (count == -1) {
     2317        if (count < 0) {
    17202318                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    17212319        }
     
    17342332
    17352333        /* sort the results by name */
    1736         qsort(entries, count, sizeof(*entries),
    1737               (comparison_fn_t)compare_TrustDomainInfoInfoEx);
     2334        TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
    17382335
    17392336        if (*r->in.resume_handle >= count) {
     
    18142411        struct dcesrv_handle *h;
    18152412        struct lsa_account_state *astate;
    1816         int ret, i;
     2413        int ret;
     2414        unsigned int i, j;
    18172415        struct ldb_message **res;
    18182416        const char * const attrs[] = { "privilege", NULL};
     
    18402438        }
    18412439
    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,
    18432441                           "objectSid=%s", sidstr);
     2442        if (ret < 0) {
     2443                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     2444        }
    18442445        if (ret != 1) {
    18452446                return NT_STATUS_OK;
     
    18572458        }
    18582459
     2460        j = 0;
    18592461        for (i=0;i<el->num_values;i++) {
    18602462                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;
    18702474
    18712475        return NT_STATUS_OK;
     
    18812485        struct dcesrv_handle *h;
    18822486        struct lsa_policy_state *state;
    1883         int ret, i;
     2487        int ret;
     2488        unsigned int i;
    18842489        struct ldb_message **res;
    18852490        const char * const attrs[] = { "privilege", NULL};
     
    18962501        }
    18972502
    1898         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
     2503        ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    18992504                           "(&(objectSid=%s)(privilege=*))", sidstr);
    19002505        if (ret == 0) {
    19012506                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    19022507        }
    1903         if (ret > 1) {
    1904                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1905         }
    1906         if (ret == -1) {
     2508        if (ret != 1) {
    19072509                DEBUG(3, ("searching for account rights for SID: %s failed: %s",
    19082510                          dom_sid_string(mem_ctx, r->in.sid),
    1909                           ldb_errstring(state->sam_ldb)));
     2511                          ldb_errstring(state->pdb)));
    19102512                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    19112513        }
     
    19422544                                           const struct lsa_RightSet *rights)
    19432545{
    1944         const char *sidstr;
     2546        const char *sidstr, *sidndrstr;
    19452547        struct ldb_message *msg;
    19462548        struct ldb_message_element *el;
    1947         int i, ret;
     2549        int ret;
     2550        uint32_t i;
    19482551        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;
    19532558        }
    19542559
     
    19582563        }
    19592564
    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) {
    19802578                NTSTATUS status;
    19812579
     
    19912589
    19922590        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);
    19942598                        return NT_STATUS_NO_SUCH_PRIVILEGE;
    19952599                }
    19962600
    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;
    19992603                        for (j=0;j<r2.out.rights->count;j++) {
    20002604                                if (strcasecmp_m(r2.out.rights->names[j].string,
     
    20082612                ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
    20092613                if (ret != LDB_SUCCESS) {
     2614                        talloc_free(msg);
    20102615                        return NT_STATUS_NO_MEMORY;
    20112616                }
     
    20142619        el = ldb_msg_find_element(msg, "privilege");
    20152620        if (!el) {
     2621                talloc_free(msg);
    20162622                return NT_STATUS_OK;
    20172623        }
    20182624
    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;
    20232640                }
    20242641                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);
    20272645                return NT_STATUS_UNEXPECTED_IO_ERROR;
    20282646        }
    20292647
     2648        talloc_free(msg);
    20302649        return NT_STATUS_OK;
    20312650}
     
    20402659        struct dcesrv_handle *h;
    20412660        struct lsa_account_state *astate;
    2042         int i;
     2661        uint32_t i;
    20432662
    20442663        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
     
    20772696        struct dcesrv_handle *h;
    20782697        struct lsa_account_state *astate;
    2079         int i;
     2698        uint32_t i;
    20802699
    20812700        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
     
    21562775                       struct lsa_GetSystemAccessAccount *r)
    21572776{
    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;
    21782785
    21792786        *(r->out.access_mask) = 0x00000000;
    21802787
    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;
    21952818        }
    21962819
     
    22312854        ZERO_STRUCTP(r->out.sec_handle);
    22322855       
    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))
    22342857        {
    22352858        case SECURITY_SYSTEM:
     
    22482871       
    22492872        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);
    22532874        secret_state->policy = policy_state;
    22542875
     
    22602881        if (strncmp("G$", r->in.name.string, 2) == 0) {
    22612882                const char *name2;
     2883
     2884                secret_state->global = true;
     2885
    22622886                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) {
    22692888                        return NT_STATUS_INVALID_PARAMETER;
    22702889                }
    22712890
    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
    22732902                /* search for the secret record */
    22742903                ret = gendb_search(secret_state->sam_ldb,
     
    22802909                }
    22812910               
    2282                 if (ret == -1) {
     2911                if (ret < 0) {
    22832912                        DEBUG(0,("Failure searching for CN=%s: %s\n",
    22842913                                 name2, ldb_errstring(secret_state->sam_ldb)));
     
    22872916
    22882917                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)) {
    22902920                        return NT_STATUS_NO_MEMORY;
    22912921                }
    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;
    22952925        } else {
    22962926                secret_state->global = false;
    22972927
    22982928                name = r->in.name.string;
    2299                 if (strlen(name) < 1) {
     2929                if (strlen(name) == 0) {
    23002930                        return NT_STATUS_INVALID_PARAMETER;
    23012931                }
    23022932
    23032933                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
    23052937                /* search for the secret record */
    23062938                ret = gendb_search(secret_state->sam_ldb, mem_ctx,
     
    23132945                }
    23142946               
    2315                 if (ret == -1) {
     2947                if (ret < 0) {
    23162948                        DEBUG(0,("Failure searching for CN=%s: %s\n",
    23172949                                 name, ldb_errstring(secret_state->sam_ldb)));
     
    23192951                }
    23202952
    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;
    23232958        }
    23242959
    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;
    23262962       
    23272963        secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
     2964        NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
    23282965
    23292966        /* create the secret */
    23302967        ret = ldb_add(secret_state->sam_ldb, msg);
    2331         if (ret != 0) {
     2968        if (ret != LDB_SUCCESS) {
    23322969                DEBUG(0,("Failed to create secret record %s: %s\n",
    23332970                         ldb_dn_get_linearized(msg->dn),
     
    23362973        }
    23372974
     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*/
     2993static 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       
    23383089        handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
    23393090        if (!handle) {
     
    23533104
    23543105/*
    2355   lsa_OpenSecret
    2356 */
    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                 NULL
    2368         };
    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 /*
    24703106  lsa_SetSecret
    24713107*/
     
    25183154               
    25193155                /* 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) {
    25223157                        return NT_STATUS_NO_MEMORY;
    25233158                }
     
    25253160                /* set old value mtime */
    25263161                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) {
    25283163                        return NT_STATUS_NO_MEMORY;
    25293164                }
     
    25593194                if (old_val) {
    25603195                        /* 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) {
    25643198                                return NT_STATUS_NO_MEMORY;
    25653199                        }
    25663200                } else {
    25673201                        if (samdb_msg_add_delete(secret_state->sam_ldb,
    2568                                                  mem_ctx, msg, "priorValue")) {
     3202                                                 mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
    25693203                                return NT_STATUS_NO_MEMORY;
    25703204                        }
     
    25753209                if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
    25763210                        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) {
    25783212                                return NT_STATUS_NO_MEMORY;
    25793213                        }
    25803214                } else {
    25813215                        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) {
    25833217                                return NT_STATUS_NO_MEMORY;
    25843218                        }
     
    26003234               
    26013235                /* 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) {
    26043237                        return NT_STATUS_NO_MEMORY;
    26053238                }
     
    26073240                /* set new value mtime */
    26083241                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) {
    26103243                        return NT_STATUS_NO_MEMORY;
    26113244                }
     
    26143247                /* NULL out the NEW value */
    26153248                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) {
    26173250                        return NT_STATUS_NO_MEMORY;
    26183251                }
    26193252                if (samdb_msg_add_delete(secret_state->sam_ldb,
    2620                                          mem_ctx, msg, "currentValue")) {
     3253                                         mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
    26213254                        return NT_STATUS_NO_MEMORY;
    26223255                }
     
    26243257
    26253258        /* 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) {
    26283261                /* we really need samdb.c to return NTSTATUS */
    26293262                return NT_STATUS_UNSUCCESSFUL;
     
    26603293
    26613294        /* 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))
    26633296        {
    26643297        case SECURITY_SYSTEM:
     
    27763409
    27773410        id = sec_privilege_id(r->in.name->string);
    2778         if (id == -1) {
     3411        if (id == SEC_PRIV_INVALID) {
    27793412                return NT_STATUS_NO_SUCH_PRIVILEGE;
    27803413        }
     
    28353468        struct lsa_policy_state *state;
    28363469        struct lsa_StringLarge *disp_name = NULL;
    2837         int id;
     3470        enum sec_privilege id;
    28383471
    28393472        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     
    28423475
    28433476        id = sec_privilege_id(r->in.name->string);
    2844         if (id == -1) {
     3477        if (id == SEC_PRIV_INVALID) {
    28453478                return NT_STATUS_NO_SUCH_PRIVILEGE;
    28463479        }
     
    28863519
    28873520        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) {
    28893522                return NT_STATUS_NO_SUCH_PRIVILEGE;
    28903523        }
    28913524
    2892         ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
     3525        ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    28933526                           "privilege=%s", privname);
    2894         if (ret == -1) {
     3527        if (ret < 0) {
    28953528                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    28963529        }
     
    30043637        }
    30053638
    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);
    30083641
    30093642        _account_name = talloc(mem_ctx, struct lsa_String);
     
    30453678        union lsa_DomainInformationPolicy *info;
    30463679
    3047         info = talloc(r->out.info, union lsa_DomainInformationPolicy);
     3680        info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
    30483681        if (!info) {
    30493682                return NT_STATUS_NO_MEMORY;
     
    30683701                        return NT_STATUS_INTERNAL_ERROR;
    30693702                }
    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);
    30753706                talloc_free(smb_krb5_context);
    30763707                *r->out.info = info;
     
    32333864}
    32343865
    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 */
     3873static 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 */
     3913static 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
     3934static 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
     3985static 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
     4050static 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
     4054static 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
     4193static 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*/
     4228static 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}
    32454417
    32464418/*
  • trunk/server/source4/rpc_server/lsa/lsa.h

    r414 r745  
    2727#include "dsdb/samdb/samdb.h"
    2828#include "libcli/ldap/ldap_ndr.h"
    29 #include "lib/ldb/include/ldb_errors.h"
     29#include <ldb_errors.h>
    3030#include "libcli/security/security.h"
    3131#include "libcli/auth/libcli_auth.h"
     
    4141        struct dcesrv_handle *handle;
    4242        struct ldb_context *sam_ldb;
     43        struct ldb_context *pdb;
    4344        uint32_t access_mask;
    4445        struct ldb_dn *domain_dn;
  • trunk/server/source4/rpc_server/lsa/lsa_init.c

    r414 r745  
    4444
    4545        /* 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);
    4747        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) {
    4854                return NT_STATUS_INVALID_SYSTEM_SERVICE;
    4955        }
     
    5864        /* work out the forest root_dn - useful for so many calls its worth
    5965           fetching here */
    60         state->forest_dn = samdb_root_dn(state->sam_ldb);
     66        state->forest_dn = ldb_get_root_basedn(state->sam_ldb);
    6167        if (!state->forest_dn) {
    6268                return NT_STATUS_NO_MEMORY;             
     
    8389        talloc_free(dom_res);
    8490
    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);
    8692
    8793        state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
  • trunk/server/source4/rpc_server/lsa/lsa_lookup.c

    r414 r745  
    2222
    2323#include "rpc_server/lsa/lsa.h"
     24#include "libds/common/flag_mapping.h"
    2425
    2526static const struct {
     
    2728        const char *name;
    2829        const char *sid;
    29         int rtype;
     30        enum lsa_SidType rtype;
    3031} well_known[] = {
    3132        {
     
    194195static NTSTATUS lookup_well_known_names(TALLOC_CTX *mem_ctx, const char *domain,
    195196                                        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;
    199200        for (i=0; well_known[i].sid; i++) {
    200201                if (domain) {
     
    220221static NTSTATUS lookup_well_known_sids(TALLOC_CTX *mem_ctx,
    221222                                       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;
    225226        for (i=0; well_known[i].sid; i++) {
    226227                if (strcasecmp_m(sid_str, well_known[i].sid) == 0) {
     
    240241                                       struct loadparm_context *lp_ctx,
    241242                                       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;
    246249        struct ldb_message **res;
    247250        const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
     
    275278                status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
    276279                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;
    277289                        return NT_STATUS_OK;
    278290                }
     
    282294                        *sid =  dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
    283295                        *rtype = SID_NAME_DOMAIN;
     296                        dom_sid_split_rid(NULL, *sid, NULL, rid);
    284297                        return NT_STATUS_OK;
    285298                }
     
    288301                        *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
    289302                        *rtype = SID_NAME_DOMAIN;
     303                        *rid = 0xFFFFFFFF;
    290304                        return NT_STATUS_OK;
    291305                }
     
    294308                        *sid =  state->domain_sid;
    295309                        *rtype = SID_NAME_DOMAIN;
     310                        *rid = 0xFFFFFFFF;
    296311                        return NT_STATUS_OK;
    297312                }
     
    300315                        *sid =  state->domain_sid;
    301316                        *rtype = SID_NAME_DOMAIN;
     317                        *rid = 0xFFFFFFFF;
    302318                        return NT_STATUS_OK;
    303319                }
     
    308324                        return NT_STATUS_NO_MEMORY;
    309325                }
    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);
    311327                if (NT_STATUS_IS_OK(status)) {
    312328                        return status;
     
    318334                        return NT_STATUS_NO_MEMORY;
    319335                }
    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);
    321337                if (NT_STATUS_IS_OK(status)) {
    322338                        return status;
     
    328344                        return NT_STATUS_NO_MEMORY;
    329345                }
    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);
    331347                if (NT_STATUS_IS_OK(status)) {
    332348                        return status;
     
    339355                        *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
    340356                        *rtype = SID_NAME_DOMAIN;
     357                        dom_sid_split_rid(NULL, *sid, NULL, rid);
    341358                        return NT_STATUS_OK;
    342359                }
    343360
    344361                /* 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;
    347368        } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
    348369                *authority_name = NAME_BUILTIN;
     
    360381
    361382        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) {
    368388                return NT_STATUS_INVALID_SID;
    369389        }
     
    372392                *sid = domain_sid;
    373393                *rtype = SID_NAME_DOMAIN;
     394                *rid = 0xFFFFFFFF;
    374395                return NT_STATUS_OK;
    375396        }
     
    378399                           "(&(sAMAccountName=%s)(objectSid=*))",
    379400                           ldb_binary_encode_string(mem_ctx, username));
    380         if (ret == -1) {
    381                 return NT_STATUS_INVALID_SID;
     401        if (ret < 0) {
     402                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    382403        }
    383404
     
    393414                }
    394415
    395                 atype = samdb_result_uint(res[i], "sAMAccountType", 0);
     416                atype = ldb_msg_find_attr_as_uint(res[i], "sAMAccountType", 0);
    396417                       
    397418                *rtype = ds_atype_map(atype);
     
    400421                }
    401422
     423                dom_sid_split_rid(NULL, *sid, NULL, rid);
    402424                return NT_STATUS_OK;
    403425        }
     
    420442{
    421443        struct dom_sid *authority_sid;
    422         int i;
     444        uint32_t i;
    423445
    424446        if (rtype != SID_NAME_DOMAIN) {
     
    490512        }
    491513
     514        /* need to re-add a check for an allocated sid */
     515
    492516        ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
    493517                           "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);
    496528                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;
    514538}
    515539
     
    524548        struct lsa_policy_state *state;
    525549        struct lsa_RefDomainList *domains = NULL;
    526         int i;
     550        uint32_t i;
    527551        NTSTATUS status = NT_STATUS_OK;
    528552
     
    683707        struct lsa_LookupSids2 r2;
    684708        NTSTATUS status;
    685         int i;
     709        uint32_t i;
    686710
    687711        ZERO_STRUCT(r2);
     
    737761        struct lsa_policy_state *policy_state;
    738762        struct dcesrv_handle *policy_handle;
    739         int i;
     763        uint32_t i;
    740764        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
    741765        struct lsa_RefDomainList *domains;
     
    775799                const char *authority_name;
    776800                struct dom_sid *sid;
    777                 uint32_t sid_index;
     801                uint32_t sid_index, rid;
    778802                enum lsa_SidType rtype;
    779803                NTSTATUS status2;
     
    786810                r->out.sids->sids[i].flags       = 0;
    787811
    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);
    789814                if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
    790815                        continue;
     
    878903        struct lsa_policy_state *state;
    879904        struct dcesrv_handle *h;
    880         int i;
     905        uint32_t i;
    881906        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
    882907        struct lsa_RefDomainList *domains;
     
    916941                const char *authority_name;
    917942                struct dom_sid *sid;
    918                 uint32_t rtype, sid_index;
     943                uint32_t sid_index, rid=0;
     944                enum lsa_SidType rtype;
    919945                NTSTATUS status2;
    920946
     
    929955                r->out.sids->sids[i].unknown     = 0;
    930956
    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);
    933959                if (!NT_STATUS_IS_OK(status2)) {
    934960                        continue;
     
    942968
    943969                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;
    945971                r->out.sids->sids[i].sid_index   = sid_index;
    946972                r->out.sids->sids[i].unknown     = 0;
     
    967993        struct lsa_LookupNames2 r2;
    968994        NTSTATUS status;
    969         int i;
     995        uint32_t i;
    970996
    971997        ZERO_STRUCT(r2);
Note: See TracChangeset for help on using the changeset viewer.