1996-05-04 07:50:46 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
1996-05-04 07:50:46 +00:00
SMB messaging
1998-01-22 13:27:43 +00:00
Copyright ( C ) Andrew Tridgell 1992 - 1998
1996-05-04 07:50:46 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 19:25:36 +00:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 07:50:46 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 07:50:46 +00:00
*/
/*
This file handles the messaging system calls for winpopup style
messages
*/
# include "includes.h"
2001-12-06 13:09:15 +00:00
extern userdom_struct current_user_info ;
2007-12-09 13:45:10 +01:00
struct msg_state {
char * from ;
char * to ;
char * msg ;
} ;
static struct msg_state * smbd_msg_state ;
1996-05-04 07:50:46 +00:00
/****************************************************************************
2006-06-20 02:38:28 +00:00
Deliver the message .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-20 02:38:28 +00:00
2007-12-09 13:45:10 +01:00
static void msg_deliver ( struct msg_state * state )
1996-05-04 07:50:46 +00:00
{
2007-12-09 13:45:10 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-11-13 12:51:31 -08:00
char * name = NULL ;
2006-06-20 02:38:28 +00:00
int i ;
int fd ;
char * msg ;
int len ;
ssize_t sz ;
2007-12-09 13:45:10 +01:00
fstring alpha_buf ;
char * s ;
2006-06-20 02:38:28 +00:00
if ( ! ( * lp_msg_command ( ) ) ) {
DEBUG ( 1 , ( " no messaging command specified \n " ) ) ;
2007-12-09 13:45:10 +01:00
goto done ;
2006-06-20 02:38:28 +00:00
}
/* put it in a temporary file */
2007-12-09 13:45:10 +01:00
name = talloc_asprintf ( talloc_tos ( ) , " %s/msg.XXXXXX " , tmpdir ( ) ) ;
2007-11-13 12:51:31 -08:00
if ( ! name ) {
2007-12-09 13:45:10 +01:00
goto done ;
2007-11-13 12:51:31 -08:00
}
2006-06-20 02:38:28 +00:00
fd = smb_mkstemp ( name ) ;
if ( fd = = - 1 ) {
2007-12-09 13:45:10 +01:00
DEBUG ( 1 , ( " can't open message file %s: %s \n " , name ,
strerror ( errno ) ) ) ;
goto done ;
2006-06-20 02:38:28 +00:00
}
/*
* Incoming message is in DOS codepage format . Convert to UNIX .
*/
2007-11-13 12:51:31 -08:00
2007-12-09 13:45:10 +01:00
len = convert_string_talloc (
talloc_tos ( ) , CH_DOS , CH_UNIX , state - > msg ,
talloc_get_size ( state - > msg ) , ( void * ) & msg , true ) ;
if ( len = = - 1 ) {
DEBUG ( 3 , ( " Conversion failed, delivering message in DOS "
" codepage format \n " ) ) ;
msg = state - > msg ;
}
for ( i = 0 ; i < len ; i + + ) {
if ( ( msg [ i ] = = ' \r ' ) & & ( i < ( len - 1 ) ) & & ( msg [ i + 1 ] = = ' \n ' ) ) {
continue ;
2006-06-20 02:38:28 +00:00
}
2007-12-09 13:45:10 +01:00
sz = write ( fd , & msg [ i ] , 1 ) ;
if ( sz ! = 1 ) {
DEBUG ( 0 , ( " Write error to fd %d: %ld(%s) \n " , fd ,
( long ) sz , strerror ( errno ) ) ) ;
2006-06-20 02:38:28 +00:00
}
}
2007-12-09 13:45:10 +01:00
2006-06-20 02:38:28 +00:00
close ( fd ) ;
/* run the command */
2007-12-09 13:45:10 +01:00
s = talloc_strdup ( talloc_tos ( ) , lp_msg_command ( ) ) ;
if ( s = = NULL ) {
goto done ;
}
alpha_strcpy ( alpha_buf , state - > from , NULL , sizeof ( alpha_buf ) ) ;
s = talloc_string_sub ( talloc_tos ( ) , s , " %f " , alpha_buf ) ;
if ( s = = NULL ) {
goto done ;
}
alpha_strcpy ( alpha_buf , state - > to , NULL , sizeof ( alpha_buf ) ) ;
s = talloc_string_sub ( talloc_tos ( ) , s , " %t " , alpha_buf ) ;
if ( s = = NULL ) {
goto done ;
2006-06-20 02:38:28 +00:00
}
2007-12-09 13:45:10 +01:00
s = talloc_sub_basic ( talloc_tos ( ) , current_user_info . smb_name ,
current_user_info . domain , s ) ;
if ( s = = NULL ) {
goto done ;
}
s = talloc_string_sub ( talloc_tos ( ) , s , " %s " , name ) ;
if ( s = = NULL ) {
goto done ;
}
smbrun ( s , NULL ) ;
done :
TALLOC_FREE ( frame ) ;
return ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2006-06-20 02:38:28 +00:00
Reply to a sends .
conn POINTER CAN BE NULL HERE !
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-20 02:38:28 +00:00
2007-08-14 21:07:44 +00:00
void reply_sends ( connection_struct * conn , struct smb_request * req )
1996-05-04 07:50:46 +00:00
{
2007-12-09 13:45:10 +01:00
struct msg_state * state ;
2006-06-20 02:38:28 +00:00
int len ;
char * msg ;
char * p ;
2001-03-14 11:55:08 +00:00
2006-06-20 02:38:28 +00:00
START_PROFILE ( SMBsends ) ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
if ( ! ( * lp_msg_command ( ) ) ) {
2007-08-14 21:07:44 +00:00
reply_doserror ( req , ERRSRV , ERRmsgoff ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsends ) ;
2007-08-14 21:07:44 +00:00
return ;
2006-06-20 02:38:28 +00:00
}
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
state = talloc ( talloc_tos ( ) , struct msg_state ) ;
2007-08-14 21:07:44 +00:00
p = smb_buf ( req - > inbuf ) + 1 ;
2007-12-09 13:45:10 +01:00
p + = srvstr_pull_buf_talloc (
state , ( char * ) req - > inbuf , req - > flags2 , & state - > from , p ,
STR_ASCII | STR_TERMINATE ) + 1 ;
p + = srvstr_pull_buf_talloc (
state , ( char * ) req - > inbuf , req - > flags2 , & state - > to , p ,
STR_ASCII | STR_TERMINATE ) + 1 ;
1996-05-04 07:50:46 +00:00
2006-06-20 02:38:28 +00:00
msg = p ;
1996-05-04 07:50:46 +00:00
2006-06-20 02:38:28 +00:00
len = SVAL ( msg , 0 ) ;
2007-12-09 13:45:10 +01:00
len = MIN ( len , smb_bufrem ( req - > inbuf , msg + 2 ) ) ;
1999-12-13 13:27:58 +00:00
2007-12-09 13:45:10 +01:00
state - > msg = talloc_array ( state , char , len ) ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
if ( state - > msg = = NULL ) {
reply_nterror ( req , NT_STATUS_NO_MEMORY ) ;
END_PROFILE ( SMBsends ) ;
return ;
}
memcpy ( state - > msg , msg + 2 , len ) ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
msg_deliver ( state ) ;
1996-05-04 07:50:46 +00:00
2007-08-14 21:07:44 +00:00
reply_outbuf ( req , 0 , 0 ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsends ) ;
2007-08-14 21:07:44 +00:00
return ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2006-06-20 02:38:28 +00:00
Reply to a sendstrt .
conn POINTER CAN BE NULL HERE !
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-20 02:38:28 +00:00
2007-08-14 21:07:44 +00:00
void reply_sendstrt ( connection_struct * conn , struct smb_request * req )
1996-05-04 07:50:46 +00:00
{
2006-06-20 02:38:28 +00:00
char * p ;
2001-03-14 11:55:08 +00:00
2006-06-20 02:38:28 +00:00
START_PROFILE ( SMBsendstrt ) ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
if ( ! ( * lp_msg_command ( ) ) ) {
2007-08-14 21:07:44 +00:00
reply_doserror ( req , ERRSRV , ERRmsgoff ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsendstrt ) ;
2007-08-14 21:07:44 +00:00
return ;
2006-06-20 02:38:28 +00:00
}
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
TALLOC_FREE ( smbd_msg_state ) ;
smbd_msg_state = TALLOC_ZERO_P ( NULL , struct msg_state ) ;
if ( smbd_msg_state = = NULL ) {
reply_nterror ( req , NT_STATUS_NO_MEMORY ) ;
END_PROFILE ( SMBsendstrt ) ;
return ;
}
1996-05-04 07:50:46 +00:00
2007-08-14 21:07:44 +00:00
p = smb_buf ( req - > inbuf ) + 1 ;
2007-12-09 13:45:10 +01:00
p + = srvstr_pull_buf_talloc (
smbd_msg_state , ( char * ) req - > inbuf , req - > flags2 ,
& smbd_msg_state - > from , p , STR_ASCII | STR_TERMINATE ) + 1 ;
p + = srvstr_pull_buf_talloc (
smbd_msg_state , ( char * ) req - > inbuf , req - > flags2 ,
& smbd_msg_state - > to , p , STR_ASCII | STR_TERMINATE ) + 1 ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
DEBUG ( 3 , ( " SMBsendstrt (from %s to %s) \n " , smbd_msg_state - > from ,
smbd_msg_state - > to ) ) ;
1996-05-04 07:50:46 +00:00
2007-08-14 21:07:44 +00:00
reply_outbuf ( req , 0 , 0 ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsendstrt ) ;
2007-08-14 21:07:44 +00:00
return ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2006-06-20 02:38:28 +00:00
Reply to a sendtxt .
conn POINTER CAN BE NULL HERE !
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-20 02:38:28 +00:00
2007-08-14 21:07:44 +00:00
void reply_sendtxt ( connection_struct * conn , struct smb_request * req )
1996-05-04 07:50:46 +00:00
{
2006-06-20 02:38:28 +00:00
int len ;
char * msg ;
2007-12-09 13:45:10 +01:00
char * tmp ;
size_t old_len ;
2006-06-20 02:38:28 +00:00
START_PROFILE ( SMBsendtxt ) ;
1996-05-04 07:50:46 +00:00
2006-06-20 02:38:28 +00:00
if ( ! ( * lp_msg_command ( ) ) ) {
2007-08-14 21:07:44 +00:00
reply_doserror ( req , ERRSRV , ERRmsgoff ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsendtxt ) ;
2007-08-14 21:07:44 +00:00
return ;
2006-06-20 02:38:28 +00:00
}
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
if ( smbd_msg_state = = NULL ) {
reply_nterror ( req , NT_STATUS_INVALID_PARAMETER ) ;
END_PROFILE ( SMBsendtxt ) ;
return ;
}
2007-08-14 21:07:44 +00:00
msg = smb_buf ( req - > inbuf ) + 1 ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
old_len = talloc_get_size ( smbd_msg_state - > msg ) ;
len = MIN ( SVAL ( msg , 0 ) , smb_bufrem ( req - > inbuf , msg + 2 ) ) ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
tmp = TALLOC_REALLOC_ARRAY ( smbd_msg_state , smbd_msg_state - > msg ,
char , old_len + len ) ;
if ( tmp = = NULL ) {
reply_nterror ( req , NT_STATUS_NO_MEMORY ) ;
END_PROFILE ( SMBsendtxt ) ;
return ;
}
smbd_msg_state - > msg = tmp ;
memcpy ( & smbd_msg_state - > msg [ old_len ] , msg + 2 , len ) ;
1996-05-04 07:50:46 +00:00
2006-06-20 02:38:28 +00:00
DEBUG ( 3 , ( " SMBsendtxt \n " ) ) ;
1996-05-04 07:50:46 +00:00
2007-08-14 21:07:44 +00:00
reply_outbuf ( req , 0 , 0 ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsendtxt ) ;
2007-08-14 21:07:44 +00:00
return ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2006-06-20 02:38:28 +00:00
Reply to a sendend .
conn POINTER CAN BE NULL HERE !
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-20 02:38:28 +00:00
2007-08-14 21:07:44 +00:00
void reply_sendend ( connection_struct * conn , struct smb_request * req )
1996-05-04 07:50:46 +00:00
{
2006-06-20 02:38:28 +00:00
START_PROFILE ( SMBsendend ) ;
1996-05-04 07:50:46 +00:00
2006-06-20 02:38:28 +00:00
if ( ! ( * lp_msg_command ( ) ) ) {
2007-08-14 21:07:44 +00:00
reply_doserror ( req , ERRSRV , ERRmsgoff ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsendend ) ;
2007-08-14 21:07:44 +00:00
return ;
2006-06-20 02:38:28 +00:00
}
1996-05-04 07:50:46 +00:00
2006-06-20 02:38:28 +00:00
DEBUG ( 3 , ( " SMBsendend \n " ) ) ;
1996-05-04 07:50:46 +00:00
2007-12-09 13:45:10 +01:00
msg_deliver ( smbd_msg_state ) ;
TALLOC_FREE ( smbd_msg_state ) ;
1996-05-04 07:50:46 +00:00
2007-08-14 21:07:44 +00:00
reply_outbuf ( req , 0 , 0 ) ;
2006-06-20 02:38:28 +00:00
END_PROFILE ( SMBsendend ) ;
2007-08-14 21:07:44 +00:00
return ;
1996-05-04 07:50:46 +00:00
}