2 Unix SMB/Netbios implementation.
4 NT Domain Authentication SMB / MSRPC client
5 Copyright (C) Andrew Tridgell 1994-1997
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 extern int DEBUGLEVEL
;
34 extern struct cli_state
*smb_cli
;
43 * [HKLM]|[HKU]\[parent_keyname_components]\[subkey]|[value]
45 * reg_getsubkey() splits this down into:
46 * [HKLM]|[HKU]\[parent_keyname_components] and [subkey]|[value]
48 * do_reg_connect() splits the left side down further into:
49 * [HKLM]|[HKU] and [parent_keyname_components].
51 * HKLM is short for HKEY_LOCAL_MACHINE
52 * HKU is short for HKEY_USERS
54 * oh, and HKEY stands for "Hive Key".
58 /****************************************************************************
60 ****************************************************************************/
61 void cmd_reg_enum(struct client_info
*info
)
77 uint32 max_class_len
= 0;
80 uint32 max_subkeysize
;
82 uint32 max_valnamelen
;
83 uint32 max_valbufsize
;
88 * unknown 0x1a request
91 uint32 unk_1a_response
;
93 DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli
->fd
));
95 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
97 fprintf(out_hnd
, "regenum <key_name>\n");
101 /* open WINREG session. */
102 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
104 /* open registry receive a policy handle */
105 res
= res
? do_reg_connect(smb_cli
, full_keyname
, key_name
,
106 &info
->dom
.reg_pol_connect
) : False
;
108 if ((*key_name
) != 0)
111 res1
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
112 key_name
, 0x02000000, &key_pol
) : False
;
116 memcpy(&key_pol
, &info
->dom
.reg_pol_connect
, sizeof(key_pol
));
119 res1
= res1
? do_reg_query_key(smb_cli
,
121 key_class
, &max_class_len
,
122 &num_subkeys
, &max_subkeylen
, &max_subkeysize
,
123 &num_values
, &max_valnamelen
, &max_valbufsize
,
124 &sec_desc
, &mod_time
) : False
;
126 if (res1
&& num_subkeys
> 0)
128 fprintf(out_hnd
,"Subkeys\n");
129 fprintf(out_hnd
,"-------\n");
132 for (i
= 0; i
< num_subkeys
; i
++)
144 res2
= res1
? do_reg_unknown_1a(smb_cli
, &key_pol
,
145 &unk_1a_response
) : False
;
147 if (res2
&& unk_1a_response
!= 5)
149 fprintf(out_hnd
,"Unknown 1a response: %x\n", unk_1a_response
);
153 res2
= res2
? do_reg_enum_key(smb_cli
, &key_pol
,
155 &enum_unk1
, &enum_unk2
,
156 &key_mod_time
) : False
;
160 display_reg_key_info(out_hnd
, ACTION_HEADER
, enum_name
, key_mod_time
);
161 display_reg_key_info(out_hnd
, ACTION_ENUMERATE
, enum_name
, key_mod_time
);
162 display_reg_key_info(out_hnd
, ACTION_FOOTER
, enum_name
, key_mod_time
);
169 fprintf(out_hnd
,"Key Values\n");
170 fprintf(out_hnd
,"----------\n");
173 for (i
= 0; i
< num_values
; i
++)
184 res2
= res1
? do_reg_unknown_1a(smb_cli
, &key_pol
,
185 &unk_1a_response
) : False
;
187 if (res2
&& unk_1a_response
!= 5)
189 fprintf(out_hnd
,"Unknown 1a response: %x\n", unk_1a_response
);
193 res2
= res2
? do_reg_enum_val(smb_cli
, &key_pol
,
194 i
, max_valnamelen
, max_valbufsize
,
195 val_name
, &val_type
, &value
) : False
;
199 display_reg_value_info(out_hnd
, ACTION_HEADER
, val_name
, val_type
, &value
);
200 display_reg_value_info(out_hnd
, ACTION_ENUMERATE
, val_name
, val_type
, &value
);
201 display_reg_value_info(out_hnd
, ACTION_FOOTER
, val_name
, val_type
, &value
);
205 /* close the handles */
206 if ((*key_name
) != 0)
208 res1
= res1
? do_reg_close(smb_cli
, &key_pol
) : False
;
210 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
212 /* close the session */
213 cli_nt_session_close(smb_cli
);
215 if (res
&& res1
&& res2
)
217 DEBUG(5,("cmd_reg_enum: query succeeded\n"));
221 DEBUG(5,("cmd_reg_enum: query failed\n"));
225 /****************************************************************************
226 nt registry query key
227 ****************************************************************************/
228 void cmd_reg_query_key(struct client_info
*info
)
234 fstring full_keyname
;
242 uint32 key_class_len
= 0;
244 uint32 max_subkeylen
;
245 uint32 max_subkeysize
;
247 uint32 max_valnamelen
;
248 uint32 max_valbufsize
;
252 DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli
->fd
));
254 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
256 fprintf(out_hnd
, "regquery key_name\n");
260 /* open WINREG session. */
261 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
263 /* open registry receive a policy handle */
264 res
= res
? do_reg_connect(smb_cli
, full_keyname
, key_name
,
265 &info
->dom
.reg_pol_connect
) : False
;
267 if ((*key_name
) != 0)
270 res1
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
271 key_name
, 0x02000000, &key_pol
) : False
;
275 memcpy(&key_pol
, &info
->dom
.reg_pol_connect
, sizeof(key_pol
));
278 res1
= res1
? do_reg_query_key(smb_cli
,
280 key_class
, &key_class_len
,
281 &num_subkeys
, &max_subkeylen
, &max_subkeysize
,
282 &num_values
, &max_valnamelen
, &max_valbufsize
,
283 &sec_desc
, &mod_time
) : False
;
285 if (res1
&& key_class_len
!= 0)
287 res1
= res1
? do_reg_query_key(smb_cli
,
289 key_class
, &key_class_len
,
290 &num_subkeys
, &max_subkeylen
, &max_subkeysize
,
291 &num_values
, &max_valnamelen
, &max_valbufsize
,
292 &sec_desc
, &mod_time
) : False
;
297 fprintf(out_hnd
,"Registry Query Info Key\n");
298 fprintf(out_hnd
,"key class: %s\n", key_class
);
299 fprintf(out_hnd
,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys
, max_subkeylen
, max_subkeysize
);
300 fprintf(out_hnd
,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values
, max_valnamelen
, max_valbufsize
);
301 fprintf(out_hnd
,"sec desc: 0x%x\n", sec_desc
);
302 fprintf(out_hnd
,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time
)));
305 /* close the handles */
306 if ((*key_name
) != 0)
308 res1
= res1
? do_reg_close(smb_cli
, &key_pol
) : False
;
310 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
312 /* close the session */
313 cli_nt_session_close(smb_cli
);
317 DEBUG(5,("cmd_reg_query: query succeeded\n"));
321 DEBUG(5,("cmd_reg_query: query failed\n"));
325 /****************************************************************************
326 nt registry create value
327 ****************************************************************************/
328 void cmd_reg_create_val(struct client_info
*info
)
334 POLICY_HND parent_pol
;
335 fstring full_keyname
;
347 res1
= res1
? do_reg_query_info(smb_cli
, &val_pol
,
348 type
, &unk_0
, &unk_1
) : False
;
351 DEBUG(5, ("cmd_reg_create_val: smb_cli->fd:%d\n", smb_cli
->fd
));
353 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
355 fprintf(out_hnd
, "regcreate <val_name> <val_type> <val>\n");
359 reg_get_subkey(full_keyname
, keyname
, val_name
);
361 if (keyname
[0] == 0 || val_name
[0] == 0)
363 fprintf(out_hnd
, "invalid key name\n");
367 if (!next_token(NULL
, tmp
, NULL
, sizeof(tmp
)))
369 fprintf(out_hnd
, "regcreate <val_name> <val_type (1|4)> <val>\n");
373 val_type
= atoi(tmp
);
375 if (val_type
!= 1 && val_type
!= 3 && val_type
!= 4)
377 fprintf(out_hnd
, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
381 if (!next_token(NULL
, tmp
, NULL
, sizeof(tmp
)))
383 fprintf(out_hnd
, "regcreate <val_name> <val_type (1|4)> <val>\n");
389 case 0x01: /* UNISTR */
391 init_buffer3_str(&value
, tmp
, strlen(tmp
)+1);
394 case 0x03: /* BYTES */
396 init_buffer3_hex(&value
, tmp
);
399 case 0x04: /* DWORD */
402 if (strnequal(tmp
, "0x", 2))
404 tmp_val
= strtol(tmp
, (char**)NULL
, 16);
408 tmp_val
= strtol(tmp
, (char**)NULL
, 10);
410 init_buffer3_uint32(&value
, tmp_val
);
415 fprintf(out_hnd
, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
420 DEBUG(10,("key data:\n"));
421 dump_data(10, (char *)value
.buffer
, value
.buf_len
);
423 /* open WINREG session. */
424 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
426 /* open registry receive a policy handle */
427 res
= res
? do_reg_connect(smb_cli
, keyname
, parent_name
,
428 &info
->dom
.reg_pol_connect
) : False
;
430 if ((*val_name
) != 0)
433 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
434 parent_name
, 0x02000000, &parent_pol
) : False
;
438 memcpy(&parent_pol
, &info
->dom
.reg_pol_connect
, sizeof(parent_pol
));
441 /* create an entry */
442 res4
= res3
? do_reg_create_val(smb_cli
, &parent_pol
,
443 val_name
, val_type
, &value
) : False
;
445 /* flush the modified key */
446 res4
= res4
? do_reg_flush_key(smb_cli
, &parent_pol
) : False
;
448 /* close the val handle */
449 if ((*val_name
) != 0)
451 res3
= res3
? do_reg_close(smb_cli
, &parent_pol
) : False
;
454 /* close the registry handles */
455 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
457 /* close the session */
458 cli_nt_session_close(smb_cli
);
460 if (res
&& res3
&& res4
)
462 DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
463 fprintf(out_hnd
,"OK\n");
467 DEBUG(5,("cmd_reg_create_val: query failed\n"));
471 /****************************************************************************
472 nt registry delete value
473 ****************************************************************************/
474 void cmd_reg_delete_val(struct client_info
*info
)
480 POLICY_HND parent_pol
;
481 fstring full_keyname
;
486 DEBUG(5, ("cmd_reg_delete_val: smb_cli->fd:%d\n", smb_cli
->fd
));
488 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
490 fprintf(out_hnd
, "regdelete <val_name>\n");
494 reg_get_subkey(full_keyname
, keyname
, val_name
);
496 if (keyname
[0] == 0 || val_name
[0] == 0)
498 fprintf(out_hnd
, "invalid key name\n");
502 /* open WINREG session. */
503 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
505 /* open registry receive a policy handle */
506 res
= res
? do_reg_connect(smb_cli
, keyname
, parent_name
,
507 &info
->dom
.reg_pol_connect
) : False
;
509 if ((*val_name
) != 0)
512 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
513 parent_name
, 0x02000000, &parent_pol
) : False
;
517 memcpy(&parent_pol
, &info
->dom
.reg_pol_connect
, sizeof(parent_pol
));
520 /* delete an entry */
521 res4
= res3
? do_reg_delete_val(smb_cli
, &parent_pol
, val_name
) : False
;
523 /* flush the modified key */
524 res4
= res4
? do_reg_flush_key(smb_cli
, &parent_pol
) : False
;
526 /* close the key handle */
527 res3
= res3
? do_reg_close(smb_cli
, &parent_pol
) : False
;
529 /* close the registry handles */
530 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
532 /* close the session */
533 cli_nt_session_close(smb_cli
);
535 if (res
&& res3
&& res4
)
537 DEBUG(5,("cmd_reg_delete_val: query succeeded\n"));
538 fprintf(out_hnd
,"OK\n");
542 DEBUG(5,("cmd_reg_delete_val: query failed\n"));
546 /****************************************************************************
547 nt registry delete key
548 ****************************************************************************/
549 void cmd_reg_delete_key(struct client_info
*info
)
555 POLICY_HND parent_pol
;
556 fstring full_keyname
;
561 DEBUG(5, ("cmd_reg_delete_key: smb_cli->fd:%d\n", smb_cli
->fd
));
563 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
565 fprintf(out_hnd
, "regdeletekey <key_name>\n");
569 reg_get_subkey(full_keyname
, parent_name
, subkey_name
);
571 if (parent_name
[0] == 0 || subkey_name
[0] == 0)
573 fprintf(out_hnd
, "invalid key name\n");
577 /* open WINREG session. */
578 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
580 /* open registry receive a policy handle */
581 res
= res
? do_reg_connect(smb_cli
, parent_name
, key_name
,
582 &info
->dom
.reg_pol_connect
) : False
;
584 if ((*key_name
) != 0)
587 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
588 key_name
, 0x02000000, &parent_pol
) : False
;
592 memcpy(&parent_pol
, &info
->dom
.reg_pol_connect
, sizeof(parent_pol
));
595 /* create an entry */
596 res4
= res3
? do_reg_delete_key(smb_cli
, &parent_pol
, subkey_name
) : False
;
598 /* flush the modified key */
599 res4
= res4
? do_reg_flush_key(smb_cli
, &parent_pol
) : False
;
601 /* close the key handle */
602 if ((*key_name
) != 0)
604 res3
= res3
? do_reg_close(smb_cli
, &parent_pol
) : False
;
607 /* close the registry handles */
608 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
610 /* close the session */
611 cli_nt_session_close(smb_cli
);
613 if (res
&& res3
&& res4
)
615 DEBUG(5,("cmd_reg_delete_key: query succeeded\n"));
616 fprintf(out_hnd
,"OK\n");
620 DEBUG(5,("cmd_reg_delete_key: query failed\n"));
624 /****************************************************************************
625 nt registry create key
626 ****************************************************************************/
627 void cmd_reg_create_key(struct client_info
*info
)
633 POLICY_HND parent_pol
;
635 fstring full_keyname
;
640 SEC_ACCESS sam_access
;
642 DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli
->fd
));
644 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
646 fprintf(out_hnd
, "regcreate <key_name> [key_class]\n");
650 reg_get_subkey(full_keyname
, parent_key
, key_name
);
652 if (parent_key
[0] == 0 || key_name
[0] == 0)
654 fprintf(out_hnd
, "invalid key name\n");
658 if (!next_token(NULL
, key_class
, NULL
, sizeof(key_class
)))
660 memset(key_class
, 0, sizeof(key_class
));
663 /* set access permissions */
664 sam_access
.mask
= SEC_RIGHTS_READ
;
666 /* open WINREG session. */
667 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
669 /* open registry receive a policy handle */
670 res
= res
? do_reg_connect(smb_cli
, parent_key
, parent_name
,
671 &info
->dom
.reg_pol_connect
) : False
;
673 if ((*parent_name
) != 0)
676 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
677 parent_name
, 0x02000000, &parent_pol
) : False
;
681 memcpy(&parent_pol
, &info
->dom
.reg_pol_connect
, sizeof(parent_pol
));
684 /* create an entry */
685 res4
= res3
? do_reg_create_key(smb_cli
, &parent_pol
,
686 key_name
, key_class
, &sam_access
, &key_pol
) : False
;
688 /* flush the modified key */
689 res4
= res4
? do_reg_flush_key(smb_cli
, &parent_pol
) : False
;
691 /* close the key handle */
692 res4
= res4
? do_reg_close(smb_cli
, &key_pol
) : False
;
694 /* close the key handle */
695 if ((*parent_name
) != 0)
697 res3
= res3
? do_reg_close(smb_cli
, &parent_pol
) : False
;
700 /* close the registry handles */
701 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
703 /* close the session */
704 cli_nt_session_close(smb_cli
);
706 if (res
&& res3
&& res4
)
708 DEBUG(5,("cmd_reg_create_key: query succeeded\n"));
709 fprintf(out_hnd
,"OK\n");
713 DEBUG(5,("cmd_reg_create_key: query failed\n"));
717 /****************************************************************************
718 nt registry security info
719 ****************************************************************************/
720 void cmd_reg_test_key_sec(struct client_info
*info
)
727 fstring full_keyname
;
737 DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli
->fd
));
739 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
741 fprintf(out_hnd
, "reggetsec <key_name>\n");
745 /* open WINREG session. */
746 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
748 /* open registry receive a policy handle */
749 res
= res
? do_reg_connect(smb_cli
, full_keyname
, key_name
,
750 &info
->dom
.reg_pol_connect
) : False
;
752 if ((*key_name
) != 0)
755 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
756 key_name
, 0x02000000, &key_pol
) : False
;
760 memcpy(&key_pol
, &info
->dom
.reg_pol_connect
, sizeof(key_pol
));
764 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
765 key_name
, 0x02000000, &key_pol
) : False
;
767 /* query key sec info. first call sets sec_buf_size. */
770 res4
= res3
? do_reg_get_key_sec(smb_cli
, &key_pol
,
771 &sec_buf_size
, &psdb
) : False
;
773 free_sec_desc_buf(&psdb
);
775 res4
= res4
? do_reg_get_key_sec(smb_cli
, &key_pol
,
776 &sec_buf_size
, &psdb
) : False
;
778 if (res4
&& psdb
->len
> 0 && psdb
->sec
!= NULL
)
780 display_sec_desc(out_hnd
, ACTION_HEADER
, psdb
->sec
);
781 display_sec_desc(out_hnd
, ACTION_ENUMERATE
, psdb
->sec
);
782 display_sec_desc(out_hnd
, ACTION_FOOTER
, psdb
->sec
);
784 res4
= res4
? do_reg_set_key_sec(smb_cli
, &key_pol
, psdb
) : False
;
787 free_sec_desc_buf(&psdb
);
789 /* close the key handle */
790 if ((*key_name
) != 0)
792 res3
= res3
? do_reg_close(smb_cli
, &key_pol
) : False
;
795 /* close the registry handles */
796 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
798 /* close the session */
799 cli_nt_session_close(smb_cli
);
801 if (res
&& res3
&& res4
)
803 DEBUG(5,("cmd_reg_test2: query succeeded\n"));
804 fprintf(out_hnd
,"Registry Test2\n");
808 DEBUG(5,("cmd_reg_test2: query failed\n"));
812 /****************************************************************************
813 nt registry security info
814 ****************************************************************************/
815 void cmd_reg_get_key_sec(struct client_info
*info
)
822 fstring full_keyname
;
832 DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli
->fd
));
834 if (!next_token(NULL
, full_keyname
, NULL
, sizeof(full_keyname
)))
836 fprintf(out_hnd
, "reggetsec <key_name>\n");
840 /* open WINREG session. */
841 res
= res
? cli_nt_session_open(smb_cli
, PIPE_WINREG
) : False
;
843 /* open registry receive a policy handle */
844 res
= res
? do_reg_connect(smb_cli
, full_keyname
, key_name
,
845 &info
->dom
.reg_pol_connect
) : False
;
847 if ((*key_name
) != 0)
850 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
851 key_name
, 0x02000000, &key_pol
) : False
;
855 memcpy(&key_pol
, &info
->dom
.reg_pol_connect
, sizeof(key_pol
));
859 res3
= res
? do_reg_open_entry(smb_cli
, &info
->dom
.reg_pol_connect
,
860 key_name
, 0x02000000, &key_pol
) : False
;
864 res4
= res3
? do_reg_get_key_sec(smb_cli
, &key_pol
,
865 &sec_buf_size
, &psdb
) : False
;
867 free_sec_desc_buf(&psdb
);
869 res4
= res4
? do_reg_get_key_sec(smb_cli
, &key_pol
,
870 &sec_buf_size
, &psdb
) : False
;
872 if (res4
&& psdb
->len
> 0 && psdb
->sec
!= NULL
)
874 display_sec_desc(out_hnd
, ACTION_HEADER
, psdb
->sec
);
875 display_sec_desc(out_hnd
, ACTION_ENUMERATE
, psdb
->sec
);
876 display_sec_desc(out_hnd
, ACTION_FOOTER
, psdb
->sec
);
879 free_sec_desc_buf(&psdb
);
881 /* close the key handle */
882 if ((*key_name
) != 0)
884 res3
= res3
? do_reg_close(smb_cli
, &key_pol
) : False
;
887 /* close the registry handles */
888 res
= res
? do_reg_close(smb_cli
, &info
->dom
.reg_pol_connect
) : False
;
890 /* close the session */
891 cli_nt_session_close(smb_cli
);
893 if (res
&& res3
&& res4
)
895 DEBUG(5,("cmd_reg_get_key_sec: query succeeded\n"));
899 DEBUG(5,("cmd_reg_get_key_sec: query failed\n"));