diff options
author | Jeremy Allison <jra@samba.org> | 2007-07-13 01:22:09 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:28:35 -0500 |
commit | e8dc2ea03d212bc4b4facc2a900f6a443365c390 (patch) | |
tree | c418222494cb9cd05250f30b8f6671e0b3046fa3 /source3/smbd/reply.c | |
parent | 79a9f6dcb86703fd48d1321e50ff2b678ce39664 (diff) | |
download | samba-e8dc2ea03d212bc4b4facc2a900f6a443365c390.tar.gz samba-e8dc2ea03d212bc4b4facc2a900f6a443365c390.tar.bz2 samba-e8dc2ea03d212bc4b4facc2a900f6a443365c390.zip |
r23858: Added srvstr_pull_buf_talloc() and srvstr_pull_talloc()
calls and converted reply_tcon and reply_tconX to use
them - to show the boilerplate usage (valgrind tested).
In conjunction with Volker's srvstr_get_path_talloc()
work this should allow us to start eliminating all
pstrings/fstrings out of the main path processing
code.
I'll watch the build farm tonight...
Jeremy.
(This used to be commit b4eff3f68089f082781afcf90d43faa317949566)
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r-- | source3/smbd/reply.c | 115 |
1 files changed, 73 insertions, 42 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 9a2dc19fa1..8b6a164a66 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -381,30 +381,40 @@ int reply_special(char *inbuf,char *outbuf) int reply_tcon(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { + TALLOC_CTX *ctx; const char *service; - pstring service_buf; - pstring password; - pstring dev; + char *service_buf = NULL; + char *password = NULL; + char *dev = NULL; int outsize = 0; uint16 vuid = SVAL(inbuf,smb_uid); int pwlen=0; NTSTATUS nt_status; char *p; DATA_BLOB password_blob; - + START_PROFILE(SMBtcon); - *service_buf = *password = *dev = 0; + ctx = talloc_init("reply_tcon"); + if (!ctx) { + END_PROFILE(SMBtcon); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } p = smb_buf(inbuf)+1; - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), service_buf, p, - sizeof(service_buf), STR_TERMINATE) + 1; - pwlen = srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), password, p, - sizeof(password), STR_TERMINATE) + 1; + p += srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2), + &service_buf, p, STR_TERMINATE) + 1; + pwlen = srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2), + &password, p, STR_TERMINATE) + 1; p += pwlen; - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), dev, p, sizeof(dev), - STR_TERMINATE) + 1; + p += srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2), + &dev, p, STR_TERMINATE) + 1; + if (service_buf == NULL || password == NULL || dev == NULL) { + TALLOC_FREE(ctx); + END_PROFILE(SMBtcon); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } p = strrchr_m(service_buf,'\\'); if (p) { service = p+1; @@ -417,21 +427,23 @@ int reply_tcon(connection_struct *conn, conn = make_connection(service,password_blob,dev,vuid,&nt_status); data_blob_clear_free(&password_blob); - + if (!conn) { + TALLOC_FREE(ctx); END_PROFILE(SMBtcon); return ERROR_NT(nt_status); } - + outsize = set_message(inbuf,outbuf,2,0,True); SSVAL(outbuf,smb_vwv0,max_recv); SSVAL(outbuf,smb_vwv1,conn->cnum); SSVAL(outbuf,smb_tid,conn->cnum); - + DEBUG(3,("tcon service=%s cnum=%d\n", service, conn->cnum)); - + END_PROFILE(SMBtcon); + TALLOC_FREE(ctx); return(outsize); } @@ -442,23 +454,22 @@ int reply_tcon(connection_struct *conn, int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - fstring service; + char *service = NULL; DATA_BLOB password; + TALLOC_CTX *ctx = NULL; /* what the cleint thinks the device is */ - fstring client_devicetype; + char *client_devicetype = NULL; /* what the server tells the client the share represents */ const char *server_devicetype; NTSTATUS nt_status; uint16 vuid = SVAL(inbuf,smb_uid); int passlen = SVAL(inbuf,smb_vwv3); - pstring path; + char *path = NULL; char *p, *q; uint16 tcon_flags = SVAL(inbuf,smb_vwv2); - - START_PROFILE(SMBtconX); - *service = *client_devicetype = 0; + START_PROFILE(SMBtconX); /* we might have to close an old one */ if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) { @@ -468,7 +479,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt if (passlen > MAX_PASS_LEN) { return ERROR_DOS(ERRDOS,ERRbuftoosmall); } - + if (global_encrypted_passwords_negotiated) { password = data_blob(smb_buf(inbuf),passlen); if (lp_security() == SEC_SHARE) { @@ -487,34 +498,53 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt p = smb_buf(inbuf) + passlen + 1; } - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), path, p, - sizeof(path), STR_TERMINATE); + ctx = talloc_init("reply_tcon_and_X"); + if (!ctx) { + END_PROFILE(SMBtconX); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + p += srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2), &path, p, + STR_TERMINATE); + + if (path == NULL) { + TALLOC_FREE(ctx); + END_PROFILE(SMBtconX); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } /* * the service name can be either: \\server\share * or share directly like on the DELL PowerVault 705 */ - if (*path=='\\') { + if (*path=='\\') { q = strchr_m(path+2,'\\'); if (!q) { + TALLOC_FREE(ctx); END_PROFILE(SMBtconX); return(ERROR_DOS(ERRDOS,ERRnosuchshare)); } - fstrcpy(service,q+1); + service = q+1; + } else { + service = path; + } + + p += srvstr_pull_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2), &client_devicetype, p, + 6, STR_ASCII); + + if (client_devicetype == NULL) { + TALLOC_FREE(ctx); + END_PROFILE(SMBtconX); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - else - fstrcpy(service,path); - - p += srvstr_pull(inbuf, SVAL(inbuf, smb_flg2), client_devicetype, p, - sizeof(client_devicetype), 6, STR_ASCII); DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service)); conn = make_connection(service,password,client_devicetype,vuid,&nt_status); - + data_blob_clear_free(&password); if (!conn) { + TALLOC_FREE(ctx); END_PROFILE(SMBtconX); return ERROR_NT(nt_status); } @@ -523,19 +553,19 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt server_devicetype = "IPC"; else if ( IS_PRINT(conn) ) server_devicetype = "LPT1:"; - else + else server_devicetype = "A:"; if (Protocol < PROTOCOL_NT1) { set_message(inbuf,outbuf,2,0,True); p = smb_buf(outbuf); - p += srvstr_push(outbuf, p, server_devicetype, -1, + p += srvstr_push(outbuf, p, server_devicetype, -1, STR_TERMINATE|STR_ASCII); set_message_end(inbuf,outbuf,p); } else { /* NT sets the fstype of IPC$ to the null string */ const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn)); - + if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) { /* Return permissions. */ uint32 perm1 = 0; @@ -559,29 +589,30 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt } p = smb_buf(outbuf); - p += srvstr_push(outbuf, p, server_devicetype, -1, + p += srvstr_push(outbuf, p, server_devicetype, -1, STR_TERMINATE|STR_ASCII); - p += srvstr_push(outbuf, p, fstype, -1, + p += srvstr_push(outbuf, p, fstype, -1, STR_TERMINATE); - + set_message_end(inbuf,outbuf,p); - + /* what does setting this bit do? It is set by NT4 and may affect the ability to autorun mounted cdroms */ SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS| (lp_csc_policy(SNUM(conn)) << 2)); - + init_dfsroot(conn, inbuf, outbuf); } - + DEBUG(3,("tconX service=%s \n", service)); - + /* set the incoming and outgoing tid to the just created one */ SSVAL(inbuf,smb_tid,conn->cnum); SSVAL(outbuf,smb_tid,conn->cnum); + TALLOC_FREE(ctx); END_PROFILE(SMBtconX); return chain_reply(inbuf,outbuf,length,bufsize); } |