diff options
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/include/proto.h | 9 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 6 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg.c | 220 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 158 |
5 files changed, 218 insertions, 177 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index ff169ce969..c5b9ab596c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -130,7 +130,7 @@ LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \ RPC_SERVER_OBJ = rpc_server/srv_lsa.o \ rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \ - rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o \ + rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o rpc_server/srv_reg_nt.o \ rpc_server/srv_samr.o rpc_server/srv_srvsvc.o \ rpc_server/srv_util.o rpc_server/srv_wkssvc.o \ rpc_server/srv_pipe.o rpc_server/srv_dfs.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 764fcf0e62..ef57669608 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3381,6 +3381,15 @@ pipes_struct *get_rpc_pipe(int pnum); BOOL api_reg_rpc(pipes_struct *p); #endif +/*The following definitions come from rpc_server/srv_reg_nt.c */ + +#if OLD_NTDOMAIN +uint32 _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u); +uint32 _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u); +uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u); +uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u); +#endif + /*The following definitions come from rpc_server/srv_samr.c */ #if OLD_NTDOMAIN diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f6ada87840..01ec5e9b29 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -198,7 +198,7 @@ BOOL name_register(int fd, const char *name, int name_type, BOOL bcast, struct in_addr to_ip, int *count) { - int i, retries = 3, retry = bcast?250:2000; + int retries = 3; struct timeval tval; struct packet_struct p; struct packet_struct *p2; @@ -274,12 +274,8 @@ BOOL name_register(int fd, const char *name, int name_type, retries--; if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); - - free(p2); /* No memory leaks ... */ - } return True; diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c index dd411fc55e..1ca9963cd4 100644 --- a/source3/rpc_server/srv_reg.c +++ b/source3/rpc_server/srv_reg.c @@ -7,7 +7,8 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. * Copyright (C) Hewlett-Packard Company 1999. - * + * Copyright (C) Jeremy Allison 2001. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -23,237 +24,113 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* This is the interface for the registry functions. */ #include "includes.h" extern int DEBUGLEVEL; /******************************************************************* - reg_reply_unknown_1 - ********************************************************************/ -static void reg_reply_close(REG_Q_CLOSE *q_r, - prs_struct *rdata) -{ - REG_R_CLOSE r_u; - - /* set up the REG unknown_1 response */ - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - - /* close the policy handle */ - if (close_lsa_policy_hnd(&(q_r->pol))) - { - r_u.status = 0; - } - else - { - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID; - } - - DEBUG(5,("reg_unknown_1: %d\n", __LINE__)); - - /* store the response in the SMB stream */ - reg_io_r_close("", &r_u, rdata, 0); - - DEBUG(5,("reg_unknown_1: %d\n", __LINE__)); -} - -/******************************************************************* api_reg_close ********************************************************************/ + static BOOL api_reg_close(pipes_struct *p) { - REG_Q_CLOSE q_r; + REG_Q_CLOSE q_u; + REG_R_CLOSE r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; - /* grab the reg unknown 1 */ - reg_io_q_close("", &q_r, data, 0); - - /* construct reply. always indicate success */ - reg_reply_close(&q_r, rdata); + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); - return True; -} - - -/******************************************************************* - reg_reply_open - ********************************************************************/ -static void reg_reply_open(REG_Q_OPEN_HKLM *q_r, - prs_struct *rdata) -{ - REG_R_OPEN_HKLM r_u; - - r_u.status = 0x0; - /* get a (unique) handle. open a policy on it. */ - if (r_u.status == 0x0 && !open_lsa_policy_hnd(&(r_u.pol))) - { - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; - } + /* grab the reg unknown 1 */ + if(!reg_io_q_close("", &q_u, data, 0)) + return False; - DEBUG(5,("reg_open: %d\n", __LINE__)); + r_u.status = _reg_close(p, &q_u, &r_u); - /* store the response in the SMB stream */ - reg_io_r_open_hklm("", &r_u, rdata, 0); + if(!reg_io_r_close("", &r_u, rdata, 0)) + return False; - DEBUG(5,("reg_open: %d\n", __LINE__)); + return True; } /******************************************************************* api_reg_open ********************************************************************/ + static BOOL api_reg_open(pipes_struct *p) { REG_Q_OPEN_HKLM q_u; + REG_R_OPEN_HKLM r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; - /* grab the reg open */ - reg_io_q_open_hklm("", &q_u, data, 0); - - /* construct reply. always indicate success */ - reg_reply_open(&q_u, rdata); - - return True; -} - - -/******************************************************************* - reg_reply_open_entry - ********************************************************************/ -static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u, - prs_struct *rdata) -{ - uint32 status = 0; - POLICY_HND pol; - REG_R_OPEN_ENTRY r_u; - fstring name; - - DEBUG(5,("reg_open_entry: %d\n", __LINE__)); - - if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1) - { - status = NT_STATUS_INVALID_HANDLE; - } + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); - if (status == 0x0 && !open_lsa_policy_hnd(&pol)) - { - status = NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */ - } - - fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len)); - - if (status == 0x0) - { - DEBUG(5,("reg_open_entry: %s\n", name)); - /* lkcl XXXX do a check on the name, here */ - if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions")) - { - status = NT_STATUS_ACCESS_DENIED; - } - } - - if (status == 0x0 && !set_lsa_policy_reg_name(&pol, name)) - { - status = NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */ - } + /* grab the reg open */ + if(!reg_io_q_open_hklm("", &q_u, data, 0)) + return False; - init_reg_r_open_entry(&r_u, &pol, status); + r_u.status = _reg_open(p, &q_u, &r_u); - /* store the response in the SMB stream */ - reg_io_r_open_entry("", &r_u, rdata, 0); + if(!reg_io_r_open_hklm("", &r_u, rdata, 0)) + return False; - DEBUG(5,("reg_open_entry: %d\n", __LINE__)); + return True; } /******************************************************************* api_reg_open_entry ********************************************************************/ + static BOOL api_reg_open_entry(pipes_struct *p) { REG_Q_OPEN_ENTRY q_u; + REG_R_OPEN_ENTRY r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + /* grab the reg open entry */ - reg_io_q_open_entry("", &q_u, data, 0); + if(!reg_io_q_open_entry("", &q_u, data, 0)) + return False; /* construct reply. */ - reg_reply_open_entry(&q_u, rdata); + r_u.status = _reg_open_entry(p, &q_u, &r_u); - return True; -} - - -/******************************************************************* - reg_reply_info - ********************************************************************/ -static void reg_reply_info(REG_Q_INFO *q_u, - prs_struct *rdata) -{ - uint32 status = 0; - char *key; - uint32 type=0x1; /* key type: REG_SZ */ - - UNISTR2 uni_key; - BUFFER2 buf; + if(!reg_io_r_open_entry("", &r_u, rdata, 0)) + return False; - REG_R_INFO r_u; - - DEBUG(5,("reg_info: %d\n", __LINE__)); - - if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1) - { - status = NT_STATUS_INVALID_HANDLE; - } - - switch (lp_server_role()) - { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - { - key = "LanmanNT"; - break; - } - case ROLE_STANDALONE: - { - key = "ServerNT"; - break; - } - case ROLE_DOMAIN_MEMBER: - { - key = "WinNT"; - break; - } - } - /* This makes the server look like a member server to clients */ - /* which tells clients that we have our own local user and */ - /* group databases and helps with ACL support. */ - init_unistr2(&uni_key, key, strlen(key)+1); - init_buffer2(&buf, (uint8*) uni_key.buffer, uni_key.uni_str_len*2); - - init_reg_r_info(q_u->ptr_buf, &r_u, &buf, type, status); - - /* store the response in the SMB stream */ - reg_io_r_info("", &r_u, rdata, 0); - - DEBUG(5,("reg_open_entry: %d\n", __LINE__)); + return True; } /******************************************************************* api_reg_info ********************************************************************/ + static BOOL api_reg_info(pipes_struct *p) { REG_Q_INFO q_u; + REG_R_INFO r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + /* grab the reg unknown 0x11*/ - reg_io_q_info("", &q_u, data, 0); + if(!reg_io_q_info("", &q_u, data, 0)) + return False; - /* construct reply. always indicate success */ - reg_reply_info(&q_u, rdata); + r_u.status = _reg_info(p, &q_u, &r_u); + + if(!reg_io_r_info("", &r_u, rdata, 0)) + return False; return True; } @@ -274,6 +151,7 @@ static struct api_struct api_reg_cmds[] = /******************************************************************* receives a reg pipe and responds. ********************************************************************/ + BOOL api_reg_rpc(pipes_struct *p) { return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds); diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c new file mode 100644 index 0000000000..769b376468 --- /dev/null +++ b/source3/rpc_server/srv_reg_nt.c @@ -0,0 +1,158 @@ +#define OLD_NTDOMAIN 1 +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-1997, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, + * Copyright (C) Paul Ashton 1997. + * Copyright (C) Hewlett-Packard Company 1999. + * Copyright (C) Jeremy Allison 2001. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Implementation of registry functions. */ + +#include "includes.h" + +extern int DEBUGLEVEL; + +/******************************************************************* + reg_reply_unknown_1 + ********************************************************************/ + +uint32 _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) +{ + /* set up the REG unknown_1 response */ + memset((char *)r_u->pol.data, '\0', POL_HND_SIZE); + + /* close the policy handle */ + if (!close_lsa_policy_hnd(&q_u->pol)) + return NT_STATUS_OBJECT_NAME_INVALID; + + return NT_STATUS_NOPROBLEMO; +} + +/******************************************************************* + reg_reply_open + ********************************************************************/ + +uint32 _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u) +{ + if (!open_lsa_policy_hnd(&r_u->pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + + return NT_STATUS_NOPROBLEMO; +} + +/******************************************************************* + reg_reply_open_entry + ********************************************************************/ + +uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u) +{ + POLICY_HND pol; + fstring name; + + DEBUG(5,("reg_open_entry: %d\n", __LINE__)); + + if (find_lsa_policy_by_hnd(&q_u->pol) == -1) + return NT_STATUS_INVALID_HANDLE; + + if (!open_lsa_policy_hnd(&pol)) + return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */ + + fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len)); + + DEBUG(5,("reg_open_entry: %s\n", name)); + + /* lkcl XXXX do a check on the name, here */ + if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions") && + !strequal(name, "System\\CurrentControlSet\\services\\Netlogon\\parameters\\")) + return NT_STATUS_ACCESS_DENIED; + + if (!set_lsa_policy_reg_name(&pol, name)) + return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */ + + init_reg_r_open_entry(r_u, &pol, NT_STATUS_NOPROBLEMO); + + DEBUG(5,("reg_open_entry: %d\n", __LINE__)); + + return r_u->status; +} + +/******************************************************************* + reg_reply_info + ********************************************************************/ + +uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) +{ + uint32 status = NT_STATUS_NOPROBLEMO; + char *key; + uint32 type=0x1; /* key type: REG_SZ */ + + UNISTR2 uni_key; + BUFFER2 buf; + fstring name; + + DEBUG(5,("_reg_info: %d\n", __LINE__)); + + if (find_lsa_policy_by_hnd(&q_u->pol) == -1) + return NT_STATUS_INVALID_HANDLE; + + fstrcpy(name, dos_unistrn2(q_u->uni_type.buffer, q_u->uni_type.uni_str_len)); + + DEBUG(5,("reg_info: checking key: %s\n", name)); + + if ( strequal(name, "RefusePasswordChange") ) { + type=0xF770; + status = ERRbadfile; + init_unistr2(&uni_key, "", 0); + init_buffer2(&buf, (uint8*) uni_key.buffer, uni_key.uni_str_len*2); + + buf.buf_max_len=4; + + goto out; + } + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + key = "LanmanNT"; + break; + case ROLE_STANDALONE: + key = "ServerNT"; + break; + case ROLE_DOMAIN_MEMBER: + key = "WinNT"; + break; + } + + /* This makes the server look like a member server to clients */ + /* which tells clients that we have our own local user and */ + /* group databases and helps with ACL support. */ + + init_unistr2(&uni_key, key, strlen(key)+1); + init_buffer2(&buf, (uint8*)uni_key.buffer, uni_key.uni_str_len*2); + + out: + init_reg_r_info(q_u->ptr_buf, r_u, &buf, type, status); + + DEBUG(5,("reg_open_entry: %d\n", __LINE__)); + + return status; +} +#undef OLD_NTDOMAIN |