Changeset 740 for vendor/current/source3/smbd/notify.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/notify.c
r587 r740 21 21 22 22 #include "includes.h" 23 #include "smbd/smbd.h" 23 24 #include "smbd/globals.h" 25 #include "../librpc/gen_ndr/ndr_notify.h" 24 26 25 27 struct notify_change_request { … … 46 48 struct notify_mid_map *prev, *next; 47 49 struct notify_change_request *req; 48 uint 16mid;50 uint64_t mid; 49 51 }; 50 52 … … 63 65 uint32 max_offset, 64 66 struct notify_change *changes, 65 prs_struct *ps)67 DATA_BLOB *final_blob) 66 68 { 67 69 int i; 68 UNISTR uni_name;69 70 70 71 if (num_changes == -1) { … … 72 73 } 73 74 74 uni_name.buffer = NULL;75 76 75 for (i=0; i<num_changes; i++) { 76 enum ndr_err_code ndr_err; 77 77 struct notify_change *c; 78 size_t namelen; 79 int rem = 0; 80 uint32 u32_tmp; /* Temp arg to prs_uint32 to avoid 81 * signed/unsigned issues */ 78 struct FILE_NOTIFY_INFORMATION m; 79 DATA_BLOB blob; 82 80 83 81 /* Coalesce any identical records. */ … … 90 88 c = &changes[i]; 91 89 92 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, 93 c->name, strlen(c->name)+1, &uni_name.buffer, 94 &namelen, True) || (uni_name.buffer == NULL)) { 95 goto fail; 96 } 97 98 namelen -= 2; /* Dump NULL termination */ 90 m.FileName1 = c->name; 91 m.FileNameLength = strlen_m(c->name)*2; 92 m.Action = c->action; 93 m.NextEntryOffset = (i == num_changes-1) ? 0 : ndr_size_FILE_NOTIFY_INFORMATION(&m, 0); 99 94 100 95 /* … … 102 97 */ 103 98 104 u32_tmp = (i == num_changes-1) ? 0 : namelen + 12; 105 106 /* Align on 4-byte boundary according to MS-CIFS 2.2.7.4.2 */ 107 if ((rem = u32_tmp % 4 ) != 0) 108 u32_tmp += 4 - rem; 109 110 if (!prs_uint32("offset", ps, 1, &u32_tmp)) goto fail; 111 112 u32_tmp = c->action; 113 if (!prs_uint32("action", ps, 1, &u32_tmp)) goto fail; 114 115 u32_tmp = namelen; 116 if (!prs_uint32("namelen", ps, 1, &u32_tmp)) goto fail; 117 118 if (!prs_unistr("name", ps, 1, &uni_name)) goto fail; 119 120 /* 121 * Not NULL terminated, decrease by the 2 UCS2 \0 chars 122 */ 123 prs_set_offset(ps, prs_offset(ps)-2); 124 125 if (rem != 0) { 126 if (!prs_align_custom(ps, 4)) goto fail; 127 } 128 129 TALLOC_FREE(uni_name.buffer); 130 131 if (prs_offset(ps) > max_offset) { 99 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &m, 100 (ndr_push_flags_fn_t)ndr_push_FILE_NOTIFY_INFORMATION); 101 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 102 return false; 103 } 104 105 if (DEBUGLEVEL >= 10) { 106 NDR_PRINT_DEBUG(FILE_NOTIFY_INFORMATION, &m); 107 } 108 109 if (!data_blob_append(talloc_tos(), final_blob, 110 blob.data, blob.length)) { 111 data_blob_free(&blob); 112 return false; 113 } 114 115 data_blob_free(&blob); 116 117 if (final_blob->length > max_offset) { 132 118 /* Too much data for client. */ 133 119 DEBUG(10, ("Client only wanted %d bytes, trying to " 134 120 "marshall %d bytes\n", (int)max_offset, 135 (int) prs_offset(ps)));121 (int)final_blob->length)); 136 122 return False; 137 123 } … … 139 125 140 126 return True; 141 142 fail:143 TALLOC_FREE(uni_name.buffer);144 return False;145 127 } 146 128 … … 149 131 *****************************************************************************/ 150 132 151 void change_notify_reply(connection_struct *conn, 152 struct smb_request *req, 133 void change_notify_reply(struct smb_request *req, 153 134 NTSTATUS error_code, 154 135 uint32_t max_param, 155 136 struct notify_change_buf *notify_buf, 156 137 void (*reply_fn)(struct smb_request *req, 157 NTSTATUS error_code,158 uint8_t *buf, size_t len))159 { 160 prs_struct ps;138 NTSTATUS error_code, 139 uint8_t *buf, size_t len)) 140 { 141 DATA_BLOB blob = data_blob_null; 161 142 162 143 if (!NT_STATUS_IS_OK(error_code)) { … … 170 151 } 171 152 172 prs_init_empty(&ps, NULL, MARSHALL);173 174 153 if (!notify_marshall_changes(notify_buf->num_changes, max_param, 175 notify_buf->changes, & ps)) {154 notify_buf->changes, &blob)) { 176 155 /* 177 156 * We exceed what the client is willing to accept. Send 178 157 * nothing. 179 158 */ 180 prs_mem_free(&ps); 181 prs_init_empty(&ps, NULL, MARSHALL); 182 } 183 184 reply_fn(req, NT_STATUS_OK, (uint8_t *)prs_data_p(&ps), prs_offset(&ps)); 185 186 prs_mem_free(&ps); 159 data_blob_free(&blob); 160 } 161 162 reply_fn(req, NT_STATUS_OK, blob.data, blob.length); 163 164 data_blob_free(&blob); 187 165 188 166 TALLOC_FREE(notify_buf->changes); … … 245 223 struct notify_change_request *request = NULL; 246 224 struct notify_mid_map *map = NULL; 247 struct smbd_server_connection *sconn = smbd_server_conn;225 struct smbd_server_connection *sconn = req->sconn; 248 226 249 227 DEBUG(10, ("change_notify_add_request: Adding request for %s: " … … 275 253 } 276 254 277 static void change_notify_remove_request(struct notify_change_request *remove_req) 255 static void change_notify_remove_request(struct smbd_server_connection *sconn, 256 struct notify_change_request *remove_req) 278 257 { 279 258 files_struct *fsp; 280 259 struct notify_change_request *req; 281 struct smbd_server_connection *sconn = smbd_server_conn;282 260 283 261 /* … … 308 286 *****************************************************************************/ 309 287 310 void remove_pending_change_notify_requests_by_mid(uint16 mid) 288 void remove_pending_change_notify_requests_by_mid( 289 struct smbd_server_connection *sconn, uint64_t mid) 311 290 { 312 291 struct notify_mid_map *map; 313 struct smbd_server_connection *sconn = smbd_server_conn;314 292 315 293 for (map = sconn->smb1.notify_mid_maps; map; map = map->next) { … … 323 301 } 324 302 325 change_notify_reply(map->req-> fsp->conn, map->req->req,303 change_notify_reply(map->req->req, 326 304 NT_STATUS_CANCELLED, 0, NULL, map->req->reply_fn); 327 change_notify_remove_request( map->req);328 } 329 330 void smbd_notify_cancel_by_smbreq( struct smbd_server_connection *sconn,331 const struct smb_request *smbreq) 332 { 305 change_notify_remove_request(sconn, map->req); 306 } 307 308 void smbd_notify_cancel_by_smbreq(const struct smb_request *smbreq) 309 { 310 struct smbd_server_connection *sconn = smbreq->sconn; 333 311 struct notify_mid_map *map; 334 312 … … 343 321 } 344 322 345 change_notify_reply(map->req-> fsp->conn, map->req->req,323 change_notify_reply(map->req->req, 346 324 NT_STATUS_CANCELLED, 0, NULL, map->req->reply_fn); 347 change_notify_remove_request( map->req);325 change_notify_remove_request(sconn, map->req); 348 326 } 349 327 … … 360 338 361 339 while (fsp->notify->requests != NULL) { 362 change_notify_reply(fsp-> conn, fsp->notify->requests->req,340 change_notify_reply(fsp->notify->requests->req, 363 341 status, 0, NULL, 364 342 fsp->notify->requests->reply_fn); 365 change_notify_remove_request(fsp->notify->requests); 343 change_notify_remove_request(fsp->conn->sconn, 344 fsp->notify->requests); 366 345 } 367 346 } … … 428 407 fsp->notify->num_changes = -1; 429 408 if (fsp->notify->requests != NULL) { 430 change_notify_reply(fsp->conn, 431 fsp->notify->requests->req, 409 change_notify_reply(fsp->notify->requests->req, 432 410 NT_STATUS_OK, 433 411 fsp->notify->requests->max_param, 434 412 fsp->notify, 435 413 fsp->notify->requests->reply_fn); 436 change_notify_remove_request(fsp->notify->requests); 414 change_notify_remove_request(fsp->conn->sconn, 415 fsp->notify->requests); 437 416 } 438 417 return; … … 489 468 */ 490 469 491 change_notify_reply(fsp->conn, 492 fsp->notify->requests->req, 470 change_notify_reply(fsp->notify->requests->req, 493 471 NT_STATUS_OK, 494 472 fsp->notify->requests->max_param, … … 496 474 fsp->notify->requests->reply_fn); 497 475 498 change_notify_remove_request(fsp-> notify->requests);476 change_notify_remove_request(fsp->conn->sconn, fsp->notify->requests); 499 477 } 500 478
Note:
See TracChangeset
for help on using the changeset viewer.