root/source3/smbd/message.c

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

DEFINITIONS

This source file includes following definitions.
  1. msg_deliver
  2. reply_sends
  3. reply_sendstrt
  4. reply_sendtxt
  5. reply_sendend

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    SMB messaging
   4    Copyright (C) Andrew Tridgell 1992-1998
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 /*
  20    This file handles the messaging system calls for winpopup style
  21    messages
  22 */
  23 
  24 
  25 #include "includes.h"
  26 #include "smbd/globals.h"
  27 
  28 extern userdom_struct current_user_info;
  29 
  30 struct msg_state {
  31         char *from;
  32         char *to;
  33         char *msg;
  34 };
  35 
  36 /****************************************************************************
  37  Deliver the message.
  38 ****************************************************************************/
  39 
  40 static void msg_deliver(struct msg_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
  41 {
  42         TALLOC_CTX *frame = talloc_stackframe();
  43         char *name = NULL;
  44         int i;
  45         int fd;
  46         char *msg;
  47         size_t len;
  48         ssize_t sz;
  49         fstring alpha_buf;
  50         char *s;
  51 
  52         if (! (*lp_msg_command())) {
  53                 DEBUG(1,("no messaging command specified\n"));
  54                 goto done;
  55         }
  56 
  57         /* put it in a temporary file */
  58         name = talloc_asprintf(talloc_tos(), "%s/msg.XXXXXX", tmpdir());
  59         if (!name) {
  60                 goto done;
  61         }
  62         fd = smb_mkstemp(name);
  63 
  64         if (fd == -1) {
  65                 DEBUG(1, ("can't open message file %s: %s\n", name,
  66                           strerror(errno)));
  67                 goto done;
  68         }
  69 
  70         /*
  71          * Incoming message is in DOS codepage format. Convert to UNIX.
  72          */
  73 
  74         if (!convert_string_talloc(talloc_tos(), CH_DOS, CH_UNIX, state->msg,
  75                                    talloc_get_size(state->msg), (void *)&msg,
  76                                    &len, true)) {
  77                 DEBUG(3, ("Conversion failed, delivering message in DOS "
  78                           "codepage format\n"));
  79                 msg = state->msg;
  80         }
  81 
  82         for (i = 0; i < len; i++) {
  83                 if ((msg[i] == '\r') &&
  84                     (i < (len-1)) && (msg[i+1] == '\n')) {
  85                         continue;
  86                 }
  87                 sz = write(fd, &msg[i], 1);
  88                 if ( sz != 1 ) {
  89                         DEBUG(0, ("Write error to fd %d: %ld(%s)\n", fd,
  90                                   (long)sz, strerror(errno)));
  91                 }
  92         }
  93 
  94         close(fd);
  95 
  96         /* run the command */
  97         s = talloc_strdup(talloc_tos(), lp_msg_command());
  98         if (s == NULL) {
  99                 goto done;
 100         }
 101 
 102         alpha_strcpy(alpha_buf, state->from, NULL, sizeof(alpha_buf));
 103 
 104         s = talloc_string_sub(talloc_tos(), s, "%f", alpha_buf);
 105         if (s == NULL) {
 106                 goto done;
 107         }
 108 
 109         alpha_strcpy(alpha_buf, state->to, NULL, sizeof(alpha_buf));
 110 
 111         s = talloc_string_sub(talloc_tos(), s, "%t", alpha_buf);
 112         if (s == NULL) {
 113                 goto done;
 114         }
 115 
 116         s = talloc_sub_basic(talloc_tos(), current_user_info.smb_name,
 117                              current_user_info.domain, s);
 118         if (s == NULL) {
 119                 goto done;
 120         }
 121 
 122         s = talloc_string_sub(talloc_tos(), s, "%s", name);
 123         if (s == NULL) {
 124                 goto done;
 125         }
 126         smbrun(s,NULL);
 127 
 128  done:
 129         TALLOC_FREE(frame);
 130         return;
 131 }
 132 
 133 /****************************************************************************
 134  Reply to a sends.
 135  conn POINTER CAN BE NULL HERE !
 136 ****************************************************************************/
 137 
 138 void reply_sends(struct smb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 139 {
 140         struct msg_state *state;
 141         int len;
 142         const char *msg;
 143         const char *p;
 144 
 145         START_PROFILE(SMBsends);
 146 
 147         if (!(*lp_msg_command())) {
 148                 reply_doserror(req, ERRSRV, ERRmsgoff);
 149                 END_PROFILE(SMBsends);
 150                 return;
 151         }
 152 
 153         state = talloc(talloc_tos(), struct msg_state);
 154 
 155         p = (const char *)req->buf + 1;
 156         p += srvstr_pull_req_talloc(
 157                 state, req, &state->from, p, STR_ASCII|STR_TERMINATE) + 1;
 158         p += srvstr_pull_req_talloc(
 159                 state, req, &state->to, p, STR_ASCII|STR_TERMINATE) + 1;
 160 
 161         msg = p;
 162 
 163         len = SVAL(msg,0);
 164         len = MIN(len, smbreq_bufrem(req, msg+2));
 165 
 166         state->msg = talloc_array(state, char, len);
 167 
 168         if (state->msg == NULL) {
 169                 reply_nterror(req, NT_STATUS_NO_MEMORY);
 170                 END_PROFILE(SMBsends);
 171                 return;
 172         }
 173 
 174         memcpy(state->msg, msg+2, len);
 175 
 176         msg_deliver(state);
 177 
 178         reply_outbuf(req, 0, 0);
 179 
 180         END_PROFILE(SMBsends);
 181         return;
 182 }
 183 
 184 /****************************************************************************
 185  Reply to a sendstrt.
 186  conn POINTER CAN BE NULL HERE !
 187 ****************************************************************************/
 188 
 189 void reply_sendstrt(struct smb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 190 {
 191         const char *p;
 192 
 193         START_PROFILE(SMBsendstrt);
 194 
 195         if (!(*lp_msg_command())) {
 196                 reply_doserror(req, ERRSRV, ERRmsgoff);
 197                 END_PROFILE(SMBsendstrt);
 198                 return;
 199         }
 200 
 201         TALLOC_FREE(smbd_msg_state);
 202 
 203         smbd_msg_state = TALLOC_ZERO_P(NULL, struct msg_state);
 204 
 205         if (smbd_msg_state == NULL) {
 206                 reply_nterror(req, NT_STATUS_NO_MEMORY);
 207                 END_PROFILE(SMBsendstrt);
 208                 return;
 209         }
 210 
 211         p = (const char *)req->buf+1;
 212         p += srvstr_pull_req_talloc(
 213                 smbd_msg_state, req, &smbd_msg_state->from, p,
 214                 STR_ASCII|STR_TERMINATE) + 1;
 215         p += srvstr_pull_req_talloc(
 216                 smbd_msg_state, req, &smbd_msg_state->to, p,
 217                 STR_ASCII|STR_TERMINATE) + 1;
 218 
 219         DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", smbd_msg_state->from,
 220                     smbd_msg_state->to ) );
 221 
 222         reply_outbuf(req, 0, 0);
 223 
 224         END_PROFILE(SMBsendstrt);
 225         return;
 226 }
 227 
 228 /****************************************************************************
 229  Reply to a sendtxt.
 230  conn POINTER CAN BE NULL HERE !
 231 ****************************************************************************/
 232 
 233 void reply_sendtxt(struct smb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 234 {
 235         int len;
 236         const char *msg;
 237         char *tmp;
 238         size_t old_len;
 239 
 240         START_PROFILE(SMBsendtxt);
 241 
 242         if (! (*lp_msg_command())) {
 243                 reply_doserror(req, ERRSRV, ERRmsgoff);
 244                 END_PROFILE(SMBsendtxt);
 245                 return;
 246         }
 247 
 248         if (smbd_msg_state == NULL) {
 249                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
 250                 END_PROFILE(SMBsendtxt);
 251                 return;
 252         }
 253 
 254         msg = (const char *)req->buf + 1;
 255 
 256         old_len = talloc_get_size(smbd_msg_state->msg);
 257 
 258         len = MIN(SVAL(msg, 0), smbreq_bufrem(req, msg+2));
 259 
 260         tmp = TALLOC_REALLOC_ARRAY(smbd_msg_state, smbd_msg_state->msg,
 261                                    char, old_len + len);
 262 
 263         if (tmp == NULL) {
 264                 reply_nterror(req, NT_STATUS_NO_MEMORY);
 265                 END_PROFILE(SMBsendtxt);
 266                 return;
 267         }
 268 
 269         smbd_msg_state->msg = tmp;
 270 
 271         memcpy(&smbd_msg_state->msg[old_len], msg+2, len);
 272 
 273         DEBUG( 3, ( "SMBsendtxt\n" ) );
 274 
 275         reply_outbuf(req, 0, 0);
 276 
 277         END_PROFILE(SMBsendtxt);
 278         return;
 279 }
 280 
 281 /****************************************************************************
 282  Reply to a sendend.
 283  conn POINTER CAN BE NULL HERE !
 284 ****************************************************************************/
 285 
 286 void reply_sendend(struct smb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 287 {
 288         START_PROFILE(SMBsendend);
 289 
 290         if (! (*lp_msg_command())) {
 291                 reply_doserror(req, ERRSRV, ERRmsgoff);
 292                 END_PROFILE(SMBsendend);
 293                 return;
 294         }
 295 
 296         DEBUG(3,("SMBsendend\n"));
 297 
 298         msg_deliver(smbd_msg_state);
 299 
 300         TALLOC_FREE(smbd_msg_state);
 301 
 302         reply_outbuf(req, 0, 0);
 303 
 304         END_PROFILE(SMBsendend);
 305         return;
 306 }

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