3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1998
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8 * Copyright (C) Paul Ashton 1997-1998.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* this module apparently provides an implementation of DCE/RPC over a
26 * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
27 * documentation are available (in on-line form) from the X-Open group.
29 * this module should provide a level of abstraction between SMB
30 * and DCE/RPC, while minimising the amount of mallocs, unnecessary
31 * data copies, and network traffic.
33 * in this version, which takes a "let's learn what's going on and
34 * get something running" approach, there is additional network
35 * traffic generated, but the code should be easier to understand...
37 * ... if you read the docs. or stare at packets for weeks on end.
44 extern int DEBUGLEVEL
;
46 static void NTLMSSPcalc_p( pipes_struct
*p
, unsigned char *data
, int len
)
48 unsigned char *hash
= p
->ntlmssp_hash
;
49 unsigned char index_i
= hash
[256];
50 unsigned char index_j
= hash
[257];
53 for( ind
= 0; ind
< len
; ind
++)
59 index_j
+= hash
[index_i
];
62 hash
[index_i
] = hash
[index_j
];
65 t
= hash
[index_i
] + hash
[index_j
];
66 data
[ind
] = data
[ind
] ^ hash
[t
];
73 /*******************************************************************
74 turns a DCE/RPC request into a DCE/RPC reply
76 this is where the data really should be split up into an array of
77 headers and data sections.
79 ********************************************************************/
80 BOOL
create_rpc_reply(pipes_struct
*p
,
81 uint32 data_start
, uint32 data_end
)
84 BOOL auth_verify
= IS_BITS_SET_ALL(p
->ntlmssp_chal
.neg_flags
, NTLMSSP_NEGOTIATE_SIGN
);
85 BOOL auth_seal
= IS_BITS_SET_ALL(p
->ntlmssp_chal
.neg_flags
, NTLMSSP_NEGOTIATE_SEAL
);
89 DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
90 data_start
, data_end
, p
->hdr_ba
.bba
.max_tsize
));
92 auth_len
= p
->hdr
.auth_len
;
96 DEBUG(10,("create_rpc_reply: auth\n"));
103 prs_init(&p
->rhdr
, 0x18, 4, 0, False
);
104 prs_init(&p
->rauth
, 1024, 4, 0, False
);
105 prs_init(&p
->rverf
, 0x08, 4, 0, False
);
107 p
->hdr
.pkt_type
= RPC_RESPONSE
; /* mark header as an rpc response */
109 /* set up rpc header (fragmentation issues) */
112 p
->hdr
.flags
= RPC_FLG_FIRST
;
119 p
->hdr_resp
.alloc_hint
= data_end
- data_start
; /* calculate remaining data to be sent */
121 if (p
->hdr_resp
.alloc_hint
+ 0x18 <= p
->hdr_ba
.bba
.max_tsize
)
123 p
->hdr
.flags
|= RPC_FLG_LAST
;
124 p
->hdr
.frag_len
= p
->hdr_resp
.alloc_hint
+ 0x18;
128 p
->hdr
.frag_len
= p
->hdr_ba
.bba
.max_tsize
;
133 p
->hdr_resp
.alloc_hint
-= auth_len
+ 8;
138 data_len
= p
->hdr
.frag_len
- auth_len
- (auth_verify
? 8 : 0) - 0x18;
142 data_len
= p
->hdr
.frag_len
- 0x18;
145 p
->rhdr
.data
->offset
.start
= 0;
146 p
->rhdr
.data
->offset
.end
= 0x18;
148 /* store the header in the data stream */
149 smb_io_rpc_hdr ("hdr" , &(p
->hdr
), &(p
->rhdr
), 0);
150 smb_io_rpc_hdr_resp("resp", &(p
->hdr_resp
), &(p
->rhdr
), 0);
152 /* don't use rdata: use rdata_i instead, which moves... */
153 /* make a pointer to the rdata data, NOT A COPY */
155 p
->rdata_i
.data
= NULL
;
156 prs_init(&p
->rdata_i
, 0, p
->rdata
.align
, p
->rdata
.data
->margin
, p
->rdata
.io
);
157 data
= mem_data(&(p
->rdata
.data
), data_start
);
158 mem_create(p
->rdata_i
.data
, data
, 0, data_len
, 0, False
);
159 p
->rdata_i
.offset
= data_len
;
165 DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
166 BOOLSTR(auth_verify
), BOOLSTR(auth_seal
), data_len
, auth_len
));
170 crc32
= crc32_calc_buffer(data_len
, data
);
171 NTLMSSPcalc_p(p
, (uchar
*)data
, data_len
);
174 if (auth_seal
|| auth_verify
)
176 make_rpc_hdr_auth(&p
->auth_info
, 0x0a, 0x06, 0x08, (auth_verify
? 1 : 0));
177 smb_io_rpc_hdr_auth("hdr_auth", &p
->auth_info
, &p
->rauth
, 0);
183 p
->ntlmssp_seq_num
++;
184 make_rpc_auth_ntlmssp_chk(&p
->ntlmssp_chk
, NTLMSSP_SIGN_VERSION
, crc32
, p
->ntlmssp_seq_num
++);
185 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p
->ntlmssp_chk
), &p
->rverf
, 0);
186 auth_data
= mem_data(&p
->rverf
.data
, 4);
187 NTLMSSPcalc_p(p
, (uchar
*)auth_data
, 12);
191 /* set up the data chain */
194 prs_link(NULL
, &p
->rhdr
, &p
->rdata_i
);
195 prs_link(&p
->rhdr
, &p
->rdata_i
, &p
->rauth
);
196 prs_link(&p
->rdata_i
, &p
->rauth
, &p
->rverf
);
197 prs_link(&p
->rauth
, &p
->rverf
, NULL
);
201 prs_link(NULL
, &p
->rhdr
, &p
->rdata_i
);
202 prs_link(&p
->rhdr
, &p
->rdata_i
, NULL
);
205 /* indicate to subsequent data reads where we are up to */
206 p
->frag_len_left
= p
->hdr
.frag_len
- p
->file_offset
;
207 p
->next_frag_start
= p
->hdr
.frag_len
;
209 return p
->rhdr
.data
!= NULL
&& p
->rhdr
.offset
== 0x18;
212 static BOOL
api_pipe_ntlmssp_verify(pipes_struct
*p
)
216 struct smb_passwd
*smb_pass
= NULL
;
218 DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
220 if (p
->ntlmssp_resp
.hdr_lm_resp
.str_str_len
== 0) return False
;
221 if (p
->ntlmssp_resp
.hdr_nt_resp
.str_str_len
== 0) return False
;
222 if (p
->ntlmssp_resp
.hdr_usr
.str_str_len
== 0) return False
;
223 if (p
->ntlmssp_resp
.hdr_domain
.str_str_len
== 0) return False
;
224 if (p
->ntlmssp_resp
.hdr_wks
.str_str_len
== 0) return False
;
226 memset(p
->user_name
, 0, sizeof(p
->user_name
));
227 memset(p
->domain
, 0, sizeof(p
->domain
));
228 memset(p
->wks
, 0, sizeof(p
->wks
));
230 if (IS_BITS_SET_ALL(p
->ntlmssp_chal
.neg_flags
, NTLMSSP_NEGOTIATE_UNICODE
))
232 fstrcpy(p
->user_name
, unistrn2((uint16
*)p
->ntlmssp_resp
.user
, p
->ntlmssp_resp
.hdr_usr
.str_str_len
/2));
233 fstrcpy(p
->domain
, unistrn2((uint16
*)p
->ntlmssp_resp
.domain
, p
->ntlmssp_resp
.hdr_domain
.str_str_len
/2));
234 fstrcpy(p
->wks
, unistrn2((uint16
*)p
->ntlmssp_resp
.wks
, p
->ntlmssp_resp
.hdr_wks
.str_str_len
/2));
238 fstrcpy(p
->user_name
, p
->ntlmssp_resp
.user
);
239 fstrcpy(p
->domain
, p
->ntlmssp_resp
.domain
);
240 fstrcpy(p
->wks
, p
->ntlmssp_resp
.wks
);
243 DEBUG(5,("user: %s domain: %s wks: %s\n", p
->user_name
, p
->domain
, p
->wks
));
245 memcpy(lm_owf
, p
->ntlmssp_resp
.lm_resp
, sizeof(lm_owf
));
246 memcpy(nt_owf
, p
->ntlmssp_resp
.nt_resp
, sizeof(nt_owf
));
248 #ifdef DEBUG_PASSWORD
249 DEBUG(100,("lm, nt owfs, chal\n"));
250 dump_data(100, lm_owf
, sizeof(lm_owf
));
251 dump_data(100, nt_owf
, sizeof(nt_owf
));
252 dump_data(100, p
->ntlmssp_chal
.challenge
, 8);
255 p
->ntlmssp_validated
= pass_check_smb(p
->user_name
, p
->domain
,
256 (uchar
*)p
->ntlmssp_chal
.challenge
,
257 lm_owf
, nt_owf
, NULL
);
258 smb_pass
= getsmbpwnam(p
->user_name
);
261 if (p
->ntlmssp_validated
&& smb_pass
!= NULL
&& smb_pass
->smb_passwd
)
264 NTLMSSPOWFencrypt(smb_pass
->smb_passwd
, lm_owf
, p24
);
276 for (ind
= 0; ind
< 256; ind
++)
278 p
->ntlmssp_hash
[ind
] = (unsigned char)ind
;
281 for( ind
= 0; ind
< 256; ind
++)
285 j
+= (p
->ntlmssp_hash
[ind
] + k2
[ind
%8]);
287 tc
= p
->ntlmssp_hash
[ind
];
288 p
->ntlmssp_hash
[ind
] = p
->ntlmssp_hash
[j
];
289 p
->ntlmssp_hash
[j
] = tc
;
292 p
->ntlmssp_hash
[256] = 0;
293 p
->ntlmssp_hash
[257] = 0;
295 /* NTLMSSPhash(p->ntlmssp_hash, p24); */
296 p
->ntlmssp_seq_num
= 0;
300 p
->ntlmssp_validated
= False
;
303 return p
->ntlmssp_validated
;
306 static BOOL
api_pipe_ntlmssp(pipes_struct
*p
, prs_struct
*pd
)
308 /* receive a negotiate; send a challenge; receive a response */
309 switch (p
->auth_verifier
.msg_type
)
311 case NTLMSSP_NEGOTIATE
:
313 smb_io_rpc_auth_ntlmssp_neg("", &p
->ntlmssp_neg
, pd
, 0);
318 smb_io_rpc_auth_ntlmssp_resp("", &p
->ntlmssp_resp
, pd
, 0);
319 if (!api_pipe_ntlmssp_verify(p
))
327 /* NTLMSSP expected: unexpected message type */
328 DEBUG(3,("unexpected message type in NTLMSSP %d\n",
329 p
->auth_verifier
.msg_type
));
334 return (pd
->offset
!= 0);
339 char * pipe_clnt_name
;
340 char * pipe_srv_name
;
341 BOOL (*fn
) (pipes_struct
*, prs_struct
*);
344 static struct api_cmd api_fd_commands
[] =
346 { "lsarpc", "lsass", api_ntlsa_rpc
},
347 { "samr", "lsass", api_samr_rpc
},
348 { "srvsvc", "ntsvcs", api_srvsvc_rpc
},
349 { "wkssvc", "ntsvcs", api_wkssvc_rpc
},
350 { "NETLOGON", "lsass", api_netlog_rpc
},
351 { "winreg", "winreg", api_reg_rpc
},
355 static BOOL
api_pipe_bind_auth_resp(pipes_struct
*p
, prs_struct
*pd
)
357 DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__
));
359 if (p
->hdr
.auth_len
== 0) return False
;
361 /* decode the authentication verifier response */
362 smb_io_rpc_hdr_autha("", &p
->autha_info
, pd
, 0);
363 if (pd
->offset
== 0) return False
;
365 if (!rpc_hdr_auth_chk(&(p
->auth_info
))) return False
;
367 smb_io_rpc_auth_verifier("", &p
->auth_verifier
, pd
, 0);
368 if (pd
->offset
== 0) return False
;
370 if (!rpc_auth_verifier_chk(&(p
->auth_verifier
), "NTLMSSP", NTLMSSP_AUTH
)) return False
;
372 return api_pipe_ntlmssp(p
, pd
);
375 static BOOL
api_pipe_bind_req(pipes_struct
*p
, prs_struct
*pd
)
378 fstring ack_pipe_name
;
381 p
->ntlmssp_auth
= False
;
383 DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__
));
385 for (i
= 0; api_fd_commands
[i
].pipe_clnt_name
; i
++)
387 if (strequal(api_fd_commands
[i
].pipe_clnt_name
, p
->name
) &&
388 api_fd_commands
[i
].fn
!= NULL
)
390 DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
391 api_fd_commands
[i
].pipe_clnt_name
,
392 api_fd_commands
[i
].pipe_srv_name
));
393 fstrcpy(p
->pipe_srv_name
, api_fd_commands
[i
].pipe_srv_name
);
398 if (api_fd_commands
[i
].fn
== NULL
) return False
;
400 /* decode the bind request */
401 smb_io_rpc_hdr_rb("", &p
->hdr_rb
, pd
, 0);
403 if (pd
->offset
== 0) return False
;
405 if (p
->hdr
.auth_len
!= 0)
407 /* decode the authentication verifier */
408 smb_io_rpc_hdr_auth ("", &p
->auth_info
, pd
, 0);
409 if (pd
->offset
== 0) return False
;
411 p
->ntlmssp_auth
= p
->auth_info
.auth_type
= 0x0a;
415 smb_io_rpc_auth_verifier("", &p
->auth_verifier
, pd
, 0);
416 if (pd
->offset
== 0) return False
;
418 p
->ntlmssp_auth
= strequal(p
->auth_verifier
.signature
, "NTLMSSP");
423 if (!api_pipe_ntlmssp(p
, pd
)) return False
;
427 /* name has to be \PIPE\xxxxx */
428 fstrcpy(ack_pipe_name
, "\\PIPE\\");
429 fstrcat(ack_pipe_name
, p
->pipe_srv_name
);
431 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__
));
433 prs_init(&(p
->rdata
), 1024, 4, 0, False
);
434 prs_init(&(p
->rhdr
), 0x18, 4, 0, False
);
435 prs_init(&(p
->rauth
), 1024, 4, 0, False
);
436 prs_init(&(p
->rverf
), 0x08, 4, 0, False
);
437 prs_init(&(p
->rntlm
), 1024, 4, 0, False
);
440 /*** do the bind ack first ***/
449 assoc_gid
= p
->hdr_rb
.bba
.assoc_gid
;
452 make_rpc_hdr_ba(&p
->hdr_ba
,
453 p
->hdr_rb
.bba
.max_tsize
,
454 p
->hdr_rb
.bba
.max_rsize
,
458 &(p
->hdr_rb
.transfer
));
460 smb_io_rpc_hdr_ba("", &p
->hdr_ba
, &p
->rdata
, 0);
461 mem_realloc_data(p
->rdata
.data
, p
->rdata
.offset
);
464 /*** now the authentication ***/
470 generate_random_buffer(challenge
, 8, False
);
472 /*** authentication info ***/
474 make_rpc_hdr_auth(&p
->auth_info
, 0x0a, 0x06, 0, 1);
475 smb_io_rpc_hdr_auth("", &p
->auth_info
, &p
->rverf
, 0);
476 mem_realloc_data(p
->rverf
.data
, p
->rverf
.offset
);
478 /*** NTLMSSP verifier ***/
480 make_rpc_auth_verifier(&p
->auth_verifier
,
481 "NTLMSSP", NTLMSSP_CHALLENGE
);
482 smb_io_rpc_auth_verifier("", &p
->auth_verifier
, &p
->rauth
, 0);
483 mem_realloc_data(p
->rauth
.data
, p
->rauth
.offset
);
485 /* NTLMSSP challenge ***/
487 make_rpc_auth_ntlmssp_chal(&p
->ntlmssp_chal
,
488 0x000082b1, challenge
);
489 smb_io_rpc_auth_ntlmssp_chal("", &p
->ntlmssp_chal
, &p
->rntlm
, 0);
490 mem_realloc_data(p
->rntlm
.data
, p
->rntlm
.offset
);
494 /*** then do the header, now we know the length ***/
497 make_rpc_hdr(&p
->hdr
, RPC_BINDACK
, RPC_FLG_FIRST
| RPC_FLG_LAST
,
499 p
->rdata
.offset
+ p
->rverf
.offset
+ p
->rauth
.offset
+ p
->rntlm
.offset
+ 0x10,
500 p
->rauth
.offset
+ p
->rntlm
.offset
);
502 smb_io_rpc_hdr("", &p
->hdr
, &p
->rhdr
, 0);
503 mem_realloc_data(p
->rhdr
.data
, p
->rdata
.offset
);
506 /*** link rpc header, bind acknowledgment and authentication responses ***/
511 prs_link(NULL
, &p
->rhdr
, &p
->rdata
);
512 prs_link(&p
->rhdr
, &p
->rdata
, &p
->rverf
);
513 prs_link(&p
->rdata
, &p
->rverf
, &p
->rauth
);
514 prs_link(&p
->rverf
, &p
->rauth
, &p
->rntlm
);
515 prs_link(&p
->rauth
, &p
->rntlm
, NULL
);
519 prs_link(NULL
, &p
->rhdr
, &p
->rdata
);
520 prs_link(&p
->rhdr
, &p
->rdata
, NULL
);
527 static BOOL
api_pipe_auth_process(pipes_struct
*p
, prs_struct
*pd
)
529 BOOL auth_verify
= IS_BITS_SET_ALL(p
->ntlmssp_chal
.neg_flags
, NTLMSSP_NEGOTIATE_SIGN
);
530 BOOL auth_seal
= IS_BITS_SET_ALL(p
->ntlmssp_chal
.neg_flags
, NTLMSSP_NEGOTIATE_SEAL
);
536 auth_len
= p
->hdr
.auth_len
;
538 if (auth_len
!= 16 && auth_verify
)
543 data_len
= p
->hdr
.frag_len
- auth_len
- (auth_verify
? 8 : 0) - 0x18;
545 DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
546 BOOLSTR(auth_verify
), BOOLSTR(auth_seal
), data_len
, auth_len
));
550 char *data
= mem_data(&pd
->data
, pd
->offset
);
551 DEBUG(5,("api_pipe_auth_process: data %d\n", pd
->offset
));
552 NTLMSSPcalc_p(p
, (uchar
*)data
, data_len
);
553 crc32
= crc32_calc_buffer(data_len
, data
);
556 /*** skip the data, record the offset so we can restore it again */
557 old_offset
= pd
->offset
;
559 if (auth_seal
|| auth_verify
)
561 pd
->offset
+= data_len
;
562 smb_io_rpc_hdr_auth("hdr_auth", &p
->auth_info
, pd
, 0);
567 char *req_data
= mem_data(&pd
->data
, pd
->offset
+ 4);
568 DEBUG(5,("api_pipe_auth_process: auth %d\n", pd
->offset
+ 4));
569 NTLMSSPcalc_p(p
, (uchar
*)req_data
, 12);
570 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p
->ntlmssp_chk
), pd
, 0);
572 if (!rpc_auth_ntlmssp_chk(&(p
->ntlmssp_chk
), crc32
,
579 pd
->offset
= old_offset
;
584 static BOOL
api_pipe_request(pipes_struct
*p
, prs_struct
*pd
)
588 if (p
->ntlmssp_auth
&& p
->ntlmssp_validated
)
590 if (!api_pipe_auth_process(p
, pd
)) return False
;
592 DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
598 for (i
= 0; api_fd_commands
[i
].pipe_clnt_name
; i
++)
600 if (strequal(api_fd_commands
[i
].pipe_clnt_name
, p
->name
) &&
601 api_fd_commands
[i
].fn
!= NULL
)
603 DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands
[i
].pipe_clnt_name
));
604 return api_fd_commands
[i
].fn(p
, pd
);
610 BOOL
rpc_command(pipes_struct
*p
, prs_struct
*pd
)
613 if (pd
->data
== NULL
) return False
;
615 /* process the rpc header */
616 smb_io_rpc_hdr("", &p
->hdr
, pd
, 0);
618 if (pd
->offset
== 0) return False
;
620 switch (p
->hdr
.pkt_type
)
624 reply
= api_pipe_bind_req(p
, pd
);
629 if (p
->ntlmssp_auth
&& !p
->ntlmssp_validated
)
631 /* authentication _was_ requested
632 and it failed. sorry, no deal!
638 /* read the rpc header */
639 smb_io_rpc_hdr_req("req", &(p
->hdr_req
), pd
, 0);
640 reply
= api_pipe_request(p
, pd
);
644 case RPC_BINDRESP
: /* not the real name! */
646 reply
= api_pipe_bind_auth_resp(p
, pd
);
647 p
->ntlmssp_auth
= reply
;
654 DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
661 /*******************************************************************
662 receives a netlogon pipe and responds.
663 ********************************************************************/
664 static BOOL
api_rpc_command(pipes_struct
*p
,
665 char *rpc_name
, struct api_struct
*api_rpc_cmds
,
669 DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name
, p
->hdr_req
.opnum
));
671 for (fn_num
= 0; api_rpc_cmds
[fn_num
].name
; fn_num
++)
673 if (api_rpc_cmds
[fn_num
].opnum
== p
->hdr_req
.opnum
&& api_rpc_cmds
[fn_num
].fn
!= NULL
)
675 DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds
[fn_num
].name
));
680 if (api_rpc_cmds
[fn_num
].name
== NULL
)
682 DEBUG(4, ("unknown\n"));
686 /* start off with 1024 bytes, and a large safety margin too */
687 prs_init(&p
->rdata
, 1024, 4, SAFETY_MARGIN
, False
);
689 /* do the actual command */
690 api_rpc_cmds
[fn_num
].fn(p
->vuid
, data
, &(p
->rdata
));
692 if (p
->rdata
.data
== NULL
|| p
->rdata
.offset
== 0)
694 mem_free_data(p
->rdata
.data
);
698 mem_realloc_data(p
->rdata
.data
, p
->rdata
.offset
);
700 DEBUG(10,("called %s\n", rpc_name
));
706 /*******************************************************************
707 receives a netlogon pipe and responds.
708 ********************************************************************/
709 BOOL
api_rpcTNP(pipes_struct
*p
, char *rpc_name
, struct api_struct
*api_rpc_cmds
,
712 if (data
== NULL
|| data
->data
== NULL
)
714 DEBUG(2,("%s: NULL data received\n", rpc_name
));
718 /* interpret the command */
719 if (!api_rpc_command(p
, rpc_name
, api_rpc_cmds
, data
))
724 /* create the rpc header */
725 if (!create_rpc_reply(p
, 0, p
->rdata
.offset
+ (p
->ntlmssp_auth
? (16 + 8) : 0)))