Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source4/smb_server
Files:
1 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/smb_server/blob.c

    r740 r988  
    181181                                   int flags)
    182182{
    183         size_t ret;
     183        ssize_t ret;
    184184        uint32_t offset;
    185185        const int max_bytes_per_char = 3;
     
    293293                return NT_STATUS_OK;
    294294        }
     295
     296        case RAW_QFS_SECTOR_SIZE_INFORMATION:
     297                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, 28));
     298                SIVAL(blob->data,  0,
     299                      fsinfo->sector_size_info.out.logical_bytes_per_sector);
     300                SIVAL(blob->data,  4,
     301                     fsinfo->sector_size_info.out.phys_bytes_per_sector_atomic);
     302                SIVAL(blob->data,  8,
     303                      fsinfo->sector_size_info.out.phys_bytes_per_sector_perf);
     304                SIVAL(blob->data, 12,
     305                      fsinfo->sector_size_info.out.fs_effective_phys_bytes_per_sector_atomic);
     306                SIVAL(blob->data, 16,
     307                      fsinfo->sector_size_info.out.flags);
     308                SIVAL(blob->data, 20,
     309                      fsinfo->sector_size_info.out.byte_off_sector_align);
     310                SIVAL(blob->data, 24,
     311                      fsinfo->sector_size_info.out.byte_off_partition_align);
     312
     313                return NT_STATUS_OK;
     314
    295315        default:
    296316                return NT_STATUS_INVALID_LEVEL;
     
    626646                return NT_STATUS_OK;
    627647
     648        case RAW_SFILEINFO_FULL_EA_INFORMATION:
     649                return ea_pull_list_chained(blob,
     650                                            mem_ctx,
     651                                        &st->full_ea_information.in.eas.num_eas,
     652                                        &st->full_ea_information.in.eas.eas);
     653
    628654        case RAW_SFILEINFO_MODE_INFORMATION:
    629655                BLOB_CHECK_MIN_SIZE(blob, 4);
  • vendor/current/source4/smb_server/service_smb.c

    r740 r988  
    3434#include "dsdb/samdb/samdb.h"
    3535#include "param/param.h"
     36#include "file_server/file_server.h"
    3637
    3738/*
     
    4950                struct interface *ifaces;
    5051
    51                 load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces);
     52                load_interface_list(task, task->lp_ctx, &ifaces);
    5253
    53                 num_interfaces = iface_count(ifaces);
     54                num_interfaces = iface_list_count(ifaces);
    5455
    5556                /* We have been given an interfaces line, and been
     
    5859                */
    5960                for(i = 0; i < num_interfaces; i++) {
    60                         const char *address = iface_n_ip(ifaces, i);
     61                        const char *address = iface_list_n_ip(ifaces, i);
    6162                        status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, address);
    6263                        if (!NT_STATUS_IS_OK(status)) goto failed;
    6364                }
    6465        } else {
    65                 /* Just bind to lpcfg_socket_address() (usually 0.0.0.0) */
    66                 status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops,
    67                                            lpcfg_socket_address(task->lp_ctx));
    68                 if (!NT_STATUS_IS_OK(status)) goto failed;
     66                char **wcard;
     67                int i;
     68                wcard = iface_list_wildcard(task);
     69                if (wcard == NULL) {
     70                        DEBUG(0,("No wildcard addresses available\n"));
     71                        goto failed;
     72                }
     73                for (i=0; wcard[i]; i++) {
     74                        status = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, wcard[i]);
     75                        if (!NT_STATUS_IS_OK(status)) goto failed;
     76                }
     77                talloc_free(wcard);
    6978        }
    7079
     80        irpc_add_name(task->msg_ctx, "smb_server");
    7181        return;
    7282failed:
  • vendor/current/source4/smb_server/session.c

    r414 r988  
    8686        if (!p) return NULL;
    8787
    88         /* only return an unfinished session */
    89         sess = talloc_get_type(p, struct smbsrv_session);
    90         if (sess && !sess->session_info) {
    91                 return sess;
    92         }
    93         return NULL;
     88        sess = talloc_get_type_abort(p, struct smbsrv_session);
     89
     90        return sess;
    9491}
    9592
     
    141138        int i;
    142139
    143         /* Ensure no vuid gets registered in share level security. */
    144         if (smb_conn->config.security == SEC_SHARE) return NULL;
    145 
    146140        sess = talloc_zero(mem_ctx, struct smbsrv_session);
    147141        if (!sess) return NULL;
  • vendor/current/source4/smb_server/smb/negprot.c

    r740 r988  
    1919
    2020#include "includes.h"
     21#include "system/filesys.h"
    2122#include "auth/credentials/credentials.h"
    2223#include "auth/gensec/gensec.h"
     
    8990static void reply_coreplus(struct smbsrv_request *req, uint16_t choice)
    9091{
    91         uint16_t raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);
     92        uint16_t raw;
     93        if (lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx)) {
     94                raw = 0;
     95        } else {
     96                raw = (lpcfg_read_raw(req->smb_conn->lp_ctx)?1:0) |
     97                      (lpcfg_write_raw(req->smb_conn->lp_ctx)?2:0);
     98        }
    9299
    93100        smbsrv_setup_reply(req, 13, 0);
     
    120127static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
    121128{
    122         int raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);
    123129        int secword=0;
    124130        time_t t = req->request_time.tv_sec;
    125 
    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)
    129                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
     131        uint16_t raw;
     132
     133        if (lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx)) {
     134                raw = 0;
     135        } else {
     136                raw = (lpcfg_read_raw(req->smb_conn->lp_ctx)?1:0) |
     137                      (lpcfg_write_raw(req->smb_conn->lp_ctx)?2:0);
     138        }
     139
     140        req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt_passwords(req->smb_conn->lp_ctx);
    130141
    131142        if (req->smb_conn->negotiate.encrypted_passwords)
     
    143154        SSVAL(req->out.vwv, VWV(1), secword);
    144155        SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv);
    145         SSVAL(req->out.vwv, VWV(3), lpcfg_maxmux(req->smb_conn->lp_ctx));
     156        SSVAL(req->out.vwv, VWV(3), lpcfg_max_mux(req->smb_conn->lp_ctx));
    146157        SSVAL(req->out.vwv, VWV(4), 1);
    147158        SSVAL(req->out.vwv, VWV(5), raw);
    148         SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id);
     159        SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.pid);
    149160        srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t);
    150161        SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60);
     
    178189static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
    179190{
    180         int raw = (lpcfg_readraw(req->smb_conn->lp_ctx)?1:0) | (lpcfg_writeraw(req->smb_conn->lp_ctx)?2:0);
    181191        int secword=0;
    182192        time_t t = req->request_time.tv_sec;
    183 
    184         req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx);
     193        uint16_t raw;
     194        if (lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx)) {
     195                raw = 0;
     196        } else {
     197                raw = (lpcfg_read_raw(req->smb_conn->lp_ctx)?1:0) |
     198                      (lpcfg_write_raw(req->smb_conn->lp_ctx)?2:0);
     199        }
     200
     201        req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt_passwords(req->smb_conn->lp_ctx);
    185202 
    186         if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE)
    187                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
    188 
    189203        if (req->smb_conn->negotiate.encrypted_passwords)
    190204                secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
     
    197211        SSVAL(req->out.vwv, VWV(1), secword);
    198212        SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv);
    199         SSVAL(req->out.vwv, VWV(3), lpcfg_maxmux(req->smb_conn->lp_ctx));
     213        SSVAL(req->out.vwv, VWV(3), lpcfg_max_mux(req->smb_conn->lp_ctx));
    200214        SSVAL(req->out.vwv, VWV(4), 1);
    201215        SSVAL(req->out.vwv, VWV(5), raw);
    202         SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id);
     216        SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.pid);
    203217        srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t);
    204218        SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60);
     
    239253}
    240254
     255/*
     256  try to determine if the filesystem supports large files
     257*/
     258static bool large_file_support(const char *path)
     259{
     260        int fd;
     261        ssize_t ret;
     262        char c;
     263
     264        fd = open(path, O_RDWR|O_CREAT, 0600);
     265        unlink(path);
     266        if (fd == -1) {
     267                /* have to assume large files are OK */
     268                return true;
     269        }
     270        ret = pread(fd, &c, 1, ((uint64_t)1)<<32);
     271        close(fd);
     272        return ret == 0;
     273}
     274
    241275/****************************************************************************
    242276 Reply for the nt protocol.
     
    258292                CAP_LEVEL_II_OPLOCKS | CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
    259293
    260         req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypted_passwords(req->smb_conn->lp_ctx);
     294        req->smb_conn->negotiate.encrypted_passwords = lpcfg_encrypt_passwords(req->smb_conn->lp_ctx);
    261295
    262296        /* do spnego in user level security if the client
     
    264298       
    265299        if (req->smb_conn->negotiate.encrypted_passwords &&
    266             (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) &&
    267300            lpcfg_use_spnego(req->smb_conn->lp_ctx) &&
    268301            (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
     
    271304        }
    272305       
    273         if (lpcfg_unix_extensions(req->smb_conn->lp_ctx)) {
    274                 capabilities |= CAP_UNIX;
    275         }
    276        
    277306        if (lpcfg_large_readwrite(req->smb_conn->lp_ctx)) {
    278307                capabilities |= CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS;
    279308        }
    280309
    281         large_test_path = lock_path(req, req->smb_conn->lp_ctx, "large_test.dat");
     310        large_test_path = lpcfg_lock_path(req, req->smb_conn->lp_ctx, "large_test.dat");
    282311        if (large_file_support(large_test_path)) {
    283312                capabilities |= CAP_LARGE_FILES;
    284313        }
    285314
    286         if (lpcfg_readraw(req->smb_conn->lp_ctx) &&
    287             lpcfg_writeraw(req->smb_conn->lp_ctx)) {
     315        if (!lpcfg_async_smb_echo_handler(req->smb_conn->lp_ctx) &&
     316            lpcfg_read_raw(req->smb_conn->lp_ctx) &&
     317            lpcfg_write_raw(req->smb_conn->lp_ctx)) {
    288318                capabilities |= CAP_RAW_MODE;
    289319        }
     
    302332        }
    303333       
    304         if (lpcfg_security(req->smb_conn->lp_ctx) != SEC_SHARE) {
    305                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
    306         }
     334        secword |= NEGOTIATE_SECURITY_USER_LEVEL;
    307335
    308336        if (req->smb_conn->negotiate.encrypted_passwords) {
     
    329357           the specification - all the command words after the secword
    330358           are offset by 1 byte */
    331         SSVAL(req->out.vwv+1, VWV(1), lpcfg_maxmux(req->smb_conn->lp_ctx));
     359        SSVAL(req->out.vwv+1, VWV(1), lpcfg_max_mux(req->smb_conn->lp_ctx));
    332360        SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */
    333361        SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv);
    334362        SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */
    335         SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.id); /* session key */
     363        SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id.pid); /* session key */
     364
    336365        SIVAL(req->out.vwv+1, VWV(9), capabilities);
    337366        push_nttime(req->out.vwv+1, VWV(11), nttime);
     
    359388                if (!NT_STATUS_IS_OK(nt_status)) {
    360389                        DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status)));
    361                         talloc_free(server_credentials);
    362                         server_credentials = NULL;
     390                        /*
     391                         * We keep the server_credentials as anonymous
     392                         * this is required for the spoolss.notify test
     393                         */
    363394                }
    364395
     
    383414                req->smb_conn->negotiate.server_credentials = talloc_reparent(req, req->smb_conn, server_credentials);
    384415
    385                 gensec_set_target_service(gensec_security, "cifs");
    386 
    387                 gensec_set_credentials(gensec_security, server_credentials);
    388 
    389416                oid = GENSEC_OID_SPNEGO;
    390417                nt_status = gensec_start_mech_by_oid(gensec_security, oid);
     
    392419                if (NT_STATUS_IS_OK(nt_status)) {
    393420                        /* Get and push the proposed OID list into the packets */
    394                         nt_status = gensec_update(gensec_security, req, null_data_blob, &blob);
     421                        nt_status = gensec_update_ev(gensec_security, req, req->smb_conn->connection->event.ctx, null_data_blob, &blob);
    395422
    396423                        if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     
    465492        int protocol_level;
    466493} supported_protocols[] = {
    467         {"SMB 2.002",                   "SMB2",         reply_smb2,     PROTOCOL_SMB2},
     494        {"SMB 2.002",                   "SMB2",         reply_smb2,     PROTOCOL_SMB2_02},
    468495        {"NT LANMAN 1.0",               "NT1",          reply_nt1,      PROTOCOL_NT1},
    469496        {"NT LM 0.12",                  "NT1",          reply_nt1,      PROTOCOL_NT1},
     
    489516        uint8_t *p;
    490517        uint32_t protos_count = 0;
    491         char **protos = NULL;
     518        const char **protos = NULL;
    492519
    493520        if (req->smb_conn->negotiate.done_negprot) {
     
    501528                size_t len;
    502529
    503                 protos = talloc_realloc(req, protos, char *, protos_count + 1);
     530                protos = talloc_realloc(req, protos, const char *, protos_count + 1);
    504531                if (!protos) {
    505532                        smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY));
     
    507534                }
    508535                protos[protos_count] = NULL;
    509                 len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
     536                len = req_pull_ascii4(&req->in.bufinfo, &protos[protos_count], p, STR_ASCII|STR_TERMINATE);
    510537                p += len;
    511538                if (len == 0 || !protos[protos_count]) break;
     
    519546                int i;
    520547
    521                 if (supported_protocols[protocol].protocol_level > lpcfg_srv_maxprotocol(req->smb_conn->lp_ctx))
     548                if (supported_protocols[protocol].protocol_level > lpcfg_server_max_protocol(req->smb_conn->lp_ctx))
    522549                        continue;
    523                 if (supported_protocols[protocol].protocol_level < lpcfg_srv_minprotocol(req->smb_conn->lp_ctx))
     550                if (supported_protocols[protocol].protocol_level < lpcfg_server_min_protocol(req->smb_conn->lp_ctx))
    524551                        continue;
    525552
  • vendor/current/source4/smb_server/smb/receive.c

    r740 r988  
    2626#include "system/filesys.h"
    2727#include "param/param.h"
    28 
     28#include "cluster/cluster.h"
    2929
    3030/*
     
    104104/* 0x0e */ { "SMBctemp",        smbsrv_reply_ctemp,             NEED_SESS|NEED_TCON },
    105105/* 0x0f */ { "SMBmknew",        smbsrv_reply_mknew,             NEED_SESS|NEED_TCON },
    106 /* 0x10 */ { "SMBchkpth",       smbsrv_reply_chkpth,            NEED_SESS|NEED_TCON },
     106/* 0x10 */ { "SMBcheckpath",    smbsrv_reply_chkpth,            NEED_SESS|NEED_TCON },
    107107/* 0x11 */ { "SMBexit",         smbsrv_reply_exit,              NEED_SESS },
    108108/* 0x12 */ { "SMBlseek",        smbsrv_reply_lseek,             NEED_SESS|NEED_TCON },
     
    472472        struct smbsrv_connection *smb_conn = req->smb_conn;
    473473        NTSTATUS status;
     474        struct server_id_buf idbuf;
    474475
    475476        type &= 0xff;
     
    492493                   chaining) */
    493494
    494                 /* In share mode security we must ignore the vuid. */
    495                 if (smb_conn->config.security == SEC_SHARE) {
    496                         if (req->tcon) {
    497                                 req->session = req->tcon->sec_share.session;
    498                         }
    499                 } else {
    500                         req->session = smbsrv_session_find(req->smb_conn, SVAL(req->in.hdr,HDR_UID), req->request_time);
    501                 }
    502         }
    503 
    504         DEBUG(5,("switch message %s (task_id %u)\n",
    505                  smb_fn_name(type), (unsigned)req->smb_conn->connection->server_id.id));
     495                req->session = smbsrv_session_find(req->smb_conn, SVAL(req->in.hdr,HDR_UID), req->request_time);
     496        }
     497
     498        DEBUG(5, ("switch message %s (task_id %s)\n",
     499                  smb_fn_name(type),
     500                  server_id_str_buf(req->smb_conn->connection->server_id,
     501                                    &idbuf)));
    506502
    507503        /* this must be called before we do any reply */
     
    638634
    639635        /* cleanup somestuff for the next request */
    640         talloc_free(req->ntvfs);
     636        DLIST_REMOVE(req->smb_conn->requests, req);
     637        talloc_unlink(req, req->ntvfs);
    641638        req->ntvfs = NULL;
    642639        talloc_free(req->io_ptr);
     
    668665        smb_conn->negotiate.zone_offset = get_time_zone(time(NULL));
    669666
    670         smb_conn->config.security = lpcfg_security(lp_ctx);
    671667        smb_conn->config.nt_status_support = lpcfg_nt_status_support(lp_ctx);
    672668
  • vendor/current/source4/smb_server/smb/reply.c

    r740 r988  
    2828#include "ntvfs/ntvfs.h"
    2929#include "librpc/gen_ndr/ndr_nbt.h"
     30#include "libcli/nbt/libnbt.h"
    3031
    3132
     
    848849{
    849850        union smb_read *io;
     851        uint16_t high_part = 0;
    850852
    851853        /* parse request */
     
    869871        }
    870872
    871         if (req->smb_conn->negotiate.client_caps & CAP_LARGE_READX) {
    872                 uint32_t high_part = IVAL(req->in.vwv, VWV(7));
    873                 if (high_part == 1) {
    874                         io->readx.in.maxcnt |= high_part << 16;
    875                 }
    876         }
    877        
     873        if (req->smb_conn->negotiate.protocol == PROTOCOL_NT1) {
     874                high_part = SVAL(req->in.vwv, VWV(7));
     875        }
     876        if (high_part != UINT16_MAX) {
     877                io->readx.in.maxcnt |= high_part << 16;
     878        }
     879
     880        /*
     881         * Windows truncates the length to 0x10000
     882         */
     883        io->readx.in.maxcnt = MIN(io->readx.in.maxcnt, 0x10000);
     884
    878885        /* the 64 bit variant */
    879886        if (req->in.wct == 12) {
     
    23342341       
    23352342        switch (msg_type) {
    2336         case 0x81: /* session request */
     2343        case NBSSrequest: /* session request */
    23372344                if (req->smb_conn->negotiate.done_nbt_session) {
    23382345                        DEBUG(0,("Warning: ignoring secondary session request\n"));
     
    23542361        case 0x89: /* session keepalive request
    23552362                      (some old clients produce this?) */
    2356                 SCVAL(buf, 0, SMBkeepalive);
     2363                SCVAL(buf, 0, NBSSkeepalive);
    23572364                SCVAL(buf, 3, 0);
    23582365                req->out.buffer = buf;
     
    23612368                return;
    23622369               
    2363         case SMBkeepalive:
     2370        case NBSSkeepalive:
    23642371                /* session keepalive - swallow it */
    23652372                talloc_free(req);
  • vendor/current/source4/smb_server/smb/request.c

    r740 r988  
    312312
    313313        if (req->out.size > NBT_HDR_SIZE) {
    314                 _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
     314                _smb_setlen_nbt(req->out.buffer, req->out.size - NBT_HDR_SIZE);
    315315        }
    316316
     
    484484        bool ret;
    485485        char *dest2;
     486        size_t converted_size = 0;
    486487
    487488        if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
     
    513514        }
    514515
    515         ret = convert_string_talloc(bufinfo->mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, NULL, false);
     516        ret = convert_string_talloc(bufinfo->mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, &converted_size);
    516517
    517518        if (!ret) {
     
    542543        bool ret;
    543544        char *dest2;
     545        size_t converted_size = 0;
    544546
    545547        if (flags & STR_NO_RANGE_CHECK) {
     
    562564        }
    563565
    564         ret = convert_string_talloc(bufinfo->mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, NULL, false);
     566        ret = convert_string_talloc(bufinfo->mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, &converted_size);
    565567
    566568        if (!ret) {
  • vendor/current/source4/smb_server/smb/service.c

    r740 r988  
    112112        const char *type_str;
    113113        struct share_config *scfg;
    114         const char *sharetype;
     114        char *sharetype;
    115115
    116116        /* the service might be of the form \\SERVER\SHARE. Should we put
     
    125125        status = share_get_config(req, req->smb_conn->share_context, service, &scfg);
    126126        if (!NT_STATUS_IS_OK(status)) {
    127                 DEBUG(0,("make_connection: couldn't find service %s\n", service));
     127                DEBUG(0,("make_connection: couldn't find service %s: %s\n", service, nt_errstr(status)));
    128128                return NT_STATUS_BAD_NETWORK_NAME;
    129129        }
     
    139139
    140140        /* work out what sort of connection this is */
    141         sharetype = share_string_option(scfg, "type", "DISK");
     141        sharetype = share_string_option(req, scfg, "type", "DISK");
    142142        if (sharetype && strcmp(sharetype, "IPC") == 0) {
    143143                type = NTVFS_IPC;
     
    150150                type_str = "A:";
    151151        }
     152        TALLOC_FREE(sharetype);
    152153
    153154        if (strcmp(dev, "?????") != 0 && strcasecmp(type_str, dev) != 0) {
  • vendor/current/source4/smb_server/smb/sesssetup.c

    r740 r988  
    3535
    3636struct sesssetup_context {
    37         struct auth_context *auth_context;
     37        struct auth4_context *auth_context;
    3838        struct smbsrv_request *req;
    3939};
     
    8484        }
    8585        /* 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);
     86        status = req->smb_conn->negotiate.auth_context->generate_session_info(req->smb_conn->negotiate.auth_context,
     87                                                                              req,
     88                                                                              user_info_dc, sess->old.in.user,
     89                                                                              flags, &session_info);
    8990        if (!NT_STATUS_IS_OK(status)) goto failed;
    9091
     
    215216        }
    216217        /* This references user_info_dc into session_info */
    217         status = state->auth_context->generate_session_info(req,
    218                                                             state->auth_context,
     218        status = state->auth_context->generate_session_info(state->auth_context,
     219                                                            req,
    219220                                                            user_info_dc,
     221                                                            sess->nt1.in.user,
    220222                                                            flags,
    221223                                                            &session_info);
     
    262264        struct tevent_req *subreq;
    263265        struct sesssetup_context *state;
     266        bool allow_raw = lpcfg_raw_ntlmv2_auth(req->smb_conn->lp_ctx);
    264267
    265268        sess->nt1.out.vuid = 0;
     
    337340        user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);
    338341
     342        if (!allow_raw && user_info->password.response.nt.length >= 48) {
     343                /*
     344                 * NTLMv2_RESPONSE has at least 48 bytes
     345                 * and should only be supported via NTLMSSP.
     346                 */
     347                status = NT_STATUS_INVALID_PARAMETER;
     348                goto failed;
     349        }
     350
    339351        subreq = auth_check_password_send(state,
    340352                                          req->smb_conn->connection->event.ctx,
     
    380392        }
    381393
    382         status = gensec_session_info(smb_sess->gensec_ctx, &session_info);
    383         if (!NT_STATUS_IS_OK(status)) goto failed;
    384 
    385         skey_status = gensec_session_key(smb_sess->gensec_ctx, &session_key);
     394        status = gensec_session_info(smb_sess->gensec_ctx, smb_sess, &session_info);
     395        if (!NT_STATUS_IS_OK(status)) goto failed;
     396
     397        /* The session_key is only needed until the end of the smbsrv_setup_signing() call */
     398        skey_status = gensec_session_key(smb_sess->gensec_ctx, req, &session_key);
    386399        if (NT_STATUS_IS_OK(skey_status)) {
    387400                smbsrv_setup_signing(req->smb_conn, &session_key, NULL);
     
    413426        NTSTATUS status;
    414427        struct smbsrv_session *smb_sess = NULL;
     428        bool is_smb_sess_new = false;
    415429        struct sesssetup_spnego_state *s = NULL;
    416430        uint16_t vuid;
     
    433447
    434448        /* lookup an existing session */
    435         smb_sess = smbsrv_session_find_sesssetup(req->smb_conn, vuid);
    436         if (!smb_sess) {
     449        if (vuid == 0) {
    437450                struct gensec_security *gensec_ctx;
    438451
     
    464477                        goto failed;
    465478                }
     479                is_smb_sess_new = true;
     480        } else {
     481                smb_sess = smbsrv_session_find_sesssetup(req->smb_conn, vuid);
    466482        }
    467483
    468484        if (!smb_sess) {
    469                 status = NT_STATUS_ACCESS_DENIED;
     485                status = NT_STATUS_DOS(ERRSRV, ERRbaduid);
     486                goto failed;
     487        }
     488
     489        if (smb_sess->session_info) {
     490                status = NT_STATUS_INVALID_PARAMETER;
    470491                goto failed;
    471492        }
     
    502523        status = NT_STATUS_NO_MEMORY;
    503524failed:
    504         talloc_free(smb_sess);
     525        if (is_smb_sess_new) {
     526                talloc_free(smb_sess);
     527        }
    505528        status = nt_status_squash(status);
    506529        smbsrv_sesssetup_backend_send(req, sess, status);
  • vendor/current/source4/smb_server/smb/signing.c

    r740 r988  
    8282                return false;
    8383        }
    84        
    85         switch (lpcfg_server_signing(smb_conn->lp_ctx)) {
    86         case SMB_SIGNING_OFF:
    87                 smb_conn->signing.allow_smb_signing = false;
    88                 break;
    89         case SMB_SIGNING_SUPPORTED:
    90                 smb_conn->signing.allow_smb_signing = true;
    91                 break;
    92         case SMB_SIGNING_REQUIRED:
    93                 smb_conn->signing.allow_smb_signing = true;
    94                 smb_conn->signing.mandatory_signing = true;
    95                 break;
    96         case SMB_SIGNING_AUTO:
    97                 /* If we are a domain controller, SMB signing is
    98                  * really important, as it can prevent a number of
    99                  * attacks on communications between us and the
    100                  * clients */
    10184
    102                 if (lpcfg_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
    103                         smb_conn->signing.allow_smb_signing = true;
    104                         smb_conn->signing.mandatory_signing = true;
    105                 } else {
    106                         /* However, it really sucks (no sendfile, CPU
    107                          * overhead) performance-wise when used on a
    108                          * file server, so disable it by default (auto
    109                          * is the default) on non-DCs */
    110                         smb_conn->signing.allow_smb_signing = false;
    111                 }
    112                 break;
    113         }
     85        smb_conn->signing.allow_smb_signing
     86                = lpcfg_server_signing_allowed(smb_conn->lp_ctx,
     87                                               &smb_conn->signing.mandatory_signing);
    11488        return true;
    11589}
  • vendor/current/source4/smb_server/smb/trans2.c

    r740 r988  
    33   transaction2 handling
    44   Copyright (C) Andrew Tridgell 2003
    5    Copyright Matthieu Patou 2010 mat@matws.net
     5   Copyright Matthieu Patou <mat@matws.net> 2010-2011
    66
    77   This program is free software; you can redistribute it and/or modify
     
    3434#include "param/param.h"
    3535#include "lib/tsocket/tsocket.h"
     36#include "dfs_server/dfs_server_ad.h"
    3637
    3738#define MAX_DFS_RESPONSE 56*1024 /* 56 Kb */
     
    6465        void *op_info;
    6566};
    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 */
    69 struct dc_set {
    70         const char **names;
    71         uint32_t count;
    72 };
     67
    7368#define CHECK_MIN_BLOB_SIZE(blob, size) do { \
    7469        if ((blob)->length < (size)) { \
     
    859854}
    860855
    861 
    862 /*
    863   fill a referral type structure
    864  */
    865 static 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  */
    908 static 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  */
    949 static 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  */
    1042 static 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 
    1213 static 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  */
    1364 static 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 
    1606856/*
    1607857  trans2 getdfsreferral implementation
     
    1612862        enum ndr_err_code ndr_err;
    1613863        struct smb_trans2 *trans = op->trans;
    1614         struct dfs_GetDFSReferral_in dfsreq;
    1615         TALLOC_CTX *context;
    1616864        struct ldb_context *ldb;
    1617865        struct loadparm_context *lp_ctx;
    1618         const char *realm, *nbname, *requestedname;
    1619         char *fqdn, *tmp;
    1620866        NTSTATUS status;
     867        struct dfs_GetDFSReferral *r;
     868        DATA_BLOB outblob = data_blob_null;
     869        uint16_t nb_referrals = 0;
    1621870
    1622871        lp_ctx = req->tcon->ntvfs->lp_ctx;
     
    1625874        }
    1626875
    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);
     876        r = talloc_zero(req, struct dfs_GetDFSReferral);
     877        NT_STATUS_HAVE_NO_MEMORY(r);
     878
     879        ldb = samdb_connect(r, req->tcon->ntvfs->event_ctx, lp_ctx, system_session(lp_ctx), 0);
    1631880        if (ldb == NULL) {
    1632881                DEBUG(2,(__location__ ": Failed to open samdb\n"));
    1633                 talloc_free(context);
     882                talloc_free(r);
    1634883                return NT_STATUS_INTERNAL_ERROR;
    1635884        }
    1636885
    1637         ndr_err = ndr_pull_struct_blob(&trans->in.params, op,
    1638                                        &dfsreq,
     886        ndr_err = ndr_pull_struct_blob(&trans->in.params, r,
     887                                       &r->in.req,
    1639888                                       (ndr_pull_flags_fn_t)ndr_pull_dfs_GetDFSReferral_in);
    1640889        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    1642891                DEBUG(2,(__location__ ": Failed to parse GetDFSReferral_in - %s\n",
    1643892                         nt_errstr(status)));
    1644                 talloc_free(context);
     893                talloc_free(r);
    1645894                return status;
    1646895        }
    1647896
    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) ) {
     897        DEBUG(8, ("Requested DFS name: %s length: %u\n",
     898                   r->in.req.servername,
     899                   (unsigned int)strlen_m(r->in.req.servername)*2));
     900
     901        status = dfs_server_ad_get_referrals(lp_ctx, ldb,
     902                                req->smb_conn->connection->remote_address, r);
     903        if (!NT_STATUS_IS_OK(status)) {
     904                talloc_free(r);
     905                return status;
     906        }
     907
     908        ndr_err = ndr_push_struct_blob(&outblob, trans,
     909                                r->out.resp,
     910                                (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     911        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     912                DEBUG(2,(__location__ ":NDR marchalling of domain deferral response failed\n"));
     913                talloc_free(r);
     914                return NT_STATUS_INTERNAL_ERROR;
     915        }
     916
     917        nb_referrals = r->out.resp->nb_referrals;
     918
     919        if (outblob.length > trans->in.max_data) {
     920                bool ok = false;
     921
     922                DEBUG(3, ("Blob is too big for the output buffer "
     923                          "size %u max %u\n",
     924                          (unsigned int)outblob.length, trans->in.max_data));
     925
     926                if (trans->in.max_data != MAX_DFS_RESPONSE) {
     927                        /* As specified in MS-DFSC.pdf 3.3.5.2 */
     928                        talloc_free(r);
     929                        return STATUS_BUFFER_OVERFLOW;
     930                }
     931
    1667932                /*
    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.
     933                 * The answer is too big, so let's remove some answers
    1675934                 */
    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;
     935                while (!ok && r->out.resp->nb_referrals > 2) {
     936                        data_blob_free(&outblob);
     937
     938                        /*
     939                         * Let's scrap the last referral (for now)
     940                         */
     941                        r->out.resp->nb_referrals -= 1;
     942
     943                        ndr_err = ndr_push_struct_blob(&outblob, trans,
     944                                r->out.resp,
     945                                (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     946                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     947                                talloc_free(r);
     948                                return NT_STATUS_INTERNAL_ERROR;
     949                        }
     950
     951                        if (outblob.length <= MAX_DFS_RESPONSE) {
     952                                DEBUG(10,("DFS: managed to reduce the size of referral initial"
     953                                          "number of referral %d, actual count: %d",
     954                                          nb_referrals, r->out.resp->nb_referrals));
     955                                ok = true;
     956                                break;
     957                        }
     958                }
     959
     960                if (!ok && r->out.resp->nb_referrals <= 2) {
     961                        DEBUG(8, (__location__ "; Not able to fit the domain and realm in DFS a "
     962                                  " 56K buffer, something must be broken"));
     963                        talloc_free(r);
     964                        return NT_STATUS_INTERNAL_ERROR;
     965                }
     966        }
     967
     968        TRANS2_CHECK(trans2_setup_reply(trans, 0, outblob.length, 0));
     969
     970        trans->out.data = outblob;
     971        talloc_free(r);
     972        return NT_STATUS_OK;
    1718973}
    1719974
  • vendor/current/source4/smb_server/smb/wscript_build

    r740 r988  
    44        source='receive.c negprot.c nttrans.c reply.c request.c search.c service.c sesssetup.c srvtime.c trans2.c signing.c',
    55        autoproto='smb_proto.h',
    6         public_deps='ntvfs LIBPACKET credentials samba_server_gensec'
     6        deps='dfs_server_ad',
     7        public_deps='ntvfs LIBPACKET samba-credentials samba_server_gensec',
     8        enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
    79        )
    810
  • vendor/current/source4/smb_server/smb2/fileinfo.c

    r740 r988  
    251251        SMB2SRV_CHECK_ASYNC_STATUS(op, struct smb2srv_setinfo_op);
    252252
    253         SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x02, false, 0));
     253        SMB2SRV_CHECK(smb2srv_setup_reply(op->req, 0x02, false, 0));
    254254
    255255        smb2srv_send_reply(req);
  • vendor/current/source4/smb_server/smb2/keepalive.c

    r414 r988  
    5252void smb2srv_keepalive_recv(struct smb2srv_request *req)
    5353{
    54         uint16_t _pad;
    55 
    5654        if (req->in.body_size != 0x04) {
    5755                smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
     
    6462        }
    6563
    66         _pad    = SVAL(req->in.body, 0x02);
    67 
    6864        req->status = smb2srv_keepalive_backend(req);
    6965
  • vendor/current/source4/smb_server/smb2/negprot.c

    r740 r988  
    5050        if (!NT_STATUS_IS_OK(nt_status)) {
    5151                DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status)));
    52                 talloc_free(server_credentials);
    53                 server_credentials = NULL;
     52                /*
     53                 * We keep the server_credentials as anonymous
     54                 * this is required for the spoolss.notify test
     55                 */
    5456        }
    5557
     
    8082        }
    8183
    82         nt_status = gensec_update(gensec_security, req, null_data_blob, &blob);
     84        nt_status = gensec_update_ev(gensec_security, req, req->smb_conn->connection->event.ctx, null_data_blob, &blob);
    8385        if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    8486                DEBUG(0, ("Failed to get SPNEGO to give us the first token: %s\n", nt_errstr(nt_status)));
     
    98100        uint16_t i;
    99101        uint16_t dialect = 0;
     102        enum smb_signing_setting signing_setting;
     103        struct loadparm_context *lp_ctx = req->smb_conn->lp_ctx;
    100104
    101105        /* we only do one dialect for now */
     
    114118        }
    115119
    116         req->smb_conn->negotiate.protocol = PROTOCOL_SMB2;
     120        req->smb_conn->negotiate.protocol = PROTOCOL_SMB2_02;
    117121
    118122        current_time = timeval_current(); /* TODO: handle timezone?! */
     
    120124
    121125        ZERO_STRUCT(io->out);
    122         switch (lpcfg_server_signing(req->smb_conn->lp_ctx)) {
     126
     127        signing_setting = lpcfg_server_signing(lp_ctx);
     128        if (signing_setting == SMB_SIGNING_DEFAULT) {
     129                /*
     130                 * If we are a domain controller, SMB signing is
     131                 * really important, as it can prevent a number of
     132                 * attacks on communications between us and the
     133                 * clients
     134                 *
     135                 * However, it really sucks (no sendfile, CPU
     136                 * overhead) performance-wise when used on a
     137                 * file server, so disable it by default
     138                 * on non-DCs
     139                 */
     140
     141                if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) {
     142                        signing_setting = SMB_SIGNING_REQUIRED;
     143                } else {
     144                        signing_setting = SMB_SIGNING_OFF;
     145                }
     146        }
     147
     148        switch (signing_setting) {
     149        case SMB_SIGNING_DEFAULT:
     150        case SMB_SIGNING_IPC_DEFAULT:
     151                smb_panic(__location__);
     152                break;
    123153        case SMB_SIGNING_OFF:
    124154                io->out.security_mode = 0;
    125155                break;
    126         case SMB_SIGNING_SUPPORTED:
    127         case SMB_SIGNING_AUTO:
     156        case SMB_SIGNING_DESIRED:
     157        case SMB_SIGNING_IF_REQUIRED:
    128158                io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
    129159                break;
  • vendor/current/source4/smb_server/smb2/receive.c

    r740 r988  
    7070        req->smb_conn = smb_conn;
    7171
     72        req->chained_session_id = UINT64_MAX;
     73        req->chained_tree_id = UINT32_MAX;
     74
    7275        talloc_set_destructor(req, smb2srv_request_destructor);
    7376
     
    7881                             bool body_dynamic_present, uint32_t body_dynamic_size)
    7982{
    80         uint32_t flags = SMB2_HDR_FLAG_REDIRECT;
     83        uint32_t flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS);
    8184        uint32_t pid = IVAL(req->in.hdr, SMB2_HDR_PID);
    8285        uint32_t tid = IVAL(req->in.hdr, SMB2_HDR_TID);
     86        uint16_t credits = SVAL(req->in.hdr, SMB2_HDR_CREDIT);
     87
     88        if (credits == 0) {
     89                credits = 1;
     90        }
     91
     92        flags |= SMB2_HDR_FLAG_REDIRECT;
    8393
    8494        if (req->pending_id) {
     
    8696                pid = req->pending_id;
    8797                tid = 0;
     98                credits = 0;
    8899        }
    89100
     
    111122        SIVAL(req->out.hdr, 0,                          SMB2_MAGIC);
    112123        SSVAL(req->out.hdr, SMB2_HDR_LENGTH,            SMB2_HDR_BODY);
    113         SSVAL(req->out.hdr, SMB2_HDR_EPOCH,             0);
     124        SSVAL(req->out.hdr, SMB2_HDR_CREDIT_CHARGE,
     125              SVAL(req->in.hdr, SMB2_HDR_CREDIT_CHARGE));
    114126        SIVAL(req->out.hdr, SMB2_HDR_STATUS,            NT_STATUS_V(req->status));
    115127        SSVAL(req->out.hdr, SMB2_HDR_OPCODE,            SVAL(req->in.hdr, SMB2_HDR_OPCODE));
    116         SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            0x0001);
     128        SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            credits);
    117129        SIVAL(req->out.hdr, SMB2_HDR_FLAGS,             flags);
    118130        SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND,      0);
     
    121133        SIVAL(req->out.hdr, SMB2_HDR_TID,               tid);
    122134        SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID,        BVAL(req->in.hdr, SMB2_HDR_SESSION_ID));
    123         memset(req->out.hdr+SMB2_HDR_SIGNATURE, 0, 16);
     135        memcpy(req->out.hdr+SMB2_HDR_SIGNATURE,
     136               req->in.hdr+SMB2_HDR_SIGNATURE, 16);
    124137
    125138        /* set the length of the fixed body part and +1 if there's a dynamic part also */
     
    143156{
    144157        NTSTATUS status;
     158        struct smbsrv_connection *smb_conn = p_req->smb_conn;
    145159        struct smb2srv_request *req;
    146160        uint32_t chain_offset;
     
    159173                DEBUG(2,("Invalid SMB2 chained packet at offset 0x%X from last hdr 0x%X\n",
    160174                        chain_offset, last_hdr_offset));
    161                 smbsrv_terminate_connection(p_req->smb_conn, "Invalid SMB2 chained packet");
     175                smbsrv_terminate_connection(smb_conn, "Invalid SMB2 chained packet");
    162176                return;
    163177        }
     
    167181                DEBUG(2,("Invalid SMB chained packet: protocol prefix: 0x%08X\n",
    168182                         protocol_version));
    169                 smbsrv_terminate_connection(p_req->smb_conn, "NON-SMB2 chained packet");
    170                 return;
    171         }
    172 
    173         req = smb2srv_init_request(p_req->smb_conn);
     183                smbsrv_terminate_connection(smb_conn, "NON-SMB2 chained packet");
     184                return;
     185        }
     186
     187        req = smb2srv_init_request(smb_conn);
    174188        if (!req) {
    175                 smbsrv_terminate_connection(p_req->smb_conn, "SMB2 chained packet - no memory");
    176                 return;
    177         }
     189                smbsrv_terminate_connection(smb_conn, "SMB2 chained packet - no memory");
     190                return;
     191        }
     192
     193        talloc_steal(req, p_req);
    178194
    179195        req->in.buffer          = talloc_steal(req, p_req->in.buffer);
     
    194210                uint16_t opcode = SVAL(req->in.hdr, SMB2_HDR_OPCODE);
    195211                if (opcode == SMB2_OP_NEGPROT) {
    196                         smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot");                   
     212                        smbsrv_terminate_connection(smb_conn, "Bad body size in SMB2 negprot");
     213                        return;
    197214                } else {
    198215                        smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER);
     216                        return;
    199217                }
    200218        }
     
    224242                        req->chained_file_handle = req->_chained_file_handle;
    225243                }
     244                req->chained_session_id = p_req->chained_session_id;
     245                req->chained_tree_id = p_req->chained_tree_id;
    226246                req->chain_status = p_req->chain_status;
    227247        }
     
    234254        status = smb2srv_reply(req);
    235255        if (!NT_STATUS_IS_OK(status)) {
    236                 smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
    237                 talloc_free(req);
     256                smbsrv_terminate_connection(smb_conn, nt_errstr(status));
    238257                return;
    239258        }
     
    252271
    253272        if (req->out.size > NBT_HDR_SIZE) {
    254                 _smb2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
     273                _smb_setlen_tcp(req->out.buffer, req->out.size - NBT_HDR_SIZE);
    255274        }
    256275
     
    270289        if (!NT_STATUS_IS_OK(status)) {
    271290                smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
     291                return;
    272292        }
    273293        if (req->chain_offset) {
     
    333353        }
    334354
     355        if (flags & SMB2_HDR_FLAG_CHAINED) {
     356                uid = req->chained_session_id;
     357                tid = req->chained_tree_id;
     358        }
     359
    335360        req->session    = smbsrv_session_find(req->smb_conn, uid, req->request_time);
    336361        req->tcon       = smbsrv_smb2_tcon_find(req->session, tid, req->request_time);
     362
     363        req->chained_session_id = uid;
     364        req->chained_tree_id = tid;
    337365
    338366        errno = 0;
     
    425453                smb2srv_keepalive_recv(req);
    426454                return NT_STATUS_OK;
    427         case SMB2_OP_FIND:
     455        case SMB2_OP_QUERY_DIRECTORY:
    428456                if (!req->session) goto nosession;
    429457                if (!req->tcon) goto notcon;
     
    570598        bool signing_used = false;
    571599        int id;
     600        uint16_t credits = SVAL(req->in.hdr, SMB2_HDR_CREDIT);
     601
     602        if (credits == 0) {
     603                credits = 1;
     604        }
    572605
    573606        if (req->pending_id) {
    574607                return NT_STATUS_INTERNAL_ERROR;
     608        }
     609
     610        if (req->smb_conn->connection->event.fde == NULL) {
     611                /* the socket has been destroyed - no point trying to send an error! */
     612                return NT_STATUS_REMOTE_DISCONNECT;
    575613        }
    576614
     
    581619        }
    582620
    583         DLIST_ADD_END(req->smb_conn->requests2.list, req, struct smb2srv_request *);
     621        DLIST_ADD_END(req->smb_conn->requests2.list, req);
    584622        req->pending_id = id;
    585 
    586         if (req->smb_conn->connection->event.fde == NULL) {
    587                 /* the socket has been destroyed - no point trying to send an error! */
    588                 return NT_STATUS_REMOTE_DISCONNECT;
    589         }
    590623
    591624        talloc_set_destructor(req, smb2srv_request_deny_destructor);
     
    597630
    598631        SIVAL(req->out.hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
     632        SSVAL(req->out.hdr, SMB2_HDR_CREDIT, credits);
    599633
    600634        SSVAL(req->out.body, 0x02, 0);
     
    664698        smb_conn->negotiate.zone_offset = get_time_zone(time(NULL));
    665699
    666         smb_conn->config.security = SEC_USER;
    667700        smb_conn->config.nt_status_support = true;
    668701
  • vendor/current/source4/smb_server/smb2/sesssetup.c

    r740 r988  
    3232static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io)
    3333{
    34         uint16_t credit;
    35 
    3634        if (NT_STATUS_IS_OK(req->status)) {
    37                 credit = 0x0003;
     35                /* nothing */
    3836        } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    39                 credit = 0x0002;
     37                /* nothing */
    4038        } else {
    4139                smb2srv_send_error(req, req->status);
     
    4543        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, io->smb2.out.secblob.length));
    4644
    47         SSVAL(req->out.hdr, SMB2_HDR_CREDIT,    credit);
    4845        SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID,        io->smb2.out.uid);
    4946
     
    6865        struct smbsrv_session *smb_sess = ctx->smb_sess;
    6966        struct auth_session_info *session_info = NULL;
     67        enum security_user_level user_level;
    7068        NTSTATUS status;
    7169
     
    8078        }
    8179
    82         status = gensec_session_info(smb_sess->gensec_ctx, &session_info);
     80        status = gensec_session_info(smb_sess->gensec_ctx, smb_sess, &session_info);
    8381        if (!NT_STATUS_IS_OK(status)) {
    8482                goto failed;
     
    9391        req->session = smb_sess;
    9492
    95         if (smb_sess->smb2_signing.required) {
    96                 /* activate smb2 signing on the session */
    97                 smb_sess->smb2_signing.active = true;
    98         }
     93        user_level = security_session_user_level(smb_sess->session_info, NULL);
     94        if (user_level >= SECURITY_USER) {
     95                if (smb_sess->smb2_signing.required) {
     96                        /* activate smb2 signing on the session */
     97                        smb_sess->smb2_signing.active = true;
     98                }
     99                /* we need to sign the session setup response */
     100                req->is_signed = true;
     101        }
     102
    99103done:
    100104        io->smb2.out.uid = smb_sess->vuid;
     
    164168
    165169        if (!smb_sess) {
     170                status = NT_STATUS_USER_SESSION_DELETED;
     171                goto failed;
     172        }
     173
     174        if (smb_sess->session_info) {
    166175                /* see WSPP test suite - test 11 */
    167176                status = NT_STATUS_REQUEST_NOT_ACCEPTED;
     
    193202        if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
    194203                smb_sess->smb2_signing.required = true;
    195         } else if (req->smb_conn->smb2_signing_required) {
    196                 /*
    197                  * if required signing was negotiates in SMB2 Negotiate
    198                  * then the client made an error not using it here
    199                  */
    200                 DEBUG(1, ("SMB2 signing required on the connection but not used on session\n"));
    201                 req->status = NT_STATUS_FOOBAR;
    202                 goto failed;
    203204        }
    204205
     
    274275void smb2srv_logoff_recv(struct smb2srv_request *req)
    275276{
    276         uint16_t _pad;
    277 
    278277        SMB2SRV_CHECK_BODY_SIZE(req, 0x04, false);
    279 
    280         _pad    = SVAL(req->in.body, 0x02);
    281278
    282279        req->status = smb2srv_logoff_backend(req);
  • vendor/current/source4/smb_server/smb2/smb2_server.h

    r414 r988  
    6565        uint8_t _chained_file_handle[16];
    6666        uint8_t *chained_file_handle;
     67        uint64_t chained_session_id;
     68        uint32_t chained_tree_id;
    6769
    6870        bool is_signed;
  • vendor/current/source4/smb_server/smb2/tcon.c

    r740 r988  
    242242        const char *service = io->smb2.in.path;
    243243        struct share_config *scfg;
    244         const char *sharetype;
     244        char *sharetype;
    245245        uint64_t ntvfs_caps = 0;
    246246
     
    266266
    267267        /* work out what sort of connection this is */
    268         sharetype = share_string_option(scfg, SHARE_TYPE, "DISK");
     268        sharetype = share_string_option(req, scfg, SHARE_TYPE, "DISK");
    269269        if (sharetype && strcmp(sharetype, "IPC") == 0) {
    270270                type = NTVFS_IPC;
     
    274274                type = NTVFS_DISK;
    275275        }
     276        TALLOC_FREE(sharetype);
    276277
    277278        tcon = smbsrv_smb2_tcon_new(req->session, scfg->name);
     
    360361static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io)
    361362{
    362         uint16_t credit;
    363 
    364363        if (!NT_STATUS_IS_OK(req->status)) {
    365364                smb2srv_send_error(req, req->status);
    366365                return;
    367366        }
    368         if (io->smb2.out.share_type == NTVFS_IPC) {
    369                 /* if it's an IPC share vista returns 0x0005 */
    370                 credit = 0x0005;
    371         } else {
    372                 credit = 0x0001;
    373         }
    374367
    375368        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, false, 0));
    376369
    377370        SIVAL(req->out.hdr,     SMB2_HDR_TID,   io->smb2.out.tid);
    378         SSVAL(req->out.hdr,     SMB2_HDR_CREDIT,credit);
    379371
    380372        SCVAL(req->out.body,    0x02,           io->smb2.out.share_type);
     
    443435void smb2srv_tdis_recv(struct smb2srv_request *req)
    444436{
    445         uint16_t _pad;
    446 
    447437        SMB2SRV_CHECK_BODY_SIZE(req, 0x04, false);
    448 
    449         _pad    = SVAL(req->in.body, 0x02);
    450438
    451439        req->status = smb2srv_tdis_backend(req);
  • vendor/current/source4/smb_server/smb2/wscript_build

    r740 r988  
    44        source='receive.c negprot.c sesssetup.c tcon.c fileio.c fileinfo.c find.c keepalive.c',
    55        autoproto='smb2_proto.h',
    6         public_deps='ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec NDR_DFSBLOBS'
     6        public_deps='ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec NDR_DFSBLOBS',
     7        enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
    78        )
    89
  • vendor/current/source4/smb_server/smb_server.c

    r740 r988  
    6464                return smbsrv_recv_smb_request(smb_conn, blob);
    6565        case SMB2_MAGIC:
    66                 if (lpcfg_srv_maxprotocol(smb_conn->lp_ctx) < PROTOCOL_SMB2) break;
     66                if (lpcfg_server_max_protocol(smb_conn->lp_ctx) < PROTOCOL_SMB2_02) break;
    6767                status = smbsrv_init_smb2_connection(smb_conn);
    6868                NT_STATUS_NOT_OK_RETURN(status);
     
    191191                status = stream_setup_socket(mem_ctx, event_context, lp_ctx,
    192192                                             model_ops, &smb_stream_ops,
    193                                              "ipv4", address, &port,
     193                                             "ip", address, &port,
    194194                                             lpcfg_socket_options(lp_ctx),
    195195                                             NULL);
  • vendor/current/source4/smb_server/smb_server.h

    r740 r988  
    2323#include "libcli/raw/interfaces.h"
    2424#include "lib/socket/socket.h"
     25#include "libds/common/roles.h"
    2526#include "../lib/util/dlinklist.h"
    2627#include "../librpc/gen_ndr/nbt.h"
     
    265266        struct smb_request_buffer out;
    266267};
    267 
    268 enum security_types {SEC_SHARE,SEC_USER};
    269268
    270269/* smb server context structure. This should contain all the state
     
    301300
    302301                /* authentication context for multi-part negprot */
    303                 struct auth_context *auth_context;
     302                struct auth4_context *auth_context;
    304303       
    305304                /* reference to the kerberos keytab, or machine trust account */
     
    372371        /* configuration parameters */
    373372        struct {
    374                 enum security_types security;
    375373                bool nt_status_support;
    376374        } config;
     
    478476        req->ntvfs->async_states->status = cmd; \
    479477        if (req->ntvfs->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \
    480                 DLIST_ADD_END(req->smb_conn->requests, req, struct smbsrv_request *); \
     478                DLIST_ADD_END(req->smb_conn->requests, req); \
    481479        } else { \
    482480                req->ntvfs->async_states->send_fn(req->ntvfs); \
  • vendor/current/source4/smb_server/wscript_build

    r740 r988  
    88        deps='SMB_SERVER netif shares samba-hostconfig',
    99        internal_module=False,
     10        enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
    1011        )
    11 
    12 
    13 bld.SAMBA_MODULE('service_samba3_smb',
    14         source='smb_samba3.c',
    15         subsystem='service',
    16         init_function='server_service_samba3_smb_init',
    17         deps='talloc',
    18         internal_module=False,
    19         )
    20 
    2112
    2213bld.SAMBA_SUBSYSTEM('SMB_SERVER',
    2314        source='handle.c tcon.c session.c blob.c management.c smb_server.c',
    2415        autoproto='smb_server_proto.h',
    25         public_deps='share LIBPACKET SMB_PROTOCOL SMB2_PROTOCOL'
     16        public_deps='share LIBPACKET SMB_PROTOCOL SMB2_PROTOCOL',
     17        enabled=bld.CONFIG_SET('WITH_NTVFS_FILESERVER')
    2618        )
    2719
Note: See TracChangeset for help on using the changeset viewer.