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

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/service.c

    r480 r745  
    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;
     
    189188
    190189        snum = SNUM(conn);
    191  
     190
    192191        if (do_chdir &&
    193192            vfs_ChDir(conn,conn->connectpath) != 0 &&
     
    204203        last_conn = conn;
    205204        last_flags = flags;
    206        
     205
    207206        /* Obey the client case sensitivity requests - only for clients that support it. */
    208207        switch (lp_casesensitive(snum)) {
     
    298297                return -1;
    299298        }
    300        
     299
    301300        return lp_servicenumber(service);
    302301
     
    309308 **/
    310309
    311 int find_service(fstring service)
     310int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
    312311{
    313312        int iService;
    314         struct smbd_server_connection *sconn = smbd_server_conn;
    315 
    316         all_string_sub(service,"\\","/",0);
    317 
    318         iService = lp_servicenumber(service);
     313
     314        if (!service_in) {
     315                return -1;
     316        }
     317
     318        /* First make a copy. */
     319        *p_service_out = talloc_strdup(ctx, service_in);
     320        if (!*p_service_out) {
     321                return -1;
     322        }
     323
     324        all_string_sub(*p_service_out,"\\","/",0);
     325
     326        iService = lp_servicenumber(*p_service_out);
    319327
    320328        /* now handle the special case of a home directory */
    321329        if (iService < 0) {
    322                 char *phome_dir = get_user_home_dir(talloc_tos(), service);
     330                char *phome_dir = get_user_home_dir(ctx, *p_service_out);
    323331
    324332                if(!phome_dir) {
     
    327335                         * be a Windows to unix mapped user name.
    328336                         */
    329                         if(map_username(sconn, service))
     337                        if(map_username(ctx, *p_service_out, p_service_out)) {
     338                                if (*p_service_out == NULL) {
     339                                        /* Out of memory. */
     340                                        return -1;
     341                                }
    330342                                phome_dir = get_user_home_dir(
    331                                         talloc_tos(), service);
    332                 }
    333 
    334                 DEBUG(3,("checking for home directory %s gave %s\n",service,
     343                                                ctx, *p_service_out);
     344                        }
     345                }
     346
     347                DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,
    335348                        phome_dir?phome_dir:"(NULL)"));
    336349
    337                 iService = add_home_service(service,service /* 'username' */, phome_dir);
     350                iService = add_home_service(*p_service_out,*p_service_out /* 'username' */, phome_dir);
    338351        }
    339352
     
    346359                }
    347360                if (iPrinterService >= 0) {
    348                         DEBUG(3,("checking whether %s is a valid printer name...\n", service));
    349                         if (pcap_printername_ok(service)) {
    350                                 DEBUG(3,("%s is a valid printer name\n", service));
    351                                 DEBUG(3,("adding %s as a printer service\n", service));
    352                                 lp_add_printer(service, iPrinterService);
    353                                 iService = lp_servicenumber(service);
     361                        DEBUG(3,("checking whether %s is a valid printer name...\n",
     362                                *p_service_out));
     363                        if (pcap_printername_ok(*p_service_out)) {
     364                                DEBUG(3,("%s is a valid printer name\n",
     365                                        *p_service_out));
     366                                DEBUG(3,("adding %s as a printer service\n",
     367                                        *p_service_out));
     368                                lp_add_printer(*p_service_out, iPrinterService);
     369                                iService = lp_servicenumber(*p_service_out);
    354370                                if (iService < 0) {
    355                                         DEBUG(0,("failed to add %s as a printer service!\n", service));
     371                                        DEBUG(0,("failed to add %s as a printer service!\n",
     372                                                *p_service_out));
    356373                                }
    357374                        } else {
    358                                 DEBUG(3,("%s is not a valid printer name\n", service));
     375                                DEBUG(3,("%s is not a valid printer name\n",
     376                                        *p_service_out));
    359377                        }
    360378                }
     
    366384
    367385        if (iService < 0) {
    368                 iService = load_registry_service(service);
     386                iService = load_registry_service(*p_service_out);
    369387        }
    370388
     
    372390        if (iService < 0 && *lp_usershare_path()) {
    373391                /* Ensure the name is canonicalized. */
    374                 strlower_m(service);
    375                 iService = load_usershare_service(service);
     392                strlower_m(*p_service_out);
     393                iService = load_usershare_service(*p_service_out);
    376394        }
    377395
     
    379397        if (iService < 0) {
    380398                char *pdefservice = lp_defaultservice();
    381                 if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
     399                if (pdefservice &&
     400                                *pdefservice &&
     401                                !strequal(pdefservice, *p_service_out)
     402                                && !strstr_m(*p_service_out,"..")) {
    382403                        /*
    383404                         * We need to do a local copy here as lp_defaultservice()
     
    386407                         * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
    387408                         */
    388                         char *defservice = SMB_STRDUP(pdefservice);
     409                        char *defservice = talloc_strdup(ctx, pdefservice);
    389410
    390411                        if (!defservice) {
     
    396417                                        strequal(defservice, PRINTERS_NAME) ||
    397418                                        strequal(defservice, "IPC$")) {
    398                                 SAFE_FREE(defservice);
     419                                TALLOC_FREE(defservice);
    399420                                goto fail;
    400421                        }
    401422
    402                         iService = find_service(defservice);
     423                        iService = find_service(ctx, defservice, p_service_out);
     424                        if (!*p_service_out) {
     425                                TALLOC_FREE(defservice);
     426                                iService = -1;
     427                                goto fail;
     428                        }
    403429                        if (iService >= 0) {
    404                                 all_string_sub(service, "_","/",0);
    405                                 iService = lp_add_service(service, iService);
     430                                all_string_sub(*p_service_out, "_","/",0);
     431                                iService = lp_add_service(*p_service_out, iService);
    406432                        }
    407                         SAFE_FREE(defservice);
     433                        TALLOC_FREE(defservice);
    408434                }
    409435        }
     
    411437        if (iService >= 0) {
    412438                if (!VALID_SNUM(iService)) {
    413                         DEBUG(0,("Invalid snum %d for %s\n",iService, service));
     439                        DEBUG(0,("Invalid snum %d for %s\n",iService,
     440                                *p_service_out));
    414441                        iService = -1;
    415442                }
     
    418445  fail:
    419446
    420         if (iService < 0)
    421                 DEBUG(3,("find_service() failed to find service %s\n", service));
     447        if (iService < 0) {
     448                DEBUG(3,("find_service() failed to find service %s\n",
     449                        *p_service_out));
     450        }
    422451
    423452        return (iService);
     
    430459****************************************************************************/
    431460
    432 static NTSTATUS share_sanity_checks(int snum, fstring dev)
     461static NTSTATUS share_sanity_checks(struct client_address *client_id, int snum,
     462                                    fstring dev)
    433463{
    434        
    435464        if (!lp_snum_ok(snum) ||
    436             !check_access(smbd_server_fd(),
    437                           lp_hostsallow(snum), lp_hostsdeny(snum))) {   
     465            !allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
     466                          client_id->name, client_id->addr)) {
    438467                return NT_STATUS_ACCESS_DENIED;
    439468        }
     
    480509static NTSTATUS find_forced_group(bool force_user,
    481510                                  int snum, const char *username,
    482                                   DOM_SID *pgroup_sid,
     511                                  struct dom_sid *pgroup_sid,
    483512                                  gid_t *pgid)
    484513{
    485514        NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
    486515        TALLOC_CTX *frame = talloc_stackframe();
    487         DOM_SID group_sid;
     516        struct dom_sid group_sid;
    488517        enum lsa_SidType type;
    489518        char *groupname;
     
    568597****************************************************************************/
    569598
    570 static NTSTATUS create_connection_server_info(struct smbd_server_connection *sconn,
     599static NTSTATUS create_connection_session_info(struct smbd_server_connection *sconn,
    571600                                              TALLOC_CTX *mem_ctx, int snum,
    572601                                              struct auth_serversupplied_info *vuid_serverinfo,
     
    595624                } else {
    596625                        if (!user_ok_token(vuid_serverinfo->unix_name,
    597                                            pdb_get_domain(vuid_serverinfo->sam_account),
    598                                            vuid_serverinfo->ptok, snum)) {
     626                                           vuid_serverinfo->info3->base.domain.string,
     627                                           vuid_serverinfo->security_token, snum)) {
    599628                                DEBUG(2, ("user '%s' (from session setup) not "
    600629                                          "permitted to access this share "
     
    641670}
    642671
     672/****************************************************************************
     673  set relavent user and group settings corresponding to force user/group
     674  configuration for the given snum.
     675****************************************************************************/
     676
     677NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
     678{
     679        NTSTATUS status;
     680
     681        if (*lp_force_user(snum)) {
     682
     683                /*
     684                 * Replace conn->session_info with a completely faked up one
     685                 * from the username we are forced into :-)
     686                 */
     687
     688                char *fuser;
     689                struct auth_serversupplied_info *forced_serverinfo;
     690
     691                fuser = talloc_string_sub(conn, lp_force_user(snum), "%S",
     692                                          lp_const_servicename(snum));
     693                if (fuser == NULL) {
     694                        return NT_STATUS_NO_MEMORY;
     695                }
     696
     697                status = make_serverinfo_from_username(
     698                        conn, fuser, conn->session_info->guest,
     699                        &forced_serverinfo);
     700                if (!NT_STATUS_IS_OK(status)) {
     701                        return status;
     702                }
     703
     704                TALLOC_FREE(conn->session_info);
     705                conn->session_info = forced_serverinfo;
     706
     707                conn->force_user = true;
     708                DEBUG(3,("Forced user %s\n", fuser));
     709        }
     710
     711        /*
     712         * If force group is true, then override
     713         * any groupid stored for the connecting user.
     714         */
     715
     716        if (*lp_force_group(snum)) {
     717
     718                status = find_forced_group(
     719                        conn->force_user, snum, conn->session_info->unix_name,
     720                        &conn->session_info->security_token->sids[1],
     721                        &conn->session_info->utok.gid);
     722
     723                if (!NT_STATUS_IS_OK(status)) {
     724                        return status;
     725                }
     726
     727                /*
     728                 * We need to cache this gid, to use within
     729                 * change_to_user() separately from the conn->session_info
     730                 * struct. We only use conn->session_info directly if
     731                 * "force_user" was set.
     732                 */
     733                conn->force_group_gid = conn->session_info->utok.gid;
     734        }
     735
     736        return NT_STATUS_OK;
     737}
    643738
    644739/****************************************************************************
     
    653748                                        NTSTATUS *pstatus)
    654749{
    655         connection_struct *conn;
     750        connection_struct *conn = NULL;
    656751        struct smb_filename *smb_fname_cpath = NULL;
    657752        fstring dev;
    658753        int ret;
    659         char addr[INET6_ADDRSTRLEN];
     754        bool on_err_call_dis_hook = false;
     755        bool claimed_connection = false;
     756        uid_t effuid;
     757        gid_t effgid;
    660758        NTSTATUS status;
    661759
    662760        fstrcpy(dev, pdev);
    663761
    664         if (NT_STATUS_IS_ERR(*pstatus = share_sanity_checks(snum, dev))) {
    665                 return NULL;
    666         }       
     762        *pstatus = share_sanity_checks(&sconn->client_id, snum, dev);
     763        if (NT_STATUS_IS_ERR(*pstatus)) {
     764                goto err_root_exit;
     765        }
    667766
    668767        conn = conn_new(sconn);
     
    670769                DEBUG(0,("Couldn't find free connection.\n"));
    671770                *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
    672                 return NULL;
     771                goto err_root_exit;
    673772        }
    674773
    675774        conn->params->service = snum;
    676775
    677         status = create_connection_server_info(sconn,
    678                 conn, snum, vuser ? vuser->server_info : NULL, password,
    679                 &conn->server_info);
     776        status = create_connection_session_info(sconn,
     777                conn, snum, vuser ? vuser->session_info : NULL, password,
     778                &conn->session_info);
    680779
    681780        if (!NT_STATUS_IS_OK(status)) {
    682                 DEBUG(1, ("create_connection_server_info failed: %s\n",
     781                DEBUG(1, ("create_connection_session_info failed: %s\n",
    683782                          nt_errstr(status)));
    684783                *pstatus = status;
    685                 conn_free(conn);
    686                 return NULL;
     784                goto err_root_exit;
    687785        }
    688786
     
    691789        }
    692790
    693         add_session_user(sconn, conn->server_info->unix_name);
    694 
    695         safe_strcpy(conn->client_address,
    696                         client_addr(get_client_fd(),addr,sizeof(addr)),
    697                         sizeof(conn->client_address)-1);
     791        add_session_user(sconn, conn->session_info->unix_name);
     792
    698793        conn->num_files_open = 0;
    699794        conn->lastused = conn->lastused_count = time(NULL);
     
    723818
    724819        conn->read_only = lp_readonly(SNUM(conn));
    725         conn->admin_user = False;
    726 
    727         if (*lp_force_user(snum)) {
    728 
    729                 /*
    730                  * Replace conn->server_info with a completely faked up one
    731                  * from the username we are forced into :-)
    732                  */
    733 
    734                 char *fuser;
    735                 struct auth_serversupplied_info *forced_serverinfo;
    736 
    737                 fuser = talloc_string_sub(conn, lp_force_user(snum), "%S",
    738                                           lp_servicename(snum));
    739                 if (fuser == NULL) {
    740                         conn_free(conn);
    741                         *pstatus = NT_STATUS_NO_MEMORY;
    742                         return NULL;
    743                 }
    744 
    745                 status = make_serverinfo_from_username(
    746                         conn, fuser, conn->server_info->guest,
    747                         &forced_serverinfo);
    748                 if (!NT_STATUS_IS_OK(status)) {
    749                         conn_free(conn);
    750                         *pstatus = status;
    751                         return NULL;
    752                 }
    753 
    754                 TALLOC_FREE(conn->server_info);
    755                 conn->server_info = forced_serverinfo;
    756 
    757                 conn->force_user = True;
    758                 DEBUG(3,("Forced user %s\n", fuser));
    759         }
    760 
    761         /*
    762          * If force group is true, then override
    763          * any groupid stored for the connecting user.
    764          */
    765 
    766         if (*lp_force_group(snum)) {
    767 
    768                 status = find_forced_group(
    769                         conn->force_user, snum, conn->server_info->unix_name,
    770                         &conn->server_info->ptok->user_sids[1],
    771                         &conn->server_info->utok.gid);
    772 
    773                 if (!NT_STATUS_IS_OK(status)) {
    774                         conn_free(conn);
    775                         *pstatus = status;
    776                         return NULL;
    777                 }
    778 
    779                 /*
    780                  * We need to cache this gid, to use within
    781                  * change_to_user() separately from the conn->server_info
    782                  * struct. We only use conn->server_info directly if
    783                  * "force_user" was set.
    784                  */
    785                 conn->force_group_gid = conn->server_info->utok.gid;
     820
     821        status = set_conn_force_user_group(conn, snum);
     822        if (!NT_STATUS_IS_OK(status)) {
     823                conn_free(conn);
     824                *pstatus = status;
     825                return NULL;
    786826        }
    787827
     
    791831                char *s = talloc_sub_advanced(talloc_tos(),
    792832                                        lp_servicename(SNUM(conn)),
    793                                         conn->server_info->unix_name,
     833                                        conn->session_info->unix_name,
    794834                                        conn->connectpath,
    795                                         conn->server_info->utok.gid,
    796                                         conn->server_info->sanitized_username,
    797                                         pdb_get_domain(conn->server_info->sam_account),
     835                                        conn->session_info->utok.gid,
     836                                        conn->session_info->sanitized_username,
     837                                        conn->session_info->info3->base.domain.string,
    798838                                        lp_pathname(snum));
    799839                if (!s) {
    800                         conn_free(conn);
    801840                        *pstatus = NT_STATUS_NO_MEMORY;
    802                         return NULL;
     841                        goto err_root_exit;
    803842                }
    804843
    805844                if (!set_conn_connectpath(conn,s)) {
    806845                        TALLOC_FREE(s);
    807                         conn_free(conn);
    808846                        *pstatus = NT_STATUS_NO_MEMORY;
    809                         return NULL;
     847                        goto err_root_exit;
    810848                }
    811849                DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
     
    821859         */
    822860
    823         {
    824                 bool can_write = False;
    825 
    826                 can_write = share_access_check(conn->server_info->ptok,
    827                                                lp_servicename(snum),
    828                                                FILE_WRITE_DATA);
    829 
    830                 if (!can_write) {
    831                         if (!share_access_check(conn->server_info->ptok,
    832                                                 lp_servicename(snum),
    833                                                 FILE_READ_DATA)) {
    834                                 /* No access, read or write. */
    835                                 DEBUG(0,("make_connection: connection to %s "
    836                                          "denied due to security "
    837                                          "descriptor.\n",
    838                                           lp_servicename(snum)));
    839                                 conn_free(conn);
    840                                 *pstatus = NT_STATUS_ACCESS_DENIED;
    841                                 return NULL;
    842                         } else {
    843                                 conn->read_only = True;
    844                         }
     861        share_access_check(conn->session_info->security_token,
     862                           lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS,
     863                           &conn->share_access);
     864
     865        if ((conn->share_access & FILE_WRITE_DATA) == 0) {
     866                if ((conn->share_access & FILE_READ_DATA) == 0) {
     867                        /* No access, read or write. */
     868                        DEBUG(0,("make_connection: connection to %s "
     869                                 "denied due to security "
     870                                 "descriptor.\n",
     871                                 lp_servicename(snum)));
     872                        *pstatus = NT_STATUS_ACCESS_DENIED;
     873                        goto err_root_exit;
     874                } else {
     875                        conn->read_only = True;
    845876                }
    846877        }
     
    850881                DEBUG(0, ("vfs_init failed for service %s\n",
    851882                          lp_servicename(snum)));
    852                 conn_free(conn);
    853883                *pstatus = NT_STATUS_BAD_NETWORK_NAME;
    854                 return NULL;
    855         }
    856 
    857         if ((!conn->printer) && (!conn->ipc)) {
    858                 conn->notify_ctx = notify_init(conn, server_id_self(),
    859                                                smbd_messaging_context(),
    860                                                smbd_event_context(),
    861                                                conn);
     884                goto err_root_exit;
    862885        }
    863886
     
    877900                DEBUG(1, ("Max connections (%d) exceeded for %s\n",
    878901                          lp_max_connections(snum), lp_servicename(snum)));
    879                 conn_free(conn);
    880902                *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
    881                 return NULL;
    882         } 
     903                goto err_root_exit;
     904        }
    883905
    884906        /*
    885907         * Get us an entry in the connections db
    886908         */
    887         if (!claim_connection(conn, lp_servicename(snum), 0)) {
     909        if (!claim_connection(conn, lp_servicename(snum))) {
    888910                DEBUG(1, ("Could not store connections entry\n"));
    889                 conn_free(conn);
    890911                *pstatus = NT_STATUS_INTERNAL_DB_ERROR;
    891                 return NULL;
    892         } 
    893 
    894         /* Invoke VFS make connection hook - must be the first
    895            VFS operation we do. */
     912                goto err_root_exit;
     913        }
     914        claimed_connection = true;
     915
     916        /* Invoke VFS make connection hook - this must be the first
     917           filesystem operation that we do. */
    896918
    897919        if (SMB_VFS_CONNECT(conn, lp_servicename(snum),
    898                             conn->server_info->unix_name) < 0) {
     920                            conn->session_info->unix_name) < 0) {
    899921                DEBUG(0,("make_connection: VFS make connection failed!\n"));
    900                 yield_connection(conn, lp_servicename(snum));
    901                 conn_free(conn);
    902922                *pstatus = NT_STATUS_UNSUCCESSFUL;
    903                 return NULL;
     923                goto err_root_exit;
     924        }
     925
     926        /* Any error exit after here needs to call the disconnect hook. */
     927        on_err_call_dis_hook = true;
     928
     929        if ((!conn->printer) && (!conn->ipc)) {
     930                conn->notify_ctx = notify_init(conn,
     931                                               sconn_server_id(sconn),
     932                                               sconn->msg_ctx,
     933                                               smbd_event_context(),
     934                                               conn);
    904935        }
    905936
     
    922953                char *cmd = talloc_sub_advanced(talloc_tos(),
    923954                                        lp_servicename(SNUM(conn)),
    924                                         conn->server_info->unix_name,
     955                                        conn->session_info->unix_name,
    925956                                        conn->connectpath,
    926                                         conn->server_info->utok.gid,
    927                                         conn->server_info->sanitized_username,
    928                                         pdb_get_domain(conn->server_info->sam_account),
     957                                        conn->session_info->utok.gid,
     958                                        conn->session_info->sanitized_username,
     959                                        conn->session_info->info3->base.domain.string,
    929960                                        lp_rootpreexec(snum));
    930961                DEBUG(5,("cmd=%s\n",cmd));
     
    934965                        DEBUG(1,("root preexec gave %d - failing "
    935966                                 "connection\n", ret));
    936                         SMB_VFS_DISCONNECT(conn);
    937                         yield_connection(conn, lp_servicename(snum));
    938                         conn_free(conn);
    939967                        *pstatus = NT_STATUS_ACCESS_DENIED;
    940                         return NULL;
     968                        goto err_root_exit;
    941969                }
    942970        }
     
    946974                /* No point continuing if they fail the basic checks */
    947975                DEBUG(0,("Can't become connected user!\n"));
    948                 SMB_VFS_DISCONNECT(conn);
    949                 yield_connection(conn, lp_servicename(snum));
    950                 conn_free(conn);
    951976                *pstatus = NT_STATUS_LOGON_FAILURE;
    952                 return NULL;
    953         }
     977                goto err_root_exit;
     978        }
     979
     980        effuid = geteuid();
     981        effgid = getegid();
    954982
    955983        /* Remember that a different vuid can connect later without these
    956984         * checks... */
    957        
     985
    958986        /* Preexecs are done here as they might make the dir we are to ChDir
    959987         * to below */
     
    963991                char *cmd = talloc_sub_advanced(talloc_tos(),
    964992                                        lp_servicename(SNUM(conn)),
    965                                         conn->server_info->unix_name,
     993                                        conn->session_info->unix_name,
    966994                                        conn->connectpath,
    967                                         conn->server_info->utok.gid,
    968                                         conn->server_info->sanitized_username,
    969                                         pdb_get_domain(conn->server_info->sam_account),
     995                                        conn->session_info->utok.gid,
     996                                        conn->session_info->sanitized_username,
     997                                        conn->session_info->info3->base.domain.string,
    970998                                        lp_preexec(snum));
    971999                ret = smbrun(cmd,NULL);
     
    9781006                }
    9791007        }
     1008
     1009#ifdef WITH_FAKE_KASERVER
     1010        if (lp_afs_share(snum)) {
     1011                afs_login(conn);
     1012        }
     1013#endif
     1014
     1015        /*
     1016         * we've finished with the user stuff - go back to root
     1017         * so the SMB_VFS_STAT call will only fail on path errors,
     1018         * not permission problems.
     1019         */
     1020        change_to_root_user();
     1021/* ROOT Activites: */
    9801022
    9811023        /*
     
    9971039        }
    9981040
    999 #ifdef WITH_FAKE_KASERVER
    1000         if (lp_afs_share(snum)) {
    1001                 afs_login(conn);
    1002         }
    1003 #endif
    1004        
    10051041        /* Add veto/hide lists */
    10061042        if (!IS_IPC(conn) && !IS_PRINT(conn)) {
     
    10111047                                lp_aio_write_behind(snum));
    10121048        }
    1013        
    10141049        status = create_synthetic_smb_fname(talloc_tos(), conn->connectpath,
    10151050                                            NULL, NULL, &smb_fname_cpath);
     
    10241059           I have disabled this chdir check (tridge) */
    10251060        /* the alternative is just to check the directory exists */
     1061
    10261062        if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
    10271063            !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
     
    10431079        string_set(&conn->origpath,conn->connectpath);
    10441080
    1045 #if SOFTLINK_OPTIMISATION
    1046         /* resolve any soft links early if possible */
    1047         if (vfs_ChDir(conn,conn->connectpath) == 0) {
    1048                 TALLOC_CTX *ctx = talloc_tos();
    1049                 char *s = vfs_GetWd(ctx,s);
    1050                 if (!s) {
    1051                         *status = map_nt_error_from_unix(errno);
    1052                         goto err_root_exit;
    1053                 }
    1054                 if (!set_conn_connectpath(conn,s)) {
    1055                         *status = NT_STATUS_NO_MEMORY;
    1056                         goto err_root_exit;
    1057                 }
    1058                 vfs_ChDir(conn,conn->connectpath);
    1059         }
    1060 #endif
    1061 
    10621081        /* Figure out the characteristics of the underlying filesystem. This
    10631082         * assumes that all the filesystem mounted withing a share path have
     
    10751094        if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
    10761095                dbgtext( "%s (%s) ", get_remote_machine_name(),
    1077                          conn->client_address );
    1078                 dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : "");
     1096                         conn->sconn->client_id.addr );
     1097                dbgtext( "%s", srv_is_signing_active(sconn) ? "signed " : "");
    10791098                dbgtext( "connect to service %s ", lp_servicename(snum) );
    10801099                dbgtext( "initially as user %s ",
    1081                          conn->server_info->unix_name );
    1082                 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
     1100                         conn->session_info->unix_name );
     1101                dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid );
    10831102                dbgtext( "(pid %d)\n", (int)sys_getpid() );
    10841103        }
    10851104
    1086         /* we've finished with the user stuff - go back to root */
    1087         change_to_root_user();
    10881105        return(conn);
    10891106
    10901107  err_root_exit:
    10911108        TALLOC_FREE(smb_fname_cpath);
    1092         change_to_root_user();
    1093         /* Call VFS disconnect hook */
    1094         SMB_VFS_DISCONNECT(conn);
    1095         yield_connection(conn, lp_servicename(snum));
    1096         conn_free(conn);
     1109        /* We must exit this function as root. */
     1110        if (geteuid() != 0) {
     1111                change_to_root_user();
     1112        }
     1113        if (on_err_call_dis_hook) {
     1114                /* Call VFS disconnect hook */
     1115                SMB_VFS_DISCONNECT(conn);
     1116        }
     1117        if (claimed_connection) {
     1118                yield_connection(conn, lp_servicename(snum));
     1119        }
     1120        if (conn) {
     1121                conn_free(conn);
     1122        }
    10971123        return NULL;
    10981124}
     
    11111137        uid_t euid;
    11121138        user_struct *vuser = NULL;
    1113         fstring service;
     1139        char *service = NULL;
    11141140        fstring dev;
    11151141        int snum = -1;
    1116         char addr[INET6_ADDRSTRLEN];
    11171142
    11181143        fstrcpy(dev, pdev);
     
    11711196                         * current_user_info.smb_name as the username.  */
    11721197                        if (*current_user_info.smb_name) {
    1173                                 fstring unix_username;
    1174                                 fstrcpy(unix_username,
    1175                                         current_user_info.smb_name);
    1176                                 map_username(sconn, unix_username);
    1177                                 snum = find_service(unix_username);
    1178                         }
     1198                                char *unix_username = NULL;
     1199                                (void)map_username(talloc_tos(),
     1200                                                current_user_info.smb_name,
     1201                                                &unix_username);
     1202                                snum = find_service(talloc_tos(),
     1203                                                unix_username,
     1204                                                &unix_username);
     1205                                if (!unix_username) {
     1206                                        *status = NT_STATUS_NO_MEMORY;
     1207                                }
     1208                                return NULL;
     1209                        }
    11791210                        if (snum != -1) {
    11801211                                DEBUG(5, ("making a connection to 'homes' "
     
    11981229                                            dev, status);
    11991230        }
    1200        
    1201         fstrcpy(service, service_in);
     1231
     1232        service = talloc_strdup(talloc_tos(), service_in);
     1233        if (!service) {
     1234                *status = NT_STATUS_NO_MEMORY;
     1235                return NULL;
     1236        }
    12021237
    12031238        strlower_m(service);
    12041239
    1205         snum = find_service(service);
     1240        snum = find_service(talloc_tos(), service, &service);
     1241        if (!service) {
     1242                *status = NT_STATUS_NO_MEMORY;
     1243                return NULL;
     1244        }
    12061245
    12071246        if (snum < 0) {
     
    12151254                DEBUG(3,("%s (%s) couldn't find service %s\n",
    12161255                        get_remote_machine_name(),
    1217                         client_addr(get_client_fd(),addr,sizeof(addr)),
     1256                        tsocket_address_string(
     1257                                sconn->remote_address, talloc_tos()),
    12181258                        service));
    12191259                *status = NT_STATUS_BAD_NETWORK_NAME;
     
    12531293        DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
    12541294                                 get_remote_machine_name(),
    1255                                  conn->client_address,
     1295                                 conn->sconn->client_id.addr,
    12561296                                 lp_servicename(SNUM(conn))));
    12571297
     
    12691309                char *cmd = talloc_sub_advanced(talloc_tos(),
    12701310                                        lp_servicename(SNUM(conn)),
    1271                                         conn->server_info->unix_name,
     1311                                        conn->session_info->unix_name,
    12721312                                        conn->connectpath,
    1273                                         conn->server_info->utok.gid,
    1274                                         conn->server_info->sanitized_username,
    1275                                         pdb_get_domain(conn->server_info->sam_account),
     1313                                        conn->session_info->utok.gid,
     1314                                        conn->session_info->sanitized_username,
     1315                                        conn->session_info->info3->base.domain.string,
    12761316                                        lp_postexec(SNUM(conn)));
    12771317                smbrun(cmd,NULL);
     
    12851325                char *cmd = talloc_sub_advanced(talloc_tos(),
    12861326                                        lp_servicename(SNUM(conn)),
    1287                                         conn->server_info->unix_name,
     1327                                        conn->session_info->unix_name,
    12881328                                        conn->connectpath,
    1289                                         conn->server_info->utok.gid,
    1290                                         conn->server_info->sanitized_username,
    1291                                         pdb_get_domain(conn->server_info->sam_account),
     1329                                        conn->session_info->utok.gid,
     1330                                        conn->session_info->sanitized_username,
     1331                                        conn->session_info->info3->base.domain.string,
    12921332                                        lp_rootpostexec(SNUM(conn)));
    12931333                smbrun(cmd,NULL);
Note: See TracChangeset for help on using the changeset viewer.