Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/smbd/service.c

    r478 r740  
    33   service (connection) opening and closing
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    1919
    2020#include "includes.h"
     21#include "system/filesys.h"
     22#include "../lib/tsocket/tsocket.h"
     23#include "smbd/smbd.h"
    2124#include "smbd/globals.h"
     25#include "../librpc/gen_ndr/netlogon.h"
     26#include "../libcli/security/security.h"
     27#include "printing/pcap.h"
     28#include "passdb/lookup_sid.h"
     29#include "auth.h"
    2230
    2331extern userdom_struct current_user_info;
     
    2533static bool canonicalize_connect_path(connection_struct *conn)
    2634{
    27 #ifdef REALPATH_TAKES_NULL
    2835        bool ret;
    29         char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath,NULL);
     36        char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath);
    3037        if (!resolved_name) {
    3138                return false;
     
    3441        SAFE_FREE(resolved_name);
    3542        return ret;
    36 #else
    37         char resolved_name_buf[PATH_MAX+1];
    38         char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath,resolved_name_buf);
    39         if (!resolved_name) {
    40                 return false;
    41         }
    42         return set_conn_connectpath(conn,resolved_name);
    43 #endif /* REALPATH_TAKES_NULL */
    4443}
    4544
     
    6261
    6362        /* Allocate for strlen + '\0' + possible leading '/' */
    64         destname = SMB_MALLOC(strlen(connectpath) + 2);
     63        destname = (char *)SMB_MALLOC(strlen(connectpath) + 2);
    6564        if (!destname) {
    6665                return false;
     
    184183
    185184        snum = SNUM(conn);
    186  
     185
    187186        if (do_chdir &&
    188187            vfs_ChDir(conn,conn->connectpath) != 0 &&
     
    199198        last_conn = conn;
    200199        last_flags = flags;
    201        
     200
    202201        /* Obey the client case sensitivity requests - only for clients that support it. */
    203202        switch (lp_casesensitive(snum)) {
     
    293292                return -1;
    294293        }
    295        
     294
    296295        return lp_servicenumber(service);
    297296
     
    304303 **/
    305304
    306 int find_service(fstring service)
     305int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
    307306{
    308307        int iService;
    309         struct smbd_server_connection *sconn = smbd_server_conn;
    310 
    311         all_string_sub(service,"\\","/",0);
    312 
    313         iService = lp_servicenumber(service);
     308
     309        if (!service_in) {
     310                return -1;
     311        }
     312
     313        /* First make a copy. */
     314        *p_service_out = talloc_strdup(ctx, service_in);
     315        if (!*p_service_out) {
     316                return -1;
     317        }
     318
     319        all_string_sub(*p_service_out,"\\","/",0);
     320
     321        iService = lp_servicenumber(*p_service_out);
    314322
    315323        /* now handle the special case of a home directory */
    316324        if (iService < 0) {
    317                 char *phome_dir = get_user_home_dir(talloc_tos(), service);
     325                char *phome_dir = get_user_home_dir(ctx, *p_service_out);
    318326
    319327                if(!phome_dir) {
     
    322330                         * be a Windows to unix mapped user name.
    323331                         */
    324                         if(map_username(sconn, service))
     332                        if(map_username(ctx, *p_service_out, p_service_out)) {
     333                                if (*p_service_out == NULL) {
     334                                        /* Out of memory. */
     335                                        return -1;
     336                                }
    325337                                phome_dir = get_user_home_dir(
    326                                         talloc_tos(), service);
    327                 }
    328 
    329                 DEBUG(3,("checking for home directory %s gave %s\n",service,
     338                                                ctx, *p_service_out);
     339                        }
     340                }
     341
     342                DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,
    330343                        phome_dir?phome_dir:"(NULL)"));
    331344
    332                 iService = add_home_service(service,service /* 'username' */, phome_dir);
     345                iService = add_home_service(*p_service_out,*p_service_out /* 'username' */, phome_dir);
    333346        }
    334347
     
    341354                }
    342355                if (iPrinterService >= 0) {
    343                         DEBUG(3,("checking whether %s is a valid printer name...\n", service));
    344                         if (pcap_printername_ok(service)) {
    345                                 DEBUG(3,("%s is a valid printer name\n", service));
    346                                 DEBUG(3,("adding %s as a printer service\n", service));
    347                                 lp_add_printer(service, iPrinterService);
    348                                 iService = lp_servicenumber(service);
     356                        DEBUG(3,("checking whether %s is a valid printer name...\n",
     357                                *p_service_out));
     358                        if (pcap_printername_ok(*p_service_out)) {
     359                                DEBUG(3,("%s is a valid printer name\n",
     360                                        *p_service_out));
     361                                DEBUG(3,("adding %s as a printer service\n",
     362                                        *p_service_out));
     363                                lp_add_printer(*p_service_out, iPrinterService);
     364                                iService = lp_servicenumber(*p_service_out);
    349365                                if (iService < 0) {
    350                                         DEBUG(0,("failed to add %s as a printer service!\n", service));
     366                                        DEBUG(0,("failed to add %s as a printer service!\n",
     367                                                *p_service_out));
    351368                                }
    352369                        } else {
    353                                 DEBUG(3,("%s is not a valid printer name\n", service));
     370                                DEBUG(3,("%s is not a valid printer name\n",
     371                                        *p_service_out));
    354372                        }
    355373                }
     
    361379
    362380        if (iService < 0) {
    363                 iService = load_registry_service(service);
     381                iService = load_registry_service(*p_service_out);
    364382        }
    365383
     
    367385        if (iService < 0 && *lp_usershare_path()) {
    368386                /* Ensure the name is canonicalized. */
    369                 strlower_m(service);
    370                 iService = load_usershare_service(service);
     387                strlower_m(*p_service_out);
     388                iService = load_usershare_service(*p_service_out);
    371389        }
    372390
     
    374392        if (iService < 0) {
    375393                char *pdefservice = lp_defaultservice();
    376                 if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
     394                if (pdefservice &&
     395                                *pdefservice &&
     396                                !strequal(pdefservice, *p_service_out)
     397                                && !strstr_m(*p_service_out,"..")) {
    377398                        /*
    378399                         * We need to do a local copy here as lp_defaultservice()
     
    381402                         * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
    382403                         */
    383                         char *defservice = SMB_STRDUP(pdefservice);
     404                        char *defservice = talloc_strdup(ctx, pdefservice);
    384405
    385406                        if (!defservice) {
     
    391412                                        strequal(defservice, PRINTERS_NAME) ||
    392413                                        strequal(defservice, "IPC$")) {
    393                                 SAFE_FREE(defservice);
     414                                TALLOC_FREE(defservice);
    394415                                goto fail;
    395416                        }
    396417
    397                         iService = find_service(defservice);
     418                        iService = find_service(ctx, defservice, p_service_out);
     419                        if (!*p_service_out) {
     420                                TALLOC_FREE(defservice);
     421                                iService = -1;
     422                                goto fail;
     423                        }
    398424                        if (iService >= 0) {
    399                                 all_string_sub(service, "_","/",0);
    400                                 iService = lp_add_service(service, iService);
     425                                all_string_sub(*p_service_out, "_","/",0);
     426                                iService = lp_add_service(*p_service_out, iService);
    401427                        }
    402                         SAFE_FREE(defservice);
     428                        TALLOC_FREE(defservice);
    403429                }
    404430        }
     
    406432        if (iService >= 0) {
    407433                if (!VALID_SNUM(iService)) {
    408                         DEBUG(0,("Invalid snum %d for %s\n",iService, service));
     434                        DEBUG(0,("Invalid snum %d for %s\n",iService,
     435                                *p_service_out));
    409436                        iService = -1;
    410437                }
     
    413440  fail:
    414441
    415         if (iService < 0)
    416                 DEBUG(3,("find_service() failed to find service %s\n", service));
     442        if (iService < 0) {
     443                DEBUG(3,("find_service() failed to find service %s\n",
     444                        *p_service_out));
     445        }
    417446
    418447        return (iService);
     
    425454****************************************************************************/
    426455
    427 static NTSTATUS share_sanity_checks(int snum, fstring dev)
     456static NTSTATUS share_sanity_checks(struct client_address *client_id, int snum,
     457                                    fstring dev)
    428458{
    429        
    430459        if (!lp_snum_ok(snum) ||
    431             !check_access(smbd_server_fd(),
    432                           lp_hostsallow(snum), lp_hostsdeny(snum))) {   
     460            !allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
     461                          client_id->name, client_id->addr)) {
    433462                return NT_STATUS_ACCESS_DENIED;
    434463        }
     
    475504static NTSTATUS find_forced_group(bool force_user,
    476505                                  int snum, const char *username,
    477                                   DOM_SID *pgroup_sid,
     506                                  struct dom_sid *pgroup_sid,
    478507                                  gid_t *pgid)
    479508{
    480509        NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
    481510        TALLOC_CTX *frame = talloc_stackframe();
    482         DOM_SID group_sid;
     511        struct dom_sid group_sid;
    483512        enum lsa_SidType type;
    484513        char *groupname;
     
    563592****************************************************************************/
    564593
    565 static NTSTATUS create_connection_server_info(struct smbd_server_connection *sconn,
     594static NTSTATUS create_connection_session_info(struct smbd_server_connection *sconn,
    566595                                              TALLOC_CTX *mem_ctx, int snum,
    567596                                              struct auth_serversupplied_info *vuid_serverinfo,
     
    590619                } else {
    591620                        if (!user_ok_token(vuid_serverinfo->unix_name,
    592                                            pdb_get_domain(vuid_serverinfo->sam_account),
    593                                            vuid_serverinfo->ptok, snum)) {
     621                                           vuid_serverinfo->info3->base.domain.string,
     622                                           vuid_serverinfo->security_token, snum)) {
    594623                                DEBUG(2, ("user '%s' (from session setup) not "
    595624                                          "permitted to access this share "
     
    636665}
    637666
     667/****************************************************************************
     668  set relavent user and group settings corresponding to force user/group
     669  configuration for the given snum.
     670****************************************************************************/
     671
     672NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
     673{
     674        NTSTATUS status;
     675
     676        if (*lp_force_user(snum)) {
     677
     678                /*
     679                 * Replace conn->session_info with a completely faked up one
     680                 * from the username we are forced into :-)
     681                 */
     682
     683                char *fuser;
     684                struct auth_serversupplied_info *forced_serverinfo;
     685
     686                fuser = talloc_string_sub(conn, lp_force_user(snum), "%S",
     687                                          lp_const_servicename(snum));
     688                if (fuser == NULL) {
     689                        return NT_STATUS_NO_MEMORY;
     690                }
     691
     692                status = make_serverinfo_from_username(
     693                        conn, fuser, conn->session_info->guest,
     694                        &forced_serverinfo);
     695                if (!NT_STATUS_IS_OK(status)) {
     696                        return status;
     697                }
     698
     699                TALLOC_FREE(conn->session_info);
     700                conn->session_info = forced_serverinfo;
     701
     702                conn->force_user = true;
     703                DEBUG(3,("Forced user %s\n", fuser));
     704        }
     705
     706        /*
     707         * If force group is true, then override
     708         * any groupid stored for the connecting user.
     709         */
     710
     711        if (*lp_force_group(snum)) {
     712
     713                status = find_forced_group(
     714                        conn->force_user, snum, conn->session_info->unix_name,
     715                        &conn->session_info->security_token->sids[1],
     716                        &conn->session_info->utok.gid);
     717
     718                if (!NT_STATUS_IS_OK(status)) {
     719                        return status;
     720                }
     721
     722                /*
     723                 * We need to cache this gid, to use within
     724                 * change_to_user() separately from the conn->session_info
     725                 * struct. We only use conn->session_info directly if
     726                 * "force_user" was set.
     727                 */
     728                conn->force_group_gid = conn->session_info->utok.gid;
     729        }
     730
     731        return NT_STATUS_OK;
     732}
    638733
    639734/****************************************************************************
     
    648743                                        NTSTATUS *pstatus)
    649744{
    650         connection_struct *conn;
     745        connection_struct *conn = NULL;
    651746        struct smb_filename *smb_fname_cpath = NULL;
    652747        fstring dev;
    653748        int ret;
    654         char addr[INET6_ADDRSTRLEN];
     749        bool on_err_call_dis_hook = false;
     750        bool claimed_connection = false;
     751        uid_t effuid;
     752        gid_t effgid;
    655753        NTSTATUS status;
    656754
    657755        fstrcpy(dev, pdev);
    658756
    659         if (NT_STATUS_IS_ERR(*pstatus = share_sanity_checks(snum, dev))) {
    660                 return NULL;
    661         }       
     757        *pstatus = share_sanity_checks(&sconn->client_id, snum, dev);
     758        if (NT_STATUS_IS_ERR(*pstatus)) {
     759                goto err_root_exit;
     760        }
    662761
    663762        conn = conn_new(sconn);
     
    665764                DEBUG(0,("Couldn't find free connection.\n"));
    666765                *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
    667                 return NULL;
     766                goto err_root_exit;
    668767        }
    669768
    670769        conn->params->service = snum;
    671770
    672         status = create_connection_server_info(sconn,
    673                 conn, snum, vuser ? vuser->server_info : NULL, password,
    674                 &conn->server_info);
     771        status = create_connection_session_info(sconn,
     772                conn, snum, vuser ? vuser->session_info : NULL, password,
     773                &conn->session_info);
    675774
    676775        if (!NT_STATUS_IS_OK(status)) {
    677                 DEBUG(1, ("create_connection_server_info failed: %s\n",
     776                DEBUG(1, ("create_connection_session_info failed: %s\n",
    678777                          nt_errstr(status)));
    679778                *pstatus = status;
    680                 conn_free(conn);
    681                 return NULL;
     779                goto err_root_exit;
    682780        }
    683781
     
    686784        }
    687785
    688         add_session_user(sconn, conn->server_info->unix_name);
    689 
    690         safe_strcpy(conn->client_address,
    691                         client_addr(get_client_fd(),addr,sizeof(addr)),
    692                         sizeof(conn->client_address)-1);
     786        add_session_user(sconn, conn->session_info->unix_name);
     787
    693788        conn->num_files_open = 0;
    694789        conn->lastused = conn->lastused_count = time(NULL);
     
    718813
    719814        conn->read_only = lp_readonly(SNUM(conn));
    720         conn->admin_user = False;
    721 
    722         if (*lp_force_user(snum)) {
    723 
    724                 /*
    725                  * Replace conn->server_info with a completely faked up one
    726                  * from the username we are forced into :-)
    727                  */
    728 
    729                 char *fuser;
    730                 struct auth_serversupplied_info *forced_serverinfo;
    731 
    732                 fuser = talloc_string_sub(conn, lp_force_user(snum), "%S",
    733                                           lp_servicename(snum));
    734                 if (fuser == NULL) {
    735                         conn_free(conn);
    736                         *pstatus = NT_STATUS_NO_MEMORY;
    737                         return NULL;
    738                 }
    739 
    740                 status = make_serverinfo_from_username(
    741                         conn, fuser, conn->server_info->guest,
    742                         &forced_serverinfo);
    743                 if (!NT_STATUS_IS_OK(status)) {
    744                         conn_free(conn);
    745                         *pstatus = status;
    746                         return NULL;
    747                 }
    748 
    749                 TALLOC_FREE(conn->server_info);
    750                 conn->server_info = forced_serverinfo;
    751 
    752                 conn->force_user = True;
    753                 DEBUG(3,("Forced user %s\n", fuser));
    754         }
    755 
    756         /*
    757          * If force group is true, then override
    758          * any groupid stored for the connecting user.
    759          */
    760 
    761         if (*lp_force_group(snum)) {
    762 
    763                 status = find_forced_group(
    764                         conn->force_user, snum, conn->server_info->unix_name,
    765                         &conn->server_info->ptok->user_sids[1],
    766                         &conn->server_info->utok.gid);
    767 
    768                 if (!NT_STATUS_IS_OK(status)) {
    769                         conn_free(conn);
    770                         *pstatus = status;
    771                         return NULL;
    772                 }
    773 
    774                 /*
    775                  * We need to cache this gid, to use within
    776                  * change_to_user() separately from the conn->server_info
    777                  * struct. We only use conn->server_info directly if
    778                  * "force_user" was set.
    779                  */
    780                 conn->force_group_gid = conn->server_info->utok.gid;
     815
     816        status = set_conn_force_user_group(conn, snum);
     817        if (!NT_STATUS_IS_OK(status)) {
     818                conn_free(conn);
     819                *pstatus = status;
     820                return NULL;
    781821        }
    782822
     
    786826                char *s = talloc_sub_advanced(talloc_tos(),
    787827                                        lp_servicename(SNUM(conn)),
    788                                         conn->server_info->unix_name,
     828                                        conn->session_info->unix_name,
    789829                                        conn->connectpath,
    790                                         conn->server_info->utok.gid,
    791                                         conn->server_info->sanitized_username,
    792                                         pdb_get_domain(conn->server_info->sam_account),
     830                                        conn->session_info->utok.gid,
     831                                        conn->session_info->sanitized_username,
     832                                        conn->session_info->info3->base.domain.string,
    793833                                        lp_pathname(snum));
    794834                if (!s) {
    795                         conn_free(conn);
    796835                        *pstatus = NT_STATUS_NO_MEMORY;
    797                         return NULL;
     836                        goto err_root_exit;
    798837                }
    799838
    800839                if (!set_conn_connectpath(conn,s)) {
    801840                        TALLOC_FREE(s);
    802                         conn_free(conn);
    803841                        *pstatus = NT_STATUS_NO_MEMORY;
    804                         return NULL;
     842                        goto err_root_exit;
    805843                }
    806844                DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
     
    816854         */
    817855
    818         {
    819                 bool can_write = False;
    820 
    821                 can_write = share_access_check(conn->server_info->ptok,
    822                                                lp_servicename(snum),
    823                                                FILE_WRITE_DATA);
    824 
    825                 if (!can_write) {
    826                         if (!share_access_check(conn->server_info->ptok,
    827                                                 lp_servicename(snum),
    828                                                 FILE_READ_DATA)) {
    829                                 /* No access, read or write. */
    830                                 DEBUG(0,("make_connection: connection to %s "
    831                                          "denied due to security "
    832                                          "descriptor.\n",
    833                                           lp_servicename(snum)));
    834                                 conn_free(conn);
    835                                 *pstatus = NT_STATUS_ACCESS_DENIED;
    836                                 return NULL;
    837                         } else {
    838                                 conn->read_only = True;
    839                         }
     856        share_access_check(conn->session_info->security_token,
     857                           lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS,
     858                           &conn->share_access);
     859
     860        if ((conn->share_access & FILE_WRITE_DATA) == 0) {
     861                if ((conn->share_access & FILE_READ_DATA) == 0) {
     862                        /* No access, read or write. */
     863                        DEBUG(0,("make_connection: connection to %s "
     864                                 "denied due to security "
     865                                 "descriptor.\n",
     866                                 lp_servicename(snum)));
     867                        *pstatus = NT_STATUS_ACCESS_DENIED;
     868                        goto err_root_exit;
     869                } else {
     870                        conn->read_only = True;
    840871                }
    841872        }
     
    845876                DEBUG(0, ("vfs_init failed for service %s\n",
    846877                          lp_servicename(snum)));
    847                 conn_free(conn);
    848878                *pstatus = NT_STATUS_BAD_NETWORK_NAME;
    849                 return NULL;
    850         }
    851 
    852         if ((!conn->printer) && (!conn->ipc)) {
    853                 conn->notify_ctx = notify_init(conn, server_id_self(),
    854                                                smbd_messaging_context(),
    855                                                smbd_event_context(),
    856                                                conn);
     879                goto err_root_exit;
    857880        }
    858881
     
    872895                DEBUG(1, ("Max connections (%d) exceeded for %s\n",
    873896                          lp_max_connections(snum), lp_servicename(snum)));
    874                 conn_free(conn);
    875897                *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
    876                 return NULL;
    877         } 
     898                goto err_root_exit;
     899        }
    878900
    879901        /*
    880902         * Get us an entry in the connections db
    881903         */
    882         if (!claim_connection(conn, lp_servicename(snum), 0)) {
     904        if (!claim_connection(conn, lp_servicename(snum))) {
    883905                DEBUG(1, ("Could not store connections entry\n"));
    884                 conn_free(conn);
    885906                *pstatus = NT_STATUS_INTERNAL_DB_ERROR;
    886                 return NULL;
    887         } 
    888 
    889         /* Invoke VFS make connection hook - must be the first
    890            VFS operation we do. */
     907                goto err_root_exit;
     908        }
     909        claimed_connection = true;
     910
     911        /* Invoke VFS make connection hook - this must be the first
     912           filesystem operation that we do. */
    891913
    892914        if (SMB_VFS_CONNECT(conn, lp_servicename(snum),
    893                             conn->server_info->unix_name) < 0) {
     915                            conn->session_info->unix_name) < 0) {
    894916                DEBUG(0,("make_connection: VFS make connection failed!\n"));
    895                 yield_connection(conn, lp_servicename(snum));
    896                 conn_free(conn);
    897917                *pstatus = NT_STATUS_UNSUCCESSFUL;
    898                 return NULL;
     918                goto err_root_exit;
     919        }
     920
     921        /* Any error exit after here needs to call the disconnect hook. */
     922        on_err_call_dis_hook = true;
     923
     924        if ((!conn->printer) && (!conn->ipc)) {
     925                conn->notify_ctx = notify_init(conn,
     926                                               sconn_server_id(sconn),
     927                                               sconn->msg_ctx,
     928                                               smbd_event_context(),
     929                                               conn);
    899930        }
    900931
     
    917948                char *cmd = talloc_sub_advanced(talloc_tos(),
    918949                                        lp_servicename(SNUM(conn)),
    919                                         conn->server_info->unix_name,
     950                                        conn->session_info->unix_name,
    920951                                        conn->connectpath,
    921                                         conn->server_info->utok.gid,
    922                                         conn->server_info->sanitized_username,
    923                                         pdb_get_domain(conn->server_info->sam_account),
     952                                        conn->session_info->utok.gid,
     953                                        conn->session_info->sanitized_username,
     954                                        conn->session_info->info3->base.domain.string,
    924955                                        lp_rootpreexec(snum));
    925956                DEBUG(5,("cmd=%s\n",cmd));
     
    929960                        DEBUG(1,("root preexec gave %d - failing "
    930961                                 "connection\n", ret));
    931                         SMB_VFS_DISCONNECT(conn);
    932                         yield_connection(conn, lp_servicename(snum));
    933                         conn_free(conn);
    934962                        *pstatus = NT_STATUS_ACCESS_DENIED;
    935                         return NULL;
     963                        goto err_root_exit;
    936964                }
    937965        }
     
    941969                /* No point continuing if they fail the basic checks */
    942970                DEBUG(0,("Can't become connected user!\n"));
    943                 SMB_VFS_DISCONNECT(conn);
    944                 yield_connection(conn, lp_servicename(snum));
    945                 conn_free(conn);
    946971                *pstatus = NT_STATUS_LOGON_FAILURE;
    947                 return NULL;
    948         }
     972                goto err_root_exit;
     973        }
     974
     975        effuid = geteuid();
     976        effgid = getegid();
    949977
    950978        /* Remember that a different vuid can connect later without these
    951979         * checks... */
    952        
     980
    953981        /* Preexecs are done here as they might make the dir we are to ChDir
    954982         * to below */
     
    958986                char *cmd = talloc_sub_advanced(talloc_tos(),
    959987                                        lp_servicename(SNUM(conn)),
    960                                         conn->server_info->unix_name,
     988                                        conn->session_info->unix_name,
    961989                                        conn->connectpath,
    962                                         conn->server_info->utok.gid,
    963                                         conn->server_info->sanitized_username,
    964                                         pdb_get_domain(conn->server_info->sam_account),
     990                                        conn->session_info->utok.gid,
     991                                        conn->session_info->sanitized_username,
     992                                        conn->session_info->info3->base.domain.string,
    965993                                        lp_preexec(snum));
    966994                ret = smbrun(cmd,NULL);
     
    9731001                }
    9741002        }
     1003
     1004#ifdef WITH_FAKE_KASERVER
     1005        if (lp_afs_share(snum)) {
     1006                afs_login(conn);
     1007        }
     1008#endif
     1009
     1010        /*
     1011         * we've finished with the user stuff - go back to root
     1012         * so the SMB_VFS_STAT call will only fail on path errors,
     1013         * not permission problems.
     1014         */
     1015        change_to_root_user();
     1016/* ROOT Activites: */
    9751017
    9761018        /*
     
    9921034        }
    9931035
    994 #ifdef WITH_FAKE_KASERVER
    995         if (lp_afs_share(snum)) {
    996                 afs_login(conn);
    997         }
    998 #endif
    999        
    10001036        /* Add veto/hide lists */
    10011037        if (!IS_IPC(conn) && !IS_PRINT(conn)) {
     
    10061042                                lp_aio_write_behind(snum));
    10071043        }
    1008        
    10091044        status = create_synthetic_smb_fname(talloc_tos(), conn->connectpath,
    10101045                                            NULL, NULL, &smb_fname_cpath);
     
    10191054           I have disabled this chdir check (tridge) */
    10201055        /* the alternative is just to check the directory exists */
     1056
    10211057        if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
    10221058            !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
     
    10381074        string_set(&conn->origpath,conn->connectpath);
    10391075
    1040 #if SOFTLINK_OPTIMISATION
    1041         /* resolve any soft links early if possible */
    1042         if (vfs_ChDir(conn,conn->connectpath) == 0) {
    1043                 TALLOC_CTX *ctx = talloc_tos();
    1044                 char *s = vfs_GetWd(ctx,s);
    1045                 if (!s) {
    1046                         *status = map_nt_error_from_unix(errno);
    1047                         goto err_root_exit;
    1048                 }
    1049                 if (!set_conn_connectpath(conn,s)) {
    1050                         *status = NT_STATUS_NO_MEMORY;
    1051                         goto err_root_exit;
    1052                 }
    1053                 vfs_ChDir(conn,conn->connectpath);
    1054         }
    1055 #endif
    1056 
    10571076        /* Figure out the characteristics of the underlying filesystem. This
    10581077         * assumes that all the filesystem mounted withing a share path have
     
    10701089        if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
    10711090                dbgtext( "%s (%s) ", get_remote_machine_name(),
    1072                          conn->client_address );
    1073                 dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : "");
     1091                         conn->sconn->client_id.addr );
     1092                dbgtext( "%s", srv_is_signing_active(sconn) ? "signed " : "");
    10741093                dbgtext( "connect to service %s ", lp_servicename(snum) );
    10751094                dbgtext( "initially as user %s ",
    1076                          conn->server_info->unix_name );
    1077                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
     1095                         conn->session_info->unix_name );
     1096                dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid );
    10781097                dbgtext( "(pid %d)\n", (int)sys_getpid() );
    10791098        }
    10801099
    1081         /* we've finished with the user stuff - go back to root */
    1082         change_to_root_user();
    10831100        return(conn);
    10841101
    10851102  err_root_exit:
    10861103        TALLOC_FREE(smb_fname_cpath);
    1087         change_to_root_user();
    1088         /* Call VFS disconnect hook */
    1089         SMB_VFS_DISCONNECT(conn);
    1090         yield_connection(conn, lp_servicename(snum));
    1091         conn_free(conn);
     1104        /* We must exit this function as root. */
     1105        if (geteuid() != 0) {
     1106                change_to_root_user();
     1107        }
     1108        if (on_err_call_dis_hook) {
     1109                /* Call VFS disconnect hook */
     1110                SMB_VFS_DISCONNECT(conn);
     1111        }
     1112        if (claimed_connection) {
     1113                yield_connection(conn, lp_servicename(snum));
     1114        }
     1115        if (conn) {
     1116                conn_free(conn);
     1117        }
    10921118        return NULL;
    10931119}
     
    11061132        uid_t euid;
    11071133        user_struct *vuser = NULL;
    1108         fstring service;
     1134        char *service = NULL;
    11091135        fstring dev;
    11101136        int snum = -1;
    1111         char addr[INET6_ADDRSTRLEN];
    11121137
    11131138        fstrcpy(dev, pdev);
     
    11661191                         * current_user_info.smb_name as the username.  */
    11671192                        if (*current_user_info.smb_name) {
    1168                                 fstring unix_username;
    1169                                 fstrcpy(unix_username,
    1170                                         current_user_info.smb_name);
    1171                                 map_username(sconn, unix_username);
    1172                                 snum = find_service(unix_username);
    1173                         }
     1193                                char *unix_username = NULL;
     1194                                (void)map_username(talloc_tos(),
     1195                                                current_user_info.smb_name,
     1196                                                &unix_username);
     1197                                snum = find_service(talloc_tos(),
     1198                                                unix_username,
     1199                                                &unix_username);
     1200                                if (!unix_username) {
     1201                                        *status = NT_STATUS_NO_MEMORY;
     1202                                }
     1203                                return NULL;
     1204                        }
    11741205                        if (snum != -1) {
    11751206                                DEBUG(5, ("making a connection to 'homes' "
     
    11931224                                            dev, status);
    11941225        }
    1195        
    1196         fstrcpy(service, service_in);
     1226
     1227        service = talloc_strdup(talloc_tos(), service_in);
     1228        if (!service) {
     1229                *status = NT_STATUS_NO_MEMORY;
     1230                return NULL;
     1231        }
    11971232
    11981233        strlower_m(service);
    11991234
    1200         snum = find_service(service);
     1235        snum = find_service(talloc_tos(), service, &service);
     1236        if (!service) {
     1237                *status = NT_STATUS_NO_MEMORY;
     1238                return NULL;
     1239        }
    12011240
    12021241        if (snum < 0) {
     
    12101249                DEBUG(3,("%s (%s) couldn't find service %s\n",
    12111250                        get_remote_machine_name(),
    1212                         client_addr(get_client_fd(),addr,sizeof(addr)),
     1251                        tsocket_address_string(
     1252                                sconn->remote_address, talloc_tos()),
    12131253                        service));
    12141254                *status = NT_STATUS_BAD_NETWORK_NAME;
     
    12481288        DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
    12491289                                 get_remote_machine_name(),
    1250                                  conn->client_address,
     1290                                 conn->sconn->client_id.addr,
    12511291                                 lp_servicename(SNUM(conn))));
    12521292
     
    12641304                char *cmd = talloc_sub_advanced(talloc_tos(),
    12651305                                        lp_servicename(SNUM(conn)),
    1266                                         conn->server_info->unix_name,
     1306                                        conn->session_info->unix_name,
    12671307                                        conn->connectpath,
    1268                                         conn->server_info->utok.gid,
    1269                                         conn->server_info->sanitized_username,
    1270                                         pdb_get_domain(conn->server_info->sam_account),
     1308                                        conn->session_info->utok.gid,
     1309                                        conn->session_info->sanitized_username,
     1310                                        conn->session_info->info3->base.domain.string,
    12711311                                        lp_postexec(SNUM(conn)));
    12721312                smbrun(cmd,NULL);
     
    12801320                char *cmd = talloc_sub_advanced(talloc_tos(),
    12811321                                        lp_servicename(SNUM(conn)),
    1282                                         conn->server_info->unix_name,
     1322                                        conn->session_info->unix_name,
    12831323                                        conn->connectpath,
    1284                                         conn->server_info->utok.gid,
    1285                                         conn->server_info->sanitized_username,
    1286                                         pdb_get_domain(conn->server_info->sam_account),
     1324                                        conn->session_info->utok.gid,
     1325                                        conn->session_info->sanitized_username,
     1326                                        conn->session_info->info3->base.domain.string,
    12871327                                        lp_rootpostexec(SNUM(conn)));
    12881328                smbrun(cmd,NULL);
Note: See TracChangeset for help on using the changeset viewer.