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:
1 deleted
10 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/smb_server/smb/negprot.c

    r414 r745  
    3434{
    3535        NTSTATUS nt_status;
    36         const uint8_t *challenge;
    3736
    3837        /* muliple negprots are not premitted */
     
    5453        }
    5554
    56         nt_status = auth_get_challenge(smb_conn->negotiate.auth_context, &challenge);
     55        nt_status = auth_get_challenge(smb_conn->negotiate.auth_context, buff);
    5756        if (!NT_STATUS_IS_OK(nt_status)) {
    5857                DEBUG(0, ("auth_get_challenge() returned %s", nt_errstr(nt_status)));
    5958                return nt_status;
    6059        }
    61 
    62         memcpy(buff, challenge, 8);
    6360
    6461        return NT_STATUS_OK;
     
    9289static void reply_coreplus(struct smbsrv_request *req, uint16_t choice)
    9390{
    94         uint16_t raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0);
     91        uint16_t raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);
    9592
    9693        smbsrv_setup_reply(req, 13, 0);
     
    123120static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
    124121{
    125         int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0);
     122        int raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);
    126123        int secword=0;
    127124        time_t t = req->request_time.tv_sec;
    128125
    129         req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx);
    130 
    131         if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE)
     126        req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx);
     127
     128        if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE)
    132129                secword |= NEGOTIATE_SECURITY_USER_LEVEL;
    133130
     
    146143        SSVAL(req->out.vwv, VWV(1), secword);
    147144        SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv);
    148         SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx));
     145        SSVAL(req->out.vwv, VWV(3), lpcfg_maxmux(req->smb_conn->lp_ctx));
    149146        SSVAL(req->out.vwv, VWV(4), 1);
    150147        SSVAL(req->out.vwv, VWV(5), raw);
     
    181178static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
    182179{
    183         int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0);
     180        int raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);
    184181        int secword=0;
    185182        time_t t = req->request_time.tv_sec;
    186183
    187         req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx);
     184        req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx);
    188185 
    189         if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE)
     186        if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE)
    190187                secword |= NEGOTIATE_SECURITY_USER_LEVEL;
    191188
     
    200197        SSVAL(req->out.vwv, VWV(1), secword);
    201198        SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv);
    202         SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx));
     199        SSVAL(req->out.vwv, VWV(3), lpcfg_maxmux(req->smb_conn->lp_ctx));
    203200        SSVAL(req->out.vwv, VWV(4), 1);
    204201        SSVAL(req->out.vwv, VWV(5), raw);
     
    215212        }
    216213
    217         req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_TERMINATE);
     214        req_push_str(req, NULL, lpcfg_workgroup(req->smb_conn->lp_ctx), -1, STR_TERMINATE);
    218215
    219216        if (req->smb_conn->signing.mandatory_signing) {
     
    237234                SCVAL(req->out.vwv+1, VWV(16), 8);
    238235        }
    239         req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
    240         req_push_str(req, NULL, lp_netbios_name(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
     236        req_push_str(req, NULL, lpcfg_workgroup(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
     237        req_push_str(req, NULL, lpcfg_netbios_name(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
    241238        DEBUG(3,("not using extended security (SPNEGO or NTLMSSP)\n"));
    242239}
     
    261258                CAP_LEVEL_II_OPLOCKS | CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
    262259
    263         req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx);
     260        req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx);
    264261
    265262        /* do spnego in user level security if the client
     
    267264       
    268265        if (req->smb_conn->negotiate.encrypted_passwords &&
    269             (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) &&
    270             lp_use_spnego(req->smb_conn->lp_ctx) &&
     266            (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) &&
     267            lpcfg_use_spnego(req->smb_conn->lp_ctx) &&
    271268            (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
    272269                negotiate_spnego = true;
     
    274271        }
    275272       
    276         if (lp_unix_extensions(req->smb_conn->lp_ctx)) {
     273        if (lpcfg_unix_extensions(req->smb_conn->lp_ctx)) {
    277274                capabilities |= CAP_UNIX;
    278275        }
    279276       
    280         if (lp_large_readwrite(req->smb_conn->lp_ctx)) {
     277        if (lpcfg_large_readwrite(req->smb_conn->lp_ctx)) {
    281278                capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS;
    282279        }
     
    287284        }
    288285
    289         if (lp_readraw(req->smb_conn->lp_ctx) &&
    290             lp_writeraw(req->smb_conn->lp_ctx)) {
     286        if (lpcfg_readraw(req->smb_conn->lp_ctx) &&
     287            lpcfg_writeraw(req->smb_conn->lp_ctx)) {
    291288                capabilities |= CAP_RAW_MODE;
    292289        }
    293290       
    294291        /* allow for disabling unicode */
    295         if (lp_unicode(req->smb_conn->lp_ctx)) {
     292        if (lpcfg_unicode(req->smb_conn->lp_ctx)) {
    296293                capabilities |= CAP_UNICODE;
    297294        }
    298295
    299         if (lp_nt_status_support(req->smb_conn->lp_ctx)) {
     296        if (lpcfg_nt_status_support(req->smb_conn->lp_ctx)) {
    300297                capabilities |= CAP_STATUS32;
    301298        }
    302299       
    303         if (lp_host_msdfs(req->smb_conn->lp_ctx)) {
     300        if (lpcfg_host_msdfs(req->smb_conn->lp_ctx)) {
    304301                capabilities |= CAP_DFS;
    305302        }
    306303       
    307         if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) {
     304        if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) {
    308305                secword |= NEGOTIATE_SECURITY_USER_LEVEL;
    309306        }
     
    332329           the specification - all the command words after the secword
    333330           are offset by 1 byte */
    334         SSVAL(req->out.vwv+1, VWV(1), lp_maxmux(req->smb_conn->lp_ctx));
     331        SSVAL(req->out.vwv+1, VWV(1), lpcfg_maxmux(req->smb_conn->lp_ctx));
    335332        SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */
    336333        SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv);
     
    522519                int i;
    523520
    524                 if (supported_protocols[protocol].protocol_level > lp_srv_maxprotocol(req->smb_conn->lp_ctx))
     521                if (supported_protocols[protocol].protocol_level > lpcfg_srv_maxprotocol(req->smb_conn->lp_ctx))
    525522                        continue;
    526                 if (supported_protocols[protocol].protocol_level < lp_srv_minprotocol(req->smb_conn->lp_ctx))
     523                if (supported_protocols[protocol].protocol_level < lpcfg_srv_minprotocol(req->smb_conn->lp_ctx))
    527524                        continue;
    528525
  • trunk/server/source4/smb_server/smb/nttrans.c

    r414 r745  
    120120
    121121        io->ntcreatex.in.flags            = IVAL(params,  0);
    122         io->ntcreatex.in.root_fid         = IVAL(params, 4);
     122        io->ntcreatex.in.root_fid.ntvfs   = smbsrv_pull_fnum(req, params, 4);
    123123        io->ntcreatex.in.access_mask      = IVAL(params,  8);
    124124        io->ntcreatex.in.alloc_size       = BVAL(params, 12);
     
    135135        io->ntcreatex.in.ea_list          = NULL;
    136136        io->ntcreatex.in.query_maximal_access = false;
     137        io->ntcreatex.in.private_flags    = 0;
    137138
    138139        req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname,
     
    159160                        return NT_STATUS_NO_MEMORY;
    160161                }
    161                 ndr_err = ndr_pull_struct_blob(&blob, io, NULL,
     162                ndr_err = ndr_pull_struct_blob(&blob, io,
    162163                                               io->ntcreatex.in.sec_desc,
    163164                                               (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     
    206207        params = op->trans->out.params.data;
    207208
    208         ndr_err = ndr_push_struct_blob(&op->trans->out.data, op, NULL,
     209        ndr_err = ndr_push_struct_blob(&op->trans->out.data, op,
    209210                                       io->query_secdesc.out.sd,
    210211                                       (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     
    272273        NT_STATUS_HAVE_NO_MEMORY(io->set_secdesc.in.sd);
    273274
    274         ndr_err = ndr_pull_struct_blob(&trans->in.data, req, NULL,
     275        ndr_err = ndr_pull_struct_blob(&trans->in.data, req,
    275276                                       io->set_secdesc.in.sd,
    276277                                       (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     
    528529        do {
    529530                uint32_t this_data, this_param, max_bytes;
    530                 uint_t align1 = 1, align2 = (params_left ? 2 : 0);
     531                unsigned int align1 = 1, align2 = (params_left ? 2 : 0);
    531532                struct smbsrv_request *this_req;
    532533
  • trunk/server/source4/smb_server/smb/receive.c

    r414 r745  
    664664        /* this is the size that w2k uses, and it appears to be important for
    665665           good performance */
    666         smb_conn->negotiate.max_recv = lp_max_xmit(lp_ctx);
     666        smb_conn->negotiate.max_recv = lpcfg_max_xmit(lp_ctx);
    667667
    668668        smb_conn->negotiate.zone_offset = get_time_zone(time(NULL));
    669669
    670         smb_conn->config.security = lp_security(lp_ctx);
    671         smb_conn->config.nt_status_support = lp_nt_status_support(lp_ctx);
     670        smb_conn->config.security = lpcfg_security(lp_ctx);
     671        smb_conn->config.nt_status_support = lpcfg_nt_status_support(lp_ctx);
    672672
    673673        status = smbsrv_init_sessions(smb_conn, UINT16_MAX);
  • trunk/server/source4/smb_server/smb/reply.c

    r414 r745  
    812812        union smb_read *io;
    813813
    814         SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read);
     814        SMBSRV_CHECK_ASYNC_STATUS_ERR(io, union smb_read);
    815815
    816816        /* readx reply packets can be over-sized */
     
    835835        SMBSRV_VWV_RESERVED(8, 4);
    836836
     837        if (!NT_STATUS_IS_OK(req->ntvfs->async_states->status)) {
     838                smbsrv_setup_error(req, req->ntvfs->async_states->status);
     839        }
     840
    837841        smbsrv_chain_reply(req);
    838842}
     
    13811385        union smb_lpq *lpq;
    13821386        int i, maxcount;
    1383         const uint_t el_size = 28;
     1387        const unsigned int el_size = 28;
    13841388
    13851389        SMBSRV_CHECK_ASYNC_STATUS(lpq,union smb_lpq);
     
    16481652{
    16491653        union smb_lock *lck;
    1650         uint_t total_locks, i;
    1651         uint_t lck_size;
     1654        unsigned int total_locks, i;
     1655        unsigned int lck_size;
    16521656        uint8_t *p;
    16531657
     
    22172221        fname_len =                         SVAL(req->in.vwv, 5);
    22182222        io->ntcreatex.in.flags =            IVAL(req->in.vwv, 7);
    2219         io->ntcreatex.in.root_fid =         IVAL(req->in.vwv, 11);
     2223        io->ntcreatex.in.root_fid.ntvfs =   smbsrv_pull_fnum(req, req->in.vwv, 11);
    22202224        io->ntcreatex.in.access_mask =      IVAL(req->in.vwv, 15);
    22212225        io->ntcreatex.in.alloc_size =       BVAL(req->in.vwv, 19);
     
    22292233        io->ntcreatex.in.sec_desc         = NULL;
    22302234        io->ntcreatex.in.query_maximal_access = false;
    2231 
    2232         /* we use a couple of bits of the create options internally */
    2233         if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
    2234                 smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
    2235                 return;
    2236         }
     2235        io->ntcreatex.in.private_flags    = 0;
    22372236
    22382237        /* we need a neater way to handle this alignment */
  • trunk/server/source4/smb_server/smb/request.c

    r414 r745  
    7777  setup a chained reply in req->out with the given word count and initial data buffer size.
    7878*/
    79 static void req_setup_chain_reply(struct smbsrv_request *req, uint_t wct, uint_t buflen)
     79static void req_setup_chain_reply(struct smbsrv_request *req, unsigned int wct, unsigned int buflen)
    8080{
    8181        uint32_t chain_base_size = req->out.size;
     
    111111  send the reply on its way
    112112*/
    113 void smbsrv_setup_reply(struct smbsrv_request *req, uint_t wct, size_t buflen)
     113void smbsrv_setup_reply(struct smbsrv_request *req, unsigned int wct, size_t buflen)
    114114{
    115115        uint16_t flags2;
     
    234234  point at the same offset into the packet as before this call
    235235*/
    236 static void req_grow_allocation(struct smbsrv_request *req, uint_t new_size)
     236static void req_grow_allocation(struct smbsrv_request *req, unsigned int new_size)
    237237{
    238238        int delta;
     
    400400{
    401401        size_t len;
    402         uint_t grow_size;
     402        unsigned int grow_size;
    403403        uint8_t *buf0;
    404404        const int max_bytes_per_char = 3;
     
    479479  of bytes consumed in the packet is returned
    480480*/
    481 static size_t req_pull_ucs2(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
     481static size_t req_pull_ucs2(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, unsigned int flags)
    482482{
    483483        int src_len, src_len2, alignment=0;
     
    537537  of bytes consumed in the packet is returned
    538538*/
    539 static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
     539static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, unsigned int flags)
    540540{
    541541        int src_len, src_len2;
     
    586586  of bytes consumed in the packet is returned
    587587*/
    588 size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
     588size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, unsigned int flags)
    589589{
    590590        if (!(flags & STR_ASCII) &&
     
    606606  match win2000 behaviour
    607607*/
    608 size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, uint_t flags)
     608size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, unsigned int flags)
    609609{
    610610        ssize_t ret;
     
    668668   pull an open file handle from a packet, taking account of the chained_fnum
    669669*/
    670 static uint16_t req_fnum(struct smbsrv_request *req, const uint8_t *base, uint_t offset)
     670static uint16_t req_fnum(struct smbsrv_request *req, const uint8_t *base, unsigned int offset)
    671671{
    672672        if (req->chained_fnum != -1) {
     
    676676}
    677677
    678 struct ntvfs_handle *smbsrv_pull_fnum(struct smbsrv_request *req, const uint8_t *base, uint_t offset)
     678struct ntvfs_handle *smbsrv_pull_fnum(struct smbsrv_request *req, const uint8_t *base, unsigned int offset)
    679679{
    680680        struct smbsrv_handle *handle;
     
    700700}
    701701
    702 void smbsrv_push_fnum(uint8_t *base, uint_t offset, struct ntvfs_handle *ntvfs)
     702void smbsrv_push_fnum(uint8_t *base, unsigned int offset, struct ntvfs_handle *ntvfs)
    703703{
    704704        struct smbsrv_handle *handle = talloc_get_type(ntvfs->frontend_data.private_data,
  • trunk/server/source4/smb_server/smb/service.c

    r414 r745  
    7171        }
    7272
    73         status = ntvfs_set_addr_callbacks(tcon->ntvfs, smbsrv_get_my_addr, smbsrv_get_peer_addr, req->smb_conn);
     73        status = ntvfs_set_addresses(tcon->ntvfs,
     74                                     req->smb_conn->connection->local_address,
     75                                     req->smb_conn->connection->remote_address);
    7476        if (!NT_STATUS_IS_OK(status)) {
    75                 DEBUG(0,("make_connection: NTVFS failed to set the addr callbacks!\n"));
     77                DEBUG(0,("make_connection: NTVFS failed to set the addresses!\n"));
    7678                goto failed;
    7779        }
     
    190192        con->tconx.out.tid = req->tcon->tid;
    191193        con->tconx.out.options = SMB_SUPPORT_SEARCH_BITS | (share_int_option(req->tcon->ntvfs->config, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT) << 2);
    192         if (share_bool_option(req->tcon->ntvfs->config, SHARE_MSDFS_ROOT, SHARE_MSDFS_ROOT_DEFAULT) && lp_host_msdfs(req->smb_conn->lp_ctx)) {
     194        if (share_bool_option(req->tcon->ntvfs->config, SHARE_MSDFS_ROOT, SHARE_MSDFS_ROOT_DEFAULT) && lpcfg_host_msdfs(req->smb_conn->lp_ctx)) {
    193195                con->tconx.out.options |= SMB_SHARE_IN_DFS;
    194196        }
  • trunk/server/source4/smb_server/smb/sesssetup.c

    r414 r745  
    2424
    2525#include "includes.h"
     26#include <tevent.h>
    2627#include "version.h"
    2728#include "auth/gensec/gensec.h"
     
    3031#include "smbd/service_stream.h"
    3132#include "param/param.h"
     33#include "../lib/tsocket/tsocket.h"
     34#include "lib/stream/packet.h"
     35
     36struct sesssetup_context {
     37        struct auth_context *auth_context;
     38        struct smbsrv_request *req;
     39};
    3240
    3341/*
     
    4048        (*lanman) = talloc_asprintf(req, "Samba %s", SAMBA_VERSION_STRING);
    4149        (*domain) = talloc_asprintf(req, "%s",
    42                                     lp_workgroup(req->smb_conn->lp_ctx));
     50                                    lpcfg_workgroup(req->smb_conn->lp_ctx));
    4351}
    4452
     
    5563}
    5664
    57 static void sesssetup_old_send(struct auth_check_password_request *areq,
    58                                void *private_data)
    59 {
    60         struct smbsrv_request *req = talloc_get_type(private_data, struct smbsrv_request);
     65static void sesssetup_old_send(struct tevent_req *subreq)
     66{
     67        struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
     68        struct smbsrv_request *req = state->req;
     69
    6170        union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
    62         struct auth_serversupplied_info *server_info = NULL;
     71        struct auth_user_info_dc *user_info_dc = NULL;
    6372        struct auth_session_info *session_info;
    6473        struct smbsrv_session *smb_sess;
    6574        NTSTATUS status;
    66 
    67         status = auth_check_password_recv(areq, req, &server_info);
    68         if (!NT_STATUS_IS_OK(status)) goto failed;
    69 
    70         /* This references server_info into session_info */
    71         status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx, req->smb_conn->lp_ctx,
    72                                             server_info, &session_info);
     75        uint32_t flags;
     76
     77        status = auth_check_password_recv(subreq, req, &user_info_dc);
     78        TALLOC_FREE(subreq);
     79        if (!NT_STATUS_IS_OK(status)) goto failed;
     80
     81        flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
     82        if (user_info_dc->info->authenticated) {
     83                flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     84        }
     85        /* This references user_info_dc into session_info */
     86        status = req->smb_conn->negotiate.auth_context->generate_session_info(req,
     87                                                                              req->smb_conn->negotiate.auth_context,
     88                                                                              user_info_dc, flags, &session_info);
    7389        if (!NT_STATUS_IS_OK(status)) goto failed;
    7490
     
    91107
    92108failed:
    93         status = auth_nt_status_squash(status);
     109        status = nt_status_squash(status);
    94110        smbsrv_sesssetup_backend_send(req, sess, status);
    95111}
     
    101117{
    102118        struct auth_usersupplied_info *user_info = NULL;
    103         struct socket_address *remote_address;
     119        struct tsocket_address *remote_address;
    104120        const char *remote_machine = NULL;
     121        struct tevent_req *subreq;
     122        struct sesssetup_context *state;
    105123
    106124        sess->old.out.vuid = 0;
     
    120138        }
    121139       
    122         remote_address = socket_get_peer_addr(req->smb_conn->connection->socket, req);
     140        remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
    123141        if (!remote_address) goto nomem;
    124142
    125143        if (!remote_machine) {
    126                 remote_machine = remote_address->addr;
    127         }
    128 
    129         user_info = talloc(req, struct auth_usersupplied_info);
     144                remote_machine = tsocket_address_inet_addr_string(remote_address, req);
     145                if (!remote_machine) goto nomem;
     146        }
     147
     148        user_info = talloc_zero(req, struct auth_usersupplied_info);
    130149        if (!user_info) goto nomem;
    131150       
     
    143162        user_info->password.response.nt = data_blob(NULL, 0);
    144163
    145         auth_check_password_send(req->smb_conn->negotiate.auth_context, user_info,
    146                                  sesssetup_old_send, req);
     164        state = talloc(req, struct sesssetup_context);
     165        if (!state) goto nomem;
     166
     167        if (req->smb_conn->negotiate.auth_context) {
     168                state->auth_context = req->smb_conn->negotiate.auth_context;
     169        } else {
     170                /* TODO: should we use just "anonymous" here? */
     171                NTSTATUS status = auth_context_create(state,
     172                                                      req->smb_conn->connection->event.ctx,
     173                                                      req->smb_conn->connection->msg_ctx,
     174                                                      req->smb_conn->lp_ctx,
     175                                                      &state->auth_context);
     176                if (!NT_STATUS_IS_OK(status)) {
     177                        smbsrv_sesssetup_backend_send(req, sess, status);
     178                        return;
     179                }
     180        }
     181
     182        state->req = req;
     183
     184        subreq = auth_check_password_send(state,
     185                                          req->smb_conn->connection->event.ctx,
     186                                          req->smb_conn->negotiate.auth_context,
     187                                          user_info);
     188        if (!subreq) goto nomem;
     189        tevent_req_set_callback(subreq, sesssetup_old_send, state);
    147190        return;
    148191
     
    151194}
    152195
    153 static void sesssetup_nt1_send(struct auth_check_password_request *areq,
    154                                void *private_data)
    155 {
    156         struct smbsrv_request *req = talloc_get_type(private_data, struct smbsrv_request);
     196static void sesssetup_nt1_send(struct tevent_req *subreq)
     197{
     198        struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
     199        struct smbsrv_request *req = state->req;
    157200        union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
    158         struct auth_serversupplied_info *server_info = NULL;
     201        struct auth_user_info_dc *user_info_dc = NULL;
    159202        struct auth_session_info *session_info;
    160203        struct smbsrv_session *smb_sess;
     204
     205        uint32_t flags;
    161206        NTSTATUS status;
    162207
    163         status = auth_check_password_recv(areq, req, &server_info);
    164         if (!NT_STATUS_IS_OK(status)) goto failed;
    165 
    166         /* This references server_info into session_info */
    167         status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx,
    168                                             req->smb_conn->lp_ctx,
    169                                             server_info, &session_info);
     208        status = auth_check_password_recv(subreq, req, &user_info_dc);
     209        TALLOC_FREE(subreq);
     210        if (!NT_STATUS_IS_OK(status)) goto failed;
     211
     212        flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
     213        if (user_info_dc->info->authenticated) {
     214                flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     215        }
     216        /* This references user_info_dc into session_info */
     217        status = state->auth_context->generate_session_info(req,
     218                                                            state->auth_context,
     219                                                            user_info_dc,
     220                                                            flags,
     221                                                            &session_info);
    170222        if (!NT_STATUS_IS_OK(status)) goto failed;
    171223
     
    195247        status = NT_STATUS_OK;
    196248failed:
    197         status = auth_nt_status_squash(status);
     249        status = nt_status_squash(status);
    198250        smbsrv_sesssetup_backend_send(req, sess, status);
    199251}
     
    205257{
    206258        NTSTATUS status;
    207         struct auth_context *auth_context;
    208259        struct auth_usersupplied_info *user_info = NULL;
    209         struct socket_address *remote_address;
     260        struct tsocket_address *remote_address;
    210261        const char *remote_machine = NULL;
    211        
     262        struct tevent_req *subreq;
     263        struct sesssetup_context *state;
     264
    212265        sess->nt1.out.vuid = 0;
    213266        sess->nt1.out.action = 0;
     
    222275                req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities;
    223276        }
     277
     278        state = talloc(req, struct sesssetup_context);
     279        if (!state) goto nomem;
     280
     281        state->req = req;
    224282
    225283        if (req->smb_conn->negotiate.oid) {
     
    232290
    233291                /* TODO: should we use just "anonymous" here? */
    234                 status = auth_context_create(req,
     292                status = auth_context_create(state,
    235293                                             req->smb_conn->connection->event.ctx,
    236294                                             req->smb_conn->connection->msg_ctx,
    237295                                             req->smb_conn->lp_ctx,
    238                                              &auth_context);
     296                                             &state->auth_context);
    239297                if (!NT_STATUS_IS_OK(status)) goto failed;
     298        } else if (req->smb_conn->negotiate.auth_context) {
     299                state->auth_context = req->smb_conn->negotiate.auth_context;
    240300        } else {
    241                 auth_context = req->smb_conn->negotiate.auth_context;
     301                /* TODO: should we use just "anonymous" here? */
     302                status = auth_context_create(state,
     303                                             req->smb_conn->connection->event.ctx,
     304                                             req->smb_conn->connection->msg_ctx,
     305                                             req->smb_conn->lp_ctx,
     306                                             &state->auth_context);
     307                if (!NT_STATUS_IS_OK(status)) goto failed;
    242308        }
    243309
     
    246312        }
    247313
    248         remote_address = socket_get_peer_addr(req->smb_conn->connection->socket, req);
     314        remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
    249315        if (!remote_address) goto nomem;
    250316
    251317        if (!remote_machine) {
    252                 remote_machine = remote_address->addr;
    253         }
    254 
    255         user_info = talloc(req, struct auth_usersupplied_info);
     318                remote_machine = tsocket_address_inet_addr_string(remote_address, req);
     319                if (!remote_machine) goto nomem;
     320        }
     321
     322        user_info = talloc_zero(req, struct auth_usersupplied_info);
    256323        if (!user_info) goto nomem;
    257324
     
    270337        user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);
    271338
    272         auth_check_password_send(auth_context, user_info,
    273                                  sesssetup_nt1_send, req);
     339        subreq = auth_check_password_send(state,
     340                                          req->smb_conn->connection->event.ctx,
     341                                          state->auth_context,
     342                                          user_info);
     343        if (!subreq) goto nomem;
     344        tevent_req_set_callback(subreq, sesssetup_nt1_send, state);
     345
    274346        return;
    275347
     
    277349        status = NT_STATUS_NO_MEMORY;
    278350failed:
    279         status = auth_nt_status_squash(status);
     351        status = nt_status_squash(status);
    280352        smbsrv_sesssetup_backend_send(req, sess, status);
    281353}
     
    287359};
    288360
    289 static void sesssetup_spnego_send(struct gensec_update_request *greq, void *private_data)
    290 {
    291         struct sesssetup_spnego_state *s = talloc_get_type(private_data,
     361static void sesssetup_spnego_send(struct tevent_req *subreq)
     362{
     363        struct sesssetup_spnego_state *s = tevent_req_callback_data(subreq,
    292364                                           struct sesssetup_spnego_state);
    293365        struct smbsrv_request *req = s->req;
     
    299371        DATA_BLOB session_key;
    300372
    301         status = gensec_update_recv(greq, req, &sess->spnego.out.secblob);
     373        status = gensec_update_recv(subreq, req, &sess->spnego.out.secblob);
     374        packet_recv_enable(req->smb_conn->packet);
     375        TALLOC_FREE(subreq);
    302376        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    303377                goto done;
     
    324398        sess->spnego.out.vuid = smb_sess->vuid;
    325399failed:
    326         status = auth_nt_status_squash(status);
     400        status = nt_status_squash(status);
    327401        smbsrv_sesssetup_backend_send(req, sess, status);
    328402        if (!NT_STATUS_IS_OK(status) &&
     
    341415        struct sesssetup_spnego_state *s = NULL;
    342416        uint16_t vuid;
     417        struct tevent_req *subreq;
    343418
    344419        sess->spnego.out.vuid = 0;
     
    408483        s->smb_sess     = smb_sess;
    409484
    410         gensec_update_send(smb_sess->gensec_ctx, sess->spnego.in.secblob,
    411                            sesssetup_spnego_send, s);
     485        subreq = gensec_update_send(s,
     486                                    req->smb_conn->connection->event.ctx,
     487                                    smb_sess->gensec_ctx,
     488                                    sess->spnego.in.secblob);
     489        if (!subreq) {
     490                goto nomem;
     491        }
     492        /* disable receipt of more packets on this socket until we've
     493           finished with the session setup. This avoids a problem with
     494           crashes if we get EOF on the socket while processing a session
     495           setup */
     496        packet_recv_disable(req->smb_conn->packet);
     497        tevent_req_set_callback(subreq, sesssetup_spnego_send, s);
     498
    412499        return;
    413500
     
    416503failed:
    417504        talloc_free(smb_sess);
    418         status = auth_nt_status_squash(status);
     505        status = nt_status_squash(status);
    419506        smbsrv_sesssetup_backend_send(req, sess, status);
    420507}
  • trunk/server/source4/smb_server/smb/signing.c

    r414 r745  
    8383        }
    8484       
    85         switch (lp_server_signing(smb_conn->lp_ctx)) {
     85        switch (lpcfg_server_signing(smb_conn->lp_ctx)) {
    8686        case SMB_SIGNING_OFF:
    8787                smb_conn->signing.allow_smb_signing = false;
     
    100100                 * clients */
    101101
    102                 if (lp_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
     102                if (lpcfg_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
    103103                        smb_conn->signing.allow_smb_signing = true;
    104104                        smb_conn->signing.mandatory_signing = true;
  • trunk/server/source4/smb_server/smb/trans2.c

    r414 r745  
    33   transaction2 handling
    44   Copyright (C) Andrew Tridgell 2003
     5   Copyright Matthieu Patou 2010 mat@matws.net
    56
    67   This program is free software; you can redistribute it and/or modify
     
    2223
    2324#include "includes.h"
     25#include "smbd/service_stream.h"
    2426#include "smb_server/smb_server.h"
    2527#include "ntvfs/ntvfs.h"
    2628#include "libcli/raw/libcliraw.h"
    2729#include "libcli/raw/raw_proto.h"
     30#include "librpc/gen_ndr/dfsblobs.h"
     31#include "librpc/gen_ndr/ndr_dfsblobs.h"
     32#include "dsdb/samdb/samdb.h"
     33#include "auth/session.h"
     34#include "param/param.h"
     35#include "lib/tsocket/tsocket.h"
     36
     37#define MAX_DFS_RESPONSE 56*1024 /* 56 Kb */
    2838
    2939#define TRANS2_CHECK_ASYNC_STATUS_SIMPLE do { \
     
    5464        void *op_info;
    5565};
    56 
     66/* A DC set is a group of DC, they might have been grouped together
     67   because they belong to the same site, or to site with same cost ...
     68*/
     69struct dc_set {
     70        const char **names;
     71        uint32_t count;
     72};
    5773#define CHECK_MIN_BLOB_SIZE(blob, size) do { \
    5874        if ((blob)->length < (size)) { \
     
    205221        smbsrv_push_fnum(trans->out.params.data, VWV(0), io->t2open.out.file.ntvfs);
    206222        SSVAL(trans->out.params.data, VWV(1), io->t2open.out.attrib);
    207         srv_push_dos_date3(req->smb_conn, trans->out.params.data, 
     223        srv_push_dos_date3(req->smb_conn, trans->out.params.data,
    208224                           VWV(2), io->t2open.out.write_time);
    209225        SIVAL(trans->out.params.data, VWV(4), io->t2open.out.size);
     
    240256        io->t2open.in.search_attrs = SVAL(trans->in.params.data, VWV(2));
    241257        io->t2open.in.file_attrs   = SVAL(trans->in.params.data, VWV(3));
    242         io->t2open.in.write_time   = srv_pull_dos_date(req->smb_conn, 
     258        io->t2open.in.write_time   = srv_pull_dos_date(req->smb_conn,
    243259                                                    trans->in.params.data + VWV(4));
    244260        io->t2open.in.open_func    = SVAL(trans->in.params.data, VWV(6));
     
    301317        }
    302318
    303         TRANS2_CHECK(ea_pull_list(&trans->in.data, io, 
    304                                   &io->t2mkdir.in.num_eas, 
     319        TRANS2_CHECK(ea_pull_list(&trans->in.data, io,
     320                                  &io->t2mkdir.in.num_eas,
    305321                                  &io->t2mkdir.in.eas));
    306322
     
    363379                TRANS2_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size));
    364380
    365                 ea_put_list(blob->data, 
     381                ea_put_list(blob->data,
    366382                            st->ea_list.out.num_eas, st->ea_list.out.eas);
    367383                return NT_STATUS_OK;
     
    372388                TRANS2_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size));
    373389
    374                 ea_put_list(blob->data, 
     390                ea_put_list(blob->data,
    375391                            st->all_eas.out.num_eas, st->all_eas.out.eas);
    376392                return NT_STATUS_OK;
     
    473489
    474490        if (st->generic.level == RAW_FILEINFO_EA_LIST) {
    475                 TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req, 
     491                TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
    476492                                               &st->ea_list.in.num_names,
    477493                                               &st->ea_list.in.ea_names));
     
    514530
    515531        if (st->generic.level == RAW_FILEINFO_EA_LIST) {
    516                 TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req, 
     532                TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
    517533                                               &st->ea_list.in.num_names,
    518534                                               &st->ea_list.in.ea_names));
     
    554570
    555571        case RAW_SFILEINFO_EA_SET:
    556                 return ea_pull_list(blob, req, 
    557                                     &st->ea_set.in.num_eas, 
     572                return ea_pull_list(blob, req,
     573                                    &st->ea_set.in.num_eas,
    558574                                    &st->ea_set.in.eas);
    559575
     
    699715
    700716/*
    701   fill a single entry in a trans2 find reply 
     717  fill a single entry in a trans2 find reply
    702718*/
    703719static NTSTATUS find_fill_info(struct find_state *state,
     
    707723        struct smb_trans2 *trans = state->op->trans;
    708724        uint8_t *data;
    709         uint_t ofs = trans->out.data.length;
     725        unsigned int ofs = trans->out.data.length;
    710726        uint32_t ea_size;
    711727
     
    731747                SIVAL(data, 16, file->standard.alloc_size);
    732748                SSVAL(data, 20, file->standard.attrib);
    733                 TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->standard.name.s, 
     749                TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->standard.name.s,
    734750                                                       ofs + 22, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
    735751                                                       STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM));
     
    752768                SSVAL(data, 20, file->ea_size.attrib);
    753769                SIVAL(data, 22, file->ea_size.ea_size);
    754                 TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_size.name.s, 
     770                TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_size.name.s,
    755771                                                       ofs + 26, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
    756772                                                       STR_LEN8BIT | STR_NOALIGN));
     
    775791                SSVAL(data, 20, file->ea_list.attrib);
    776792                ea_put_list(data+22, file->ea_list.eas.num_eas, file->ea_list.eas.eas);
    777                 TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_list.name.s, 
     793                TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_list.name.s,
    778794                                                       ofs + 22 + ea_size, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
    779795                                                       STR_LEN8BIT | STR_NOALIGN));
     
    803819        struct find_state *state = talloc_get_type(private_data, struct find_state);
    804820        struct smb_trans2 *trans = state->op->trans;
    805         uint_t old_length;
     821        unsigned int old_length;
    806822
    807823        old_length = trans->out.data.length;
     
    845861
    846862/*
     863  fill a referral type structure
     864 */
     865static NTSTATUS fill_normal_dfs_referraltype(struct dfs_referral_type *ref,
     866                                             uint16_t version,
     867                                             const char *dfs_path,
     868                                             const char *server_path, int isfirstoffset)
     869{
     870
     871        switch (version) {
     872        case 3:
     873                ZERO_STRUCTP(ref);
     874                ref->version = version;
     875                ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT;
     876                /* "normal" referral seems to always include the GUID */
     877                ref->referral.v3.size = 34;
     878
     879                ref->referral.v3.data.entry_flags = 0;
     880                ref->referral.v3.data.ttl = 600; /* As w2k3 */
     881                ref->referral.v3.data.referrals.r1.DFS_path = dfs_path;
     882                ref->referral.v3.data.referrals.r1.DFS_alt_path = dfs_path;
     883                ref->referral.v3.data.referrals.r1.netw_address = server_path;
     884                return NT_STATUS_OK;
     885        case 4:
     886                ZERO_STRUCTP(ref);
     887                ref->version = version;
     888                ref->referral.v4.server_type = DFS_SERVER_NON_ROOT;
     889                /* "normal" referral seems to always include the GUID */
     890                ref->referral.v4.size = 34;
     891
     892                if (isfirstoffset) {
     893                        ref->referral.v4.entry_flags =  DFS_HEADER_FLAG_TARGET_BCK;
     894                }
     895                ref->referral.v4.ttl = 600; /* As w2k3 */
     896                ref->referral.v4.r1.DFS_path = dfs_path;
     897                ref->referral.v4.r1.DFS_alt_path = dfs_path;
     898                ref->referral.v4.r1.netw_address = server_path;
     899
     900                return NT_STATUS_OK;
     901        }
     902        return NT_STATUS_INVALID_LEVEL;
     903}
     904
     905/*
     906  fill a domain refererral
     907 */
     908static NTSTATUS fill_domain_dfs_referraltype(struct dfs_referral_type *ref,
     909                                             uint16_t version,
     910                                             const char *domain,
     911                                             const char **names,
     912                                             uint16_t numnames)
     913{
     914        switch (version) {
     915        case 3:
     916                ZERO_STRUCTP(ref);
     917                ref->version = version;
     918                ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT;
     919                /* It's hard coded ... don't think it's a good way but the sizeof return not the
     920                 * correct values
     921                 *
     922                 * We have 18 if the GUID is not included 34 otherwise
     923                */
     924                ref->referral.v3.size = 18;
     925                ref->referral.v3.data.entry_flags = DFS_FLAG_REFERRAL_DOMAIN_RESP;
     926                ref->referral.v3.data.ttl = 600; /* As w2k3 */
     927                ref->referral.v3.data.referrals.r2.special_name = domain;
     928                ref->referral.v3.data.referrals.r2.nb_expanded_names = numnames;
     929                /* Put the final terminator */
     930                if (names) {
     931                        const char **names2 = talloc_array(ref, const char *, numnames+1);
     932                        NT_STATUS_HAVE_NO_MEMORY(names2);
     933                        int i;
     934                        for (i = 0; i<numnames; i++) {
     935                                names2[i] = talloc_asprintf(names2, "\\%s", names[i]);
     936                                NT_STATUS_HAVE_NO_MEMORY(names2[i]);
     937                        }
     938                        names2[numnames] = 0;
     939                        ref->referral.v3.data.referrals.r2.expanded_names = names2;
     940                }
     941                return NT_STATUS_OK;
     942        }
     943        return NT_STATUS_INVALID_LEVEL;
     944}
     945
     946/*
     947  get the DCs list within a site
     948 */
     949static NTSTATUS get_dcs_insite(TALLOC_CTX *ctx, struct ldb_context *ldb,
     950                               struct ldb_dn *sitedn, struct dc_set *list,
     951                               bool dofqdn)
     952{
     953        static const char *attrs[] = { "serverReference", NULL };
     954        static const char *attrs2[] = { "dNSHostName", "sAMAccountName", NULL };
     955        struct ldb_result *r;
     956        unsigned int i;
     957        int ret;
     958        const char **dc_list;
     959
     960        ret = ldb_search(ldb, ctx, &r, sitedn, LDB_SCOPE_SUBTREE, attrs,
     961                         "(&(objectClass=server)(serverReference=*))");
     962        if (ret != LDB_SUCCESS) {
     963                DEBUG(2,(__location__ ": Failed to get list of servers - %s\n",
     964                         ldb_errstring(ldb)));
     965                return NT_STATUS_INTERNAL_ERROR;
     966        }
     967
     968        if (r->count == 0) {
     969                /* none in this site */
     970                talloc_free(r);
     971                return NT_STATUS_OK;
     972        }
     973
     974        /*
     975         * need to search for all server object to know the size of the array.
     976         * Search all the object of class server in this site
     977         */
     978        dc_list = talloc_array(r, const char *, r->count);
     979        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dc_list, r);
     980
     981        /* TODO put some random here in the order */
     982        list->names = talloc_realloc(list, list->names, const char *, list->count + r->count);
     983        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names, r);
     984
     985        for (i = 0; i<r->count; i++) {
     986                struct ldb_dn  *dn;
     987                struct ldb_result *r2;
     988
     989                dn = ldb_msg_find_attr_as_dn(ldb, ctx, r->msgs[i], "serverReference");
     990                if (!dn) {
     991                        return NT_STATUS_INTERNAL_ERROR;
     992                }
     993
     994                ret = ldb_search(ldb, r, &r2, dn, LDB_SCOPE_BASE, attrs2, "(objectClass=computer)");
     995                if (ret != LDB_SUCCESS) {
     996                        DEBUG(2,(__location__ ": Search for computer on %s failed - %s\n",
     997                                 ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
     998                        return NT_STATUS_INTERNAL_ERROR;
     999                }
     1000
     1001                if (dofqdn) {
     1002                        const char *dns = ldb_msg_find_attr_as_string(r2->msgs[0], "dNSHostName", NULL);
     1003                        if (dns == NULL) {
     1004                                DEBUG(2,(__location__ ": dNSHostName missing on %s\n",
     1005                                         ldb_dn_get_linearized(dn)));
     1006                                talloc_free(r);
     1007                                return NT_STATUS_INTERNAL_ERROR;
     1008                        }
     1009
     1010                        list->names[list->count] = talloc_strdup(list->names, dns);
     1011                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names[list->count], r);
     1012                } else {
     1013                        char *tmp;
     1014                        const char *acct = ldb_msg_find_attr_as_string(r2->msgs[0], "sAMAccountName", NULL);
     1015                        if (acct == NULL) {
     1016                                DEBUG(2,(__location__ ": sAMAccountName missing on %s\n",
     1017                                         ldb_dn_get_linearized(dn)));
     1018                                talloc_free(r);
     1019                                return NT_STATUS_INTERNAL_ERROR;
     1020                        }
     1021
     1022                        tmp = talloc_strdup(list->names, acct);
     1023                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tmp, r);
     1024
     1025                        /* Netbios name is also the sAMAccountName for
     1026                           computer but without the final $ */
     1027                        tmp[strlen(tmp) - 1] = '\0';
     1028                        list->names[list->count] = tmp;
     1029                }
     1030                list->count++;
     1031                talloc_free(r2);
     1032        }
     1033
     1034        talloc_free(r);
     1035        return NT_STATUS_OK;
     1036}
     1037
     1038
     1039/*
     1040  get all DCs
     1041 */
     1042static NTSTATUS get_dcs(TALLOC_CTX *ctx, struct ldb_context *ldb,
     1043                        const char *searched_site, bool need_fqdn,
     1044                        struct dc_set ***pset_list, uint32_t flags)
     1045{
     1046        /*
     1047         * Flags will be used later to indicate things like least-expensive
     1048         * or same-site options
     1049         */
     1050        const char *attrs_none[] = { NULL };
     1051        const char *attrs3[] = { "name", NULL };
     1052        struct ldb_dn *configdn, *sitedn, *dn, *sitescontainerdn;
     1053        struct ldb_result *r;
     1054        struct dc_set **set_list = NULL;
     1055        uint32_t i;
     1056        int ret;
     1057        uint32_t current_pos = 0;
     1058        NTSTATUS status;
     1059        TALLOC_CTX *subctx = talloc_new(ctx);
     1060
     1061        *pset_list = set_list = NULL;
     1062
     1063        subctx = talloc_new(ctx);
     1064        NT_STATUS_HAVE_NO_MEMORY(subctx);
     1065
     1066        configdn = ldb_get_config_basedn(ldb);
     1067
     1068        /* Let's search for the Site container */
     1069        ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE, attrs_none,
     1070                         "(objectClass=sitesContainer)");
     1071        if (ret != LDB_SUCCESS) {
     1072                DEBUG(2,(__location__ ": Failed to find sitesContainer within %s - %s\n",
     1073                         ldb_dn_get_linearized(configdn), ldb_errstring(ldb)));
     1074                talloc_free(subctx);
     1075                return NT_STATUS_INTERNAL_ERROR;
     1076        }
     1077        if (r->count > 1) {
     1078                DEBUG(2,(__location__ ": Expected 1 sitesContainer - found %u within %s\n",
     1079                         r->count, ldb_dn_get_linearized(configdn)));
     1080                talloc_free(subctx);
     1081                return NT_STATUS_INTERNAL_ERROR;
     1082        }
     1083
     1084        sitescontainerdn = talloc_steal(subctx, r->msgs[0]->dn);
     1085        talloc_free(r);
     1086
     1087        /*
     1088         * TODO: Here we should have a more subtle handling
     1089         * for the case "same-site"
     1090         */
     1091        ret = ldb_search(ldb, subctx, &r, sitescontainerdn, LDB_SCOPE_SUBTREE,
     1092                         attrs_none, "(objectClass=server)");
     1093        if (ret != LDB_SUCCESS) {
     1094                DEBUG(2,(__location__ ": Failed to find servers within %s - %s\n",
     1095                         ldb_dn_get_linearized(sitescontainerdn), ldb_errstring(ldb)));
     1096                talloc_free(subctx);
     1097                return NT_STATUS_INTERNAL_ERROR;
     1098        }
     1099        talloc_free(r);
     1100
     1101        if (searched_site != NULL) {
     1102                ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE,
     1103                                 attrs_none, "(&(name=%s)(objectClass=site))", searched_site);
     1104                if (ret != LDB_SUCCESS) {
     1105                        talloc_free(subctx);
     1106                        return NT_STATUS_FOOBAR;
     1107                } else if (r->count != 1) {
     1108                        talloc_free(subctx);
     1109                        return NT_STATUS_FOOBAR;
     1110                }
     1111
     1112                /* All of this was to get the DN of the searched_site */
     1113                sitedn = r->msgs[0]->dn;
     1114
     1115                set_list = talloc_realloc(subctx, set_list, struct dc_set *, current_pos+1);
     1116                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list, subctx);
     1117
     1118                set_list[current_pos] = talloc(set_list, struct dc_set);
     1119                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list[current_pos], subctx);
     1120
     1121                set_list[current_pos]->names = NULL;
     1122                set_list[current_pos]->count = 0;
     1123                status = get_dcs_insite(subctx, ldb, sitedn,
     1124                                        set_list[current_pos], need_fqdn);
     1125                if (!NT_STATUS_IS_OK(status)) {
     1126                        DEBUG(2,(__location__ ": Failed to get DC from site %s - %s\n",
     1127                                 ldb_dn_get_linearized(sitedn), nt_errstr(status)));
     1128                        talloc_free(subctx);
     1129                        return status;
     1130                }
     1131                talloc_free(r);
     1132                current_pos++;
     1133        }
     1134
     1135        /* Let's find all the sites */
     1136        ret = ldb_search(ldb, subctx, &r, configdn, LDB_SCOPE_SUBTREE, attrs3, "(objectClass=site)");
     1137        if (ret != LDB_SUCCESS) {
     1138                DEBUG(2,(__location__ ": Failed to find any site containers in %s\n",
     1139                         ldb_dn_get_linearized(configdn)));
     1140                talloc_free(subctx);
     1141                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     1142        }
     1143
     1144        /*
     1145         * TODO:
     1146         * We should randomize the order in the main site,
     1147         * it's mostly needed for sysvol/netlogon referral.
     1148         * Depending of flag we either randomize order of the
     1149         * not "in the same site DCs"
     1150         * or we randomize by group of site that have the same cost
     1151         * In the long run we want to manipulate an array of site_set
     1152         * All the site in one set have the same cost (if least-expansive options is selected)
     1153         * and we will put all the dc related to 1 site set into 1 DCs set.
     1154         * Within a site set, site order has to be randomized
     1155         *
     1156         * But for the moment we just return the list of sites
     1157         */
     1158        if (r->count) {
     1159                /*
     1160                 * We will realloc + 2 because we will need one additional place
     1161                 * for element at current_pos + 1 for the NULL element
     1162                 */
     1163                set_list = talloc_realloc(subctx, set_list, struct dc_set *,
     1164                                          current_pos+2);
     1165                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list, subctx);
     1166
     1167                set_list[current_pos] = talloc(ctx, struct dc_set);
     1168                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(set_list[current_pos], subctx);
     1169
     1170                set_list[current_pos]->names = NULL;
     1171                set_list[current_pos]->count = 0;
     1172
     1173                set_list[current_pos+1] = NULL;
     1174        }
     1175
     1176        for (i=0; i<r->count; i++) {
     1177                const char *site_name = ldb_msg_find_attr_as_string(r->msgs[i], "name", NULL);
     1178                if (site_name == NULL) {
     1179                        DEBUG(2,(__location__ ": Failed to find name attribute in %s\n",
     1180                                 ldb_dn_get_linearized(r->msgs[i]->dn)));
     1181                        talloc_free(subctx);
     1182                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     1183                }
     1184
     1185                if (searched_site == NULL ||
     1186                    strcmp(searched_site, site_name) != 0) {
     1187                        DEBUG(2,(__location__ ": Site: %s %s\n",
     1188                                searched_site, site_name));
     1189
     1190                        /*
     1191                         * Do all the site but the one of the client
     1192                         * (because it has already been done ...)
     1193                         */
     1194                        dn = r->msgs[i]->dn;
     1195
     1196                        status = get_dcs_insite(subctx, ldb, dn,
     1197                                                set_list[current_pos],
     1198                                                need_fqdn);
     1199                        if (!NT_STATUS_IS_OK(status)) {
     1200                                talloc_free(subctx);
     1201                                return status;
     1202                        }
     1203                }
     1204        }
     1205        current_pos++;
     1206        set_list[current_pos] = NULL;
     1207
     1208        *pset_list = talloc_move(ctx, &set_list);
     1209        talloc_free(subctx);
     1210        return NT_STATUS_OK;
     1211}
     1212
     1213static NTSTATUS dodomain_referral(TALLOC_CTX *ctx,
     1214                                  const struct dfs_GetDFSReferral_in *dfsreq,
     1215                                  struct ldb_context *ldb,
     1216                                  struct smb_trans2 *trans,
     1217                                  struct loadparm_context *lp_ctx)
     1218{
     1219        /*
     1220         * TODO for the moment we just return the local domain
     1221         */
     1222        DATA_BLOB outblob;
     1223        enum ndr_err_code ndr_err;
     1224        NTSTATUS status;
     1225        const char *dns_domain = lpcfg_dnsdomain(lp_ctx);
     1226        const char *netbios_domain = lpcfg_workgroup(lp_ctx);
     1227        struct dfs_referral_resp resp;
     1228        struct dfs_referral_type *tab;
     1229        struct dfs_referral_type *referral;
     1230        const char *referral_str;
     1231        /* In the future this needs to be fetched from the ldb */
     1232        uint32_t found_domain = 2;
     1233        uint32_t current_pos = 0;
     1234        TALLOC_CTX *context;
     1235
     1236        if (lpcfg_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
     1237                DEBUG(10 ,("Received a domain referral request on a non DC\n"));
     1238                return NT_STATUS_INVALID_PARAMETER;
     1239        }
     1240
     1241        if (dfsreq->max_referral_level < 3) {
     1242                DEBUG(2,("invalid max_referral_level %u\n",
     1243                         dfsreq->max_referral_level));
     1244                return NT_STATUS_UNSUCCESSFUL;
     1245        }
     1246
     1247        context = talloc_new(ctx);
     1248        NT_STATUS_HAVE_NO_MEMORY(context);
     1249
     1250        resp.path_consumed = 0;
     1251        resp.header_flags = 0; /* Do like w2k3 */
     1252        resp.nb_referrals = found_domain; /* the fqdn one + the NT domain */
     1253
     1254        tab = talloc_array(context, struct dfs_referral_type, found_domain);
     1255        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tab, context);
     1256
     1257        referral = talloc(tab, struct dfs_referral_type);
     1258        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);
     1259        referral_str = talloc_asprintf(referral, "\\%s", netbios_domain);
     1260        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);
     1261        status = fill_domain_dfs_referraltype(referral,  3,
     1262                                              referral_str,
     1263                                              NULL, 0);
     1264        if (!NT_STATUS_IS_OK(status)) {
     1265                DEBUG(2,(__location__ ":Unable to fill domain referral structure\n"));
     1266                talloc_free(context);
     1267                return NT_STATUS_UNSUCCESSFUL;
     1268        }
     1269
     1270        tab[current_pos] = *referral;
     1271        current_pos++;
     1272
     1273        referral = talloc(tab, struct dfs_referral_type);
     1274        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);
     1275        referral_str = talloc_asprintf(referral, "\\%s", dns_domain);
     1276        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);
     1277        status = fill_domain_dfs_referraltype(referral,  3,
     1278                                              referral_str,
     1279                                              NULL, 0);
     1280        if (!NT_STATUS_IS_OK(status)) {
     1281                DEBUG(2,(__location__ ":Unable to fill domain referral structure\n"));
     1282                talloc_free(context);
     1283                return NT_STATUS_UNSUCCESSFUL;
     1284        }
     1285        tab[current_pos] = *referral;
     1286        current_pos++;
     1287
     1288        /*
     1289         * Put here the code from filling the array for trusted domain
     1290         */
     1291        resp.referral_entries = tab;
     1292
     1293        ndr_err = ndr_push_struct_blob(&outblob, context,
     1294                                &resp,
     1295                                (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     1296        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1297                DEBUG(2,(__location__ ":NDR marchalling of domain deferral response failed\n"));
     1298                talloc_free(context);
     1299                return NT_STATUS_INTERNAL_ERROR;
     1300        }
     1301
     1302        if (outblob.length > trans->in.max_data) {
     1303                bool ok = false;
     1304
     1305                DEBUG(3, ("Blob is too big for the output buffer "
     1306                          "size %u max %u\n",
     1307                          (unsigned int)outblob.length, trans->in.max_data));
     1308
     1309                if (trans->in.max_data != MAX_DFS_RESPONSE) {
     1310                        /* As specified in MS-DFSC.pdf 3.3.5.2 */
     1311                        talloc_free(context);
     1312                        return STATUS_BUFFER_OVERFLOW;
     1313                }
     1314
     1315                /*
     1316                 * The answer is too big, so let's remove some answers
     1317                 */
     1318                while (!ok && resp.nb_referrals > 2) {
     1319                        data_blob_free(&outblob);
     1320
     1321                        /*
     1322                         * Let's scrap the first referral (for now)
     1323                         */
     1324                        resp.nb_referrals -= 1;
     1325                        resp.referral_entries += 1;
     1326
     1327                        ndr_err = ndr_push_struct_blob(&outblob, context,
     1328                                &resp,
     1329                                (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     1330                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1331                                talloc_free(context);
     1332                                return NT_STATUS_INTERNAL_ERROR;
     1333                        }
     1334
     1335                        if (outblob.length <= MAX_DFS_RESPONSE) {
     1336                                DEBUG(10,("DFS: managed to reduce the size of referral initial"
     1337                                          "number of referral %d, actual count: %d",
     1338                                          found_domain, resp.nb_referrals));
     1339                                ok = true;
     1340                                break;
     1341                        }
     1342                }
     1343
     1344                if (!ok && resp.nb_referrals == 2) {
     1345                        DEBUG(0, (__location__ "; Not able to fit the domain and realm in DFS a "
     1346                                  " 56K buffer, something must be broken"));
     1347                        talloc_free(context);
     1348                        return NT_STATUS_INTERNAL_ERROR;
     1349                }
     1350        }
     1351
     1352        TRANS2_CHECK(trans2_setup_reply(trans, 0, outblob.length, 0));
     1353
     1354        trans->out.data = outblob;
     1355        talloc_steal(ctx, outblob.data);
     1356        talloc_free(context);
     1357        return NT_STATUS_OK;
     1358}
     1359
     1360/*
     1361 * Handle the logic for dfs referral request like \\domain
     1362 * or \\domain\sysvol or \\fqdn or \\fqdn\netlogon
     1363 */
     1364static NTSTATUS dodc_or_sysvol_referral(TALLOC_CTX *ctx,
     1365                                        const struct dfs_GetDFSReferral_in dfsreq,
     1366                                        const char* requestedname,
     1367                                        struct ldb_context *ldb,
     1368                                        struct smb_trans2 *trans,
     1369                                        struct smbsrv_request *req,
     1370                                        struct loadparm_context *lp_ctx)
     1371{
     1372        /*
     1373         * It's not a "standard" DFS referral but a referral to get the DC list
     1374         * or sysvol/netlogon
     1375         * Let's check that it's for one of our domain ...
     1376         */
     1377        DATA_BLOB outblob;
     1378        NTSTATUS status;
     1379        unsigned int num_domain = 1;
     1380        enum ndr_err_code ndr_err;
     1381        const char *requesteddomain;
     1382        const char *realm = lpcfg_realm(lp_ctx);
     1383        const char *domain = lpcfg_workgroup(lp_ctx);
     1384        const char *site_name = NULL; /* Name of the site where the client is */
     1385        char *share = NULL;
     1386        bool found = false;
     1387        bool need_fqdn = false;
     1388        bool dc_referral = true;
     1389        unsigned int i;
     1390        char *tmp;
     1391        struct dc_set **set;
     1392        char const **domain_list;
     1393        struct tsocket_address *remote_address;
     1394        char *client_addr = NULL;
     1395        TALLOC_CTX *context;
     1396
     1397        if (lpcfg_server_role(lp_ctx) != ROLE_DOMAIN_CONTROLLER) {
     1398                return NT_STATUS_INVALID_PARAMETER;
     1399        }
     1400
     1401        if (dfsreq.max_referral_level < 3) {
     1402                DEBUG(2,("invalid max_referral_level %u\n",
     1403                         dfsreq.max_referral_level));
     1404                return NT_STATUS_UNSUCCESSFUL;
     1405        }
     1406
     1407        context = talloc_new(ctx);
     1408        NT_STATUS_HAVE_NO_MEMORY(context);
     1409
     1410        if (requestedname[0] == '\\' && !strchr(requestedname+1,'\\')) {
     1411                requestedname++;
     1412        }
     1413        requesteddomain = requestedname;
     1414
     1415        if (strchr(requestedname,'\\')) {
     1416                char *subpart;
     1417                /* we have a second part */
     1418                requesteddomain = talloc_strdup(context, requestedname+1);
     1419                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(requesteddomain, context);
     1420                subpart = strchr(requesteddomain,'\\');
     1421                subpart[0] = '\0';
     1422        }
     1423        tmp = strchr(requestedname + 1,'\\'); /* To get second \ if any */
     1424
     1425        if (tmp != NULL) {
     1426                /* There was a share */
     1427                share = tmp+1;
     1428                dc_referral = false;
     1429        }
     1430
     1431        /*
     1432         * We will fetch the trusted domain list soon with something like this:
     1433         *
     1434         * "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)
     1435         * (trustPartner=%s))(objectclass=trustedDomain))"
     1436         *
     1437         * Allocate for num_domain + 1 so that the last element will be NULL)
     1438         */
     1439        domain_list = talloc_array(context, const char*, num_domain+1);
     1440        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_list, context);
     1441
     1442        domain_list[0] = realm;
     1443        domain_list[1] = domain;
     1444        for (i=0; i<=num_domain; i++) {
     1445                if (strncasecmp(domain_list[i], requesteddomain, strlen(domain_list[i])) == 0) {
     1446                        found = true;
     1447                        break;
     1448                }
     1449        }
     1450
     1451        if (!found) {
     1452                /* The requested domain is not one that we support */
     1453                DEBUG(3,("Requested referral for domain %s, but we don't handle it",
     1454                         requesteddomain));
     1455                return NT_STATUS_INVALID_PARAMETER;
     1456        }
     1457
     1458        if (strchr(requestedname,'.')) {
     1459                need_fqdn = 1;
     1460        }
     1461
     1462        remote_address = req->smb_conn->connection->remote_address;
     1463        if (tsocket_address_is_inet(remote_address, "ip")) {
     1464                client_addr = tsocket_address_inet_addr_string(remote_address, context);
     1465                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(client_addr, context);
     1466        }
     1467
     1468        status = get_dcs(context, ldb, site_name, need_fqdn, &set, 0);
     1469        if (!NT_STATUS_IS_OK(status)) {
     1470                DEBUG(3,("Unable to get list of DCs\n"));
     1471                talloc_free(context);
     1472                return status;
     1473        }
     1474
     1475        if (dc_referral) {
     1476                const char **dc_list = NULL;
     1477                uint32_t num_dcs = 0;
     1478                struct dfs_referral_type *referral;
     1479                const char *referral_str;
     1480                struct dfs_referral_resp resp;
     1481
     1482                for(i=0; set[i]; i++) {
     1483                        uint32_t j;
     1484
     1485                        dc_list = talloc_realloc(context, dc_list, const char*,
     1486                                                 num_dcs + set[i]->count + 1);
     1487                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dc_list, context);
     1488
     1489                        for(j=0; j<set[i]->count; j++) {
     1490                                dc_list[num_dcs + j] = talloc_move(context, &set[i]->names[j]);
     1491                        }
     1492                        num_dcs = num_dcs + set[i]->count;
     1493                        TALLOC_FREE(set[i]);
     1494                        dc_list[num_dcs] = NULL;
     1495                }
     1496
     1497                resp.path_consumed = 0;
     1498                resp.header_flags = 0; /* Do like w2k3 and like in 3.3.5.3 of MS-DFSC*/
     1499
     1500                /*
     1501                 * The NumberOfReferrals field MUST be set to 1,
     1502                 * independent of the number of DC names
     1503                 * returned. (as stated in 3.3.5.3 of MS-DFSC)
     1504                 */
     1505                resp.nb_referrals = 1;
     1506
     1507                /* Put here the code from filling the array for trusted domain */
     1508                referral = talloc(context, struct dfs_referral_type);
     1509                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);
     1510
     1511                referral_str = talloc_asprintf(referral, "\\%s",
     1512                                               requestedname);
     1513                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);
     1514
     1515                status = fill_domain_dfs_referraltype(referral,  3,
     1516                                                referral_str,
     1517                                                dc_list, num_dcs);
     1518                if (!NT_STATUS_IS_OK(status)) {
     1519                        DEBUG(2,(__location__ ":Unable to fill domain referral structure\n"));
     1520                        talloc_free(context);
     1521                        return NT_STATUS_UNSUCCESSFUL;
     1522                }
     1523                resp.referral_entries = referral;
     1524
     1525                ndr_err = ndr_push_struct_blob(&outblob, context,
     1526                                &resp,
     1527                                (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     1528                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1529                        DEBUG(2,(__location__ ":NDR marshalling of dfs referral response failed\n"));
     1530                        talloc_free(context);
     1531                        return NT_STATUS_INTERNAL_ERROR;
     1532                }
     1533        } else {
     1534                unsigned int nb_entries = 0;
     1535                unsigned int current = 0;
     1536                struct dfs_referral_type *tab;
     1537                struct dfs_referral_resp resp;
     1538
     1539                for(i=0; set[i]; i++) {
     1540                        nb_entries = nb_entries + set[i]->count;
     1541                }
     1542
     1543                resp.path_consumed = 2*strlen(requestedname); /* The length is expected in bytes */
     1544                resp.header_flags = DFS_HEADER_FLAG_STORAGE_SVR; /* Do like w2k3 and like in 3.3.5.3 of MS-DFSC*/
     1545
     1546                /*
     1547                 * The NumberOfReferrals field MUST be set to 1,
     1548                 * independent of the number of DC names
     1549                 * returned. (as stated in 3.3.5.3 of MS-DFSC)
     1550                 */
     1551                resp.nb_referrals = nb_entries;
     1552
     1553                tab = talloc_array(context, struct dfs_referral_type, nb_entries);
     1554                NT_STATUS_HAVE_NO_MEMORY(tab);
     1555
     1556                for(i=0; set[i]; i++) {
     1557                        uint32_t j;
     1558
     1559                        for(j=0; j< set[i]->count; j++) {
     1560                                struct dfs_referral_type *referral;
     1561                                const char *referral_str;
     1562
     1563                                referral = talloc(tab, struct dfs_referral_type);
     1564                                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral, context);
     1565
     1566                                referral_str = talloc_asprintf(referral, "\\%s\\%s",
     1567                                                               set[i]->names[j], share);
     1568                                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(referral_str, context);
     1569
     1570                                status = fill_normal_dfs_referraltype(referral,
     1571                                                dfsreq.max_referral_level,
     1572                                                requestedname, referral_str, j==0);
     1573                                if (!NT_STATUS_IS_OK(status)) {
     1574                                        DEBUG(2, (__location__ ": Unable to fill a normal dfs referral object"));
     1575                                        talloc_free(context);
     1576                                        return NT_STATUS_UNSUCCESSFUL;
     1577                                }
     1578                                tab[current] = *referral;
     1579                                current++;
     1580                        }
     1581                }
     1582                resp.referral_entries = tab;
     1583
     1584                ndr_err = ndr_push_struct_blob(&outblob, context,
     1585                                        &resp,
     1586                                        (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     1587                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1588                        DEBUG(2,(__location__ ":NDR marchalling of domain deferral response failed\n"));
     1589                        talloc_free(context);
     1590                        return NT_STATUS_INTERNAL_ERROR;
     1591                }
     1592        }
     1593
     1594        TRANS2_CHECK(trans2_setup_reply(trans, 0, outblob.length, 0));
     1595
     1596        /*
     1597         * TODO If the size is too big we should remove
     1598         * some DC from the answer or return STATUS_BUFFER_OVERFLOW
     1599         */
     1600        trans->out.data = outblob;
     1601        talloc_steal(ctx, outblob.data);
     1602        talloc_free(context);
     1603        return NT_STATUS_OK;
     1604}
     1605
     1606/*
     1607  trans2 getdfsreferral implementation
     1608*/
     1609static NTSTATUS trans2_getdfsreferral(struct smbsrv_request *req,
     1610                                      struct trans_op *op)
     1611{
     1612        enum ndr_err_code ndr_err;
     1613        struct smb_trans2 *trans = op->trans;
     1614        struct dfs_GetDFSReferral_in dfsreq;
     1615        TALLOC_CTX *context;
     1616        struct ldb_context *ldb;
     1617        struct loadparm_context *lp_ctx;
     1618        const char *realm, *nbname, *requestedname;
     1619        char *fqdn, *tmp;
     1620        NTSTATUS status;
     1621
     1622        lp_ctx = req->tcon->ntvfs->lp_ctx;
     1623        if (!lpcfg_host_msdfs(lp_ctx)) {
     1624                return NT_STATUS_NOT_IMPLEMENTED;
     1625        }
     1626
     1627        context = talloc_new(req);
     1628        NT_STATUS_HAVE_NO_MEMORY(context);
     1629
     1630        ldb = samdb_connect(context, req->tcon->ntvfs->event_ctx, lp_ctx, system_session(lp_ctx), 0);
     1631        if (ldb == NULL) {
     1632                DEBUG(2,(__location__ ": Failed to open samdb\n"));
     1633                talloc_free(context);
     1634                return NT_STATUS_INTERNAL_ERROR;
     1635        }
     1636
     1637        ndr_err = ndr_pull_struct_blob(&trans->in.params, op,
     1638                                       &dfsreq,
     1639                                       (ndr_pull_flags_fn_t)ndr_pull_dfs_GetDFSReferral_in);
     1640        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1641                status = ndr_map_error2ntstatus(ndr_err);
     1642                DEBUG(2,(__location__ ": Failed to parse GetDFSReferral_in - %s\n",
     1643                         nt_errstr(status)));
     1644                talloc_free(context);
     1645                return status;
     1646        }
     1647
     1648        DEBUG(10, ("Requested DFS name: %s length: %u\n",
     1649                   dfsreq.servername, (unsigned int)strlen(dfsreq.servername)));
     1650
     1651        /*
     1652         * If the servername is "" then we are in a case of domain dfs
     1653         * and the client just searches for the list of local domain
     1654         * it is attached and also trusted ones.
     1655         */
     1656        requestedname = dfsreq.servername;
     1657        if (requestedname == NULL || requestedname[0] == '\0') {
     1658                return dodomain_referral(op, &dfsreq, ldb, trans, lp_ctx);
     1659        }
     1660
     1661        realm = lpcfg_realm(lp_ctx);
     1662        nbname = lpcfg_netbios_name(lp_ctx);
     1663        fqdn = talloc_asprintf(context, "%s.%s", nbname, realm);
     1664
     1665        if ((strncasecmp(requestedname+1, nbname, strlen(nbname)) == 0) ||
     1666            (strncasecmp(requestedname+1, fqdn, strlen(fqdn)) == 0) ) {
     1667                /*
     1668                 * the referral request starts with \NETBIOSNAME or \fqdn
     1669                 * it's a standalone referral we do not do it
     1670                 * (TODO correct this)
     1671                 * If a DFS link that is a complete prefix of the DFS referral
     1672                 * request path is identified, the server MUST return a DFS link
     1673                 * referral response; otherwise, if it has a match for the DFS root,
     1674                 * it MUST return a root referral response.
     1675                 */
     1676                DEBUG(3, ("Received a standalone request for %s, we do not support standalone referral yet",requestedname));
     1677                talloc_free(context);
     1678                return NT_STATUS_NOT_FOUND;
     1679        }
     1680        talloc_free(fqdn);
     1681
     1682        tmp = strchr(requestedname + 1,'\\'); /* To get second \ if any */
     1683
     1684        /*
     1685         * If we have no slash at the first position or (foo.bar.domain.net)
     1686         * a slash at the first position but no other slash (\foo.bar.domain.net)
     1687         * or a slash at the first position and another slash
     1688         * and netlogon or sysvol after the second slash
     1689         * (\foo.bar.domain.net\sysvol) then we will handle it because
     1690         * it's either a dc referral or a sysvol/netlogon referral
     1691         */
     1692        if (requestedname[0] != '\\' ||
     1693            tmp == NULL ||
     1694            strcasecmp(tmp+1, "sysvol") == 0 ||
     1695            strcasecmp(tmp+1, "netlogon") == 0) {
     1696                status = dodc_or_sysvol_referral(op, dfsreq, requestedname,
     1697                                               ldb, trans, req, lp_ctx);
     1698                talloc_free(context);
     1699                return status;
     1700        }
     1701
     1702        if (requestedname[0] == '\\' &&
     1703            tmp &&
     1704            strchr(tmp+1, '\\') &&
     1705            (strncasecmp(tmp+1, "sysvol", 6) == 0 ||
     1706             strncasecmp(tmp+1, "netlogon", 8) == 0)) {
     1707                /*
     1708                 * We have more than two \ so it something like
     1709                 * \domain\sysvol\foobar
     1710                 */
     1711                talloc_free(context);
     1712                return NT_STATUS_NOT_FOUND;
     1713        }
     1714
     1715        talloc_free(context);
     1716        /* By default until all the case are handled*/
     1717        return NT_STATUS_NOT_FOUND;
     1718}
     1719
     1720/*
    8471721  trans2 findfirst implementation
    8481722*/
     
    8811755        if (search->t2ffirst.data_level == RAW_SEARCH_DATA_EA_LIST) {
    8821756                TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
    883                                                &search->t2ffirst.in.num_names, 
     1757                                               &search->t2ffirst.in.num_names,
    8841758                                               &search->t2ffirst.in.ea_names));
    8851759        }
     
    9671841        if (search->t2fnext.data_level == RAW_SEARCH_DATA_EA_LIST) {
    9681842                TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
    969                                                &search->t2fnext.in.num_names, 
     1843                                               &search->t2fnext.in.num_names,
    9701844                                               &search->t2fnext.in.ea_names));
    9711845        }
     
    10111885        /* the trans2 command is in setup[0] */
    10121886        switch (trans->in.setup[0]) {
     1887        case TRANSACT2_GET_DFS_REFERRAL:
     1888                return trans2_getdfsreferral(req, op);
    10131889        case TRANSACT2_FINDFIRST:
    10141890                return trans2_findfirst(req, op);
     
    11171993        do {
    11181994                uint16_t this_data, this_param, max_bytes;
    1119                 uint_t align1 = 1, align2 = (params_left ? 2 : 0);
     1995                unsigned int align1 = 1, align2 = (params_left ? 2 : 0);
    11201996                struct smbsrv_request *this_req;
    11211997
     
    11342010
    11352011                /* don't destroy unless this is the last chunk */
    1136                 if (params_left - this_param != 0 || 
     2012                if (params_left - this_param != 0 ||
    11372013                    data_left - this_data != 0) {
    11382014                        this_req = smbsrv_setup_secondary_request(req);
     
    11522028
    11532029                SSVAL(this_req->out.vwv, VWV(6), this_data);
    1154                 SSVAL(this_req->out.vwv, VWV(7), align1 + align2 + 
     2030                SSVAL(this_req->out.vwv, VWV(7), align1 + align2 +
    11552031                      PTR_DIFF(this_req->out.data + this_param, this_req->out.hdr));
    11562032                SSVAL(this_req->out.vwv, VWV(8), PTR_DIFF(data, trans->out.data.data));
     
    13422218        if ((param_count != 0 &&
    13432219             param_disp != trans->in.params.length) ||
    1344             (data_count != 0 && 
     2220            (data_count != 0 &&
    13452221             data_disp != trans->in.data.length)) {
    13462222                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
     
    13502226        /* add to the existing request */
    13512227        if (param_count != 0) {
    1352                 trans->in.params.data = talloc_realloc(trans, 
    1353                                                          trans->in.params.data, 
    1354                                                          uint8_t, 
     2228                trans->in.params.data = talloc_realloc(trans,
     2229                                                         trans->in.params.data,
     2230                                                         uint8_t,
    13552231                                                         param_disp + param_count);
    13562232                if (trans->in.params.data == NULL) {
     
    13622238
    13632239        if (data_count != 0) {
    1364                 trans->in.data.data = talloc_realloc(trans, 
    1365                                                        trans->in.data.data, 
    1366                                                        uint8_t, 
     2240                trans->in.data.data = talloc_realloc(trans,
     2241                                                       trans->in.data.data,
     2242                                                       uint8_t,
    13672243                                                       data_disp + data_count);
    13682244                if (trans->in.data.data == NULL) {
Note: See TracChangeset for help on using the changeset viewer.