Replace deprecated talloc_init calls with talloc_named
[jelmer/openchange.git] / torture / mapi_sendattach.c
1 /*
2    OpenChange MAPI torture suite implementation.
3
4    Send attach to an Exchange server
5
6    Copyright (C) Julien Kerihuel 2007.
7    Copyright (C) Fabien Le Mentec 2007.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #include <libmapi/libmapi.h>
24 #include <gen_ndr/ndr_exchange.h>
25 #include <param.h>
26 #include <credentials.h>
27 #include <torture/mapi_torture.h>
28 #include <torture.h>
29 #include <torture/torture_proto.h>
30 #include <samba/popt.h>
31
32 #include <sys/stat.h>
33 #include <fcntl.h>
34
35
36 #define CN_MSG_PROPS 3
37
38 bool torture_rpc_mapi_sendattach(struct torture_context *torture)
39 {
40         enum MAPISTATUS         retval;
41         TALLOC_CTX              *mem_ctx;
42         bool                    ret = true;
43         const char              *subject = lp_parm_string(torture->lp_ctx, NULL, "mapi", "subject");
44         const char              *body = lp_parm_string(torture->lp_ctx, NULL, "mapi", "body");
45         const char              *filename = lp_parm_string(torture->lp_ctx, NULL, "mapi", "attachment");
46         const char              **usernames;
47         const char              **usernames_to;
48         const char              **usernames_cc;
49         const char              **usernames_bcc;
50         struct mapi_session     *session;
51         mapi_object_t           obj_store;
52         mapi_object_t           obj_outbox;
53         mapi_object_t           obj_message;
54         mapi_object_t           obj_attach;
55         mapi_object_t           obj_stream;
56         uint64_t                id_outbox;
57         struct SRowSet          *SRowSet = NULL;
58         struct SPropTagArray    *flaglist = NULL;
59         uint32_t                index = 0;
60         struct SPropTagArray    *SPropTagArray;
61         struct SPropValue       SPropValue;
62         struct SPropValue       props_attach[3];
63         unsigned long           cn_props_attach;
64         struct SPropValue       props[CN_MSG_PROPS];
65         uint32_t                msgflag;
66         DATA_BLOB               blob;
67
68         /* get the attachment filename */
69         if (!filename) {
70                 DEBUG(0, ("No filename specified with mapi:attachment\n"));
71                 return false;
72         }
73
74         /* init torture */
75         mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_sendmail");
76
77         /* init mapi */
78         if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
79
80         /* init objects */
81         mapi_object_init(&obj_store);
82         mapi_object_init(&obj_outbox);
83         mapi_object_init(&obj_message);
84         mapi_object_init(&obj_attach);
85
86         /* default if null */
87         if (subject == 0) subject = "";
88         if (body == 0) body = "";
89
90         /* session::OpenMsgStore() */
91         retval = OpenMsgStore(session, &obj_store);
92         mapi_errstr("OpenMsgStore", GetLastError());
93         if (retval != MAPI_E_SUCCESS) return false;
94
95         /* id_outbox = store->GeOutboxFolder() */
96         retval = GetOutboxFolder(&obj_store, &id_outbox);
97         mapi_errstr("GetOutboxFodler", GetLastError());
98         if (retval != MAPI_E_SUCCESS) return false;
99
100         /* outbox = store->OpenFolder(id_outbox) */
101         retval = OpenFolder(&obj_store, id_outbox, &obj_outbox);
102         if (retval != MAPI_E_SUCCESS) return false;
103
104         /* message = outbox->CreateMessage() */
105         retval = CreateMessage(&obj_outbox, &obj_message);
106         mapi_errstr("CreateMessage", GetLastError());
107         if (retval != MAPI_E_SUCCESS) return false;
108
109         SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
110                                           PR_OBJECT_TYPE,
111                                           PR_DISPLAY_TYPE,
112                                           PR_7BIT_DISPLAY_NAME,
113                                           PR_DISPLAY_NAME,
114                                           PR_SMTP_ADDRESS,
115                                           PR_GIVEN_NAME);
116
117         usernames_to = get_cmdline_recipients(mem_ctx, "to");
118         usernames_cc = get_cmdline_recipients(mem_ctx, "cc");
119         usernames_bcc = get_cmdline_recipients(mem_ctx, "bcc");
120         usernames = collapse_recipients(mem_ctx, usernames_to, usernames_cc, usernames_bcc);
121
122         retval = ResolveNames(mapi_object_get_session(&obj_outbox), usernames, 
123                               SPropTagArray, &SRowSet, &flaglist, 0);
124         mapi_errstr("ResolveNames", GetLastError());
125         if (retval != MAPI_E_SUCCESS) return false;
126
127         if (!SRowSet) {
128           SRowSet = talloc_zero(mem_ctx, struct SRowSet);
129         }
130
131         set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_to, flaglist, MAPI_TO);
132         set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_cc, flaglist, MAPI_CC);
133         set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_bcc, flaglist, MAPI_BCC);
134
135
136         SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
137         SPropValue.value.l = 0;
138         SRowSet_propcpy(mem_ctx, &SRowSet[0], SPropValue);
139
140         /* message->ModifyRecipients() */
141         retval = ModifyRecipients(&obj_message, SRowSet);
142         mapi_errstr("ModifyRecipients", GetLastError());
143         if (retval != MAPI_E_SUCCESS) return false;
144         
145         retval = MAPIFreeBuffer(SRowSet);
146         mapi_errstr("MAPIFreeBuffer: SRowSet", GetLastError());
147
148         retval = MAPIFreeBuffer(flaglist);
149         mapi_errstr("MAPIFreeBuffer: flaglist", GetLastError());
150
151         /* message->SetProps()
152          */
153         msgflag = MSGFLAG_UNSENT;
154         set_SPropValue_proptag(&props[0], PR_SUBJECT, (const void *)subject);
155         set_SPropValue_proptag(&props[1], PR_BODY, (const void *)body);
156         set_SPropValue_proptag(&props[2], PR_MESSAGE_FLAGS, (const void *)&msgflag);
157         retval = SetProps(&obj_message, props, CN_MSG_PROPS);
158         mapi_errstr("SetProps", GetLastError());
159
160         /* CreateAttach */
161         retval = CreateAttach(&obj_message, &obj_attach);
162         mapi_errstr("CreateAttach", GetLastError());
163         if (retval != MAPI_E_SUCCESS) return false;
164
165         /* send by value */
166         props_attach[0].ulPropTag = PR_ATTACH_METHOD;
167         props_attach[0].value.l = ATTACH_BY_VALUE;
168         props_attach[1].ulPropTag = PR_RENDERING_POSITION;
169         props_attach[1].value.l = 0;
170         props_attach[2].ulPropTag = PR_ATTACH_FILENAME;
171         props_attach[2].value.lpszA = get_filename(filename);
172         cn_props_attach = 3;
173
174         /* SetProps */
175         retval = SetProps(&obj_attach, props_attach, cn_props_attach);
176         mapi_errstr("SetProps", GetLastError());
177         if (retval != MAPI_E_SUCCESS) return false;
178
179         /* OpenStream on CreateAttach handle */
180         retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
181         mapi_errstr("OpenStream", GetLastError());
182         if (retval != MAPI_E_SUCCESS) return false;
183
184         /* WriteStream */
185         {
186                 int             fd;
187                 struct stat     sb;
188                 uint32_t        read_size;
189                 uint16_t        buf_readsize;
190                 uint8_t         buf[0x7000];
191
192                 if (stat(filename, &sb) != 0) return false;
193
194                 if ((fd = open(filename, O_RDONLY)) == -1) {
195                         DEBUG(0, ("Error while opening %s\n", filename));
196                         return false;
197                 }
198         
199                 while ((read_size = read(fd, buf, 0x4000))) {
200                         /* We reset errno due to read */
201                         blob.length = read_size;
202                         blob.data = talloc_size(mem_ctx, read_size);
203                         memcpy(blob.data, buf, read_size);
204                         
205                         errno = 0;
206                         retval = WriteStream(&obj_stream, &blob, &buf_readsize);
207                         mapi_errstr("WriteStream", GetLastError());
208                         talloc_free(blob.data);
209                 }
210                 close(fd);
211         }
212
213         /* message->SaveChangesAttachment() */
214         retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
215         mapi_errstr("SaveChangesAttachment", GetLastError());
216         if (retval != MAPI_E_SUCCESS) return false;
217
218         /* message->SubmitMessage() */
219         retval = SubmitMessage(&obj_message);
220         mapi_errstr("SubmitMessage", GetLastError());
221         if (retval != MAPI_E_SUCCESS) return false;
222
223         /* objects->Release()
224          */
225         mapi_object_release(&obj_attach);
226         mapi_object_release(&obj_message);
227         mapi_object_release(&obj_outbox);
228         mapi_object_release(&obj_store);
229         
230         /* session::Uninitialize()
231          */
232         MAPIUninitialize();
233
234         talloc_free(mem_ctx);
235         return ret;
236 }