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

File:
1 edited

Legend:

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

    r740 r988  
    3030#include "smbd/smbd.h"
    3131#include "smbd/globals.h"
    32 #include "dbwrap.h"
     32#include "dbwrap/dbwrap.h"
    3333#include "session.h"
    3434#include "auth.h"
     35#include "../lib/tsocket/tsocket.h"
     36#include "../libcli/security/security.h"
     37#include "messages.h"
    3538
    3639/********************************************************************
     
    3841********************************************************************/
    3942
    40 bool session_claim(struct smbd_server_connection *sconn, user_struct *vuser)
    41 {
    42         struct server_id pid = sconn_server_id(sconn);
    43         TDB_DATA data;
    44         int i = 0;
    45         struct sessionid sessionid;
    46         fstring keystr;
    47         struct db_record *rec;
    48         NTSTATUS status;
    49 
    50         vuser->session_keystr = NULL;
     43bool session_claim(struct smbXsrv_session *session)
     44{
     45        struct auth_session_info *session_info =
     46                session->global->auth_session_info;
     47        const char *username;
     48        const char *hostname;
     49        unsigned int id_num;
     50        fstring id_str;
    5151
    5252        /* don't register sessions for the guest user - its just too
    5353           expensive to go through pam session code for browsing etc */
    54         if (vuser->session_info->guest) {
    55                 return True;
    56         }
    57 
    58         if (!sessionid_init()) {
    59                 return False;
    60         }
    61 
    62         ZERO_STRUCT(sessionid);
    63 
    64         data.dptr = NULL;
    65         data.dsize = 0;
     54        if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
     55                return true;
     56        }
     57
     58        id_num = session->global->session_global_id;
     59
     60        snprintf(id_str, sizeof(id_str), "smb/%u", id_num);
     61
     62        /* Make clear that we require the optional unix_token in the source3 code */
     63        SMB_ASSERT(session_info->unix_token);
     64
     65        username = session_info->unix_info->unix_name;
     66        hostname = session->global->channels[0].remote_name;
     67
     68        if (!smb_pam_claim_session(username, id_str, hostname)) {
     69                DEBUG(1,("pam_session rejected the session for %s [%s]\n",
     70                                username, id_str));
     71                return false;
     72        }
    6673
    6774        if (lp_utmp()) {
    68 
    69                 for (i=1;i<MAX_SESSION_ID;i++) {
    70 
    71                         /*
    72                          * This is very inefficient and needs fixing -- vl
    73                          */
    74 
    75                         struct server_id sess_pid;
    76 
    77                         snprintf(keystr, sizeof(keystr), "ID/%d", i);
    78 
    79                         rec = sessionid_fetch_record(NULL, keystr);
    80                         if (rec == NULL) {
    81                                 DEBUG(1, ("Could not lock \"%s\"\n", keystr));
    82                                 return False;
    83                         }
    84 
    85                         if (rec->value.dsize != sizeof(sessionid)) {
    86                                 DEBUG(1, ("Re-using invalid record\n"));
    87                                 break;
    88                         }
    89 
    90                         memcpy(&sess_pid,
    91                                ((char *)rec->value.dptr)
    92                                + offsetof(struct sessionid, pid),
    93                                sizeof(sess_pid));
    94 
    95                         if (!process_exists(sess_pid)) {
    96                                 DEBUG(5, ("%s has died -- re-using session\n",
    97                                           procid_str_static(&sess_pid)));
    98                                 break;
    99                         }
    100 
    101                         TALLOC_FREE(rec);
    102                 }
    103 
    104                 if (i == MAX_SESSION_ID) {
    105                         SMB_ASSERT(rec == NULL);
    106                         DEBUG(1,("session_claim: out of session IDs "
    107                                  "(max is %d)\n", MAX_SESSION_ID));
    108                         return False;
    109                 }
    110 
    111                 snprintf(sessionid.id_str, sizeof(sessionid.id_str),
    112                          SESSION_UTMP_TEMPLATE, i);
    113         } else
    114         {
    115                 snprintf(keystr, sizeof(keystr), "ID/%s/%u",
    116                          procid_str_static(&pid), vuser->vuid);
    117 
    118                 rec = sessionid_fetch_record(NULL, keystr);
    119                 if (rec == NULL) {
    120                         DEBUG(1, ("Could not lock \"%s\"\n", keystr));
    121                         return False;
    122                 }
    123 
    124                 snprintf(sessionid.id_str, sizeof(sessionid.id_str),
    125                          SESSION_TEMPLATE, (long unsigned int)sys_getpid(),
    126                          vuser->vuid);
    127         }
    128 
    129         SMB_ASSERT(rec != NULL);
    130 
    131         /* If 'hostname lookup' == yes, then do the DNS lookup.  This is
    132            needed because utmp and PAM both expect DNS names
    133 
    134            client_name() handles this case internally.
    135         */
    136 
    137         fstrcpy(sessionid.username, vuser->session_info->unix_name);
    138         fstrcpy(sessionid.hostname, sconn->client_id.name);
    139         sessionid.id_num = i;  /* Only valid for utmp sessions */
    140         sessionid.pid = pid;
    141         sessionid.uid = vuser->session_info->utok.uid;
    142         sessionid.gid = vuser->session_info->utok.gid;
    143         fstrcpy(sessionid.remote_machine, get_remote_machine_name());
    144         fstrcpy(sessionid.ip_addr_str, sconn->client_id.addr);
    145         sessionid.connect_start = time(NULL);
    146 
    147         if (!smb_pam_claim_session(sessionid.username, sessionid.id_str,
    148                                    sessionid.hostname)) {
    149                 DEBUG(1,("pam_session rejected the session for %s [%s]\n",
    150                                 sessionid.username, sessionid.id_str));
    151 
    152                 TALLOC_FREE(rec);
    153                 return False;
    154         }
    155 
    156         data.dptr = (uint8 *)&sessionid;
    157         data.dsize = sizeof(sessionid);
    158 
    159         status = rec->store(rec, data, TDB_REPLACE);
    160 
    161         TALLOC_FREE(rec);
    162 
    163         if (!NT_STATUS_IS_OK(status)) {
    164                 DEBUG(1,("session_claim: unable to create session id "
    165                          "record: %s\n", nt_errstr(status)));
    166                 return False;
    167         }
     75                sys_utmp_claim(username, hostname, id_str, id_num);
     76        }
     77
     78        return true;
     79}
     80
     81/********************************************************************
     82 called when a session is destroyed
     83********************************************************************/
     84
     85void session_yield(struct smbXsrv_session *session)
     86{
     87        struct auth_session_info *session_info =
     88                session->global->auth_session_info;
     89        const char *username;
     90        const char *hostname;
     91        unsigned int id_num;
     92        fstring id_str = "";
     93
     94        id_num = session->global->session_global_id;
     95
     96        snprintf(id_str, sizeof(id_str), "smb/%u", id_num);
     97
     98        /* Make clear that we require the optional unix_token in the source3 code */
     99        SMB_ASSERT(session_info->unix_token);
     100
     101        username = session_info->unix_info->unix_name;
     102        hostname = session->global->channels[0].remote_name;
    168103
    169104        if (lp_utmp()) {
    170                 sys_utmp_claim(sessionid.username, sessionid.hostname,
    171                                sessionid.ip_addr_str,
    172                                sessionid.id_str, sessionid.id_num);
    173         }
    174 
    175         vuser->session_keystr = talloc_strdup(vuser, keystr);
    176         if (!vuser->session_keystr) {
    177                 DEBUG(0, ("session_claim:  talloc_strdup() failed for session_keystr\n"));
    178                 return False;
    179         }
    180         return True;
    181 }
    182 
    183 /********************************************************************
    184  called when a session is destroyed
    185 ********************************************************************/
    186 
    187 void session_yield(user_struct *vuser)
    188 {
    189         struct sessionid sessionid;
    190         struct db_record *rec;
    191 
    192         if (!vuser->session_keystr) {
    193                 return;
    194         }
    195 
    196         rec = sessionid_fetch_record(NULL, vuser->session_keystr);
    197         if (rec == NULL) {
    198                 return;
    199         }
    200 
    201         if (rec->value.dsize != sizeof(sessionid))
    202                 return;
    203 
    204         memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
    205 
    206         if (lp_utmp()) {
    207                 sys_utmp_yield(sessionid.username, sessionid.hostname,
    208                                sessionid.ip_addr_str,
    209                                sessionid.id_str, sessionid.id_num);
    210         }
    211 
    212         smb_pam_close_session(sessionid.username, sessionid.id_str,
    213                               sessionid.hostname);
    214 
    215         rec->delete_rec(rec);
    216 
    217         TALLOC_FREE(rec);
     105                sys_utmp_yield(username, hostname, id_str, id_num);
     106        }
     107
     108        smb_pam_close_session(username, id_str, hostname);
    218109}
    219110
     
    224115        TALLOC_CTX *mem_ctx;
    225116        int count;
     117        const char *filter_user;
     118        const char *filter_machine;
    226119        struct sessionid *sessions;
    227120};
     
    232125        struct session_list *sesslist = (struct session_list *)private_data;
    233126
    234         sesslist->sessions = TALLOC_REALLOC_ARRAY(
     127        /* filter the session if required */
     128
     129        if (sesslist->filter_user &&
     130            (sesslist->filter_user[0] != '\0') &&
     131            !strequal(session->username, sesslist->filter_user)) {
     132                return 0;
     133        }
     134
     135        if (sesslist->filter_machine &&
     136            (sesslist->filter_machine[0] != '\0') &&
     137            !strequal(session->remote_machine,
     138                      sesslist->filter_machine)) {
     139                return 0;
     140        }
     141
     142        sesslist->sessions = talloc_realloc(
    235143                sesslist->mem_ctx, sesslist->sessions, struct sessionid,
    236144                sesslist->count+1);
     
    258166{
    259167        struct session_list sesslist;
    260         int ret;
     168        NTSTATUS status;
    261169
    262170        sesslist.mem_ctx = mem_ctx;
    263171        sesslist.count = 0;
     172        sesslist.filter_user = NULL;
     173        sesslist.filter_machine = NULL;
    264174        sesslist.sessions = NULL;
    265175
    266         ret = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
    267         if (ret == -1) {
     176        status = sessionid_traverse_read(gather_sessioninfo, (void *) &sesslist);
     177        if (!NT_STATUS_IS_OK(status)) {
    268178                DEBUG(3, ("Session traverse failed\n"));
    269179                SAFE_FREE(sesslist.sessions);
     
    275185        return sesslist.count;
    276186}
     187
     188/********************************************************************
     189find the sessions that match the given username and machine
     190********************************************************************/
     191
     192int find_sessions(TALLOC_CTX *mem_ctx, const char *username,
     193                  const char *machine, struct sessionid **session_list)
     194{
     195        struct session_list sesslist;
     196        NTSTATUS status;
     197
     198        sesslist.mem_ctx = mem_ctx;
     199        sesslist.count = 0;
     200        sesslist.filter_user = username;
     201        sesslist.filter_machine = machine;
     202        sesslist.sessions = NULL;
     203
     204        status = sessionid_traverse_read(gather_sessioninfo, (void *)&sesslist);
     205        if (!NT_STATUS_IS_OK(status)) {
     206                DEBUG(3, ("Session traverse failed: %s\n", nt_errstr(status)));
     207                TALLOC_FREE(sesslist.sessions);
     208                *session_list = NULL;
     209                return 0;
     210        }
     211
     212        *session_list = sesslist.sessions;
     213        return sesslist.count;
     214}
Note: See TracChangeset for help on using the changeset viewer.