root/source4/libcli/raw/clisession.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbcli_session_init
  2. smb_raw_sesssetup_send
  3. smb_raw_sesssetup_recv
  4. smb_raw_sesssetup
  5. smb_raw_ulogoff_send
  6. smb_raw_ulogoff
  7. smb_raw_exit_send
  8. smb_raw_exit

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    SMB client session context management functions
   4 
   5    Copyright (C) Andrew Tridgell 1994-2005
   6    Copyright (C) James Myers 2003 <myersjj@samba.org>
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "libcli/raw/libcliraw.h"
  24 #include "libcli/raw/raw_proto.h"
  25 #include "system/filesys.h"
  26 
  27 #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
  28         req = smbcli_request_setup_session(session, cmd, wct, buflen); \
  29         if (!req) return NULL; \
  30 } while (0)
  31 
  32 
  33 /****************************************************************************
  34  Initialize the session context
  35 ****************************************************************************/
  36 struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, 
     /* [<][>][^][v][top][bottom][index][help] */
  37                                            TALLOC_CTX *parent_ctx, bool primary,
  38                                            struct smbcli_session_options options)
  39 {
  40         struct smbcli_session *session;
  41         uint16_t flags2;
  42         uint32_t capabilities;
  43 
  44         session = talloc_zero(parent_ctx, struct smbcli_session);
  45         if (!session) {
  46                 return NULL;
  47         }
  48 
  49         if (primary) {
  50                 session->transport = talloc_steal(session, transport);
  51         } else {
  52                 session->transport = talloc_reference(session, transport);
  53         }
  54         session->pid = (uint16_t)getpid();
  55         session->vuid = UID_FIELD_INVALID;
  56         session->options = options;
  57         
  58         capabilities = transport->negotiate.capabilities;
  59 
  60         flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
  61 
  62         if (capabilities & CAP_UNICODE) {
  63                 flags2 |= FLAGS2_UNICODE_STRINGS;
  64         }
  65         if (capabilities & CAP_STATUS32) {
  66                 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
  67         }
  68         if (capabilities & CAP_EXTENDED_SECURITY) {
  69                 flags2 |= FLAGS2_EXTENDED_SECURITY;
  70         }
  71         if (session->transport->negotiate.sign_info.doing_signing) {
  72                 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
  73         }
  74 
  75         session->flags2 = flags2;
  76 
  77         return session;
  78 }
  79 
  80 /****************************************************************************
  81  Perform a session setup (async send)
  82 ****************************************************************************/
  83 struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session, 
     /* [<][>][^][v][top][bottom][index][help] */
  84                                               union smb_sesssetup *parms) 
  85 {
  86         struct smbcli_request *req = NULL;
  87 
  88         switch (parms->old.level) {
  89         case RAW_SESSSETUP_OLD:
  90                 SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0);
  91                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
  92                 SSVAL(req->out.vwv, VWV(1), 0);
  93                 SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize);
  94                 SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max);
  95                 SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
  96                 SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
  97                 SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
  98                 SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
  99                 smbcli_req_append_blob(req, &parms->old.in.password);
 100                 smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
 101                 smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
 102                 smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE);
 103                 smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE);
 104                 break;
 105 
 106         case RAW_SESSSETUP_NT1:
 107                 SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0);
 108                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 109                 SSVAL(req->out.vwv, VWV(1), 0);
 110                 SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize);
 111                 SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max);
 112                 SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num);
 113                 SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey);
 114                 SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length);
 115                 SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length);
 116                 SIVAL(req->out.vwv, VWV(9), 0); /* reserved */
 117                 SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities);
 118                 smbcli_req_append_blob(req, &parms->nt1.in.password1);
 119                 smbcli_req_append_blob(req, &parms->nt1.in.password2);
 120                 smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE);
 121                 smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER);
 122                 smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE);
 123                 smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE);
 124                 break;
 125 
 126         case RAW_SESSSETUP_SPNEGO:
 127                 SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0);
 128                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 129                 SSVAL(req->out.vwv, VWV(1), 0);
 130                 SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize);
 131                 SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max);
 132                 SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num);
 133                 SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey);
 134                 SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length);
 135                 SIVAL(req->out.vwv, VWV(8), 0); /* reserved */
 136                 SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities);
 137                 smbcli_req_append_blob(req, &parms->spnego.in.secblob);
 138                 smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE);
 139                 smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE);
 140                 smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE);
 141                 break;
 142 
 143         case RAW_SESSSETUP_SMB2:
 144                 return NULL;
 145         }
 146 
 147         if (!smbcli_request_send(req)) {
 148                 smbcli_request_destroy(req);
 149                 return NULL;
 150         }
 151 
 152         return req;
 153 }
 154 
 155 
 156 /****************************************************************************
 157  Perform a session setup (async recv)
 158 ****************************************************************************/
 159 NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req, 
     /* [<][>][^][v][top][bottom][index][help] */
 160                                 TALLOC_CTX *mem_ctx, 
 161                                 union smb_sesssetup *parms) 
 162 {
 163         uint16_t len;
 164         uint8_t *p;
 165 
 166         if (!smbcli_request_receive(req)) {
 167                 return smbcli_request_destroy(req);
 168         }
 169         
 170         if (!NT_STATUS_IS_OK(req->status) &&
 171             !NT_STATUS_EQUAL(req->status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
 172                 return smbcli_request_destroy(req);
 173         }
 174 
 175         switch (parms->old.level) {
 176         case RAW_SESSSETUP_OLD:
 177                 SMBCLI_CHECK_WCT(req, 3);
 178                 ZERO_STRUCT(parms->old.out);
 179                 parms->old.out.vuid = SVAL(req->in.hdr, HDR_UID);
 180                 parms->old.out.action = SVAL(req->in.vwv, VWV(2));
 181                 p = req->in.data;
 182                 if (p) {
 183                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
 184                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
 185                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
 186                 }
 187                 break;
 188 
 189         case RAW_SESSSETUP_NT1:
 190                 SMBCLI_CHECK_WCT(req, 3);
 191                 ZERO_STRUCT(parms->nt1.out);
 192                 parms->nt1.out.vuid   = SVAL(req->in.hdr, HDR_UID);
 193                 parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
 194                 p = req->in.data;
 195                 if (p) {
 196                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
 197                         p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
 198                         if (p < (req->in.data + req->in.data_size)) {
 199                                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
 200                         }
 201                 }
 202                 break;
 203 
 204         case RAW_SESSSETUP_SPNEGO:
 205                 SMBCLI_CHECK_WCT(req, 4);
 206                 ZERO_STRUCT(parms->spnego.out);
 207                 parms->spnego.out.vuid   = SVAL(req->in.hdr, HDR_UID);
 208                 parms->spnego.out.action = SVAL(req->in.vwv, VWV(2));
 209                 len                      = SVAL(req->in.vwv, VWV(3));
 210                 p = req->in.data;
 211                 if (!p) {
 212                         break;
 213                 }
 214 
 215                 parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
 216                 p += parms->spnego.out.secblob.length;
 217                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
 218                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
 219                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
 220                 break;
 221 
 222         case RAW_SESSSETUP_SMB2:
 223                 req->status = NT_STATUS_INTERNAL_ERROR;
 224                 break;
 225         }
 226 
 227 failed:
 228         return smbcli_request_destroy(req);
 229 }
 230 
 231 
 232 /*
 233  Perform a session setup (sync interface)
 234 */
 235 NTSTATUS smb_raw_sesssetup(struct smbcli_session *session, 
     /* [<][>][^][v][top][bottom][index][help] */
 236                            TALLOC_CTX *mem_ctx, union smb_sesssetup *parms) 
 237 {
 238         struct smbcli_request *req = smb_raw_sesssetup_send(session, parms);
 239         return smb_raw_sesssetup_recv(req, mem_ctx, parms);
 240 }
 241 
 242 
 243 /****************************************************************************
 244  Send a ulogoff (async send)
 245 *****************************************************************************/
 246 struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session)
     /* [<][>][^][v][top][bottom][index][help] */
 247 {
 248         struct smbcli_request *req;
 249 
 250         SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0);
 251 
 252         SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 253         SSVAL(req->out.vwv, VWV(1), 0);
 254 
 255         if (!smbcli_request_send(req)) {
 256                 smbcli_request_destroy(req);
 257                 return NULL;
 258         }
 259 
 260         return req;
 261 }
 262 
 263 /****************************************************************************
 264  Send a ulogoff (sync interface)
 265 *****************************************************************************/
 266 NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
     /* [<][>][^][v][top][bottom][index][help] */
 267 {
 268         struct smbcli_request *req = smb_raw_ulogoff_send(session);
 269         return smbcli_request_simple_recv(req);
 270 }
 271 
 272 
 273 /****************************************************************************
 274  Send a exit (async send)
 275 *****************************************************************************/
 276 struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
     /* [<][>][^][v][top][bottom][index][help] */
 277 {
 278         struct smbcli_request *req;
 279 
 280         SETUP_REQUEST_SESSION(SMBexit, 0, 0);
 281 
 282         if (!smbcli_request_send(req)) {
 283                 smbcli_request_destroy(req);
 284                 return NULL;
 285         }
 286 
 287         return req;
 288 }
 289 
 290 /****************************************************************************
 291  Send a exit (sync interface)
 292 *****************************************************************************/
 293 _PUBLIC_ NTSTATUS smb_raw_exit(struct smbcli_session *session)
     /* [<][>][^][v][top][bottom][index][help] */
 294 {
 295         struct smbcli_request *req = smb_raw_exit_send(session);
 296         return smbcli_request_simple_recv(req);
 297 }

/* [<][>][^][v][top][bottom][index][help] */