diff options
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_lsa.c | 789 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 1277 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog.c | 363 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog_nt.c | 859 | ||||
-rw-r--r-- | source3/rpc_server/srv_ntsvcs.c | 107 | ||||
-rw-r--r-- | source3/rpc_server/srv_ntsvcs_nt.c | 636 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 63 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 19 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_util.c | 1 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc.c | 87 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 376 | ||||
-rw-r--r-- | source3/rpc_server/srv_svcctl.c | 180 | ||||
-rw-r--r-- | source3/rpc_server/srv_svcctl_nt.c | 502 | ||||
-rw-r--r-- | source3/rpc_server/srv_winreg_nt.c | 297 | ||||
-rw-r--r-- | source3/rpc_server/srv_wkssvc_nt.c | 91 |
15 files changed, 2199 insertions, 3448 deletions
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c deleted file mode 100644 index f48a397f1d..0000000000 --- a/source3/rpc_server/srv_lsa.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * 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) Jeremy Allison 2001, - * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003. - * Copyright (C) Gerald (Jerry) Carter 2005 - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - */ - -/* This is the interface to the lsa server code. */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -static bool proxy_lsa_call(pipes_struct *p, uint8 opnum) -{ - struct api_struct *fns; - int n_fns; - - lsarpc_get_pipe_fns(&fns, &n_fns); - - if (opnum >= n_fns) - return False; - - if (fns[opnum].opnum != opnum) { - smb_panic("LSA function table not sorted"); - } - - return fns[opnum].fn(p); -} - -/*************************************************************************** - api_lsa_open_policy2 - ***************************************************************************/ - -static bool api_lsa_open_policy2(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENPOLICY2); -} - -/*************************************************************************** -api_lsa_open_policy - ***************************************************************************/ - -static bool api_lsa_open_policy(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENPOLICY); -} - -/*************************************************************************** - api_lsa_enum_trust_dom - ***************************************************************************/ - -static bool api_lsa_enum_trust_dom(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_ENUMTRUSTDOM); -} - -/*************************************************************************** - api_lsa_query_info - ***************************************************************************/ - -static bool api_lsa_query_info(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_QUERYINFOPOLICY); -} - -/*************************************************************************** - api_lsa_lookup_sids - ***************************************************************************/ - -static bool api_lsa_lookup_sids(pipes_struct *p) -{ - LSA_Q_LOOKUP_SIDS q_u; - LSA_R_LOOKUP_SIDS 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 info class and policy handle */ - if(!lsa_io_q_lookup_sids("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n")); - return False; - } - - r_u.status = _lsa_lookup_sids(p, &q_u, &r_u); - - if(!lsa_io_r_lookup_sids("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names - ***************************************************************************/ - -static bool api_lsa_lookup_names(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES q_u; - LSA_R_LOOKUP_NAMES 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 info class and policy handle */ - if(!lsa_io_q_lookup_names("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n")); - return False; - } - - r_u.status = _lsa_lookup_names(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_close. - ***************************************************************************/ - -static bool api_lsa_close(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CLOSE); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_open_secret(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENSECRET); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_enum_privs(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_ENUMPRIVS); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_priv_get_dispname(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_LOOKUPPRIVDISPLAYNAME); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_enum_accounts(pipes_struct *p) -{ - LSA_Q_ENUM_ACCOUNTS q_u; - LSA_R_ENUM_ACCOUNTS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_accounts("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_accounts: failed to unmarshall LSA_Q_ENUM_ACCOUNTS.\n")); - return False; - } - - r_u.status = _lsa_enum_accounts(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_accounts("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_accounts: Failed to marshall LSA_R_ENUM_ACCOUNTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_UNK_GET_CONNUSER - ***************************************************************************/ - -static bool api_lsa_unk_get_connuser(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_GETUSERNAME); -} - -/*************************************************************************** - api_lsa_create_user - ***************************************************************************/ - -static bool api_lsa_create_account(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CREATEACCOUNT); -} - -/*************************************************************************** - api_lsa_open_user - ***************************************************************************/ - -static bool api_lsa_open_account(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENACCOUNT); -} - -/*************************************************************************** - api_lsa_get_privs - ***************************************************************************/ - -static bool api_lsa_enum_privsaccount(pipes_struct *p) -{ - LSA_Q_ENUMPRIVSACCOUNT q_u; - LSA_R_ENUMPRIVSACCOUNT r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_privsaccount("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_privsaccount: failed to unmarshall LSA_Q_ENUMPRIVSACCOUNT.\n")); - return False; - } - - r_u.status = _lsa_enum_privsaccount(p, rdata, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_privsaccount: Failed to marshall LSA_R_ENUMPRIVSACCOUNT.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_getsystemaccount - ***************************************************************************/ - -static bool api_lsa_getsystemaccount(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_GETSYSTEMACCESSACCOUNT); -} - - -/*************************************************************************** - api_lsa_setsystemaccount - ***************************************************************************/ - -static bool api_lsa_setsystemaccount(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_SETSYSTEMACCESSACCOUNT); -} - -/*************************************************************************** - api_lsa_addprivs - ***************************************************************************/ - -static bool api_lsa_addprivs(pipes_struct *p) -{ - LSA_Q_ADDPRIVS q_u; - LSA_R_ADDPRIVS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_addprivs("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_addprivs: failed to unmarshall LSA_Q_ADDPRIVS.\n")); - return False; - } - - r_u.status = _lsa_addprivs(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_addprivs("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_addprivs: Failed to marshall LSA_R_ADDPRIVS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_removeprivs - ***************************************************************************/ - -static bool api_lsa_removeprivs(pipes_struct *p) -{ - LSA_Q_REMOVEPRIVS q_u; - LSA_R_REMOVEPRIVS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_removeprivs("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_removeprivs: failed to unmarshall LSA_Q_REMOVEPRIVS.\n")); - return False; - } - - r_u.status = _lsa_removeprivs(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_removeprivs("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_removeprivs: Failed to marshall LSA_R_REMOVEPRIVS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_query_secobj - ***************************************************************************/ - -static bool api_lsa_query_secobj(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_QUERYSECURITY); -} - -/*************************************************************************** - api_lsa_add_acct_rights - ***************************************************************************/ - -static bool api_lsa_add_acct_rights(pipes_struct *p) -{ - LSA_Q_ADD_ACCT_RIGHTS q_u; - LSA_R_ADD_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_add_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_add_acct_rights: failed to unmarshall LSA_Q_ADD_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_add_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_add_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_add_acct_rights: Failed to marshall LSA_R_ADD_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_remove_acct_rights - ***************************************************************************/ - -static bool api_lsa_remove_acct_rights(pipes_struct *p) -{ - LSA_Q_REMOVE_ACCT_RIGHTS q_u; - LSA_R_REMOVE_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_remove_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_remove_acct_rights: failed to unmarshall LSA_Q_REMOVE_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_remove_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_remove_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_remove_acct_rights: Failed to marshall LSA_R_REMOVE_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_enum_acct_rights - ***************************************************************************/ - -static bool api_lsa_enum_acct_rights(pipes_struct *p) -{ - LSA_Q_ENUM_ACCT_RIGHTS q_u; - LSA_R_ENUM_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_acct_rights: failed to unmarshall LSA_Q_ENUM_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_enum_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_acct_rights: Failed to marshall LSA_R_ENUM_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_priv_value - ***************************************************************************/ - -static bool api_lsa_lookup_priv_value(pipes_struct *p) -{ - LSA_Q_LOOKUP_PRIV_VALUE q_u; - LSA_R_LOOKUP_PRIV_VALUE r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_lookup_priv_value("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_priv_value: failed to unmarshall LSA_Q_LOOKUP_PRIV_VALUE .\n")); - return False; - } - - r_u.status = _lsa_lookup_priv_value(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_priv_value("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_priv_value: Failed to marshall LSA_R_LOOKUP_PRIV_VALUE.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_open_trust_dom(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENTRUSTEDDOMAIN); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_create_trust_dom(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CREATETRUSTEDDOMAIN); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_create_secret(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CREATESECRET); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_set_secret(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_SETSECRET); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_delete_object(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_DELETEOBJECT); -} - -/*************************************************************************** - api_lsa_lookup_sids2 - ***************************************************************************/ - -static bool api_lsa_lookup_sids2(pipes_struct *p) -{ - LSA_Q_LOOKUP_SIDS2 q_u; - LSA_R_LOOKUP_SIDS2 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 info class and policy handle */ - if(!lsa_io_q_lookup_sids2("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_sids2: failed to unmarshall LSA_Q_LOOKUP_SIDS2.\n")); - return False; - } - - r_u.status = _lsa_lookup_sids2(p, &q_u, &r_u); - - if(!lsa_io_r_lookup_sids2("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_sids2: Failed to marshall LSA_R_LOOKUP_SIDS2.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_sids3 - ***************************************************************************/ - -static bool api_lsa_lookup_sids3(pipes_struct *p) -{ - LSA_Q_LOOKUP_SIDS3 q_u; - LSA_R_LOOKUP_SIDS3 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 info class and policy handle */ - if(!lsa_io_q_lookup_sids3("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_sids3: failed to unmarshall LSA_Q_LOOKUP_SIDS3.\n")); - return False; - } - - r_u.status = _lsa_lookup_sids3(p, &q_u, &r_u); - - if(!lsa_io_r_lookup_sids3("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_sids3: Failed to marshall LSA_R_LOOKUP_SIDS3.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names2 - ***************************************************************************/ - -static bool api_lsa_lookup_names2(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES2 q_u; - LSA_R_LOOKUP_NAMES2 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 info class and policy handle */ - if(!lsa_io_q_lookup_names2("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names2: failed to unmarshall LSA_Q_LOOKUP_NAMES2.\n")); - return False; - } - - r_u.status = _lsa_lookup_names2(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names2("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names2: Failed to marshall LSA_R_LOOKUP_NAMES2.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names3 - ***************************************************************************/ - -static bool api_lsa_lookup_names3(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES3 q_u; - LSA_R_LOOKUP_NAMES3 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 info class and policy handle */ - if(!lsa_io_q_lookup_names3("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names3: failed to unmarshall LSA_Q_LOOKUP_NAMES3.\n")); - return False; - } - - r_u.status = _lsa_lookup_names3(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names3("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names3: Failed to marshall LSA_R_LOOKUP_NAMES3.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names4 - ***************************************************************************/ - -static bool api_lsa_lookup_names4(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES4 q_u; - LSA_R_LOOKUP_NAMES4 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 info class and policy handle */ - if(!lsa_io_q_lookup_names4("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names4: failed to unmarshall LSA_Q_LOOKUP_NAMES4.\n")); - return False; - } - - r_u.status = _lsa_lookup_names4(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names4("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names4: Failed to marshall LSA_R_LOOKUP_NAMES4.\n")); - return False; - } - - return True; -} - -#if 0 /* AD DC work in ongoing in Samba 4 */ - -/*************************************************************************** - api_lsa_query_info2 - ***************************************************************************/ - -static bool api_lsa_query_info2(pipes_struct *p) -{ - LSA_Q_QUERY_INFO2 q_u; - LSA_R_QUERY_INFO2 r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_query_info2("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_query_info2: failed to unmarshall LSA_Q_QUERY_INFO2.\n")); - return False; - } - - r_u.status = _lsa_query_info2(p, &q_u, &r_u); - - if (!lsa_io_r_query_info2("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_query_info2: failed to marshall LSA_R_QUERY_INFO2.\n")); - return False; - } - - return True; -} -#endif /* AD DC work in ongoing in Samba 4 */ - -/*************************************************************************** - \PIPE\ntlsa commands - ***************************************************************************/ - -static struct api_struct api_lsa_cmds[] = -{ - { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, - { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, - { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info }, - { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom }, - { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close }, - { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, - { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids }, - { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names }, - { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs }, - { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname}, - { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts }, - { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser }, - { "LSA_CREATEACCOUNT" , LSA_CREATEACCOUNT , api_lsa_create_account }, - { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account }, - { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount}, - { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount }, - { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount }, - { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs }, - { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs }, - { "LSA_ADDACCTRIGHTS" , LSA_ADDACCTRIGHTS , api_lsa_add_acct_rights }, - { "LSA_REMOVEACCTRIGHTS", LSA_REMOVEACCTRIGHTS, api_lsa_remove_acct_rights }, - { "LSA_ENUMACCTRIGHTS" , LSA_ENUMACCTRIGHTS , api_lsa_enum_acct_rights }, - { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj }, - { "LSA_LOOKUPPRIVVALUE" , LSA_LOOKUPPRIVVALUE , api_lsa_lookup_priv_value }, - { "LSA_OPENTRUSTDOM" , LSA_OPENTRUSTDOM , api_lsa_open_trust_dom }, - { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, - { "LSA_CREATETRUSTDOM" , LSA_CREATETRUSTDOM , api_lsa_create_trust_dom }, - { "LSA_CREATSECRET" , LSA_CREATESECRET , api_lsa_create_secret }, - { "LSA_SETSECRET" , LSA_SETSECRET , api_lsa_set_secret }, - { "LSA_DELETEOBJECT" , LSA_DELETEOBJECT , api_lsa_delete_object }, - { "LSA_LOOKUPSIDS2" , LSA_LOOKUPSIDS2 , api_lsa_lookup_sids2 }, - { "LSA_LOOKUPNAMES2" , LSA_LOOKUPNAMES2 , api_lsa_lookup_names2 }, - { "LSA_LOOKUPNAMES3" , LSA_LOOKUPNAMES3 , api_lsa_lookup_names3 }, - { "LSA_LOOKUPSIDS3" , LSA_LOOKUPSIDS3 , api_lsa_lookup_sids3 }, - { "LSA_LOOKUPNAMES4" , LSA_LOOKUPNAMES4 , api_lsa_lookup_names4 } -#if 0 /* AD DC work in ongoing in Samba 4 */ - /* be careful of the adding of new RPC's. See commentrs below about - ADS DC capabilities */ - { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 } -#endif /* AD DC work in ongoing in Samba 4 */ -}; - -static int count_fns(void) -{ - int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct); - -#if 0 /* AD DC work is on going in Samba 4 */ - /* - * NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure - * these calls are always last and that you decrement by the amount of calls - * to disable. - */ - if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) { - funcs -= 1; - } -#endif /* AD DC work in ongoing in Samba 4 */ - - return funcs; -} - -void lsa_get_pipe_fns( struct api_struct **fns, int *n_fns ) -{ - *fns = api_lsa_cmds; - *n_fns = count_fns(); -} - - -NTSTATUS rpc_lsa_init(void) -{ - int funcs = count_fns(); - - return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds, - funcs); -} diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 3cf83962ee..20c910e46d 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -10,17 +10,18 @@ * Copyright (C) Simo Sorce 2003. * Copyright (C) Gerald (Jerry) Carter 2005. * Copyright (C) Volker Lendecke 2005. + * Copyright (C) Guenther Deschner 2008. * * 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -40,12 +41,59 @@ struct lsa_info { }; const struct generic_mapping lsa_generic_mapping = { - POLICY_READ, - POLICY_WRITE, - POLICY_EXECUTE, - POLICY_ALL_ACCESS + LSA_POLICY_READ, + LSA_POLICY_WRITE, + LSA_POLICY_EXECUTE, + LSA_POLICY_ALL_ACCESS }; +/*************************************************************************** + init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index. +***************************************************************************/ + +static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx, + struct lsa_RefDomainList *ref, + const char *dom_name, + DOM_SID *dom_sid) +{ + int num = 0; + + if (dom_name != NULL) { + for (num = 0; num < ref->count; num++) { + if (sid_equal(dom_sid, ref->domains[num].sid)) { + return num; + } + } + } else { + num = ref->count; + } + + if (num >= MAX_REF_DOMAINS) { + /* index not found, already at maximum domain limit */ + return -1; + } + + ref->count = num + 1; + ref->max_size = MAX_REF_DOMAINS; + + ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains, + struct lsa_DomainInfo, ref->count); + if (!ref->domains) { + return -1; + } + + ZERO_STRUCT(ref->domains[num]); + + init_lsa_StringLarge(&ref->domains[num].name, dom_name); + ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid); + if (!ref->domains[num].sid) { + return -1; + } + + return num; +} + + /******************************************************************* Function to free the per handle data. ********************************************************************/ @@ -82,53 +130,16 @@ static void init_dom_query_5(struct lsa_DomainInfo *r, } /*************************************************************************** - init_dom_ref - adds a domain if it's not already in, returns the index. -***************************************************************************/ - -static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid) -{ - int num = 0; - - if (dom_name != NULL) { - for (num = 0; num < ref->num_ref_doms_1; num++) { - if (sid_equal(dom_sid, &ref->ref_dom[num].ref_dom.sid)) - return num; - } - } else { - num = ref->num_ref_doms_1; - } - - if (num >= MAX_REF_DOMAINS) { - /* index not found, already at maximum domain limit */ - return -1; - } - - ref->num_ref_doms_1 = num+1; - ref->ptr_ref_dom = 1; - ref->max_entries = MAX_REF_DOMAINS; - ref->num_ref_doms_2 = num+1; - - ref->hdr_ref_dom[num].ptr_dom_sid = 1; /* dom sid cannot be NULL. */ - - init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE); - init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name); - - init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid ); - - return num; -} - -/*************************************************************************** lookup_lsa_rids. Must be called as root for lookup_name to work. ***************************************************************************/ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, - DOM_R_REF *ref, - DOM_RID *prid, - uint32 num_entries, - const UNISTR2 *name, - int flags, - uint32 *pmapped_count) + struct lsa_RefDomainList *ref, + struct lsa_TranslatedSid *prid, + uint32_t num_entries, + struct lsa_String *name, + int flags, + uint32_t *pmapped_count) { uint32 mapped_count, i; @@ -141,15 +152,14 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, DOM_SID sid; uint32 rid; int dom_idx; - char *full_name; + const char *full_name; const char *domain; enum lsa_SidType type = SID_NAME_UNKNOWN; /* Split name into domain and user component */ - full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]); + full_name = name[i].string; if (full_name == NULL) { - DEBUG(0, ("pull_ucs2_talloc failed\n")); return NT_STATUS_NO_MEMORY; } @@ -182,11 +192,11 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, if (type != SID_NAME_UNKNOWN) { sid_split_rid(&sid, &rid); - dom_idx = init_dom_ref(ref, domain, &sid); + dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid); mapped_count++; } - init_dom_rid(&prid[i], rid, type, dom_idx); + init_lsa_translated_sid(&prid[i], type, rid, dom_idx); } *pmapped_count = mapped_count; @@ -198,12 +208,12 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, ***************************************************************************/ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, - DOM_R_REF *ref, - LSA_TRANSLATED_SID3 *trans_sids, - uint32 num_entries, - const UNISTR2 *name, - int flags, - uint32 *pmapped_count) + struct lsa_RefDomainList *ref, + struct lsa_TranslatedSid3 *trans_sids, + uint32_t num_entries, + struct lsa_String *name, + int flags, + uint32 *pmapped_count) { uint32 mapped_count, i; @@ -216,15 +226,16 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, DOM_SID sid; uint32 rid; int dom_idx; - char *full_name; + const char *full_name; const char *domain; enum lsa_SidType type = SID_NAME_UNKNOWN; + ZERO_STRUCT(sid); + /* Split name into domain and user component */ - full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]); + full_name = name[i].string; if (full_name == NULL) { - DEBUG(0, ("pull_ucs2_talloc failed\n")); return NT_STATUS_NO_MEMORY; } @@ -259,164 +270,20 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, DOM_SID domain_sid; sid_copy(&domain_sid, &sid); sid_split_rid(&domain_sid, &rid); - dom_idx = init_dom_ref(ref, domain, &domain_sid); + dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid); mapped_count++; } - /* Initialize the LSA_TRANSLATED_SID3 return. */ + /* Initialize the lsa_TranslatedSid3 return. */ trans_sids[i].sid_type = type; - trans_sids[i].sid2 = TALLOC_P(mem_ctx, DOM_SID2); - if (trans_sids[i].sid2 == NULL) { - return NT_STATUS_NO_MEMORY; - } - init_dom_sid2(trans_sids[i].sid2, &sid); - trans_sids[i].sid_idx = dom_idx; + trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid); + trans_sids[i].sid_index = dom_idx; } *pmapped_count = mapped_count; return NT_STATUS_OK; } -/*************************************************************************** - init_reply_lookup_names - ***************************************************************************/ - -static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l, - DOM_R_REF *ref, uint32 num_entries, - DOM_RID *rid, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->dom_rid = rid; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - init_reply_lookup_names2 - ***************************************************************************/ - -static void init_reply_lookup_names2(LSA_R_LOOKUP_NAMES2 *r_l, - DOM_R_REF *ref, uint32 num_entries, - DOM_RID2 *rid, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->dom_rid = rid; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - init_reply_lookup_names3 - ***************************************************************************/ - -static void init_reply_lookup_names3(LSA_R_LOOKUP_NAMES3 *r_l, - DOM_R_REF *ref, uint32 num_entries, - LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->trans_sids = trans_sids; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - init_reply_lookup_names4 - ***************************************************************************/ - -static void init_reply_lookup_names4(LSA_R_LOOKUP_NAMES4 *r_l, - DOM_R_REF *ref, uint32 num_entries, - LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->trans_sids = trans_sids; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - Init_reply_lookup_sids. - ***************************************************************************/ - -static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l, - DOM_R_REF *ref, - uint32 mapped_count) -{ - r_l->ptr_dom_ref = ref ? 1 : 0; - r_l->dom_ref = ref; - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - Init_reply_lookup_sids. - ***************************************************************************/ - -static void init_reply_lookup_sids3(LSA_R_LOOKUP_SIDS3 *r_l, - DOM_R_REF *ref, - uint32 mapped_count) -{ - r_l->ptr_dom_ref = ref ? 1 : 0; - r_l->dom_ref = ref; - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - Init_reply_lookup_sids. - ***************************************************************************/ - -static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx, - LSA_R_LOOKUP_SIDS *r_l, - DOM_R_REF *ref, - LSA_TRANS_NAME_ENUM2 *names, - uint32 mapped_count) -{ - LSA_TRANS_NAME_ENUM *oldnames = &r_l->names; - - oldnames->num_entries = names->num_entries; - oldnames->ptr_trans_names = names->ptr_trans_names; - oldnames->num_entries2 = names->num_entries2; - oldnames->uni_name = names->uni_name; - - if (names->num_entries) { - int i; - - oldnames->name = TALLOC_ARRAY(mem_ctx, LSA_TRANS_NAME, names->num_entries); - - if (!oldnames->name) { - return NT_STATUS_NO_MEMORY; - } - for (i = 0; i < names->num_entries; i++) { - oldnames->name[i].sid_name_use = names->name[i].sid_name_use; - oldnames->name[i].hdr_name = names->name[i].hdr_name; - oldnames->name[i].domain_idx = names->name[i].domain_idx; - } - } - - r_l->ptr_dom_ref = ref ? 1 : 0; - r_l->dom_ref = ref; - r_l->mapped_count = mapped_count; - return NT_STATUS_OK; -} - static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size) { DOM_SID local_adm_sid; @@ -427,17 +294,17 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s SEC_ACL *psa = NULL; - init_sec_access(&mask, POLICY_EXECUTE); + init_sec_access(&mask, LSA_POLICY_EXECUTE); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); sid_copy(&adm_sid, get_global_sam_sid()); sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS); - init_sec_access(&mask, POLICY_ALL_ACCESS); + init_sec_access(&mask, LSA_POLICY_ALL_ACCESS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); sid_copy(&local_adm_sid, &global_sid_Builtin); sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS); - init_sec_access(&mask, POLICY_ALL_ACCESS); + init_sec_access(&mask, LSA_POLICY_ALL_ACCESS); init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL) @@ -467,7 +334,7 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, r_l->hdr_nb_dom_name.uni_max_len += 2; r_l->uni_nb_dom_name.uni_max_len += 1; } - + if (dns_name && *dns_name) { init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE); init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name); @@ -486,7 +353,7 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, if (dom_guid) { memcpy(&r_l->dom_guid, dom_guid, sizeof(struct GUID)); } - + if (dom_sid) { r_l->ptr_dom_sid = 1; init_dom_sid2(&r_l->dom_sid, dom_sid); @@ -528,7 +395,7 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p, /* This is needed for lsa_open_account and rpcclient .... :-) */ if (p->pipe_user.ut.uid == sec_initial_uid()) - acc_granted = POLICY_ALL_ACCESS; + acc_granted = LSA_POLICY_ALL_ACCESS; /* associate the domain SID with the (unique) handle. */ if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) @@ -621,7 +488,7 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ - if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains); @@ -667,6 +534,10 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p, return nt_status; } +#define LSA_AUDIT_NUM_CATEGORIES_NT4 7 +#define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9 +#define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4 + /*************************************************************************** _lsa_QueryInfoPolicy ***************************************************************************/ @@ -696,7 +567,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, uint32 policy_def = LSA_AUDIT_POLICY_ALL; /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) { + if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) { DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n")); return NT_STATUS_ACCESS_DENIED; } @@ -724,7 +595,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, } case 0x03: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* Request PolicyPrimaryDomainInformation. */ @@ -732,15 +603,22 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = get_global_sam_name(); - sid = get_global_sam_sid(); + sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid()); + if (!sid) { + return NT_STATUS_NO_MEMORY; + } break; case ROLE_DOMAIN_MEMBER: name = lp_workgroup(); /* We need to return the Domain SID here. */ - if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) - sid = &domain_sid; - else + if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + sid = sid_dup_talloc(p->mem_ctx, &domain_sid); + if (!sid) { + return NT_STATUS_NO_MEMORY; + } + } else { return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } break; case ROLE_STANDALONE: name = lp_workgroup(); @@ -753,7 +631,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, break; case 0x05: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* Request PolicyAccountDomainInformation. */ @@ -764,7 +642,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, break; case 0x06: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; switch (lp_server_role()) { @@ -801,38 +679,40 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, ***************************************************************************/ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, - uint16 level, /* input */ - int num_sids, /* input */ - const DOM_SID2 *sid, /* input */ - DOM_R_REF **pp_ref, /* output */ - LSA_TRANS_NAME_ENUM2 *names, /* input/output */ - uint32 *pp_mapped_count) + TALLOC_CTX *mem_ctx, + uint16_t level, /* input */ + int num_sids, /* input */ + struct lsa_SidPtr *sid, /* input */ + struct lsa_RefDomainList **pp_ref, /* input/output */ + struct lsa_TranslatedName2 **pp_names,/* input/output */ + uint32_t *pp_mapped_count) /* input/output */ { NTSTATUS status; int i; const DOM_SID **sids = NULL; - DOM_R_REF *ref = NULL; + struct lsa_RefDomainList *ref = NULL; uint32 mapped_count = 0; struct lsa_dom_info *dom_infos = NULL; struct lsa_name_info *name_infos = NULL; + struct lsa_TranslatedName2 *names = NULL; *pp_mapped_count = 0; + *pp_names = NULL; *pp_ref = NULL; - ZERO_STRUCTP(names); if (num_sids == 0) { return NT_STATUS_OK; } sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids); - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); + ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList); if (sids == NULL || ref == NULL) { return NT_STATUS_NO_MEMORY; } for (i=0; i<num_sids; i++) { - sids[i] = &sid[i].sid; + sids[i] = sid[i].sid; } status = lookup_sids(p->mem_ctx, num_sids, sids, level, @@ -842,9 +722,8 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, return status; } - names->name = TALLOC_ARRAY(p->mem_ctx, LSA_TRANS_NAME2, num_sids); - names->uni_name = TALLOC_ARRAY(p->mem_ctx, UNISTR2, num_sids); - if ((names->name == NULL) || (names->uni_name == NULL)) { + names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids); + if (names == NULL) { return NT_STATUS_NO_MEMORY; } @@ -854,8 +733,9 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, break; } - if (init_dom_ref(ref, dom_infos[i].name, - &dom_infos[i].sid) != i) { + if (init_lsa_ref_domain_list(mem_ctx, ref, + dom_infos[i].name, + &dom_infos[i].sid) != i) { DEBUG(0, ("Domain %s mentioned twice??\n", dom_infos[i].name)); return NT_STATUS_INTERNAL_ERROR; @@ -874,7 +754,7 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, * RID as 8 bytes hex, in others it returns the full * SID. We (Jerry/VL) could not figure out which the * hard cases are, so leave it with the SID. */ - name->name = talloc_asprintf(p->mem_ctx, "%s", + name->name = talloc_asprintf(p->mem_ctx, "%s", sid_to_fstring(tmp, sids[i])); if (name->name == NULL) { @@ -883,13 +763,10 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, } else { mapped_count += 1; } - init_lsa_trans_name2(&names->name[i], &names->uni_name[i], - name->type, name->name, name->dom_idx); - } - names->num_entries = num_sids; - names->ptr_trans_names = 1; - names->num_entries2 = num_sids; + init_lsa_translated_name2(&names[i], name->type, + name->name, name->dom_idx, 0); + } status = NT_STATUS_NONE_MAPPED; if (mapped_count > 0) { @@ -901,147 +778,173 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, num_sids, mapped_count, nt_errstr(status))); *pp_mapped_count = mapped_count; + *pp_names = names; *pp_ref = ref; return status; } /*************************************************************************** - _lsa_lookup_sids + _lsa_LookupSids ***************************************************************************/ -NTSTATUS _lsa_lookup_sids(pipes_struct *p, - LSA_Q_LOOKUP_SIDS *q_u, - LSA_R_LOOKUP_SIDS *r_u) +NTSTATUS _lsa_LookupSids(pipes_struct *p, + struct lsa_LookupSids *r) { + NTSTATUS status; struct lsa_info *handle; - int num_sids = q_u->sids.num_entries; + int num_sids = r->in.sids->num_sids; uint32 mapped_count = 0; - DOM_R_REF *ref = NULL; - LSA_TRANS_NAME_ENUM2 names; - NTSTATUS status; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedName *names_out = NULL; + struct lsa_TranslatedName2 *names = NULL; + int i; - if ((q_u->level < 1) || (q_u->level > 6)) { + if ((r->in.level < 1) || (r->in.level > 6)) { return NT_STATUS_INVALID_PARAMETER; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { return NT_STATUS_INVALID_HANDLE; } /* check if the user has enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { return NT_STATUS_ACCESS_DENIED; } if (num_sids > MAX_LOOKUP_SIDS) { - DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, requested %d\n", + DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n", MAX_LOOKUP_SIDS, num_sids)); return NT_STATUS_NONE_MAPPED; } - r_u->status = _lsa_lookup_sids_internal(p, - q_u->level, - num_sids, - q_u->sids.sid, - &ref, - &names, - &mapped_count); + status = _lsa_lookup_sids_internal(p, + p->mem_ctx, + r->in.level, + num_sids, + r->in.sids->sids, + &domains, + &names, + &mapped_count); - /* Convert from LSA_TRANS_NAME_ENUM2 to LSA_TRANS_NAME_ENUM */ + /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */ + names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName, + num_sids); + if (!names_out) { + return NT_STATUS_NO_MEMORY; + } - status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, &names, mapped_count); - if (!NT_STATUS_IS_OK(status)) { - return status; + for (i=0; i<num_sids; i++) { + names_out[i].sid_type = names[i].sid_type; + names_out[i].name = names[i].name; + names_out[i].sid_index = names[i].sid_index; } - return r_u->status; + + *r->out.domains = domains; + r->out.names->count = num_sids; + r->out.names->names = names_out; + *r->out.count = mapped_count; + + return status; } /*************************************************************************** - _lsa_lookup_sids2 + _lsa_LookupSids2 ***************************************************************************/ -NTSTATUS _lsa_lookup_sids2(pipes_struct *p, - LSA_Q_LOOKUP_SIDS2 *q_u, - LSA_R_LOOKUP_SIDS2 *r_u) +NTSTATUS _lsa_LookupSids2(pipes_struct *p, + struct lsa_LookupSids2 *r) { + NTSTATUS status; struct lsa_info *handle; - int num_sids = q_u->sids.num_entries; + int num_sids = r->in.sids->num_sids; uint32 mapped_count = 0; - DOM_R_REF *ref = NULL; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedName2 *names = NULL; + bool check_policy = true; - if ((q_u->level < 1) || (q_u->level > 6)) { - return NT_STATUS_INVALID_PARAMETER; + switch (p->hdr_req.opnum) { + case NDR_LSA_LOOKUPSIDS3: + check_policy = false; + break; + case NDR_LSA_LOOKUPSIDS2: + default: + check_policy = true; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - return NT_STATUS_INVALID_HANDLE; + if ((r->in.level < 1) || (r->in.level > 6)) { + return NT_STATUS_INVALID_PARAMETER; } - /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - return NT_STATUS_ACCESS_DENIED; + if (check_policy) { + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { + return NT_STATUS_INVALID_HANDLE; + } + + /* check if the user have enough rights */ + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { + return NT_STATUS_ACCESS_DENIED; + } } if (num_sids > MAX_LOOKUP_SIDS) { - DEBUG(5,("_lsa_lookup_sids2: limit of %d exceeded, requested %d\n", + DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n", MAX_LOOKUP_SIDS, num_sids)); return NT_STATUS_NONE_MAPPED; } - r_u->status = _lsa_lookup_sids_internal(p, - q_u->level, - num_sids, - q_u->sids.sid, - &ref, - &r_u->names, - &mapped_count); + status = _lsa_lookup_sids_internal(p, + p->mem_ctx, + r->in.level, + num_sids, + r->in.sids->sids, + &domains, + &names, + &mapped_count); - init_reply_lookup_sids2(r_u, ref, mapped_count); - return r_u->status; + *r->out.domains = domains; + r->out.names->count = num_sids; + r->out.names->names = names; + *r->out.count = mapped_count; + + return status; } /*************************************************************************** - _lsa_lookup_sida3 + _lsa_LookupSids3 ***************************************************************************/ -NTSTATUS _lsa_lookup_sids3(pipes_struct *p, - LSA_Q_LOOKUP_SIDS3 *q_u, - LSA_R_LOOKUP_SIDS3 *r_u) +NTSTATUS _lsa_LookupSids3(pipes_struct *p, + struct lsa_LookupSids3 *r) { - int num_sids = q_u->sids.num_entries; - uint32 mapped_count = 0; - DOM_R_REF *ref = NULL; - - if ((q_u->level < 1) || (q_u->level > 6)) { - return NT_STATUS_INVALID_PARAMETER; - } + struct lsa_LookupSids2 q; /* No policy handle on this call. Restrict to crypto connections. */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - DEBUG(0,("_lsa_lookup_sids3: client %s not using schannel for netlogon\n", + DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_INVALID_PARAMETER; } - if (num_sids > MAX_LOOKUP_SIDS) { - DEBUG(5,("_lsa_lookup_sids3: limit of %d exceeded, requested %d\n", - MAX_LOOKUP_SIDS, num_sids)); - return NT_STATUS_NONE_MAPPED; - } + q.in.handle = NULL; + q.in.sids = r->in.sids; + q.in.level = r->in.level; + q.in.unknown1 = r->in.unknown1; + q.in.unknown2 = r->in.unknown2; + q.in.names = r->in.names; + q.in.count = r->in.count; - r_u->status = _lsa_lookup_sids_internal(p, - q_u->level, - num_sids, - q_u->sids.sid, - &ref, - &r_u->names, - &mapped_count); + q.out.domains = r->out.domains; + q.out.names = r->out.names; + q.out.count = r->out.count; - init_reply_lookup_sids3(r_u, ref, mapped_count); - return r_u->status; + return _lsa_LookupSids2(p, &q); } +/*************************************************************************** + ***************************************************************************/ + static int lsa_lookup_level_to_flags(uint16 level) { int flags; @@ -1068,33 +971,37 @@ static int lsa_lookup_level_to_flags(uint16 level) } /*************************************************************************** -lsa_reply_lookup_names + _lsa_LookupNames ***************************************************************************/ -NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u) +NTSTATUS _lsa_LookupNames(pipes_struct *p, + struct lsa_LookupNames *r) { + NTSTATUS status = NT_STATUS_NONE_MAPPED; struct lsa_info *handle; - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref; - DOM_RID *rids; + struct lsa_String *names = r->in.names; + uint32 num_entries = r->in.num_names; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedSid *rids = NULL; uint32 mapped_count = 0; int flags = 0; if (num_entries > MAX_LOOKUP_SIDS) { num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries)); + DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n", + num_entries)); } - - flags = lsa_lookup_level_to_flags(q_u->lookup_level); - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (!ref) { + flags = lsa_lookup_level_to_flags(r->in.level); + + domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList); + if (!domains) { return NT_STATUS_NO_MEMORY; } if (num_entries) { - rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries); + rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid, + num_entries); if (!rids) { return NT_STATUS_NO_MEMORY; } @@ -1102,146 +1009,136 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP rids = NULL; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - r_u->status = NT_STATUS_INVALID_HANDLE; + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { + status = NT_STATUS_INVALID_HANDLE; goto done; } /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - r_u->status = NT_STATUS_ACCESS_DENIED; + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { + status = NT_STATUS_ACCESS_DENIED; goto done; } /* set up the LSA Lookup RIDs response */ become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries, - names, flags, &mapped_count); + status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries, + names, flags, &mapped_count); unbecome_root(); done: - if (NT_STATUS_IS_OK(r_u->status) && (num_entries != 0) ) { - if (mapped_count == 0) - r_u->status = NT_STATUS_NONE_MAPPED; - else if (mapped_count != num_entries) - r_u->status = STATUS_SOME_UNMAPPED; + if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) { + if (mapped_count == 0) { + status = NT_STATUS_NONE_MAPPED; + } else if (mapped_count != num_entries) { + status = STATUS_SOME_UNMAPPED; + } } - init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count); - return r_u->status; + *r->out.count = mapped_count; + *r->out.domains = domains; + r->out.sids->sids = rids; + r->out.sids->count = num_entries; + + return status; } /*************************************************************************** -lsa_reply_lookup_names2 + _lsa_LookupNames2 ***************************************************************************/ -NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOOKUP_NAMES2 *r_u) +NTSTATUS _lsa_LookupNames2(pipes_struct *p, + struct lsa_LookupNames2 *r) { - struct lsa_info *handle; - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref; - DOM_RID *rids; - DOM_RID2 *rids2; - int i; - uint32 mapped_count = 0; - int flags = 0; - - if (num_entries > MAX_LOOKUP_SIDS) { - num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names2: truncating name lookup list to %d\n", num_entries)); - } - - flags = lsa_lookup_level_to_flags(q_u->lookup_level); + NTSTATUS status; + struct lsa_LookupNames q; + struct lsa_TransSidArray2 *sid_array2 = r->in.sids; + struct lsa_TransSidArray *sid_array = NULL; + uint32_t i; - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (ref == NULL) { - r_u->status = NT_STATUS_NO_MEMORY; + sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray); + if (!sid_array) { return NT_STATUS_NO_MEMORY; } - if (num_entries) { - rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries); - rids2 = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries); - if ((rids == NULL) || (rids2 == NULL)) { - r_u->status = NT_STATUS_NO_MEMORY; - return NT_STATUS_NO_MEMORY; - } - } else { - rids = NULL; - rids2 = NULL; - } - - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - r_u->status = NT_STATUS_INVALID_HANDLE; - goto done; - } + q.in.handle = r->in.handle; + q.in.num_names = r->in.num_names; + q.in.names = r->in.names; + q.in.level = r->in.level; + q.in.sids = sid_array; + q.in.count = r->in.count; + /* we do not know what this is for */ + /* = r->in.unknown1; */ + /* = r->in.unknown2; */ - /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - r_u->status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - /* set up the LSA Lookup RIDs response */ - become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries, - names, flags, &mapped_count); - unbecome_root(); + q.out.domains = r->out.domains; + q.out.sids = sid_array; + q.out.count = r->out.count; -done: + status = _lsa_LookupNames(p, &q); - if (NT_STATUS_IS_OK(r_u->status)) { - if (mapped_count == 0) { - r_u->status = NT_STATUS_NONE_MAPPED; - } else if (mapped_count != num_entries) { - r_u->status = STATUS_SOME_UNMAPPED; - } + sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count); + if (!sid_array2->sids) { + return NT_STATUS_NO_MEMORY; } - /* Convert the rids array to rids2. */ - for (i = 0; i < num_entries; i++) { - rids2[i].type = rids[i].type; - rids2[i].rid = rids[i].rid; - rids2[i].rid_idx = rids[i].rid_idx; - rids2[i].unknown = 0; + for (i=0; i<sid_array->count; i++) { + sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type; + sid_array2->sids[i].rid = sid_array->sids[i].rid; + sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index; + sid_array2->sids[i].unknown = 0; } - init_reply_lookup_names2(r_u, ref, num_entries, rids2, mapped_count); - return r_u->status; + r->out.sids = sid_array2; + + return status; } /*************************************************************************** -lsa_reply_lookup_names3. + _lsa_LookupNames3 ***************************************************************************/ -NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOOKUP_NAMES3 *r_u) +NTSTATUS _lsa_LookupNames3(pipes_struct *p, + struct lsa_LookupNames3 *r) { + NTSTATUS status; struct lsa_info *handle; - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref = NULL; - LSA_TRANSLATED_SID3 *trans_sids = NULL; + struct lsa_String *names = r->in.names; + uint32 num_entries = r->in.num_names; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedSid3 *trans_sids = NULL; uint32 mapped_count = 0; int flags = 0; + bool check_policy = true; + + switch (p->hdr_req.opnum) { + case NDR_LSA_LOOKUPNAMES4: + check_policy = false; + break; + case NDR_LSA_LOOKUPNAMES3: + default: + check_policy = true; + } if (num_entries > MAX_LOOKUP_SIDS) { num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names3: truncating name lookup list to %d\n", num_entries)); + DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries)); } - + /* Probably the lookup_level is some sort of bitmask. */ - if (q_u->lookup_level == 1) { + if (r->in.level == 1) { flags = LOOKUP_NAME_ALL; } - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (ref == NULL) { + domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList); + if (!domains) { return NT_STATUS_NO_MEMORY; } + if (num_entries) { - trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries); + trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3, + num_entries); if (!trans_sids) { return NT_STATUS_NO_MEMORY; } @@ -1249,59 +1146,52 @@ NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOO trans_sids = NULL; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - r_u->status = NT_STATUS_INVALID_HANDLE; - goto done; - } + if (check_policy) { - /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - r_u->status = NT_STATUS_ACCESS_DENIED; - goto done; + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { + status = NT_STATUS_INVALID_HANDLE; + goto done; + } + + /* check if the user have enough rights */ + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { + status = NT_STATUS_ACCESS_DENIED; + goto done; + } } /* set up the LSA Lookup SIDs response */ become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries, - names, flags, &mapped_count); + status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries, + names, flags, &mapped_count); unbecome_root(); done: - if (NT_STATUS_IS_OK(r_u->status)) { + if (NT_STATUS_IS_OK(status)) { if (mapped_count == 0) { - r_u->status = NT_STATUS_NONE_MAPPED; + status = NT_STATUS_NONE_MAPPED; } else if (mapped_count != num_entries) { - r_u->status = STATUS_SOME_UNMAPPED; + status = STATUS_SOME_UNMAPPED; } } - init_reply_lookup_names3(r_u, ref, num_entries, trans_sids, mapped_count); - return r_u->status; + *r->out.count = mapped_count; + *r->out.domains = domains; + r->out.sids->sids = trans_sids; + r->out.sids->count = num_entries; + + return status; } /*************************************************************************** -lsa_reply_lookup_names4. + _lsa_LookupNames4 ***************************************************************************/ -NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOOKUP_NAMES4 *r_u) +NTSTATUS _lsa_LookupNames4(pipes_struct *p, + struct lsa_LookupNames4 *r) { - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref = NULL; - LSA_TRANSLATED_SID3 *trans_sids = NULL; - uint32 mapped_count = 0; - int flags = 0; - - if (num_entries > MAX_LOOKUP_SIDS) { - num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names4: truncating name lookup list to %d\n", num_entries)); - } - - /* Probably the lookup_level is some sort of bitmask. */ - if (q_u->lookup_level == 1) { - flags = LOOKUP_NAME_ALL; - } + struct lsa_LookupNames3 q; /* No policy handle on this call. Restrict to crypto connections. */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { @@ -1310,36 +1200,20 @@ NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOO return NT_STATUS_INVALID_PARAMETER; } - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (!ref) { - return NT_STATUS_NO_MEMORY; - } - - if (num_entries) { - trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries); - if (!trans_sids) { - return NT_STATUS_NO_MEMORY; - } - } else { - trans_sids = NULL; - } - - /* set up the LSA Lookup SIDs response */ - become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries, - names, flags, &mapped_count); - unbecome_root(); + q.in.handle = NULL; + q.in.num_names = r->in.num_names; + q.in.names = r->in.names; + q.in.level = r->in.level; + q.in.unknown1 = r->in.unknown1; + q.in.unknown2 = r->in.unknown2; + q.in.sids = r->in.sids; + q.in.count = r->in.count; - if (NT_STATUS_IS_OK(r_u->status)) { - if (mapped_count == 0) { - r_u->status = NT_STATUS_NONE_MAPPED; - } else if (mapped_count != num_entries) { - r_u->status = STATUS_SOME_UNMAPPED; - } - } + q.out.domains = r->out.domains; + q.out.sids = r->out.sids; + q.out.count = r->out.count; - init_reply_lookup_names4(r_u, ref, num_entries, trans_sids, mapped_count); - return r_u->status; + return _lsa_LookupNames3(p, &q); } /*************************************************************************** @@ -1353,6 +1227,7 @@ NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r) } close_policy_hnd(p, r->in.handle); + ZERO_STRUCTP(r->out.handle); return NT_STATUS_OK; } @@ -1424,17 +1299,17 @@ NTSTATUS _lsa_EnumPrivs(pipes_struct *p, if ( enum_context >= num_privs ) return NT_STATUS_NO_MORE_ENTRIES; - - DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", + + DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n", enum_context, num_privs)); - + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights I don't know if it's the right one. not documented. */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; if (num_privs) { @@ -1492,7 +1367,7 @@ NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p, /* * I don't know if it's the right one. not documented. */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string)); @@ -1519,21 +1394,22 @@ NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p, } /*************************************************************************** -_lsa_enum_accounts. + _lsa_EnumAccounts ***************************************************************************/ -NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u) +NTSTATUS _lsa_EnumAccounts(pipes_struct *p, + struct lsa_EnumAccounts *r) { struct lsa_info *handle; DOM_SID *sid_list; int i, j, num_entries; - LSA_SID_ENUM *sids=&r_u->sids; - NTSTATUS ret; + NTSTATUS status; + struct lsa_SidPtr *sids = NULL; - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; sid_list = NULL; @@ -1542,34 +1418,37 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU /* The only way we can currently find out all the SIDs that have been privileged is to scan all privileges */ - if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) { - return ret; + status = privilege_enumerate_accounts(&sid_list, &num_entries); + if (!NT_STATUS_IS_OK(status)) { + return status; } - if (q_u->enum_context >= num_entries) + if (*r->in.resume_handle >= num_entries) { return NT_STATUS_NO_MORE_ENTRIES; + } - if (num_entries-q_u->enum_context) { - sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context); - sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context); - - if (sids->ptr_sid==NULL || sids->sid==NULL) { + if (num_entries - *r->in.resume_handle) { + sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, + num_entries - *r->in.resume_handle); + if (!sids) { SAFE_FREE(sid_list); return NT_STATUS_NO_MEMORY; } - for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) { - init_dom_sid2(&(*sids).sid[j], &sid_list[i]); - (*sids).ptr_sid[j] = 1; + for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) { + sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]); + if (!sids[j].sid) { + SAFE_FREE(sid_list); + return NT_STATUS_NO_MEMORY; + } } - } else { - sids->ptr_sid = NULL; - sids->sid = NULL; } talloc_free(sid_list); - init_lsa_r_enum_accounts(r_u, num_entries); + *r->out.resume_handle = num_entries; + r->out.sids->num_sids = num_entries; + r->out.sids->sids = sids; return NT_STATUS_OK; } @@ -1643,20 +1522,20 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p, * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ - if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) + if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - /* check to see if the pipe_user is a Domain Admin since + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) return NT_STATUS_ACCESS_DENIED; - + if ( is_privileged_sid( r->in.sid ) ) return NT_STATUS_OBJECT_NAME_COLLISION; /* associate the user/group SID with the (unique) handle. */ - + if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) return NT_STATUS_NO_MEMORY; @@ -1692,7 +1571,7 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p, * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ - if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) + if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* TODO: Fis the parsing routine before reenabling this check! */ @@ -1716,38 +1595,69 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p, } /*************************************************************************** + _lsa_EnumPrivsAccount For a given SID, enumerate all the privilege this account has. ***************************************************************************/ -NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u) +NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p, + struct lsa_EnumPrivsAccount *r) { + NTSTATUS status = NT_STATUS_OK; struct lsa_info *info=NULL; SE_PRIV mask; PRIVILEGE_SET privileges; + struct lsa_PrivilegeSet *priv_set = NULL; + struct lsa_LUIDAttribute *luid_attrs = NULL; + int i; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) + if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) return NT_STATUS_OBJECT_NAME_NOT_FOUND; privilege_set_init( &privileges ); if ( se_priv_to_privilege_set( &privileges, &mask ) ) { - DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", + DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n", sid_string_dbg(&info->sid), privileges.count)); - r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0); + priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet); + if (!priv_set) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, + struct lsa_LUIDAttribute, + privileges.count); + if (!luid_attrs) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i=0; i<privileges.count; i++) { + luid_attrs[i].luid.low = privileges.set[i].luid.low; + luid_attrs[i].luid.high = privileges.set[i].luid.high; + luid_attrs[i].attribute = privileges.set[i].attr; + } + + priv_set->count = privileges.count; + priv_set->unknown = 0; + priv_set->set = luid_attrs; + + *r->out.privs = priv_set; + } else { + status = NT_STATUS_NO_SUCH_PRIVILEGE; } - else - r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; + done: privilege_set_free( &privileges ); - return r_u->status; + return status; } /*************************************************************************** @@ -1772,7 +1682,7 @@ NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p, 0x02 -> Access this computer from network 0x04 -> Log on as a batch job 0x10 -> Log on as a service - + they can be ORed together */ @@ -1795,9 +1705,9 @@ NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p, if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - /* check to see if the pipe_user is a Domain Admin since + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) return NT_STATUS_ACCESS_DENIED; @@ -1808,35 +1718,36 @@ NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p, } /*************************************************************************** + _lsa_AddPrivilegesToAccount For a given SID, add some privileges. ***************************************************************************/ -NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u) +NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p, + struct lsa_AddPrivilegesToAccount *r) { struct lsa_info *info = NULL; SE_PRIV mask; - PRIVILEGE_SET *set = NULL; + struct lsa_PrivilegeSet *set = NULL; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - /* check to see if the pipe_user is root or a Domain Admin since + + /* check to see if the pipe_user is root or a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - - if ( p->pipe_user.ut.uid != sec_initial_uid() + + if ( p->pipe_user.ut.uid != sec_initial_uid() && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } - set = &q_u->set; - + set = r->in.privs; if ( !privilege_set_to_se_priv( &mask, set ) ) return NT_STATUS_NO_SUCH_PRIVILEGE; if ( !grant_privilege( &info->sid, &mask ) ) { - DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n", + DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n", sid_string_dbg(&info->sid) )); DEBUG(3,("Privilege mask:\n")); dump_se_priv( DBGC_ALL, 3, &mask ); @@ -1847,35 +1758,37 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u } /*************************************************************************** + _lsa_RemovePrivilegesFromAccount For a given SID, remove some privileges. ***************************************************************************/ -NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u) +NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p, + struct lsa_RemovePrivilegesFromAccount *r) { struct lsa_info *info = NULL; SE_PRIV mask; - PRIVILEGE_SET *set = NULL; + struct lsa_PrivilegeSet *set = NULL; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - /* check to see if the pipe_user is root or a Domain Admin since + /* check to see if the pipe_user is root or a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( p->pipe_user.ut.uid != sec_initial_uid() - && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) + && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } - set = &q_u->set; + set = r->in.privs; if ( !privilege_set_to_se_priv( &mask, set ) ) return NT_STATUS_NO_SUCH_PRIVILEGE; if ( !revoke_privilege( &info->sid, &mask ) ) { - DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n", + DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n", sid_string_dbg(&info->sid) )); DEBUG(3,("Privilege mask:\n")); dump_se_priv( DBGC_ALL, 3, &mask ); @@ -1902,7 +1815,7 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; @@ -1959,7 +1872,7 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, switch (q_u->info_class) { case 0x0c: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* Request PolicyPrimaryDomainInformation. */ @@ -1985,7 +1898,7 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, default: return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, + init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, forest_name,&guid,sid); break; default: @@ -2004,54 +1917,46 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, #endif /* AD DC work in ongoing in Samba 4 */ /*************************************************************************** + _lsa_AddAccountRights ***************************************************************************/ -NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u) +NTSTATUS _lsa_AddAccountRights(pipes_struct *p, + struct lsa_AddAccountRights *r) { struct lsa_info *info = NULL; int i = 0; DOM_SID sid; - fstring privname; - UNISTR4_ARRAY *uni_privnames = q_u->rights; - /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - /* check to see if the pipe_user is a Domain Admin since + + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( p->pipe_user.ut.uid != sec_initial_uid() - && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) + && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } /* according to an NT4 PDC, you can add privileges to SIDs even without call_lsa_create_account() first. And you can use any arbitrary SID. */ - - sid_copy( &sid, &q_u->sid.sid ); - - /* just a little sanity check */ - - if ( q_u->count != uni_privnames->count ) { - DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n")); - return NT_STATUS_INVALID_HANDLE; - } - - for ( i=0; i<q_u->count; i++ ) { - UNISTR4 *uni4_str = &uni_privnames->strings[i]; + + sid_copy( &sid, r->in.sid ); + + for ( i=0; i < r->in.rights->count; i++ ) { + + const char *privname = r->in.rights->names[i].string; /* only try to add non-null strings */ - if ( !uni4_str->string ) + if ( !privname ) continue; - rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE ); - if ( !grant_privilege_by_name( &sid, privname ) ) { - DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname )); + DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n", + privname )); return NT_STATUS_NO_SUCH_PRIVILEGE; } } @@ -2060,58 +1965,51 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R } /*************************************************************************** + _lsa_RemoveAccountRights ***************************************************************************/ -NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u) +NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p, + struct lsa_RemoveAccountRights *r) { struct lsa_info *info = NULL; int i = 0; DOM_SID sid; - fstring privname; - UNISTR4_ARRAY *uni_privnames = q_u->rights; - + const char *privname = NULL; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - /* check to see if the pipe_user is a Domain Admin since + + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( p->pipe_user.ut.uid != sec_initial_uid() && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } - sid_copy( &sid, &q_u->sid.sid ); + sid_copy( &sid, r->in.sid ); - if ( q_u->removeall ) { - if ( !revoke_all_privileges( &sid ) ) + if ( r->in.remove_all ) { + if ( !revoke_all_privileges( &sid ) ) return NT_STATUS_ACCESS_DENIED; - + return NT_STATUS_OK; } - - /* just a little sanity check */ - - if ( q_u->count != uni_privnames->count ) { - DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n")); - return NT_STATUS_INVALID_HANDLE; - } - - for ( i=0; i<q_u->count; i++ ) { - UNISTR4 *uni4_str = &uni_privnames->strings[i]; + + for ( i=0; i < r->in.rights->count; i++ ) { + + privname = r->in.rights->names[i].string; /* only try to add non-null strings */ - if ( !uni4_str->string ) + if ( !privname ) continue; - rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE ); - if ( !revoke_privilege_by_name( &sid, privname ) ) { - DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname )); + DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n", + privname )); return NT_STATUS_NO_SUCH_PRIVILEGE; } } @@ -2119,28 +2017,70 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, return NT_STATUS_OK; } +/******************************************************************* +********************************************************************/ + +static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx, + struct lsa_RightSet *r, + PRIVILEGE_SET *privileges) +{ + uint32 i; + const char *privname; + const char **privname_array = NULL; + int num_priv = 0; + + for (i=0; i<privileges->count; i++) { + + privname = luid_to_privilege_name(&privileges->set[i].luid); + if (privname) { + if (!add_string_to_array(mem_ctx, privname, + &privname_array, &num_priv)) { + return NT_STATUS_NO_MEMORY; + } + } + } + + if (num_priv) { + + r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge, + num_priv); + if (!r->names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<num_priv; i++) { + init_lsa_StringLarge(&r->names[i], privname_array[i]); + } + + r->count = num_priv; + } + + return NT_STATUS_OK; +} /*************************************************************************** + _lsa_EnumAccountRights ***************************************************************************/ -NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u) +NTSTATUS _lsa_EnumAccountRights(pipes_struct *p, + struct lsa_EnumAccountRights *r) { + NTSTATUS status; struct lsa_info *info = NULL; DOM_SID sid; PRIVILEGE_SET privileges; SE_PRIV mask; - /* find the connection policy handle. */ - - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - + /* according to an NT4 PDC, you can add privileges to SIDs even without call_lsa_create_account() first. And you can use any arbitrary SID. */ - - sid_copy( &sid, &q_u->sid.sid ); - + + sid_copy( &sid, r->in.sid ); + if ( !get_privileges_for_sids( &mask, &sid, 1 ) ) return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -2148,37 +2088,38 @@ NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA if ( se_priv_to_privilege_set( &privileges, &mask ) ) { - DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n", + DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n", sid_string_dbg(&sid), privileges.count)); - r_u->status = init_r_enum_acct_rights( r_u, &privileges ); + status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges); + } else { + status = NT_STATUS_NO_SUCH_PRIVILEGE; } - else - r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; privilege_set_free( &privileges ); - return r_u->status; + return status; } - /*************************************************************************** + _lsa_LookupPrivValue ***************************************************************************/ -NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u) +NTSTATUS _lsa_LookupPrivValue(pipes_struct *p, + struct lsa_LookupPrivValue *r) { struct lsa_info *info = NULL; - fstring name; + const char *name = NULL; LUID_ATTR priv_luid; SE_PRIV mask; - + /* find the connection policy handle. */ - - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name)); - + + name = r->in.name->string; + DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name)); if ( !se_priv_from_name( name, &mask ) ) @@ -2186,19 +2127,17 @@ NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, L priv_luid = get_privilege_luid( &mask ); - r_u->luid.low = priv_luid.luid.low; - r_u->luid.high = priv_luid.luid.high; - + r->out.luid->low = priv_luid.luid.low; + r->out.luid->high = priv_luid.luid.high; return NT_STATUS_OK; } - /* * From here on the server routines are just dummy ones to make smbd link with * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are * pulling the server stubs across one by one. - */ + */ NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r) { @@ -2230,42 +2169,6 @@ NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_EnumAccounts(pipes_struct *p, struct lsa_EnumAccounts *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupNames(pipes_struct *p, struct lsa_LookupNames *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupSids(pipes_struct *p, struct lsa_LookupSids *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p, struct lsa_EnumPrivsAccount *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p, struct lsa_AddPrivilegesToAccount *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p, struct lsa_RemovePrivilegesFromAccount *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r) { p->rng_fault_state = True; @@ -2296,12 +2199,6 @@ NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupPrivValue(pipes_struct *p, struct lsa_LookupPrivValue *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r) { p->rng_fault_state = True; @@ -2314,24 +2211,6 @@ NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccounts return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_EnumAccountRights(pipes_struct *p, struct lsa_EnumAccountRights *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_AddAccountRights(pipes_struct *p, struct lsa_AddAccountRights *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p, struct lsa_RemoveAccountRights *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r) { p->rng_fault_state = True; @@ -2428,18 +2307,6 @@ NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupSids2(pipes_struct *p, struct lsa_LookupSids2 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupNames2(pipes_struct *p, struct lsa_LookupNames2 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r) { p->rng_fault_state = True; @@ -2494,12 +2361,6 @@ NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupNames3(pipes_struct *p, struct lsa_LookupNames3 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r) { p->rng_fault_state = True; @@ -2542,18 +2403,6 @@ NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupSids3(pipes_struct *p, struct lsa_LookupSids3 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupNames4(pipes_struct *p, struct lsa_LookupNames4 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r) { p->rng_fault_state = True; diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c deleted file mode 100644 index 4f0a0142e5..0000000000 --- a/source3/rpc_server/srv_netlog.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * 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) Jeremy Allison 1998-2001, - * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. - * - * 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 3 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, see <http://www.gnu.org/licenses/>. - */ - -/* This is the interface to the netlogon pipe. */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -/******************************************************************* - ********************************************************************/ - -static bool proxy_netr_call(pipes_struct *p, uint8 opnum) -{ - struct api_struct *fns; - int n_fns; - - netlogon_get_pipe_fns(&fns, &n_fns); - - if (opnum >= n_fns) { - return false; - } - - if (fns[opnum].opnum != opnum) { - smb_panic("NETLOGON function table not sorted"); - } - - return fns[opnum].fn(p); -} - -/************************************************************************* - api_net_req_chal: - *************************************************************************/ - -static bool api_net_req_chal(pipes_struct *p) -{ - NET_Q_REQ_CHAL q_u; - NET_R_REQ_CHAL 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 challenge... */ - if(!net_io_q_req_chal("", &q_u, data, 0)) { - DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n")); - return False; - } - - r_u.status = _net_req_chal(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_req_chal("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_req_chal: Failed to marshall NET_R_REQ_CHAL.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_auth: - *************************************************************************/ - -static bool api_net_auth(pipes_struct *p) -{ - NET_Q_AUTH q_u; - NET_R_AUTH 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 challenge... */ - if(!net_io_q_auth("", &q_u, data, 0)) { - DEBUG(0,("api_net_auth: Failed to unmarshall NET_Q_AUTH.\n")); - return False; - } - - r_u.status = _net_auth(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_auth("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_auth: Failed to marshall NET_R_AUTH.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_auth_2: - *************************************************************************/ - -static bool api_net_auth_2(pipes_struct *p) -{ - NET_Q_AUTH_2 q_u; - NET_R_AUTH_2 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 challenge... */ - if(!net_io_q_auth_2("", &q_u, data, 0)) { - DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n")); - return False; - } - - r_u.status = _net_auth_2(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_auth_2("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_auth_2: Failed to marshall NET_R_AUTH_2.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_srv_pwset: - *************************************************************************/ - -static bool api_net_srv_pwset(pipes_struct *p) -{ - NET_Q_SRV_PWSET q_u; - NET_R_SRV_PWSET 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 challenge and encrypted password ... */ - if(!net_io_q_srv_pwset("", &q_u, data, 0)) { - DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n")); - return False; - } - - r_u.status = _net_srv_pwset(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_srv_pwset("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_srv_pwset: Failed to marshall NET_R_SRV_PWSET.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_sam_logoff: - *************************************************************************/ - -static bool api_net_sam_logoff(pipes_struct *p) -{ - NET_Q_SAM_LOGOFF q_u; - NET_R_SAM_LOGOFF r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!net_io_q_sam_logoff("", &q_u, data, 0)) { - DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n")); - return False; - } - - r_u.status = _net_sam_logoff(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_sam_logoff("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_sam_logoff: Failed to marshall NET_R_SAM_LOGOFF.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_sam_logon: - *************************************************************************/ - -static bool api_net_sam_logon(pipes_struct *p) -{ - NET_Q_SAM_LOGON q_u; - NET_R_SAM_LOGON r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!net_io_q_sam_logon("", &q_u, data, 0)) { - DEBUG(0, ("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n")); - return False; - } - - r_u.status = _net_sam_logon(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_sam_logon("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_sam_logon: Failed to marshall NET_R_SAM_LOGON.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_trust_dom_list: - *************************************************************************/ - -static bool api_net_trust_dom_list(pipes_struct *p) -{ - return proxy_netr_call(p, NDR_NETR_NETRENUMERATETRUSTEDDOMAINS); -} - -/************************************************************************* - api_net_logon_ctrl2: - *************************************************************************/ - -static bool api_net_logon_ctrl2(pipes_struct *p) -{ - NET_Q_LOGON_CTRL2 q_u; - NET_R_LOGON_CTRL2 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 lsa netlogon ctrl2 query... */ - if(!net_io_q_logon_ctrl2("", &q_u, data, 0)) { - DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n")); - return False; - } - - r_u.status = _net_logon_ctrl2(p, &q_u, &r_u); - - if(!net_io_r_logon_ctrl2("", &r_u, rdata, 0)) { - DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_logon_ctrl: - *************************************************************************/ - -static bool api_net_logon_ctrl(pipes_struct *p) -{ - NET_Q_LOGON_CTRL q_u; - NET_R_LOGON_CTRL 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 lsa netlogon ctrl query... */ - if(!net_io_q_logon_ctrl("", &q_u, data, 0)) { - DEBUG(0,("api_net_logon_ctrl: Failed to unmarshall NET_Q_LOGON_CTRL.\n")); - return False; - } - - r_u.status = _net_logon_ctrl(p, &q_u, &r_u); - - if(!net_io_r_logon_ctrl("", &r_u, rdata, 0)) { - DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_sam_logon_ex: - *************************************************************************/ - -static bool api_net_sam_logon_ex(pipes_struct *p) -{ - NET_Q_SAM_LOGON_EX q_u; - NET_R_SAM_LOGON_EX r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!net_io_q_sam_logon_ex("", &q_u, data, 0)) { - DEBUG(0, ("api_net_sam_logon_ex: Failed to unmarshall NET_Q_SAM_LOGON_EX.\n")); - return False; - } - - r_u.status = _net_sam_logon_ex(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_sam_logon_ex("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_sam_logon_ex: Failed to marshall NET_R_SAM_LOGON_EX.\n")); - return False; - } - - return True; -} - -/******************************************************************* - array of \PIPE\NETLOGON operations - ********************************************************************/ -static struct api_struct api_net_cmds [] = - { - { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal }, - { "NET_AUTH" , NET_AUTH , api_net_auth }, - { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 }, - { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset }, - { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon }, - { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff }, - { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 }, - { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list }, - { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl }, - { "NET_SAMLOGON_EX" , NET_SAMLOGON_EX , api_net_sam_logon_ex }, - }; - -void netlog_get_pipe_fns( struct api_struct **fns, int *n_fns ) -{ - *fns = api_net_cmds; - *n_fns = sizeof(api_net_cmds) / sizeof(struct api_struct); -} - -NTSTATUS rpc_net_init(void) -{ - return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "NETLOGON", "lsass", api_net_cmds, - sizeof(api_net_cmds) / sizeof(struct api_struct)); -} diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 528a33915a..5b26f55845 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -1,4 +1,4 @@ -/* +/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, @@ -6,17 +6,18 @@ * Copyright (C) Paul Ashton 1997. * Copyright (C) Jeremy Allison 1998-2001. * Copyright (C) Andrew Bartlett 2001. + * Copyright (C) Guenther Deschner 2008. * * 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -34,30 +35,83 @@ extern userdom_struct current_user_info; init_net_r_req_chal: *************************************************************************/ -static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c, - DOM_CHAL *srv_chal, NTSTATUS status) +static void init_net_r_req_chal(struct netr_Credential *r, + struct netr_Credential *srv_chal) { DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__)); - memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); - r_c->status = status; + + memcpy(r->data, srv_chal->data, sizeof(r->data)); +} + +/******************************************************************* + Inits a netr_NETLOGON_INFO_1 structure. +********************************************************************/ + +static void init_netlogon_info1(struct netr_NETLOGON_INFO_1 *r, + uint32_t flags, + uint32_t pdc_connection_status) +{ + r->flags = flags; + r->pdc_connection_status = pdc_connection_status; +} + +/******************************************************************* + Inits a netr_NETLOGON_INFO_2 structure. +********************************************************************/ + +static void init_netlogon_info2(struct netr_NETLOGON_INFO_2 *r, + uint32_t flags, + uint32_t pdc_connection_status, + const char *trusted_dc_name, + uint32_t tc_connection_status) +{ + r->flags = flags; + r->pdc_connection_status = pdc_connection_status; + r->trusted_dc_name = trusted_dc_name; + r->tc_connection_status = tc_connection_status; +} + +/******************************************************************* + Inits a netr_NETLOGON_INFO_3 structure. +********************************************************************/ + +static void init_netlogon_info3(struct netr_NETLOGON_INFO_3 *r, + uint32_t flags, + uint32_t logon_attempts) +{ + r->flags = flags; + r->logon_attempts = logon_attempts; } /************************************************************************* - net_reply_logon_ctrl: + _netr_LogonControl *************************************************************************/ -NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u, - NET_R_LOGON_CTRL *r_u) +WERROR _netr_LogonControl(pipes_struct *p, + struct netr_LogonControl *r) { - uint32 flags = 0x0; - uint32 pdc_connection_status = 0x00; /* Maybe a win32 error code? */ - + struct netr_NETLOGON_INFO_1 *info1; + uint32_t flags = 0x0; + uint32_t pdc_connection_status = W_ERROR_V(WERR_OK); + /* Setup the Logon Control response */ - init_net_r_logon_ctrl(r_u, q_u->query_level, flags, - pdc_connection_status); + switch (r->in.level) { + case 1: + info1 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_1); + if (!info1) { + return WERR_NOMEM; + } + init_netlogon_info1(info1, + flags, + pdc_connection_status); + r->out.info->info1 = info1; + break; + default: + return WERR_UNKNOWN_LEVEL; + } - return r_u->status; + return WERR_OK; } /**************************************************************************** @@ -72,76 +126,109 @@ static void send_sync_message(void) } /************************************************************************* - net_reply_logon_ctrl2: + _netr_LogonControl2 *************************************************************************/ -NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u) +WERROR _netr_LogonControl2(pipes_struct *p, + struct netr_LogonControl2 *r) { uint32 flags = 0x0; uint32 pdc_connection_status = 0x0; uint32 logon_attempts = 0x0; uint32 tc_status; - fstring servername, domain, dc_name, dc_name2; + fstring dc_name, dc_name2; struct sockaddr_storage dc_ss; + const char *domain = NULL; + struct netr_NETLOGON_INFO_1 *info1; + struct netr_NETLOGON_INFO_2 *info2; + struct netr_NETLOGON_INFO_3 *info3; - /* this should be \\global_myname() */ - unistr2_to_ascii(servername, &q_u->uni_server_name, sizeof(servername)); - - r_u->status = NT_STATUS_OK; - tc_status = W_ERROR_V(WERR_NO_SUCH_DOMAIN); fstrcpy( dc_name, "" ); - - switch ( q_u->function_code ) { + + switch (r->in.function_code) { case NETLOGON_CONTROL_TC_QUERY: - unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); - + domain = r->in.data->domain; + if ( !is_trusted_domain( domain ) ) break; - + if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) { tc_status = W_ERROR_V(WERR_NO_LOGON_SERVERS); break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); - + tc_status = W_ERROR_V(WERR_OK); - + break; - + case NETLOGON_CONTROL_REDISCOVER: - unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); - + domain = r->in.data->domain; + if ( !is_trusted_domain( domain ) ) break; - + if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) { tc_status = W_ERROR_V(WERR_NO_LOGON_SERVERS); break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); - + tc_status = W_ERROR_V(WERR_OK); - + break; - + default: /* no idea what this should be */ - DEBUG(0,("_net_logon_ctrl2: unimplemented function level [%d]\n", - q_u->function_code)); + DEBUG(0,("_netr_LogonControl2: unimplemented function level [%d]\n", + r->in.function_code)); + return WERR_UNKNOWN_LEVEL; } - + /* prepare the response */ - - init_net_r_logon_ctrl2( r_u, q_u->query_level, flags, - pdc_connection_status, logon_attempts, tc_status, dc_name ); - if (lp_server_role() == ROLE_DOMAIN_BDC) + switch (r->in.level) { + case 1: + info1 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_1); + W_ERROR_HAVE_NO_MEMORY(info1); + + init_netlogon_info1(info1, + flags, + pdc_connection_status); + r->out.query->info1 = info1; + break; + case 2: + info2 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_2); + W_ERROR_HAVE_NO_MEMORY(info2); + + init_netlogon_info2(info2, + flags, + pdc_connection_status, + dc_name, + tc_status); + r->out.query->info2 = info2; + break; + case 3: + info3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_3); + W_ERROR_HAVE_NO_MEMORY(info3); + + init_netlogon_info3(info3, + flags, + logon_attempts); + r->out.query->info3 = info3; + break; + default: + return WERR_UNKNOWN_LEVEL; + } + + if (lp_server_role() == ROLE_DOMAIN_BDC) { send_sync_message(); + } - return r_u->status; + return WERR_OK; } /************************************************************************* @@ -169,38 +256,23 @@ WERROR _netr_NetrEnumerateTrustedDomains(pipes_struct *p, return WERR_OK; } -/*********************************************************************************** - init_net_r_srv_pwset: - ***********************************************************************************/ - -static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s, - DOM_CRED *srv_cred, NTSTATUS status) -{ - DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__)); - - memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred)); - r_s->status = status; - - DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__)); -} - /****************************************************************** gets a machine password entry. checks access rights of the host. ******************************************************************/ -static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) +static NTSTATUS get_md4pw(char *md4pw, const char *mach_acct, uint16 sec_chan_type) { struct samu *sampass = NULL; const uint8 *pass; bool ret; uint32 acct_ctrl; - + #if 0 char addr[INET6_ADDRSTRLEN]; /* * Currently this code is redundent as we already have a filter - * by hostname list. What this code really needs to do is to + * by hostname list. What this code really needs to do is to * get a hosts allowed/hosts denied list from the SAM database * on a per user basis, and make the access decision there. * I will leave this code here for now as a reminder to implement @@ -223,7 +295,7 @@ static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) become_root(); ret = pdb_getsampwnam(sampass, mach_acct); unbecome_root(); - + if (!ret) { DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct)); TALLOC_FREE(sampass); @@ -239,7 +311,7 @@ static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) if (!(acct_ctrl & ACB_SVRTRUST) && !(acct_ctrl & ACB_WSTRUST) && - !(acct_ctrl & ACB_DOMTRUST)) + !(acct_ctrl & ACB_DOMTRUST)) { DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct)); TALLOC_FREE(sampass); @@ -285,17 +357,18 @@ static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) dump_data(5, (uint8 *)md4pw, 16); TALLOC_FREE(sampass); - + return NT_STATUS_OK; - + } /************************************************************************* - _net_req_chal + _netr_ServerReqChallenge *************************************************************************/ -NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u) +NTSTATUS _netr_ServerReqChallenge(pipes_struct *p, + struct netr_ServerReqChallenge *r) { if (!p->dc) { p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo); @@ -303,65 +376,53 @@ NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u return NT_STATUS_NO_MEMORY; } } else { - DEBUG(10,("_net_req_chal: new challenge requested. Clearing old state.\n")); + DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n")); ZERO_STRUCTP(p->dc); } - rpcstr_pull(p->dc->remote_machine, - q_u->uni_logon_clnt.buffer, - sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0); + fstrcpy(p->dc->remote_machine, r->in.computer_name); /* Save the client challenge to the server. */ - memcpy(p->dc->clnt_chal.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data)); + memcpy(p->dc->clnt_chal.data, r->in.credentials->data, + sizeof(r->in.credentials->data)); /* Create a server challenge for the client */ /* Set this to a random value. */ generate_random_buffer(p->dc->srv_chal.data, 8); - + /* set up the LSA REQUEST CHALLENGE response */ - init_net_r_req_chal(r_u, &p->dc->srv_chal, NT_STATUS_OK); - + init_net_r_req_chal(r->out.return_credentials, &p->dc->srv_chal); + p->dc->challenge_sent = True; return NT_STATUS_OK; } /************************************************************************* - init_net_r_auth: - *************************************************************************/ - -static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, NTSTATUS status) -{ - memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); - r_a->status = status; -} - -/************************************************************************* - _net_auth. Create the initial credentials. + _netr_ServerAuthenticate + Create the initial credentials. *************************************************************************/ -NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u) +NTSTATUS _netr_ServerAuthenticate(pipes_struct *p, + struct netr_ServerAuthenticate *r) { NTSTATUS status; - fstring mach_acct; - fstring remote_machine; - DOM_CHAL srv_chal_out; + struct netr_Credential srv_chal_out; if (!p->dc || !p->dc->challenge_sent) { return NT_STATUS_ACCESS_DENIED; } - rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_acct_name.uni_str_len*2,0); - rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_comp_name.uni_str_len*2,0); - - status = get_md4pw((char *)p->dc->mach_pw, mach_acct, q_u->clnt_id.sec_chan); + status = get_md4pw((char *)p->dc->mach_pw, + r->in.account_name, + r->in.secure_channel_type); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("_net_auth: creds_server_check failed. Failed to " + DEBUG(0,("_netr_ServerAuthenticate: get_md4pw failed. Failed to " "get password for machine account %s " "from client %s: %s\n", - mach_acct, remote_machine, nt_errstr(status) )); + r->in.account_name, + r->in.computer_name, + nt_errstr(status) )); /* always return NT_STATUS_ACCESS_DENIED */ return NT_STATUS_ACCESS_DENIED; } @@ -372,110 +433,101 @@ NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u) &p->dc->clnt_chal, /* Stored client chal. */ &p->dc->srv_chal, /* Stored server chal. */ p->dc->mach_pw, - &srv_chal_out); + &srv_chal_out); /* Check client credentials are valid. */ - if (!creds_server_check(p->dc, &q_u->clnt_chal)) { - DEBUG(0,("_net_auth: creds_server_check failed. Rejecting auth " + if (!netlogon_creds_server_check(p->dc, r->in.credentials)) { + DEBUG(0,("_netr_ServerAuthenticate: netlogon_creds_server_check failed. Rejecting auth " "request from client %s machine account %s\n", - remote_machine, mach_acct )); + r->in.computer_name, + r->in.account_name)); return NT_STATUS_ACCESS_DENIED; } - fstrcpy(p->dc->mach_acct, mach_acct); - fstrcpy(p->dc->remote_machine, remote_machine); + fstrcpy(p->dc->mach_acct, r->in.account_name); + fstrcpy(p->dc->remote_machine, r->in.computer_name); p->dc->authenticated = True; /* set up the LSA AUTH response */ /* Return the server credentials. */ - init_net_r_auth(r_u, &srv_chal_out, NT_STATUS_OK); - return r_u->status; -} - -/************************************************************************* - init_net_r_auth_2: - *************************************************************************/ + memcpy(r->out.return_credentials->data, &srv_chal_out.data, + sizeof(r->out.return_credentials->data)); -static void init_net_r_auth_2(NET_R_AUTH_2 *r_a, - DOM_CHAL *resp_cred, NEG_FLAGS *flgs, NTSTATUS status) -{ - memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); - memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs)); - r_a->status = status; + return NT_STATUS_OK; } /************************************************************************* - _net_auth_2 + _netr_ServerAuthenticate2 *************************************************************************/ -NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) +NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p, + struct netr_ServerAuthenticate2 *r) { NTSTATUS status; - NEG_FLAGS srv_flgs; - fstring mach_acct; - fstring remote_machine; - DOM_CHAL srv_chal_out; - - rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_acct_name.uni_str_len*2,0); + uint32_t srv_flgs; + struct netr_Credential srv_chal_out; - /* We use this as the key to store the creds. */ - rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_comp_name.uni_str_len*2,0); + /* We use this as the key to store the creds: */ + /* r->in.computer_name */ if (!p->dc || !p->dc->challenge_sent) { - DEBUG(0,("_net_auth2: no challenge sent to client %s\n", - remote_machine )); + DEBUG(0,("_netr_ServerAuthenticate2: no challenge sent to client %s\n", + r->in.computer_name)); return NT_STATUS_ACCESS_DENIED; } - if ( (lp_server_schannel() == True) && - ((q_u->clnt_flgs.neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) { + if ( (lp_server_schannel() == true) && + ((*r->in.negotiate_flags & NETLOGON_NEG_SCHANNEL) == 0) ) { /* schannel must be used, but client did not offer it. */ - DEBUG(0,("_net_auth2: schannel required but client failed " + DEBUG(0,("_netr_ServerAuthenticate2: schannel required but client failed " "to offer it. Client was %s\n", - mach_acct )); + r->in.account_name)); return NT_STATUS_ACCESS_DENIED; } - status = get_md4pw((char *)p->dc->mach_pw, mach_acct, q_u->clnt_id.sec_chan); + status = get_md4pw((char *)p->dc->mach_pw, + r->in.account_name, + r->in.secure_channel_type); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("_net_auth2: failed to get machine password for " + DEBUG(0,("_netr_ServerAuthenticate2: failed to get machine password for " "account %s: %s\n", - mach_acct, nt_errstr(status) )); + r->in.account_name, nt_errstr(status) )); /* always return NT_STATUS_ACCESS_DENIED */ return NT_STATUS_ACCESS_DENIED; } /* From the client / server challenges and md4 password, generate sess key */ - creds_server_init(q_u->clnt_flgs.neg_flags, + creds_server_init(*r->in.negotiate_flags, p->dc, &p->dc->clnt_chal, /* Stored client chal. */ &p->dc->srv_chal, /* Stored server chal. */ p->dc->mach_pw, - &srv_chal_out); + &srv_chal_out); /* Check client credentials are valid. */ - if (!creds_server_check(p->dc, &q_u->clnt_chal)) { - DEBUG(0,("_net_auth2: creds_server_check failed. Rejecting auth " + if (!netlogon_creds_server_check(p->dc, r->in.credentials)) { + DEBUG(0,("_netr_ServerAuthenticate2: netlogon_creds_server_check failed. Rejecting auth " "request from client %s machine account %s\n", - remote_machine, mach_acct )); + r->in.computer_name, + r->in.account_name)); return NT_STATUS_ACCESS_DENIED; } - srv_flgs.neg_flags = 0x000001ff; + srv_flgs = 0x000001ff; - if (lp_server_schannel() != False) { - srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL; + if (lp_server_schannel() != false) { + srv_flgs |= NETLOGON_NEG_SCHANNEL; } /* set up the LSA AUTH 2 response */ - init_net_r_auth_2(r_u, &srv_chal_out, &srv_flgs, NT_STATUS_OK); + memcpy(r->out.return_credentials->data, &srv_chal_out.data, + sizeof(r->out.return_credentials->data)); + *r->out.negotiate_flags = srv_flgs; - fstrcpy(p->dc->mach_acct, mach_acct); - fstrcpy(p->dc->remote_machine, remote_machine); + fstrcpy(p->dc->mach_acct, r->in.account_name); + fstrcpy(p->dc->remote_machine, r->in.computer_name); fstrcpy(p->dc->domain, lp_workgroup() ); p->dc->authenticated = True; @@ -483,39 +535,40 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) /* Store off the state so we can continue after client disconnect. */ become_root(); secrets_store_schannel_session_info(p->mem_ctx, - remote_machine, - p->dc); + r->in.computer_name, + p->dc); unbecome_root(); - return r_u->status; + return NT_STATUS_OK; } /************************************************************************* - _net_srv_pwset + _netr_ServerPasswordSet *************************************************************************/ -NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u) +NTSTATUS _netr_ServerPasswordSet(pipes_struct *p, + struct netr_ServerPasswordSet *r) { + NTSTATUS status = NT_STATUS_OK; fstring remote_machine; struct samu *sampass=NULL; bool ret = False; unsigned char pwd[16]; int i; uint32 acct_ctrl; - DOM_CRED cred_out; + struct netr_Authenticator cred_out; const uchar *old_pw; - DEBUG(5,("_net_srv_pwset: %d\n", __LINE__)); + DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__)); /* We need the remote machine name for the creds lookup. */ - rpcstr_pull(remote_machine,q_u->clnt_id.login.uni_comp_name.buffer, - sizeof(remote_machine),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0); + fstrcpy(remote_machine, r->in.computer_name); if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) { /* 'server schannel = yes' should enforce use of schannel, the client did offer it in auth2, but obviously did not use it. */ - DEBUG(0,("_net_srv_pwset: client %s not using schannel for netlogon\n", + DEBUG(0,("_netr_ServerPasswordSet: client %s not using schannel for netlogon\n", remote_machine )); return NT_STATUS_ACCESS_DENIED; } @@ -536,12 +589,12 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * return NT_STATUS_INVALID_HANDLE; } - DEBUG(3,("_net_srv_pwset: Server Password Set by remote machine:[%s] on account [%s]\n", + DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n", remote_machine, p->dc->mach_acct)); - + /* Step the creds chain forward. */ - if (!creds_server_step(p->dc, &q_u->clnt_id.cred, &cred_out)) { - DEBUG(2,("_net_srv_pwset: creds_server_step failed. Rejecting auth " + if (!netlogon_creds_server_step(p->dc, r->in.credential, &cred_out)) { + DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", remote_machine, p->dc->mach_acct )); return NT_STATUS_INVALID_PARAMETER; @@ -566,7 +619,7 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * } /* Ensure the account exists and is a machine account. */ - + acct_ctrl = pdb_get_acct_ctrl(sampass); if (!(acct_ctrl & ACB_WSTRUST || @@ -575,16 +628,16 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * TALLOC_FREE(sampass); return NT_STATUS_NO_SUCH_USER; } - + if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { TALLOC_FREE(sampass); return NT_STATUS_ACCOUNT_DISABLED; } /* Woah - what does this to to the credential chain ? JRA */ - cred_hash3( pwd, q_u->pwd, p->dc->sess_key, 0); + cred_hash3(pwd, r->in.new_password->hash, p->dc->sess_key, 0); - DEBUG(100,("Server password set : new given value was :\n")); + DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n")); for(i = 0; i < sizeof(pwd); i++) DEBUG(100,("%02X ", pwd[i])); DEBUG(100,("\n")); @@ -592,7 +645,7 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * old_pw = pdb_get_nt_passwd(sampass); if (old_pw && memcmp(pwd, old_pw, 16) == 0) { - /* Avoid backend modificiations and other fun if the + /* Avoid backend modificiations and other fun if the client changed the password to the *same thing* */ ret = True; @@ -603,43 +656,44 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * TALLOC_FREE(sampass); return NT_STATUS_NO_MEMORY; } - + if (!pdb_set_nt_passwd(sampass, pwd, PDB_CHANGED)) { TALLOC_FREE(sampass); return NT_STATUS_NO_MEMORY; } - + if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) { TALLOC_FREE(sampass); /* Not quite sure what this one qualifies as, but this will do */ - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_UNSUCCESSFUL; } - + become_root(); - r_u->status = pdb_update_sam_account(sampass); + status = pdb_update_sam_account(sampass); unbecome_root(); } /* set up the LSA Server Password Set response */ - init_net_r_srv_pwset(r_u, &cred_out, r_u->status); + + memcpy(r->out.return_authenticator, &cred_out, + sizeof(r->out.return_authenticator)); TALLOC_FREE(sampass); - return r_u->status; + return status; } /************************************************************************* - _net_sam_logoff: + _netr_LogonSamLogoff *************************************************************************/ -NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u) +NTSTATUS _netr_LogonSamLogoff(pipes_struct *p, + struct netr_LogonSamLogoff *r) { - fstring remote_machine; - if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) { /* 'server schannel = yes' should enforce use of schannel, the client did offer it in auth2, but obviously did not use it. */ - DEBUG(0,("_net_sam_logoff: client %s not using schannel for netlogon\n", + DEBUG(0,("_netr_LogonSamLogoff: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_ACCESS_DENIED; } @@ -648,9 +702,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF if (!get_valid_user_struct(p->vuid)) return NT_STATUS_NO_SUCH_USER; - /* Get the remote machine name for the creds store. */ - rpcstr_pull(remote_machine,q_u->sam_id.client.login.uni_comp_name.buffer, - sizeof(remote_machine),q_u->sam_id.client.login.uni_comp_name.uni_str_len*2,0); + /* Using the remote machine name for the creds store: */ + /* r->in.computer_name */ if (!p->dc) { /* Restore the saved state of the netlogon creds. */ @@ -658,8 +711,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF become_root(); ret = secrets_restore_schannel_session_info(p->pipe_state_mem_ctx, - remote_machine, - &p->dc); + r->in.computer_name, + &p->dc); unbecome_root(); if (!ret) { return NT_STATUS_INVALID_HANDLE; @@ -670,25 +723,22 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF return NT_STATUS_INVALID_HANDLE; } - r_u->buffer_creds = 1; /* yes, we have valid server credentials */ - /* checks and updates credentials. creates reply credentials */ - if (!creds_server_step(p->dc, &q_u->sam_id.client.cred, &r_u->srv_creds)) { - DEBUG(2,("_net_sam_logoff: creds_server_step failed. Rejecting auth " + if (!netlogon_creds_server_step(p->dc, r->in.credential, r->out.return_authenticator)) { + DEBUG(2,("_netr_LogonSamLogoff: netlogon_creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", - remote_machine, p->dc->mach_acct )); + r->in.computer_name, p->dc->mach_acct )); return NT_STATUS_INVALID_PARAMETER; } /* We must store the creds state after an update. */ become_root(); secrets_store_schannel_session_info(p->pipe_state_mem_ctx, - remote_machine, - p->dc); + r->in.computer_name, + p->dc); unbecome_root(); - r_u->status = NT_STATUS_OK; - return r_u->status; + return NT_STATUS_OK; } /******************************************************************* @@ -699,7 +749,7 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, size_t num_sids, const DOM_SID *sids, - int *numgroups, DOM_GID **pgids) + int *numgroups, DOM_GID **pgids) { int i; @@ -722,53 +772,54 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, } /************************************************************************* - _net_sam_logon + _netr_LogonSamLogon *************************************************************************/ -static NTSTATUS _net_sam_logon_internal(pipes_struct *p, - NET_Q_SAM_LOGON *q_u, - NET_R_SAM_LOGON *r_u, - bool process_creds) +NTSTATUS _netr_LogonSamLogon(pipes_struct *p, + struct netr_LogonSamLogon *r) { NTSTATUS status = NT_STATUS_OK; - NET_USER_INFO_3 *usr_info = NULL; - NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr; - UNISTR2 *uni_samlogon_user = NULL; - UNISTR2 *uni_samlogon_domain = NULL; - UNISTR2 *uni_samlogon_workstation = NULL; + struct netr_SamInfo3 *sam3 = NULL; + union netr_LogonLevel *logon = r->in.logon; fstring nt_username, nt_domain, nt_workstation; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; struct samu *sampw; struct auth_context *auth_context = NULL; - + bool process_creds = true; + + switch (p->hdr_req.opnum) { + case NDR_NETR_LOGONSAMLOGON: + process_creds = true; + break; + case NDR_NETR_LOGONSAMLOGONEX: + default: + process_creds = false; + } + if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) { /* 'server schannel = yes' should enforce use of schannel, the client did offer it in auth2, but obviously did not use it. */ - DEBUG(0,("_net_sam_logon_internal: client %s not using schannel for netlogon\n", + DEBUG(0,("_netr_LogonSamLogon: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_ACCESS_DENIED; } - usr_info = TALLOC_P(p->mem_ctx, NET_USER_INFO_3); - if (!usr_info) { + sam3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo3); + if (!sam3) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(usr_info); - /* store the user information, if there is any. */ - r_u->user = usr_info; - r_u->auth_resp = 1; /* authoritative response */ - if (q_u->validation_level != 2 && q_u->validation_level != 3) { - DEBUG(0,("_net_sam_logon: bad validation_level value %d.\n", (int)q_u->validation_level )); + r->out.validation->sam3 = sam3; + *r->out.authoritative = true; /* authoritative response */ + if (r->in.validation_level != 2 && r->in.validation_level != 3) { + DEBUG(0,("_netr_LogonSamLogon: bad validation_level value %d.\n", + (int)r->in.validation_level)); return NT_STATUS_ACCESS_DENIED; } - /* We handle the return of USER_INFO_2 instead of 3 in the parse return. Sucks, I know... */ - r_u->switch_value = q_u->validation_level; /* indicates type of validation user info */ - r_u->buffer_creds = 1; /* Ensure we always return server creds. */ - + if (!get_valid_user_struct(p->vuid)) return NT_STATUS_NO_SUCH_USER; @@ -779,8 +830,8 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, /* Note this is the remote machine this request is coming from (member server), not neccessarily the workstation name the user is logging onto. */ - rpcstr_pull(remote_machine,q_u->sam_id.client.login.uni_comp_name.buffer, - sizeof(remote_machine),q_u->sam_id.client.login.uni_comp_name.uni_str_len*2,0); + + fstrcpy(remote_machine, r->in.computer_name); if (!p->dc) { /* Restore the saved state of the netlogon creds. */ @@ -801,8 +852,8 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } /* checks and updates credentials. creates reply credentials */ - if (!creds_server_step(p->dc, &q_u->sam_id.client.cred, &r_u->srv_creds)) { - DEBUG(2,("_net_sam_logon: creds_server_step failed. Rejecting auth " + if (!netlogon_creds_server_step(p->dc, r->in.credential, r->out.return_authenticator)) { + DEBUG(2,("_netr_LogonSamLogon: creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", remote_machine, p->dc->mach_acct )); return NT_STATUS_INVALID_PARAMETER; @@ -816,20 +867,25 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, unbecome_root(); } - switch (q_u->sam_id.logon_level) { + switch (r->in.logon_level) { case INTERACTIVE_LOGON_TYPE: - uni_samlogon_user = &ctr->auth.id1.uni_user_name; - uni_samlogon_domain = &ctr->auth.id1.uni_domain_name; + fstrcpy(nt_username, + logon->password->identity_info.account_name.string); + fstrcpy(nt_domain, + logon->password->identity_info.domain_name.string); + fstrcpy(nt_workstation, + logon->password->identity_info.workstation.string); - uni_samlogon_workstation = &ctr->auth.id1.uni_wksta_name; - DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup())); break; case NET_LOGON_TYPE: - uni_samlogon_user = &ctr->auth.id2.uni_user_name; - uni_samlogon_domain = &ctr->auth.id2.uni_domain_name; - uni_samlogon_workstation = &ctr->auth.id2.uni_wksta_name; - + fstrcpy(nt_username, + logon->network->identity_info.account_name.string); + fstrcpy(nt_domain, + logon->network->identity_info.domain_name.string); + fstrcpy(nt_workstation, + logon->network->identity_info.workstation.string); + DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup())); break; default: @@ -837,24 +893,23 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, return NT_STATUS_INVALID_INFO_CLASS; } /* end switch */ - rpcstr_pull(nt_username,uni_samlogon_user->buffer,sizeof(nt_username),uni_samlogon_user->uni_str_len*2,0); - rpcstr_pull(nt_domain,uni_samlogon_domain->buffer,sizeof(nt_domain),uni_samlogon_domain->uni_str_len*2,0); - rpcstr_pull(nt_workstation,uni_samlogon_workstation->buffer,sizeof(nt_workstation),uni_samlogon_workstation->uni_str_len*2,0); - DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain)); fstrcpy(current_user_info.smb_name, nt_username); sub_set_smb_name(nt_username); - - DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username)); + + DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", + r->in.validation_level, nt_username)); status = NT_STATUS_OK; - - switch (ctr->switch_value) { + + switch (r->in.logon_level) { case NET_LOGON_TYPE: { const char *wksname = nt_workstation; - - if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) { + + status = make_auth_context_fixed(&auth_context, + logon->network->challenge); + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -865,16 +920,16 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, if (*wksname == '\\') wksname++; /* Standard challenge/response authenticaion */ - if (!make_user_info_netlogon_network(&user_info, - nt_username, nt_domain, + if (!make_user_info_netlogon_network(&user_info, + nt_username, nt_domain, wksname, - ctr->auth.id2.param_ctrl, - ctr->auth.id2.lm_chal_resp.buffer, - ctr->auth.id2.lm_chal_resp.str_str_len, - ctr->auth.id2.nt_chal_resp.buffer, - ctr->auth.id2.nt_chal_resp.str_str_len)) { + logon->network->identity_info.parameter_control, + logon->network->lm.data, + logon->network->lm.length, + logon->network->nt.data, + logon->network->nt.length)) { status = NT_STATUS_NO_MEMORY; - } + } break; } case INTERACTIVE_LOGON_TYPE: @@ -884,20 +939,20 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, on */ { const uint8 *chal; - + if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) { return status; } - + chal = auth_context->get_ntlm_challenge(auth_context); - if (!make_user_info_netlogon_interactive(&user_info, - nt_username, nt_domain, - nt_workstation, - ctr->auth.id1.param_ctrl, + if (!make_user_info_netlogon_interactive(&user_info, + nt_username, nt_domain, + nt_workstation, + logon->password->identity_info.parameter_control, chal, - ctr->auth.id1.lm_owf.data, - ctr->auth.id1.nt_owf.data, + logon->password->lmpassword.hash, + logon->password->ntpassword.hash, p->dc->sess_key)) { status = NT_STATUS_NO_MEMORY; } @@ -907,29 +962,29 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, DEBUG(2,("SAM Logon: unsupported switch value\n")); return NT_STATUS_INVALID_INFO_CLASS; } /* end switch */ - + if ( NT_STATUS_IS_OK(status) ) { - status = auth_context->check_ntlm_password(auth_context, + status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); } - (auth_context->free)(&auth_context); + (auth_context->free)(&auth_context); free_user_info(&user_info); - - DEBUG(5, ("_net_sam_logon: check_password returned status %s\n", + + DEBUG(5,("_netr_LogonSamLogon: check_password returned status %s\n", nt_errstr(status))); /* Check account and password */ - + if (!NT_STATUS_IS_OK(status)) { - /* If we don't know what this domain is, we need to - indicate that we are not authoritative. This - allows the client to decide if it needs to try + /* If we don't know what this domain is, we need to + indicate that we are not authoritative. This + allows the client to decide if it needs to try a local user. Fix by jpjanosi@us.ibm.com, #2976 */ - if ( NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) + if ( NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) && !strequal(nt_domain, get_global_sam_name()) && !is_trusted_domain(nt_domain) ) - r_u->auth_resp = 0; /* We are not authoritative */ + *r->out.authoritative = false; /* We are not authoritative */ TALLOC_FREE(server_info); return status; @@ -937,7 +992,7 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, if (server_info->guest) { /* We don't like guest domain logons... */ - DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST " + DEBUG(5,("_netr_LogonSamLogon: Attempted domain logon as GUEST " "denied.\n")); TALLOC_FREE(server_info); return NT_STATUS_LOGON_FAILURE; @@ -956,29 +1011,40 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, int num_gids = 0; const char *my_name; - unsigned char user_session_key[16]; - unsigned char lm_session_key[16]; + + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lm_session_key; unsigned char pipe_session_key[16]; - sampw = server_info->sam_account; + NTTIME last_logon, last_logoff, acct_expiry, last_password_change; + NTTIME allow_password_change, force_password_change; + struct samr_RidWithAttributeArray groups; + int i; + struct dom_sid2 *sid = NULL; + + ZERO_STRUCT(user_session_key); + ZERO_STRUCT(lm_session_key); - /* set up pointer indicating user/password failed to be - * found */ - usr_info->ptr_user_info = 0; + sampw = server_info->sam_account; user_sid = pdb_get_user_sid(sampw); group_sid = pdb_get_group_sid(sampw); if ((user_sid == NULL) || (group_sid == NULL)) { - DEBUG(1, ("_net_sam_logon: User without group or user SID\n")); + DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n")); return NT_STATUS_UNSUCCESSFUL; } sid_copy(&domain_sid, user_sid); sid_split_rid(&domain_sid, &user_rid); + sid = sid_dup_talloc(p->mem_ctx, &domain_sid); + if (!sid) { + return NT_STATUS_NO_MEMORY; + } + if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) { - DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid " + DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid " "%s\n but group sid %s.\n" "The conflicting domain portions are not " "supported for NETLOGON calls\n", @@ -1005,9 +1071,9 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } if (server_info->user_session_key.length) { - memcpy(user_session_key, + memcpy(user_session_key.key, server_info->user_session_key.data, - MIN(sizeof(user_session_key), + MIN(sizeof(user_session_key.key), server_info->user_session_key.length)); if (process_creds) { /* Get the pipe session key from the creds. */ @@ -1019,13 +1085,13 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16); } - SamOEMhash(user_session_key, pipe_session_key, 16); + SamOEMhash(user_session_key.key, pipe_session_key, 16); memset(pipe_session_key, '\0', 16); } if (server_info->lm_session_key.length) { - memcpy(lm_session_key, + memcpy(lm_session_key.key, server_info->lm_session_key.data, - MIN(sizeof(lm_session_key), + MIN(sizeof(lm_session_key.key), server_info->lm_session_key.length)); if (process_creds) { /* Get the pipe session key from the creds. */ @@ -1037,36 +1103,56 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16); } - SamOEMhash(lm_session_key, pipe_session_key, 16); + SamOEMhash(lm_session_key.key, pipe_session_key, 16); memset(pipe_session_key, '\0', 16); } - init_net_user_info3(p->mem_ctx, usr_info, - user_rid, - group_rid, - pdb_get_username(sampw), - pdb_get_fullname(sampw), - pdb_get_homedir(sampw), - pdb_get_dir_drive(sampw), - pdb_get_logon_script(sampw), - pdb_get_profile_path(sampw), - pdb_get_logon_time(sampw), - get_time_t_max(), - get_time_t_max(), - pdb_get_pass_last_set_time(sampw), - pdb_get_pass_can_change_time(sampw), - pdb_get_pass_must_change_time(sampw), - 0, /* logon_count */ - 0, /* bad_pw_count */ - num_gids, /* uint32 num_groups */ - gids , /* DOM_GID *gids */ - NETLOGON_EXTRA_SIDS, /* uint32 user_flgs (?) */ - pdb_get_acct_ctrl(sampw), - server_info->user_session_key.length ? user_session_key : NULL, - server_info->lm_session_key.length ? lm_session_key : NULL, - my_name , /* char *logon_srv */ - pdb_get_domain(sampw), - &domain_sid); /* DOM_SID *dom_sid */ + groups.count = num_gids; + groups.rids = TALLOC_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, + groups.count); + if (!groups.rids) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < groups.count; i++) { + groups.rids[i].rid = gids[i].g_rid; + groups.rids[i].attributes = gids[i].attr; + } + + unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw)); + unix_to_nt_time(&last_logoff, get_time_t_max()); + unix_to_nt_time(&acct_expiry, get_time_t_max()); + unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw)); + unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw)); + unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw)); + + init_netr_SamInfo3(sam3, + last_logon, + last_logoff, + acct_expiry, + last_password_change, + allow_password_change, + force_password_change, + talloc_strdup(p->mem_ctx, pdb_get_username(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_fullname(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_logon_script(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_profile_path(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_homedir(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_dir_drive(sampw)), + 0, /* logon_count */ + 0, /* bad_password_count */ + user_rid, + group_rid, + groups, + NETLOGON_EXTRA_SIDS, + user_session_key, + my_name, + talloc_strdup(p->mem_ctx, pdb_get_domain(sampw)), + sid, + lm_session_key, + pdb_get_acct_ctrl(sampw), + 0, /* sidcount */ + NULL); /* struct netr_SidAttr *sids */ ZERO_STRUCT(user_session_key); ZERO_STRUCT(lm_session_key); } @@ -1075,25 +1161,14 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } /************************************************************************* - _net_sam_logon + _netr_LogonSamLogonEx + - no credential chaining. Map into net sam logon. *************************************************************************/ -NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u) -{ - return _net_sam_logon_internal(p, q_u, r_u, True); -} - -/************************************************************************* - _net_sam_logon_ex - no credential chaining. Map into net sam logon. - *************************************************************************/ - -NTSTATUS _net_sam_logon_ex(pipes_struct *p, NET_Q_SAM_LOGON_EX *q_u, NET_R_SAM_LOGON_EX *r_u) +NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p, + struct netr_LogonSamLogonEx *r) { - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); + struct netr_LogonSamLogon q; /* Only allow this if the pipe is protected. */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { @@ -1102,26 +1177,20 @@ NTSTATUS _net_sam_logon_ex(pipes_struct *p, NET_Q_SAM_LOGON_EX *q_u, NET_R_SAM_L return NT_STATUS_INVALID_PARAMETER; } - /* Map a NET_Q_SAM_LOGON_EX to NET_Q_SAM_LOGON. */ - q.validation_level = q_u->validation_level; - - /* Map a DOM_SAM_INFO_EX into a DOM_SAM_INFO with no creds. */ - q.sam_id.client.login = q_u->sam_id.client; - q.sam_id.logon_level = q_u->sam_id.logon_level; - q.sam_id.ctr = q_u->sam_id.ctr; + q.in.server_name = r->in.server_name; + q.in.computer_name = r->in.computer_name; + q.in.logon_level = r->in.logon_level; + q.in.logon = r->in.logon; + q.in.validation_level = r->in.validation_level; + /* we do not handle the flags */ + /* = r->in.flags; */ - r_u->status = _net_sam_logon_internal(p, &q, &r, False); + q.out.validation = r->out.validation; + q.out.authoritative = r->out.authoritative; + /* we do not handle the flags */ + /* = r->out.flags; */ - if (!NT_STATUS_IS_OK(r_u->status)) { - return r_u->status; - } - - /* Map the NET_R_SAM_LOGON to NET_R_SAM_LOGON_EX. */ - r_u->switch_value = r.switch_value; - r_u->user = r.user; - r_u->auth_resp = r.auth_resp; - r_u->flags = 0; /* FIXME ! */ - return r_u->status; + return _netr_LogonSamLogon(p, &q); } /************************************************************************* @@ -1133,10 +1202,10 @@ NTSTATUS _net_sam_logon_ex(pipes_struct *p, NET_Q_SAM_LOGON_EX *q_u, NET_R_SAM_L { NTSTATUS status = NT_STATUS_OK; - /* TODO: According to MSDN, the can only be executed against a + /* TODO: According to MSDN, the can only be executed against a DC or domain member running Windows 2000 or later. Need - to test against a standalone 2k server and see what it - does. A windows 2000 DC includes its own domain in the + to test against a standalone 2k server and see what it + does. A windows 2000 DC includes its own domain in the list. --jerry */ return status; @@ -1167,56 +1236,6 @@ WERROR _netr_LogonUasLogoff(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _netr_LogonSamLogon(pipes_struct *p, - struct netr_LogonSamLogon *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_LogonSamLogoff(pipes_struct *p, - struct netr_LogonSamLogoff *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerReqChallenge(pipes_struct *p, - struct netr_ServerReqChallenge *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerAuthenticate(pipes_struct *p, - struct netr_ServerAuthenticate *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerPasswordSet(pipes_struct *p, - struct netr_ServerPasswordSet *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _netr_DatabaseDeltas(pipes_struct *p, struct netr_DatabaseDeltas *r) { @@ -1257,16 +1276,6 @@ NTSTATUS _netr_AccountSync(pipes_struct *p, /**************************************************************** ****************************************************************/ -WERROR _netr_LogonControl(pipes_struct *p, - struct netr_LogonControl *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** -****************************************************************/ - WERROR _netr_GetDcName(pipes_struct *p, struct netr_GetDcName *r) { @@ -1287,26 +1296,6 @@ WERROR _netr_GetAnyDCName(pipes_struct *p, /**************************************************************** ****************************************************************/ -WERROR _netr_LogonControl2(pipes_struct *p, - struct netr_LogonControl2 *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p, - struct netr_ServerAuthenticate2 *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _netr_DatabaseSync2(pipes_struct *p, struct netr_DatabaseSync2 *r) { @@ -1527,16 +1516,6 @@ WERROR _netr_DsrGetDcSiteCoverageW(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p, - struct netr_LogonSamLogonEx *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - WERROR _netr_DsrEnumerateDomainTrusts(pipes_struct *p, struct netr_DsrEnumerateDomainTrusts *r) { diff --git a/source3/rpc_server/srv_ntsvcs.c b/source3/rpc_server/srv_ntsvcs.c index b3e93ac459..12fffc3e96 100644 --- a/source3/rpc_server/srv_ntsvcs.c +++ b/source3/rpc_server/srv_ntsvcs.c @@ -25,49 +25,38 @@ /******************************************************************* ********************************************************************/ -static bool api_ntsvcs_get_version(pipes_struct *p) +static bool proxy_ntsvcs_call(pipes_struct *p, uint8_t opnum) { - NTSVCS_Q_GET_VERSION q_u; - NTSVCS_R_GET_VERSION r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); + struct api_struct *fns; + int n_fns; - if(!ntsvcs_io_q_get_version("", &q_u, data, 0)) - return False; + ntsvcs_get_pipe_fns(&fns, &n_fns); - r_u.status = _ntsvcs_get_version(p, &q_u, &r_u); + if (opnum >= n_fns) { + return false; + } - if(!ntsvcs_io_r_get_version("", &r_u, rdata, 0)) - return False; + if (fns[opnum].opnum != opnum) { + smb_panic("NTSVCS function table not sorted"); + } - return True; + return fns[opnum].fn(p); } /******************************************************************* ********************************************************************/ -static bool api_ntsvcs_get_device_list_size(pipes_struct *p) +static bool api_ntsvcs_get_version(pipes_struct *p) { - NTSVCS_Q_GET_DEVICE_LIST_SIZE q_u; - NTSVCS_R_GET_DEVICE_LIST_SIZE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_get_device_list_size("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_get_device_list_size(p, &q_u, &r_u); + return proxy_ntsvcs_call(p, NDR_PNP_GETVERSION); +} - if(!ntsvcs_io_r_get_device_list_size("", &r_u, rdata, 0)) - return False; +/******************************************************************* + ********************************************************************/ - return True; +static bool api_ntsvcs_get_device_list_size(pipes_struct *p) +{ + return proxy_ntsvcs_call(p, NDR_PNP_GETDEVICELISTSIZE); } /******************************************************************* @@ -99,23 +88,7 @@ static bool api_ntsvcs_get_device_list(pipes_struct *p) static bool api_ntsvcs_validate_device_instance(pipes_struct *p) { - NTSVCS_Q_VALIDATE_DEVICE_INSTANCE q_u; - NTSVCS_R_VALIDATE_DEVICE_INSTANCE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_validate_device_instance("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_validate_device_instance(p, &q_u, &r_u); - - if(!ntsvcs_io_r_validate_device_instance("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_ntsvcs_call(p, NDR_PNP_VALIDATEDEVICEINSTANCE); } /******************************************************************* @@ -147,23 +120,7 @@ static bool api_ntsvcs_get_device_reg_property(pipes_struct *p) static bool api_ntsvcs_get_hw_profile_info(pipes_struct *p) { - NTSVCS_Q_GET_HW_PROFILE_INFO q_u; - NTSVCS_R_GET_HW_PROFILE_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); - - if(!ntsvcs_io_q_get_hw_profile_info("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_get_hw_profile_info(p, &q_u, &r_u); - - if(!ntsvcs_io_r_get_hw_profile_info("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_ntsvcs_call(p, NDR_PNP_GETHWPROFINFO); } /******************************************************************* @@ -171,23 +128,7 @@ static bool api_ntsvcs_get_hw_profile_info(pipes_struct *p) static bool api_ntsvcs_hw_profile_flags(pipes_struct *p) { - NTSVCS_Q_HW_PROFILE_FLAGS q_u; - NTSVCS_R_HW_PROFILE_FLAGS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_hw_profile_flags("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_hw_profile_flags(p, &q_u, &r_u); - - if(!ntsvcs_io_r_hw_profile_flags("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_ntsvcs_call(p, NDR_PNP_HWPROFFLAGS); } /******************************************************************* @@ -206,13 +147,13 @@ static struct api_struct api_ntsvcs_cmds[] = }; -void ntsvcs_get_pipe_fns( struct api_struct **fns, int *n_fns ) +void ntsvcs2_get_pipe_fns( struct api_struct **fns, int *n_fns ) { *fns = api_ntsvcs_cmds; *n_fns = sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct); } -NTSTATUS rpc_ntsvcs_init(void) +NTSTATUS rpc_ntsvcs2_init(void) { return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "ntsvcs", "ntsvcs", api_ntsvcs_cmds, sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct)); diff --git a/source3/rpc_server/srv_ntsvcs_nt.c b/source3/rpc_server/srv_ntsvcs_nt.c index 16c74c5d6d..11ea5d0cd1 100644 --- a/source3/rpc_server/srv_ntsvcs_nt.c +++ b/source3/rpc_server/srv_ntsvcs_nt.c @@ -34,31 +34,31 @@ static char* get_device_path(TALLOC_CTX *mem_ctx, const char *device ) /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_get_version( pipes_struct *p, NTSVCS_Q_GET_VERSION *q_u, NTSVCS_R_GET_VERSION *r_u ) +WERROR _PNP_GetVersion(pipes_struct *p, + struct PNP_GetVersion *r) { - r_u->version = 0x00000400; /* no idea what this means */ - + *r->out.version = 0x0400; /* no idea what this means */ + return WERR_OK; } /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_get_device_list_size( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST_SIZE *q_u, NTSVCS_R_GET_DEVICE_LIST_SIZE *r_u ) +WERROR _PNP_GetDeviceListSize(pipes_struct *p, + struct PNP_GetDeviceListSize *r) { - fstring device; char *devicepath; - if ( !q_u->devicename ) + if (!r->in.devicename) { return WERR_ACCESS_DENIED; + } - rpcstr_pull(device, q_u->devicename->buffer, sizeof(device), q_u->devicename->uni_str_len*2, 0); - - if (!(devicepath = get_device_path(p->mem_ctx, device))) { + if (!(devicepath = get_device_path(p->mem_ctx, r->in.devicename))) { return WERR_NOMEM; } - r_u->size = strlen(devicepath) + 2; + *r->out.size = strlen(devicepath) + 2; TALLOC_FREE(devicepath); @@ -143,7 +143,8 @@ WERROR _ntsvcs_get_device_reg_property( pipes_struct *p, NTSVCS_Q_GET_DEVICE_REG /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_validate_device_instance( pipes_struct *p, NTSVCS_Q_VALIDATE_DEVICE_INSTANCE *q_u, NTSVCS_R_VALIDATE_DEVICE_INSTANCE *r_u ) +WERROR _PNP_ValidateDeviceInstance(pipes_struct *p, + struct PNP_ValidateDeviceInstance *r) { /* whatever dude */ return WERR_OK; @@ -152,12 +153,12 @@ WERROR _ntsvcs_validate_device_instance( pipes_struct *p, NTSVCS_Q_VALIDATE_DEVI /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_get_hw_profile_info( pipes_struct *p, NTSVCS_Q_GET_HW_PROFILE_INFO *q_u, NTSVCS_R_GET_HW_PROFILE_INFO *r_u ) +WERROR _PNP_GetHwProfInfo(pipes_struct *p, + struct PNP_GetHwProfInfo *r) { /* steal the incoming buffer */ - r_u->buffer_size = q_u->buffer_size; - r_u->buffer = q_u->buffer; + r->out.info = r->in.info; /* Take the 5th Ammentment */ @@ -167,10 +168,611 @@ WERROR _ntsvcs_get_hw_profile_info( pipes_struct *p, NTSVCS_Q_GET_HW_PROFILE_INF /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_hw_profile_flags( pipes_struct *p, NTSVCS_Q_HW_PROFILE_FLAGS *q_u, NTSVCS_R_HW_PROFILE_FLAGS *r_u ) -{ +WERROR _PNP_HwProfFlags(pipes_struct *p, + struct PNP_HwProfFlags *r) +{ /* just nod your head */ - + return WERR_OK; } +/**************************************************************** +****************************************************************/ + +WERROR _PNP_Disconnect(pipes_struct *p, + struct PNP_Disconnect *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_Connect(pipes_struct *p, + struct PNP_Connect *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetGlobalState(pipes_struct *p, + struct PNP_GetGlobalState *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_InitDetection(pipes_struct *p, + struct PNP_InitDetection *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_ReportLogOn(pipes_struct *p, + struct PNP_ReportLogOn *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetRootDeviceInstance(pipes_struct *p, + struct PNP_GetRootDeviceInstance *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetRelatedDeviceInstance(pipes_struct *p, + struct PNP_GetRelatedDeviceInstance *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_EnumerateSubKeys(pipes_struct *p, + struct PNP_EnumerateSubKeys *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDeviceList(pipes_struct *p, + struct PNP_GetDeviceList *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDepth(pipes_struct *p, + struct PNP_GetDepth *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDeviceRegProp(pipes_struct *p, + struct PNP_GetDeviceRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetDeviceRegProp(pipes_struct *p, + struct PNP_SetDeviceRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassInstance(pipes_struct *p, + struct PNP_GetClassInstance *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_CreateKey(pipes_struct *p, + struct PNP_CreateKey *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DeleteRegistryKey(pipes_struct *p, + struct PNP_DeleteRegistryKey *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassCount(pipes_struct *p, + struct PNP_GetClassCount *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassName(pipes_struct *p, + struct PNP_GetClassName *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DeleteClassKey(pipes_struct *p, + struct PNP_DeleteClassKey *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetInterfaceDeviceAlias(pipes_struct *p, + struct PNP_GetInterfaceDeviceAlias *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetInterfaceDeviceList(pipes_struct *p, + struct PNP_GetInterfaceDeviceList *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetInterfaceDeviceListSize(pipes_struct *p, + struct PNP_GetInterfaceDeviceListSize *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RegisterDeviceClassAssociation(pipes_struct *p, + struct PNP_RegisterDeviceClassAssociation *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_UnregisterDeviceClassAssociation(pipes_struct *p, + struct PNP_UnregisterDeviceClassAssociation *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassRegProp(pipes_struct *p, + struct PNP_GetClassRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetClassRegProp(pipes_struct *p, + struct PNP_SetClassRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_CreateDevInst(pipes_struct *p, + struct PNP_CreateDevInst *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DeviceInstanceAction(pipes_struct *p, + struct PNP_DeviceInstanceAction *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDeviceStatus(pipes_struct *p, + struct PNP_GetDeviceStatus *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetDeviceProblem(pipes_struct *p, + struct PNP_SetDeviceProblem *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DisableDevInst(pipes_struct *p, + struct PNP_DisableDevInst *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_UninstallDevInst(pipes_struct *p, + struct PNP_UninstallDevInst *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_AddID(pipes_struct *p, + struct PNP_AddID *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RegisterDriver(pipes_struct *p, + struct PNP_RegisterDriver *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryRemove(pipes_struct *p, + struct PNP_QueryRemove *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RequestDeviceEject(pipes_struct *p, + struct PNP_RequestDeviceEject *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_IsDockStationPresent(pipes_struct *p, + struct PNP_IsDockStationPresent *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RequestEjectPC(pipes_struct *p, + struct PNP_RequestEjectPC *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_AddEmptyLogConf(pipes_struct *p, + struct PNP_AddEmptyLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_FreeLogConf(pipes_struct *p, + struct PNP_FreeLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetFirstLogConf(pipes_struct *p, + struct PNP_GetFirstLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetNextLogConf(pipes_struct *p, + struct PNP_GetNextLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetLogConfPriority(pipes_struct *p, + struct PNP_GetLogConfPriority *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_AddResDes(pipes_struct *p, + struct PNP_AddResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_FreeResDes(pipes_struct *p, + struct PNP_FreeResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetNextResDes(pipes_struct *p, + struct PNP_GetNextResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetResDesData(pipes_struct *p, + struct PNP_GetResDesData *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetResDesDataSize(pipes_struct *p, + struct PNP_GetResDesDataSize *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_ModifyResDes(pipes_struct *p, + struct PNP_ModifyResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DetectResourceLimit(pipes_struct *p, + struct PNP_DetectResourceLimit *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryResConfList(pipes_struct *p, + struct PNP_QueryResConfList *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetHwProf(pipes_struct *p, + struct PNP_SetHwProf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryArbitratorFreeData(pipes_struct *p, + struct PNP_QueryArbitratorFreeData *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryArbitratorFreeSize(pipes_struct *p, + struct PNP_QueryArbitratorFreeSize *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RunDetection(pipes_struct *p, + struct PNP_RunDetection *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RegisterNotification(pipes_struct *p, + struct PNP_RegisterNotification *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_UnregisterNotification(pipes_struct *p, + struct PNP_UnregisterNotification *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetCustomDevProp(pipes_struct *p, + struct PNP_GetCustomDevProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetVersionInternal(pipes_struct *p, + struct PNP_GetVersionInternal *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetBlockedDriverInfo(pipes_struct *p, + struct PNP_GetBlockedDriverInfo *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetServerSideDeviceInstallFlags(pipes_struct *p, + struct PNP_GetServerSideDeviceInstallFlags *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 06694a2701..19c8db0533 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -993,7 +993,7 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ for ( i=0; pipe_names[i].client_pipe; i++ ) { - DEBUG(10,("checking %s\n", pipe_names[i].client_pipe)); + DEBUGADD(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0) @@ -1105,7 +1105,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ char *OIDs[ASN1_MAX_OIDS]; int i; NTSTATUS status; - bool got_kerberos_mechanism = False; + bool got_kerberos_mechanism = false; AUTH_NTLMSSP_STATE *a = NULL; RPC_HDR_AUTH auth_info; @@ -1133,7 +1133,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ } if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { - got_kerberos_mechanism = True; + got_kerberos_mechanism = true; } for (i=0;OIDs[i];i++) { @@ -1154,27 +1154,38 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ free_pipe_ntlmssp_auth_data(&p->auth); } - /* Initialize the NTLM engine. */ - status = auth_ntlmssp_start(&a); - if (!NT_STATUS_IS_OK(status)) { - goto err; - } + if (!got_kerberos_mechanism) { + /* Initialize the NTLM engine. */ + status = auth_ntlmssp_start(&a); + if (!NT_STATUS_IS_OK(status)) { + goto err; + } - /* - * Pass the first security blob of data to it. - * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED - * which means we need another packet to complete the bind. - */ + /* + * Pass the first security blob of data to it. + * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED + * which means we need another packet to complete the bind. + */ - status = auth_ntlmssp_update(a, secblob, &chal); + status = auth_ntlmssp_update(a, secblob, &chal); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); - goto err; - } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); + goto err; + } - /* Generate the response blob we need for step 2 of the bind. */ - response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + /* Generate the response blob we need for step 2 of the bind. */ + response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + } else { + /* + * SPNEGO negotiate down to NTLMSSP. The subsequent + * code to process follow-up packets is not complete + * yet. JRA. + */ + response = spnego_gen_auth_response(NULL, + NT_STATUS_MORE_PROCESSING_REQUIRED, + OID_NTLMSSP); + } /* Copy the blob into the pout_auth parse struct */ init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); @@ -1231,6 +1242,10 @@ static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p ZERO_STRUCT(auth_reply); ZERO_STRUCT(response); + /* + * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently + * fail here as 'a' == NULL. + */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n")); goto err; @@ -1259,7 +1274,7 @@ static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p * The following call actually checks the challenge/response data. * for correctness against the given DOMAIN\user name. */ - + if (!pipe_ntlmssp_verify_final(p, &auth_blob)) { goto err; } @@ -2361,7 +2376,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) switch ( idx ) { case PI_LSARPC: - lsa_get_pipe_fns( &cmds, &n_cmds ); + lsarpc_get_pipe_fns( &cmds, &n_cmds ); break; case PI_DSSETUP: dssetup_get_pipe_fns( &cmds, &n_cmds ); @@ -2370,7 +2385,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) samr_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NETLOGON: - netlog_get_pipe_fns( &cmds, &n_cmds ); + netlogon_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SRVSVC: srvsvc2_get_pipe_fns( &cmds, &n_cmds ); @@ -2394,7 +2409,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) eventlog2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NTSVCS: - ntsvcs_get_pipe_fns( &cmds, &n_cmds ); + ntsvcs2_get_pipe_fns( &cmds, &n_cmds ); break; #ifdef DEVELOPER case PI_RPCECHO: diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 0db74c2a1b..f38a8fcfc0 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -11,6 +11,7 @@ * Copyright (C) Gerald (Jerry) Carter 2003-2004, * Copyright (C) Simo Sorce 2003. * Copyright (C) Volker Lendecke 2005. + * Copyright (C) Guenther Deschner 2008. * * 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 @@ -876,6 +877,8 @@ static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, return NT_STATUS_OK; } +#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K + /******************************************************************* _samr_EnumDomainUsers ********************************************************************/ @@ -1315,8 +1318,8 @@ static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx, for (i = 0; i < num_entries ; i++) { - init_lsa_AsciiString(&r->entries[i].account_name, - entries[i].account_name); + init_lsa_AsciiStringLarge(&r->entries[i].account_name, + entries[i].account_name); r->entries[i].idx = start_idx+i+1; } @@ -1351,8 +1354,8 @@ static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx, for (i = 0; i < num_entries ; i++) { - init_lsa_AsciiString(&r->entries[i].account_name, - entries[i].account_name); + init_lsa_AsciiStringLarge(&r->entries[i].account_name, + entries[i].account_name); r->entries[i].idx = start_idx+i+1; } @@ -2535,10 +2538,10 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, logon_hours, pdb_get_bad_password_count(pw), pdb_get_logon_count(pw), - 0, //country_code, - 0, //code_page, - 0, //nt_password_set, - 0, //lm_password_set, + 0, /* country_code */ + 0, /* code_page */ + 0, /* nt_password_set */ + 0, /* lm_password_set */ password_expired); TALLOC_FREE(pw); diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index 364adbc0de..688d72064f 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -6,6 +6,7 @@ Copyright (C) Gerald (Jerry) Carter 2000-2001 Copyright (C) Andrew Bartlett 2001-2002 Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Guenther Deschner 2008 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 diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c index 25e652c1fd..41fc39baf7 100644 --- a/source3/rpc_server/srv_srvsvc.c +++ b/source3/rpc_server/srv_srvsvc.c @@ -34,13 +34,13 @@ static bool proxy_srvsvc_call(pipes_struct *p, uint8 opnum) struct api_struct *fns; int n_fns; - lsarpc_get_pipe_fns(&fns, &n_fns); + srvsvc_get_pipe_fns(&fns, &n_fns); if (opnum >= n_fns) return False; if (fns[opnum].opnum != opnum) { - smb_panic("LSA function table not sorted\n"); + smb_panic("SRVSVC function table not sorted\n"); } return fns[opnum].fn(p); @@ -52,25 +52,7 @@ static bool proxy_srvsvc_call(pipes_struct *p, uint8 opnum) static bool api_srv_net_srv_get_info(pipes_struct *p) { - SRV_Q_NET_SRV_GET_INFO q_u; - SRV_R_NET_SRV_GET_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 net server get info */ - if (!srv_io_q_net_srv_get_info("", &q_u, data, 0)) - return False; - - r_u.status = _srv_net_srv_get_info(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if (!srv_io_r_net_srv_get_info("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETSRVGETINFO); } /******************************************************************* @@ -79,25 +61,7 @@ static bool api_srv_net_srv_get_info(pipes_struct *p) static bool api_srv_net_srv_set_info(pipes_struct *p) { - SRV_Q_NET_SRV_SET_INFO q_u; - SRV_R_NET_SRV_SET_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 net server set info */ - if (!srv_io_q_net_srv_set_info("", &q_u, data, 0)) - return False; - - r_u.status = _srv_net_srv_set_info(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if (!srv_io_r_net_srv_set_info("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETSRVSETINFO); } /******************************************************************* @@ -306,28 +270,7 @@ static bool api_srv_net_share_get_info(pipes_struct *p) static bool api_srv_net_share_set_info(pipes_struct *p) { - SRV_Q_NET_SHARE_SET_INFO q_u; - SRV_R_NET_SHARE_SET_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); - - /* Unmarshall the net server set info. */ - if(!srv_io_q_net_share_set_info("", &q_u, data, 0)) { - DEBUG(0,("api_srv_net_share_set_info: Failed to unmarshall SRV_Q_NET_SHARE_SET_INFO.\n")); - return False; - } - - r_u.status = _srv_net_share_set_info(p, &q_u, &r_u); - - if(!srv_io_r_net_share_set_info("", &r_u, rdata, 0)) { - DEBUG(0,("api_srv_net_share_set_info: Failed to marshall SRV_R_NET_SHARE_SET_INFO.\n")); - return False; - } - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETSHARESETINFO); } /******************************************************************* @@ -426,25 +369,7 @@ static bool api_srv_net_share_del_sticky(pipes_struct *p) static bool api_srv_net_remote_tod(pipes_struct *p) { - SRV_Q_NET_REMOTE_TOD q_u; - SRV_R_NET_REMOTE_TOD 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 net server get enum */ - if(!srv_io_q_net_remote_tod("", &q_u, data, 0)) - return False; - - r_u.status = _srv_net_remote_tod(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!srv_io_r_net_remote_tod("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETREMOTETOD); } /******************************************************************* diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 1b877ee5b4..4efea33738 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -1,21 +1,21 @@ -/* +/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Jeremy Allison 2001. * Copyright (C) Nigel Williams 2001. * Copyright (C) Gerald (Jerry) Carter 2006. - * + * * 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -101,11 +101,11 @@ static int pipe_enum_fn( struct db_record *rec, void *p) ********************************************************************/ static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username, - FILE_INFO_3 **info, + FILE_INFO_3 **info, uint32 *count, uint32 resume ) { struct file_enum_count fenum; - + fenum.ctx = ctx; fenum.username = username; fenum.count = *count; @@ -202,7 +202,7 @@ static void enum_file_fn( const struct share_mode_entry *e, ********************************************************************/ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, - FILE_INFO_3 **info, + FILE_INFO_3 **info, uint32 *count, uint32 resume ) { struct file_enum_count f_enum_cnt; @@ -211,12 +211,12 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, f_enum_cnt.username = username; f_enum_cnt.count = *count; f_enum_cnt.info = *info; - + share_mode_forall( enum_file_fn, (void *)&f_enum_cnt ); - + *info = f_enum_cnt.info; *count = f_enum_cnt.count; - + return WERR_OK; } @@ -225,9 +225,6 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, ********************************************************************/ static uint32 get_share_type(int snum) { - char *net_name = lp_servicename(snum); - int len_net_name = strlen(net_name); - /* work out the share type */ uint32 type = STYPE_DISKTREE; @@ -235,7 +232,7 @@ static uint32 get_share_type(int snum) type = STYPE_PRINTQ; if (strequal(lp_fstype(snum), "IPC")) type = STYPE_IPC; - if (net_name[len_net_name-1] == '$') + if (lp_administrative_share(snum)) type |= STYPE_HIDDEN; return type; @@ -605,7 +602,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, { SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries); int i = 0; - + if (!info501) { return False; } @@ -615,7 +612,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, init_srv_share_info_501(p, &info501[i++], snum); } } - + ctr->share.info501 = info501; break; } @@ -640,7 +637,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, } /* here for completeness but not currently used with enum (1004 - 1501)*/ - + case 1004: { SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries); @@ -748,7 +745,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, ********************************************************************/ static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n, - uint32 info_level, uint32 resume_hnd, bool all) + uint32 info_level, uint32 resume_hnd, bool all) { DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__)); @@ -855,7 +852,7 @@ static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 * ss0->num_entries_read = num_entries; ss0->ptr_sess_info = num_entries > 0 ? 1 : 0; ss0->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; } @@ -870,16 +867,16 @@ static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 * /******************************************************************* ********************************************************************/ -static void sess_file_fn( const struct share_mode_entry *e, +static void sess_file_fn( const struct share_mode_entry *e, const char *sharepath, const char *fname, void *data ) { struct sess_file_count *sess = (struct sess_file_count *)data; - + if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) { sess->count++; } - + return; } @@ -893,9 +890,9 @@ static int net_count_files( uid_t uid, struct server_id pid ) s_file_cnt.count = 0; s_file_cnt.uid = uid; s_file_cnt.pid = pid; - + share_mode_forall( sess_file_fn, &s_file_cnt ); - + return s_file_cnt.count; } @@ -913,42 +910,42 @@ static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 * ss1->num_entries_read = 0; ss1->ptr_sess_info = 0; ss1->num_entries_read2 = 0; - + (*stot) = 0; return; } - + if (ss1 == NULL) { (*snum) = 0; return; } (*stot) = list_sessions(p->mem_ctx, &session_list); - + for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) { uint32 num_files; uint32 connect_time; struct passwd *pw = sys_getpwnam(session_list[*snum].username); bool guest; - + if ( !pw ) { DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n", session_list[*snum].username)); continue; } - + connect_time = (uint32)(now - session_list[*snum].connect_start); num_files = net_count_files(pw->pw_uid, session_list[*snum].pid); guest = strequal( session_list[*snum].username, lp_guestaccount() ); - - init_srv_sess_info1( &ss1->info_1[num_entries], + + init_srv_sess_info1( &ss1->info_1[num_entries], session_list[*snum].remote_machine, - session_list[*snum].username, + session_list[*snum].username, num_files, connect_time, - 0, + 0, guest); num_entries++; } @@ -956,7 +953,7 @@ static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 * ss1->num_entries_read = num_entries; ss1->ptr_sess_info = num_entries > 0 ? 1 : 0; ss1->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; } @@ -1001,7 +998,7 @@ static WERROR init_srv_sess_info_ctr(pipes_struct *p, SRV_SESS_INFO_CTR *ctr, ********************************************************************/ static void init_srv_r_net_sess_enum(pipes_struct *p, SRV_R_NET_SESS_ENUM *r_n, - uint32 resume_hnd, int sess_level, int switch_value) + uint32 resume_hnd, int sess_level, int switch_value) { DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__)); @@ -1047,7 +1044,7 @@ static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto ss0->num_entries_read = num_entries; ss0->ptr_conn_info = num_entries > 0 ? 1 : 0; ss0->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; } @@ -1104,7 +1101,7 @@ static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto ss1->num_entries_read = num_entries; ss1->ptr_conn_info = num_entries > 0 ? 1 : 0; ss1->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; @@ -1114,7 +1111,7 @@ static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto ss1->num_entries_read = 0; ss1->ptr_conn_info = 0; ss1->num_entries_read2 = 0; - + (*stot) = 0; } } @@ -1157,7 +1154,7 @@ static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr, ********************************************************************/ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n, - uint32 resume_hnd, int conn_level, int switch_value) + uint32 resume_hnd, int conn_level, int switch_value) { DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__)); @@ -1183,7 +1180,7 @@ static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, TALLOC_CTX *ctx = talloc_tos(); SRV_FILE_INFO_CTR *ctr = &r->ctr; - /* TODO -- Windows enumerates + /* TODO -- Windows enumerates (b) active pipes (c) open directories and files */ @@ -1191,12 +1188,12 @@ static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, &ctr->num_entries, resume_hnd ); if ( !W_ERROR_IS_OK(r->status)) goto done; - + r->status = net_enum_pipes( ctx, username, &ctr->file.info3, &ctr->num_entries, resume_hnd ); if ( !W_ERROR_IS_OK(r->status)) goto done; - + r->level = ctr->level = 3; r->total_entries = ctr->num_entries; /* ctr->num_entries = r->total_entries - resume_hnd; */ @@ -1206,7 +1203,7 @@ static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, r->status = WERR_OK; done: - if ( ctr->num_entries > 0 ) + if ( ctr->num_entries > 0 ) ctr->ptr_entries = 1; init_enum_hnd(&r->enum_hnd, 0); @@ -1219,105 +1216,133 @@ done: WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u) { + const char *username = NULL; + switch ( q_u->level ) { - case 3: { - char *username; - if (!(username = rpcstr_pull_unistr2_talloc( - p->mem_ctx, q_u->username))) { - return WERR_NOMEM; + case 3: + if (q_u->username) { + username = rpcstr_pull_unistr2_talloc( + p->mem_ctx, q_u->username); + if (!username) { + return WERR_NOMEM; + } } return net_file_enum_3(username, r_u, get_enum_hnd(&q_u->enum_hnd)); - } default: return WERR_UNKNOWN_LEVEL; } - + return WERR_OK; } /******************************************************************* -net server get info + _srvsvc_NetSrvGetInfo ********************************************************************/ -WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u) +WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, + struct srvsvc_NetSrvGetInfo *r) { WERROR status = WERR_OK; - SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR); - - if (!ctr) - return WERR_NOMEM; - ZERO_STRUCTP(ctr); - - DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__)); if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to srv_net_srv_get_info\n")); + DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n")); return WERR_ACCESS_DENIED; } - switch (q_u->switch_value) { + switch (r->in.level) { /* Technically level 102 should only be available to Administrators but there isn't anything super-secret here, as most of it is made up. */ - case 102: - init_srv_info_102(&ctr->srv.sv102, - 500, global_myname(), - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), - lp_major_announce_version(), lp_minor_announce_version(), - lp_default_server_announce(), - 0xffffffff, /* users */ - 0xf, /* disc */ - 0, /* hidden */ - 240, /* announce */ - 3000, /* announce delta */ - 100000, /* licenses */ - "c:\\"); /* user path */ + case 102: { + struct srvsvc_NetSrvInfo102 *info102; + + info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102); + if (!info102) { + return WERR_NOMEM; + } + + init_srvsvc_NetSrvInfo102(info102, + PLATFORM_ID_NT, + global_myname(), + lp_major_announce_version(), + lp_minor_announce_version(), + lp_default_server_announce(), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), + 0xffffffff, /* users */ + 0xf, /* disc */ + 0, /* hidden */ + 240, /* announce */ + 3000, /* announce delta */ + 100000, /* licenses */ + "c:\\"); /* user path */ + r->out.info->info102 = info102; break; - case 101: - init_srv_info_101(&ctr->srv.sv101, - 500, global_myname(), - lp_major_announce_version(), lp_minor_announce_version(), - lp_default_server_announce(), - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + } + case 101: { + struct srvsvc_NetSrvInfo101 *info101; + + info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101); + if (!info101) { + return WERR_NOMEM; + } + + init_srvsvc_NetSrvInfo101(info101, + PLATFORM_ID_NT, + global_myname(), + lp_major_announce_version(), + lp_minor_announce_version(), + lp_default_server_announce(), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + r->out.info->info101 = info101; break; - case 100: - init_srv_info_100(&ctr->srv.sv100, 500, global_myname()); + } + case 100: { + struct srvsvc_NetSrvInfo100 *info100; + + info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100); + if (!info100) { + return WERR_NOMEM; + } + + init_srvsvc_NetSrvInfo100(info100, + PLATFORM_ID_NT, + global_myname()); + r->out.info->info100 = info100; + break; + } default: status = WERR_UNKNOWN_LEVEL; break; } - /* set up the net server get info structure */ - init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status); - - DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__)); - return r_u->status; + return status; } /******************************************************************* -net server set info + _srvsvc_NetSrvSetInfo ********************************************************************/ -WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u) +WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, + struct srvsvc_NetSrvSetInfo *r) { WERROR status = WERR_OK; - DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__)); /* Set up the net server set info structure. */ - init_srv_r_net_srv_set_info(r_u, 0x0, status); - - DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__)); - return r_u->status; + return status; } /******************************************************************* @@ -1401,7 +1426,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES /* fail out now if you are not root or not a domain admin */ - if ((user.ut.uid != sec_initial_uid()) && + if ((user.ut.uid != sec_initial_uid()) && ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) { goto done; @@ -1413,7 +1438,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES strequal(session_list[snum].remote_machine, machine)) { NTSTATUS ntstat; - + if (user.ut.uid != sec_initial_uid()) { not_root = True; become_root(); @@ -1422,11 +1447,11 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES ntstat = messaging_send(smbd_messaging_context(), session_list[snum].pid, MSG_SHUTDOWN, &data_blob_null); - + if (NT_STATUS_IS_OK(ntstat)) r_u->status = WERR_OK; - if (not_root) + if (not_root) unbecome_root(); } } @@ -1539,16 +1564,17 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname) } /******************************************************************* - Net share set info. Modify share details. + _srvsvc_NetShareSetInfo. Modify share details. ********************************************************************/ -WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u) +WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, + struct srvsvc_NetShareSetInfo *r) { struct current_user user; char *command = NULL; char *share_name = NULL; char *comment = NULL; - char *pathname = NULL; + const char *pathname = NULL; int type; int snum; int ret; @@ -1558,15 +1584,16 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S bool is_disk_op = False; int max_connections = 0; TALLOC_CTX *ctx = p->mem_ctx; + union srvsvc_NetShareInfo *info = r->in.info; - DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__)); - share_name = unistr2_to_ascii_talloc(ctx, &q_u->uni_share_name); + share_name = talloc_strdup(p->mem_ctx, r->in.share_name); if (!share_name) { - return WERR_NET_NAME_NOT_FOUND; + return WERR_NOMEM; } - r_u->parm_error = 0; + *r->out.parm_error = 0; if ( strequal(share_name,"IPC$") || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) @@ -1594,44 +1621,39 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if ( user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - switch (q_u->info_level) { + switch (r->in.level) { case 1: pathname = talloc_strdup(ctx, lp_pathname(snum)); - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info2.info_2_str.uni_remark); - type = q_u->info.share.info2.info_2.type; + comment = talloc_strdup(ctx, info->info2->comment); + type = info->info2->type; psd = NULL; break; case 2: - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info2.info_2_str.uni_remark); - pathname = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info2.info_2_str.uni_path); - type = q_u->info.share.info2.info_2.type; - max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses; + comment = talloc_strdup(ctx, info->info2->comment); + pathname = info->info2->path; + type = info->info2->type; + max_connections = (info->info2->max_users == 0xffffffff) ? + 0 : info->info2->max_users; psd = NULL; break; #if 0 /* not supported on set but here for completeness */ case 501: - unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment)); - type = q_u->info.share.info501.info_501.type; + comment = talloc_strdup(ctx, info->info501->comment); + type = info->info501->type; psd = NULL; break; #endif case 502: - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info502.info_502_str.uni_remark); - pathname = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info502.info_502_str.uni_path); - type = q_u->info.share.info502.info_502.type; - psd = q_u->info.share.info502.info_502_str.sd; + comment = talloc_strdup(ctx, info->info502->comment); + pathname = info->info502->path; + type = info->info502->type; + psd = info->info502->sd; map_generic_share_sd_bits(psd); break; case 1004: pathname = talloc_strdup(ctx, lp_pathname(snum)); - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info1004.info_1004_str.uni_remark); + comment = talloc_strdup(ctx, info->info1004->comment); type = STYPE_DISKTREE; break; case 1005: @@ -1639,12 +1661,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S user, so we must compare it to see if it's what is set in smb.conf, so that we can contine other ops like setting ACLs on a share */ - if (((q_u->info.share.info1005.share_info_flags & + if (((info->info1005->dfs_flags & SHARE_1005_CSC_POLICY_MASK) >> SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum)) return WERR_OK; else { - DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n")); + DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n")); return WERR_ACCESS_DENIED; } case 1006: @@ -1653,12 +1675,13 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S case 1501: pathname = talloc_strdup(ctx, lp_pathname(snum)); comment = talloc_strdup(ctx, lp_comment(snum)); - psd = q_u->info.share.info1501.sdb->sd; + psd = info->info1501->sd; map_generic_share_sd_bits(psd); type = STYPE_DISKTREE; break; default: - DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level)); + DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n", + r->in.level)); return WERR_UNKNOWN_LEVEL; } @@ -1677,7 +1700,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S string_replace(comment, '"', ' '); } - DEBUG(10,("_srv_net_share_set_info: change share command = %s\n", + DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n", lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" )); /* Only call modify function if something changed. */ @@ -1685,7 +1708,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) || (lp_max_connections(snum) != max_connections)) { if (!lp_change_share_cmd() || !*lp_change_share_cmd()) { - DEBUG(10,("_srv_net_share_set_info: No change share command\n")); + DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n")); return WERR_ACCESS_DENIED; } @@ -1701,7 +1724,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S return WERR_NOMEM; } - DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command )); + DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command )); /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ @@ -1720,14 +1743,16 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S /********* END SeDiskOperatorPrivilege BLOCK *********/ - DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret )); + DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n", + command, ret )); TALLOC_FREE(command); if ( ret != 0 ) return WERR_ACCESS_DENIED; } else { - DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name )); + DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n", + share_name )); } /* Replace SD if changed. */ @@ -1739,12 +1764,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if (old_sd && !sec_desc_equal(old_sd, psd)) { if (!set_share_security(share_name, psd)) - DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n", + DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n", share_name )); } } - DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__)); return WERR_OK; } @@ -1819,7 +1844,7 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S map_generic_share_sd_bits(psd); break; - /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */ + /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */ case 1004: case 1005: @@ -2029,12 +2054,13 @@ WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_ } /******************************************************************* -time of day + _srvsvc_NetRemoteTOD ********************************************************************/ -WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u) +WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, + struct srvsvc_NetRemoteTOD *r) { - TIME_OF_DAY_INFO *tod; + struct srvsvc_NetRemoteTODInfo *tod; struct tm *t; time_t unixdate = time(NULL); @@ -2043,37 +2069,35 @@ WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET uint32 zone = get_time_zone(unixdate)/60; - DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__)); - if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) ) + if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) ) return WERR_NOMEM; - r_u->tod = tod; - r_u->ptr_srv_tod = 0x1; - r_u->status = WERR_OK; + *r->out.info = tod; - DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__)); t = gmtime(&unixdate); /* set up the */ - init_time_of_day_info(tod, - unixdate, - 0, - t->tm_hour, - t->tm_min, - t->tm_sec, - 0, - zone, - 10000, - t->tm_mday, - t->tm_mon + 1, - 1900+t->tm_year, - t->tm_wday); - - DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + init_srvsvc_NetRemoteTODInfo(tod, + unixdate, + 0, + t->tm_hour, + t->tm_min, + t->tm_sec, + 0, + zone, + 10000, + t->tm_mday, + t->tm_mon + 1, + 1900+t->tm_year, + t->tm_wday); + + DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__)); - return r_u->status; + return WERR_OK; } /*********************************************************************************** @@ -2362,7 +2386,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D r_u->total_entries = init_server_disk_enum(&resume); - r_u->disk_enum_ctr.unknown = 0; + r_u->disk_enum_ctr.unknown = 0; if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) { return WERR_NOMEM; @@ -2378,7 +2402,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D /*copy disk name into a unicode string*/ - init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name); + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name); } /* add a terminating null string. Is this there if there is more data to come? */ @@ -2524,12 +2548,6 @@ WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) { p->rng_fault_state = True; @@ -2548,18 +2566,6 @@ WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r) return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r) { p->rng_fault_state = True; @@ -2590,12 +2596,6 @@ WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r) { p->rng_fault_state = True; diff --git a/source3/rpc_server/srv_svcctl.c b/source3/rpc_server/srv_svcctl.c index ce81a24202..5e125145d6 100644 --- a/source3/rpc_server/srv_svcctl.c +++ b/source3/rpc_server/srv_svcctl.c @@ -53,23 +53,7 @@ static bool api_svcctl_close_service(pipes_struct *p) static bool api_svcctl_open_scmanager(pipes_struct *p) { - SVCCTL_Q_OPEN_SCMANAGER q_u; - SVCCTL_R_OPEN_SCMANAGER r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_open_scmanager("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_open_scmanager(p, &q_u, &r_u); - - if(!svcctl_io_r_open_scmanager("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_OPENSCMANAGERW); } /******************************************************************* @@ -77,23 +61,7 @@ static bool api_svcctl_open_scmanager(pipes_struct *p) static bool api_svcctl_open_service(pipes_struct *p) { - SVCCTL_Q_OPEN_SERVICE q_u; - SVCCTL_R_OPEN_SERVICE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_open_service("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_open_service(p, &q_u, &r_u); - - if(!svcctl_io_r_open_service("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_OPENSERVICEW); } /******************************************************************* @@ -101,23 +69,7 @@ static bool api_svcctl_open_service(pipes_struct *p) static bool api_svcctl_get_display_name(pipes_struct *p) { - SVCCTL_Q_GET_DISPLAY_NAME q_u; - SVCCTL_R_GET_DISPLAY_NAME r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_get_display_name("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_get_display_name(p, &q_u, &r_u); - - if(!svcctl_io_r_get_display_name("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_GETSERVICEDISPLAYNAMEW); } /******************************************************************* @@ -125,23 +77,7 @@ static bool api_svcctl_get_display_name(pipes_struct *p) static bool api_svcctl_query_status(pipes_struct *p) { - SVCCTL_Q_QUERY_STATUS q_u; - SVCCTL_R_QUERY_STATUS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_query_status("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_query_status(p, &q_u, &r_u); - - if(!svcctl_io_r_query_status("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_QUERYSERVICESTATUS); } /******************************************************************* @@ -219,23 +155,7 @@ static bool api_svcctl_enum_dependent_services(pipes_struct *p) static bool api_svcctl_start_service(pipes_struct *p) { - SVCCTL_Q_START_SERVICE q_u; - SVCCTL_R_START_SERVICE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_start_service("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_start_service(p, &q_u, &r_u); - - if(!svcctl_io_r_start_service("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_STARTSERVICEW); } /******************************************************************* @@ -243,23 +163,7 @@ static bool api_svcctl_start_service(pipes_struct *p) static bool api_svcctl_control_service(pipes_struct *p) { - SVCCTL_Q_CONTROL_SERVICE q_u; - SVCCTL_R_CONTROL_SERVICE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_control_service("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_control_service(p, &q_u, &r_u); - - if(!svcctl_io_r_control_service("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_CONTROLSERVICE); } /******************************************************************* @@ -315,23 +219,7 @@ static bool api_svcctl_query_service_config2(pipes_struct *p) static bool api_svcctl_lock_service_db(pipes_struct *p) { - SVCCTL_Q_LOCK_SERVICE_DB q_u; - SVCCTL_R_LOCK_SERVICE_DB r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_lock_service_db("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_lock_service_db(p, &q_u, &r_u); - - if(!svcctl_io_r_lock_service_db("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_LOCKSERVICEDATABASE); } @@ -340,23 +228,7 @@ static bool api_svcctl_lock_service_db(pipes_struct *p) static bool api_svcctl_unlock_service_db(pipes_struct *p) { - SVCCTL_Q_UNLOCK_SERVICE_DB q_u; - SVCCTL_R_UNLOCK_SERVICE_DB r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_unlock_service_db("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_unlock_service_db(p, &q_u, &r_u); - - if(!svcctl_io_r_unlock_service_db("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_UNLOCKSERVICEDATABASE); } /******************************************************************* @@ -364,23 +236,7 @@ static bool api_svcctl_unlock_service_db(pipes_struct *p) static bool api_svcctl_query_security_sec(pipes_struct *p) { - SVCCTL_Q_QUERY_SERVICE_SEC q_u; - SVCCTL_R_QUERY_SERVICE_SEC r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_query_service_sec("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_query_service_sec(p, &q_u, &r_u); - - if(!svcctl_io_r_query_service_sec("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_QUERYSERVICEOBJECTSECURITY); } /******************************************************************* @@ -388,23 +244,7 @@ static bool api_svcctl_query_security_sec(pipes_struct *p) static bool api_svcctl_set_security_sec(pipes_struct *p) { - SVCCTL_Q_SET_SERVICE_SEC q_u; - SVCCTL_R_SET_SERVICE_SEC r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_set_service_sec("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_set_service_sec(p, &q_u, &r_u); - - if(!svcctl_io_r_set_service_sec("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_SETSERVICEOBJECTSECURITY); } diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index ac45d8bf75..73d09b1bbb 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -1,22 +1,22 @@ -/* +/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * * Copyright (C) Marcin Krzysztof Porwit 2005. - * + * * Largely Rewritten (Again) by: * Copyright (C) Gerald (Jerry) Carter 2005. - * + * * 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -63,42 +63,42 @@ bool init_service_op_table( void ) const char **service_list = lp_svcctl_list(); int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_count( service_list ); int i; - + if ( !(svcctl_ops = TALLOC_ARRAY( NULL, struct service_control_op, num_services+1)) ) { DEBUG(0,("init_service_op_table: talloc() failed!\n")); return False; } /* services listed in smb.conf get the rc.init interface */ - + for ( i=0; service_list && service_list[i]; i++ ) { svcctl_ops[i].name = talloc_strdup( svcctl_ops, service_list[i] ); svcctl_ops[i].ops = &rcinit_svc_ops; } - + /* add builtin services */ - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" ); svcctl_ops[i].ops = &spoolss_svc_ops; i++; - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" ); svcctl_ops[i].ops = &netlogon_svc_ops; i++; - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" ); svcctl_ops[i].ops = &winreg_svc_ops; i++; - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" ); svcctl_ops[i].ops = &wins_svc_ops; i++; - + /* NULL terminate the array */ - + svcctl_ops[i].name = NULL; svcctl_ops[i].ops = NULL; - + return True; } @@ -119,7 +119,7 @@ static struct service_control_op* find_service_by_name( const char *name ) /******************************************************************** ********************************************************************/ -static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, +static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, uint32 access_desired, uint32 *access_granted ) { NTSTATUS result; @@ -128,7 +128,7 @@ static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, DEBUG(5,("svcctl_access_check: using root's token\n")); token = get_root_nt_token(); } - + se_access_check( sec_desc, token, access_desired, access_granted, &result ); return result; @@ -139,7 +139,7 @@ static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) { - SEC_ACE ace[2]; + SEC_ACE ace[2]; SEC_ACCESS mask; size_t i = 0; SEC_DESC *sd; @@ -147,18 +147,18 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) size_t sd_size; /* basic access for Everyone */ - + init_sec_access(&mask, SC_MANAGER_READ_ACCESS ); init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - + /* Full Access 'BUILTIN\Administrators' */ - + init_sec_access(&mask,SC_MANAGER_ALL_ACCESS ); init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - + + /* create the security descriptor */ - + if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) return NULL; @@ -173,7 +173,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) /****************************************************************** free() function for REGISTRY_KEY *****************************************************************/ - + static void free_service_handle_info(void *ptr) { TALLOC_FREE( ptr ); @@ -197,21 +197,21 @@ static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd) /****************************************************************** *****************************************************************/ - + static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, uint32 type, const char *service, uint32 access_granted ) { SERVICE_INFO *info = NULL; WERROR result = WERR_OK; struct service_control_op *s_op; - + if ( !(info = TALLOC_ZERO_P( NULL, SERVICE_INFO )) ) return WERR_NOMEM; /* the Service Manager has a NULL name */ - + info->type = SVC_HANDLE_IS_SCM; - + switch ( type ) { case SVC_HANDLE_IS_SCM: info->type = SVC_HANDLE_IS_SCM; @@ -220,17 +220,17 @@ static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, u case SVC_HANDLE_IS_DBLOCK: info->type = SVC_HANDLE_IS_DBLOCK; break; - + case SVC_HANDLE_IS_SERVICE: info->type = SVC_HANDLE_IS_SERVICE; - + /* lookup the SERVICE_CONTROL_OPS */ if ( !(s_op = find_service_by_name( service )) ) { result = WERR_NO_SUCH_SERVICE; goto done; } - + info->ops = s_op->ops; if ( !(info->name = talloc_strdup( info, s_op->name )) ) { @@ -244,15 +244,15 @@ static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, u goto done; } - info->access_granted = access_granted; - + info->access_granted = access_granted; + /* store the SERVICE_INFO and create an open handle */ - + if ( !create_policy_hnd( p, handle, free_service_handle_info, info ) ) { result = WERR_ACCESS_DENIED; goto done; } - + done: if ( !W_ERROR_IS_OK(result) ) free_service_handle_info( info ); @@ -263,62 +263,61 @@ done: /******************************************************************** ********************************************************************/ -WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u) +WERROR _svcctl_OpenSCManagerW(pipes_struct *p, + struct svcctl_OpenSCManagerW *r) { SEC_DESC *sec_desc; uint32 access_granted = 0; NTSTATUS status; - + /* perform access checks */ - + if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) ) return WERR_NOMEM; - - se_map_generic( &q_u->access, &scm_generic_map ); - status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); + + se_map_generic( &r->in.access_mask, &scm_generic_map ); + status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted ); if ( !NT_STATUS_IS_OK(status) ) return ntstatus_to_werror( status ); - - return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SCM, NULL, access_granted ); + + return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SCM, NULL, access_granted ); } /******************************************************************** + _svcctl_OpenServiceW ********************************************************************/ -WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u) +WERROR _svcctl_OpenServiceW(pipes_struct *p, + struct svcctl_OpenServiceW *r) { SEC_DESC *sec_desc; uint32 access_granted = 0; NTSTATUS status; - char *service = NULL; - size_t ret = rpcstr_pull_talloc(p->mem_ctx, - &service, - q_u->servicename.buffer, - q_u->servicename.uni_str_len*2, - 0); - - if (ret == (size_t)-1 || !service) { + const char *service = NULL; + + service = r->in.ServiceName; + if (!service) { return WERR_NOMEM; } - DEBUG(5, ("_svcctl_open_service: Attempting to open Service [%s], \n", service)); + DEBUG(5, ("_svcctl_OpenServiceW: Attempting to open Service [%s], \n", service)); /* based on my tests you can open a service if you have a valid scm handle */ - if ( !find_service_info_by_hnd( p, &q_u->handle ) ) + if ( !find_service_info_by_hnd( p, r->in.scmanager_handle) ) return WERR_BADFID; - /* perform access checks. Use the root token in order to ensure that we + /* perform access checks. Use the root token in order to ensure that we retrieve the security descriptor */ if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) ) return WERR_NOMEM; - se_map_generic( &q_u->access, &svc_generic_map ); - status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); + se_map_generic( &r->in.access_mask, &svc_generic_map ); + status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted ); if ( !NT_STATUS_IS_OK(status) ) return ntstatus_to_werror( status ); - return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted ); + return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SERVICE, service, access_granted ); } /******************************************************************** @@ -329,49 +328,58 @@ WERROR _svcctl_CloseServiceHandle(pipes_struct *p, struct svcctl_CloseServiceHan if ( !close_policy_hnd( p, r->in.handle ) ) return WERR_BADFID; - return WERR_OK; + return WERR_OK; } /******************************************************************** + _svcctl_GetServiceDisplayNameW ********************************************************************/ -WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u) +WERROR _svcctl_GetServiceDisplayNameW(pipes_struct *p, + struct svcctl_GetServiceDisplayNameW *r) { - fstring service; + const char *service; const char *display_name; - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* can only use an SCM handle here */ - + if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) return WERR_BADFID; - - rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); - + + service = r->in.service_name; + display_name = svcctl_lookup_dispname(p->mem_ctx, service, p->pipe_user.nt_user_token ); - init_svcctl_r_get_display_name( r_u, display_name ? display_name : ""); + if (!display_name) { + display_name = ""; + } + + *r->out.display_name = display_name; + *r->out.display_name_length = strlen(display_name); return WERR_OK; } /******************************************************************** + _svcctl_QueryServiceStatus ********************************************************************/ -WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u) +WERROR _svcctl_QueryServiceStatus(pipes_struct *p, + struct svcctl_QueryServiceStatus *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; - + if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; - + /* try the service specific status call */ - return info->ops->service_status( info->name, &r_u->svc_status ); + return info->ops->service_status( info->name, r->out.service_status ); } /******************************************************************** @@ -383,7 +391,7 @@ static int enumerate_status( TALLOC_CTX *ctx, ENUM_SERVICES_STATUS **status, NT_ int i; ENUM_SERVICES_STATUS *st; const char *display_name; - + /* just count */ while ( svcctl_ops[num_services].name ) num_services++; @@ -392,16 +400,16 @@ static int enumerate_status( TALLOC_CTX *ctx, ENUM_SERVICES_STATUS **status, NT_ DEBUG(0,("enumerate_status: talloc() failed!\n")); return -1; } - + for ( i=0; i<num_services; i++ ) { init_unistr( &st[i].servicename, svcctl_ops[i].name ); - + display_name = svcctl_lookup_dispname(ctx, svcctl_ops[i].name, token ); init_unistr( &st[i].displayname, display_name ? display_name : ""); - + svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status ); } - + *status = st; return num_services; @@ -419,12 +427,12 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT WERROR result = WERR_OK; SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); NT_USER_TOKEN *token = p->pipe_user.nt_user_token; - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) return WERR_BADFID; - + if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) ) { return WERR_ACCESS_DENIED; } @@ -464,51 +472,57 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT } /******************************************************************** + _svcctl_StartServiceW ********************************************************************/ -WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u) +WERROR _svcctl_StartServiceW(pipes_struct *p, + struct svcctl_StartServiceW *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; - + if ( !(info->access_granted & SC_RIGHT_SVC_START) ) return WERR_ACCESS_DENIED; - + return info->ops->start_service( info->name ); } /******************************************************************** + _svcctl_ControlService ********************************************************************/ -WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u) +WERROR _svcctl_ControlService(pipes_struct *p, + struct svcctl_ControlService *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ - + if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - - switch ( q_u->control ) { + return WERR_BADFID; + + switch ( r->in.control ) { case SVCCTL_CONTROL_STOP: if ( !(info->access_granted & SC_RIGHT_SVC_STOP) ) return WERR_ACCESS_DENIED; - - return info->ops->stop_service( info->name, &r_u->svc_status ); - + + return info->ops->stop_service( info->name, + r->out.service_status ); + case SVCCTL_CONTROL_INTERROGATE: if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; - - return info->ops->service_status( info->name, &r_u->svc_status ); + + return info->ops->service_status( info->name, + r->out.service_status ); } - + /* default control action */ - + return WERR_ACCESS_DENIED; } @@ -518,22 +532,22 @@ WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, S WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u ) { SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) ) return WERR_ACCESS_DENIED; - - /* we have to set the outgoing buffer size to the same as the + + /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); - + r_u->needed = q_u->buffer_size; - + /* no dependent services...basically a stub function */ r_u->returned = 0; @@ -547,21 +561,21 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ { SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; - /* we have to set the outgoing buffer size to the same as the + /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure) */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); r_u->needed = q_u->buffer_size; - + switch ( q_u->level ) { case SVC_STATUS_PROCESS_INFO: { @@ -576,18 +590,18 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ buffer_size = sizeof(SERVICE_STATUS_PROCESS); break; } - + default: - return WERR_UNKNOWN_LEVEL; + return WERR_UNKNOWN_LEVEL; } - + buffer_size += buffer_size % 4; r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; - if (buffer_size > q_u->buffer_size ) + if (buffer_size > q_u->buffer_size ) return WERR_MORE_DATA; - + return WERR_OK; } @@ -600,12 +614,12 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG REGISTRY_VALUE *val; /* retrieve the registry values for this service */ - + if ( !(values = svcctl_fetch_regvalues( name, token )) ) return WERR_REG_CORRUPT; - + /* now fill in the individual values */ - + config->displayname = TALLOC_ZERO_P( ctx, UNISTR2 ); if ( (val = regval_ctr_getvalue( values, "DisplayName" )) != NULL ) init_unistr2( config->displayname, regval_sz( val ), UNI_STR_TERMINATE ); @@ -613,23 +627,23 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG init_unistr2( config->displayname, name, UNI_STR_TERMINATE ); if ( (val = regval_ctr_getvalue( values, "ObjectName" )) != NULL ) { - config->startname = TALLOC_ZERO_P( ctx, UNISTR2 ); + config->startname = TALLOC_ZERO_P( ctx, UNISTR2 ); init_unistr2( config->startname, regval_sz( val ), UNI_STR_TERMINATE ); } - + if ( (val = regval_ctr_getvalue( values, "ImagePath" )) != NULL ) { - config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 ); + config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 ); init_unistr2( config->executablepath, regval_sz( val ), UNI_STR_TERMINATE ); } /* a few hard coded values */ /* loadordergroup and dependencies are empty */ - + config->tag_id = 0x00000000; /* unassigned loadorder group */ config->service_type = SVCCTL_WIN32_OWN_PROC; config->error_control = SVCCTL_SVC_ERROR_NORMAL; - /* set the start type. NetLogon and WINS are disabled to prevent + /* set the start type. NetLogon and WINS are disabled to prevent the client from showing the "Start" button (if of course the services are not running */ @@ -639,7 +653,7 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG config->start_type = SVCCTL_DISABLED; else config->start_type = SVCCTL_DEMAND_START; - + TALLOC_FREE( values ); @@ -654,24 +668,24 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; WERROR wresult; - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) ) return WERR_ACCESS_DENIED; - /* we have to set the outgoing buffer size to the same as the + /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ r_u->needed = q_u->buffer_size; - + wresult = fill_svc_config( p->mem_ctx, info->name, &r_u->config, p->pipe_user.nt_user_token ); if ( !W_ERROR_IS_OK(wresult) ) return wresult; - + buffer_size = svcctl_sizeof_service_config( &r_u->config ); r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; @@ -679,7 +693,7 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON ZERO_STRUCTP( &r_u->config ); return WERR_INSUFFICIENT_BUFFER; } - + return WERR_OK; } @@ -750,53 +764,61 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO } /******************************************************************** + _svcctl_LockServiceDatabase ********************************************************************/ -WERROR _svcctl_lock_service_db( pipes_struct *p, SVCCTL_Q_LOCK_SERVICE_DB *q_u, SVCCTL_R_LOCK_SERVICE_DB *r_u ) +WERROR _svcctl_LockServiceDatabase(pipes_struct *p, + struct svcctl_LockServiceDatabase *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) ) return WERR_ACCESS_DENIED; /* Just open a handle. Doesn't actually lock anything */ - - return create_open_service_handle( p, &r_u->h_lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 ); -; + + return create_open_service_handle( p, r->out.lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 ); } /******************************************************************** + _svcctl_UnlockServiceDatabase ********************************************************************/ -WERROR _svcctl_unlock_service_db( pipes_struct *p, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, SVCCTL_R_UNLOCK_SERVICE_DB *r_u ) +WERROR _svcctl_UnlockServiceDatabase(pipes_struct *p, + struct svcctl_UnlockServiceDatabase *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->h_lock ); + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.lock ); if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) ) - return WERR_BADFID; - - return close_policy_hnd( p, &q_u->h_lock) ? WERR_OK : WERR_BADFID; + return WERR_BADFID; + + return close_policy_hnd( p, r->out.lock) ? WERR_OK : WERR_BADFID; } /******************************************************************** + _svcctl_QueryServiceObjectSecurity ********************************************************************/ -WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q_u, SVCCTL_R_QUERY_SERVICE_SEC *r_u ) +WERROR _svcctl_QueryServiceObjectSecurity(pipes_struct *p, + struct svcctl_QueryServiceObjectSecurity *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); SEC_DESC *sec_desc; + NTSTATUS status; + uint8_t *buffer = NULL; + size_t len = 0; /* only support the SCM and individual services */ if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) ) - return WERR_BADFID; + return WERR_BADFID; /* check access reights (according to MSDN) */ @@ -805,7 +827,7 @@ WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q /* TODO: handle something besides DACL_SECURITY_INFORMATION */ - if ( (q_u->security_flags & DACL_SECURITY_INFORMATION) != DACL_SECURITY_INFORMATION ) + if ( (r->in.security_flags & DACL_SECURITY_INFORMATION) != DACL_SECURITY_INFORMATION ) return WERR_INVALID_PARAM; /* lookup the security descriptor and marshall it up for a reply */ @@ -813,29 +835,35 @@ WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) ) return WERR_NOMEM; - r_u->needed = ndr_size_security_descriptor( sec_desc, 0 ); + *r->out.needed = ndr_size_security_descriptor( sec_desc, 0 ); - if ( r_u->needed > q_u->buffer_size ) { - ZERO_STRUCTP( &r_u->buffer ); + if ( *r->out.needed > r->in.buffer_size ) { + ZERO_STRUCTP( &r->out.buffer ); return WERR_INSUFFICIENT_BUFFER; } - rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); + status = marshall_sec_desc(p->mem_ctx, sec_desc, &buffer, &len); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + *r->out.needed = len; + r->out.buffer = buffer; - if ( !sec_io_desc("", &sec_desc, &r_u->buffer.prs, 0 ) ) - return WERR_NOMEM; - return WERR_OK; } /******************************************************************** + _svcctl_SetServiceObjectSecurity ********************************************************************/ -WERROR _svcctl_set_service_sec( pipes_struct *p, SVCCTL_Q_SET_SERVICE_SEC *q_u, SVCCTL_R_SET_SERVICE_SEC *r_u ) +WERROR _svcctl_SetServiceObjectSecurity(pipes_struct *p, + struct svcctl_SetServiceObjectSecurity *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); SEC_DESC *sec_desc = NULL; uint32 required_access; + NTSTATUS status; if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) ) return WERR_BADFID; @@ -843,298 +871,242 @@ WERROR _svcctl_set_service_sec( pipes_struct *p, SVCCTL_Q_SET_SERVICE_SEC *q_u, /* can't set the security de4scriptor on the ServiceControlManager */ if ( info->type == SVC_HANDLE_IS_SCM ) - return WERR_ACCESS_DENIED; + return WERR_ACCESS_DENIED; /* check the access on the open handle */ - - switch ( q_u->security_flags ) { + + switch ( r->in.security_flags ) { case DACL_SECURITY_INFORMATION: required_access = STD_RIGHT_WRITE_DAC_ACCESS; break; - + case OWNER_SECURITY_INFORMATION: case GROUP_SECURITY_INFORMATION: required_access = STD_RIGHT_WRITE_OWNER_ACCESS; break; - + case SACL_SECURITY_INFORMATION: return WERR_INVALID_PARAM; default: return WERR_INVALID_PARAM; } - + if ( !(info->access_granted & required_access) ) return WERR_ACCESS_DENIED; - + /* read the security descfriptor */ - - if ( !sec_io_desc("", &sec_desc, &q_u->buffer.prs, 0 ) ) - return WERR_NOMEM; - + + status = unmarshall_sec_desc(p->mem_ctx, + r->in.buffer, r->in.buffer_size, + &sec_desc); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + /* store the new SD */ - if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) ) + if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) ) return WERR_ACCESS_DENIED; return WERR_OK; } -WERROR _svcctl_ControlService(pipes_struct *p, struct svcctl_ControlService *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _svcctl_DeleteService(pipes_struct *p, struct svcctl_DeleteService *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_LockServiceDatabase(pipes_struct *p, struct svcctl_LockServiceDatabase *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_QueryServiceObjectSecurity(pipes_struct *p, struct svcctl_QueryServiceObjectSecurity *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_SetServiceObjectSecurity(pipes_struct *p, struct svcctl_SetServiceObjectSecurity *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_QueryServiceStatus(pipes_struct *p, struct svcctl_QueryServiceStatus *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SetServiceStatus(pipes_struct *p, struct svcctl_SetServiceStatus *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_UnlockServiceDatabase(pipes_struct *p, struct svcctl_UnlockServiceDatabase *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_NotifyBootConfigStatus(pipes_struct *p, struct svcctl_NotifyBootConfigStatus *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SCSetServiceBitsW(pipes_struct *p, struct svcctl_SCSetServiceBitsW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfigW(pipes_struct *p, struct svcctl_ChangeServiceConfigW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_CreateServiceW(pipes_struct *p, struct svcctl_CreateServiceW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumDependentServicesW(pipes_struct *p, struct svcctl_EnumDependentServicesW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumServicesStatusW(pipes_struct *p, struct svcctl_EnumServicesStatusW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_OpenSCManagerW(pipes_struct *p, struct svcctl_OpenSCManagerW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_OpenServiceW(pipes_struct *p, struct svcctl_OpenServiceW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfigW(pipes_struct *p, struct svcctl_QueryServiceConfigW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceLockStatusW(pipes_struct *p, struct svcctl_QueryServiceLockStatusW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_StartServiceW(pipes_struct *p, struct svcctl_StartServiceW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_GetServiceDisplayNameW(pipes_struct *p, struct svcctl_GetServiceDisplayNameW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetServiceKeyNameW(pipes_struct *p, struct svcctl_GetServiceKeyNameW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SCSetServiceBitsA(pipes_struct *p, struct svcctl_SCSetServiceBitsA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfigA(pipes_struct *p, struct svcctl_ChangeServiceConfigA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_CreateServiceA(pipes_struct *p, struct svcctl_CreateServiceA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumDependentServicesA(pipes_struct *p, struct svcctl_EnumDependentServicesA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumServicesStatusA(pipes_struct *p, struct svcctl_EnumServicesStatusA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_OpenSCManagerA(pipes_struct *p, struct svcctl_OpenSCManagerA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_OpenServiceA(pipes_struct *p, struct svcctl_OpenServiceA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfigA(pipes_struct *p, struct svcctl_QueryServiceConfigA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceLockStatusA(pipes_struct *p, struct svcctl_QueryServiceLockStatusA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_StartServiceA(pipes_struct *p, struct svcctl_StartServiceA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetServiceDisplayNameA(pipes_struct *p, struct svcctl_GetServiceDisplayNameA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetServiceKeyNameA(pipes_struct *p, struct svcctl_GetServiceKeyNameA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetCurrentGroupeStateW(pipes_struct *p, struct svcctl_GetCurrentGroupeStateW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumServiceGroupW(pipes_struct *p, struct svcctl_EnumServiceGroupW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfig2A(pipes_struct *p, struct svcctl_ChangeServiceConfig2A *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfig2W(pipes_struct *p, struct svcctl_ChangeServiceConfig2W *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfig2A(pipes_struct *p, struct svcctl_QueryServiceConfig2A *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfig2W(pipes_struct *p, struct svcctl_QueryServiceConfig2W *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceStatusEx(pipes_struct *p, struct svcctl_QueryServiceStatusEx *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _EnumServicesStatusExA(pipes_struct *p, struct EnumServicesStatusExA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _EnumServicesStatusExW(pipes_struct *p, struct EnumServicesStatusExW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SCSendTSMessage(pipes_struct *p, struct svcctl_SCSendTSMessage *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 92c178042f..c76bc19d9c 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -21,14 +21,10 @@ /* Implementation of registry functions. */ #include "includes.h" -#include "regfio.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -static const struct generic_mapping reg_generic_map = - { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; - /****************************************************************** free() function for struct registry_key *****************************************************************/ @@ -40,7 +36,7 @@ static void free_regkey(void *ptr) } /****************************************************************** - Find a registry key handle and return a REGISTRY_KEY + Find a registry key handle and return a struct registry_key * *****************************************************************/ static struct registry_key *find_regkey_by_hnd(pipes_struct *p, @@ -512,8 +508,6 @@ WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateS /* pull the message string and perform necessary sanity checks on it */ - chkmsg[0] = '\0'; - if ( r->in.message && r->in.message->name && r->in.message->name->name ) { if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) { return WERR_NOMEM; @@ -655,125 +649,6 @@ static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname ) } /******************************************************************* - Note: topkeypat is the *full* path that this *key will be - loaded into (including the name of the key) - ********************************************************************/ - -static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath, - REGF_NK_REC *key ) -{ - REGF_NK_REC *subkey; - REGISTRY_KEY registry_key; - REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; - int i; - char *path = NULL; - WERROR result = WERR_OK; - - /* initialize the REGISTRY_KEY structure */ - - if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) { - DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n", - topkeypath )); - return WERR_BADFILE; - } - - registry_key.name = talloc_strdup( regfile->mem_ctx, topkeypath ); - if ( !registry_key.name ) { - DEBUG(0,("reg_load_tree: Talloc failed for reg_key.name!\n")); - return WERR_NOMEM; - } - - /* now start parsing the values and subkeys */ - - if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) - return WERR_NOMEM; - - if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) - return WERR_NOMEM; - - /* copy values into the REGVAL_CTR */ - - for ( i=0; i<key->num_values; i++ ) { - regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type, - (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) ); - } - - /* copy subkeys into the REGSUBKEY_CTR */ - - key->subkey_index = 0; - while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { - regsubkey_ctr_addkey( subkeys, subkey->keyname ); - } - - /* write this key and values out */ - - if ( !store_reg_values( ®istry_key, values ) - || !store_reg_keys( ®istry_key, subkeys ) ) - { - DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); - result = WERR_REG_IO_FAILURE; - } - - TALLOC_FREE( subkeys ); - - if ( !W_ERROR_IS_OK(result) ) - return result; - - /* now continue to load each subkey registry tree */ - - key->subkey_index = 0; - while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { - path = talloc_asprintf(regfile->mem_ctx, - "%s\\%s", - topkeypath, - subkey->keyname); - if (!path) { - return WERR_NOMEM; - } - result = reg_load_tree( regfile, path, subkey ); - if ( !W_ERROR_IS_OK(result) ) - break; - } - - return result; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) -{ - REGF_FILE *regfile; - REGF_NK_REC *rootkey; - WERROR result; - - /* open the registry file....fail if the file already exists */ - - if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) { - DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); - } - - /* get the rootkey from the regf file and then load the tree - via recursive calls */ - - if ( !(rootkey = regfio_rootkey( regfile )) ) { - regfio_close( regfile ); - return WERR_REG_FILE_INVALID; - } - - result = reg_load_tree( regfile, krecord->name, rootkey ); - - /* cleanup */ - - regfio_close( regfile ); - - return result; -} - -/******************************************************************* ********************************************************************/ WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r) @@ -807,175 +682,9 @@ WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r) DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n", regkey->key->name, fname, lp_servicename(snum) )); - return restore_registry_key( regkey->key, fname ); + return reg_restorekey(regkey, fname); } -/******************************************************************** -********************************************************************/ - -static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, - REGF_NK_REC *parent, SEC_DESC *sec_desc ) -{ - REGF_NK_REC *key; - REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; - int i, num_subkeys; - char *key_tmp = NULL; - char *keyname, *parentpath; - char *subkeypath = NULL; - char *subkeyname; - REGISTRY_KEY registry_key; - WERROR result = WERR_OK; - - if (!regfile) - return WERR_GENERAL_FAILURE; - - if (!keypath) - return WERR_OBJECT_PATH_INVALID; - - /* split up the registry key path */ - - key_tmp = talloc_strdup(regfile->mem_ctx, keypath); - if (!key_tmp) { - return WERR_NOMEM; - } - if (!reg_split_key( key_tmp, &parentpath, &keyname ) ) - return WERR_OBJECT_PATH_INVALID; - - if ( !keyname ) - keyname = parentpath; - - /* we need a REGISTRY_KEY object here to enumerate subkeys and values */ - - ZERO_STRUCT( registry_key ); - - if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL ) - return WERR_NOMEM; - - if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL ) - return WERR_BADFILE; - - /* lookup the values and subkeys */ - - if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) - return WERR_NOMEM; - - if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) - return WERR_NOMEM; - - fetch_reg_keys( ®istry_key, subkeys ); - fetch_reg_values( ®istry_key, values ); - - /* write out this key */ - - if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { - result = WERR_CAN_NOT_COMPLETE; - goto done; - } - - /* write each one of the subkeys out */ - - num_subkeys = regsubkey_ctr_numkeys( subkeys ); - for ( i=0; i<num_subkeys; i++ ) { - subkeyname = regsubkey_ctr_specific_key( subkeys, i ); - subkeypath = talloc_asprintf(regfile->mem_ctx, - "%s\\%s", keypath, subkeyname); - if (!subkeypath) { - result = WERR_NOMEM; - goto done; - } - result = reg_write_tree( regfile, subkeypath, key, sec_desc ); - if ( !W_ERROR_IS_OK(result) ) - goto done; - } - - DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath )); - -done: - TALLOC_FREE( subkeys ); - TALLOC_FREE( registry_key.name ); - - return result; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) -{ - DOM_SID adm_sid, owner_sid; - SEC_ACE ace[2]; /* at most 2 entries */ - SEC_ACCESS mask; - SEC_ACL *psa = NULL; - size_t sd_size; - - /* set the owner to BUILTIN\Administrator */ - - sid_copy(&owner_sid, &global_sid_Builtin); - sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN ); - - - /* basic access for Everyone */ - - init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /* add Full Access 'BUILTIN\Administrators' */ - - init_sec_access(&mask, reg_generic_map.generic_all); - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /* create the security descriptor */ - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL) - return WERR_NOMEM; - - if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, - SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, - NULL, psa, &sd_size)) == NULL) - return WERR_NOMEM; - - return WERR_OK; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ) -{ - REGF_FILE *regfile; - WERROR result; - SEC_DESC *sd = NULL; - - /* open the registry file....fail if the file already exists */ - - if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) { - DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); - } - - if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { - regfio_close( regfile ); - return result; - } - - /* write the registry tree to the file */ - - result = reg_write_tree( regfile, krecord->name, NULL, sd ); - - /* cleanup */ - - regfio_close( regfile ); - - return result; -} - -/******************************************************************* - ********************************************************************/ - WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r) { struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle ); @@ -1002,7 +711,7 @@ WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r) DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n", regkey->key->name, fname, lp_servicename(snum) )); - return backup_registry_key( regkey->key, fname ); + return reg_savekey(regkey, fname); } /******************************************************************* diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index e0103e6b58..6d03009d00 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -281,11 +281,12 @@ WERROR _wkssvc_NetrGetJoinableOus(pipes_struct *p, struct wkssvc_NetrGetJoinable } /******************************************************************** + _wkssvc_NetrJoinDomain2 ********************************************************************/ -WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r) +WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, + struct wkssvc_NetrJoinDomain2 *r) { -#if 0 struct libnet_JoinCtx *j = NULL; char *cleartext_pwd = NULL; char *admin_domain = NULL; @@ -293,7 +294,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r WERROR werr; NTSTATUS status; struct nt_user_token *token = p->pipe_user.nt_user_token; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; if (!r->in.domain_name) { return WERR_INVALID_PARAM; @@ -302,6 +303,8 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r if (!user_has_privileges(token, &se_machine_account) && !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) && !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) { + DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have " + "sufficient privileges\n")); return WERR_ACCESS_DENIED; } @@ -335,32 +338,96 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r return werr; } - j->in.dc_name = info->domain_controller_name; + j->in.dc_name = info->dc_unc; j->in.domain_name = r->in.domain_name; j->in.account_ou = r->in.account_ou; j->in.join_flags = r->in.join_flags; j->in.admin_account = admin_account; j->in.admin_password = cleartext_pwd; - j->in.modify_config = true; + j->in.debug = true; become_root(); werr = libnet_Join(p->mem_ctx, j); unbecome_root(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join gave %s\n", + j->out.error_string ? j->out.error_string : + dos_errstr(werr))); + } + + TALLOC_FREE(j); return werr; -#endif - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; } /******************************************************************** + _wkssvc_NetrUnjoinDomain2 ********************************************************************/ -WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, struct wkssvc_NetrUnjoinDomain2 *r) +WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, + struct wkssvc_NetrUnjoinDomain2 *r) { - /* FIXME: Add implementation code here */ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + struct libnet_UnjoinCtx *u = NULL; + char *cleartext_pwd = NULL; + char *admin_domain = NULL; + char *admin_account = NULL; + WERROR werr; + NTSTATUS status; + struct nt_user_token *token = p->pipe_user.nt_user_token; + struct netr_DsRGetDCNameInfo *info = NULL; + + if (!user_has_privileges(token, &se_machine_account) && + !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) && + !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) { + DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have " + "sufficient privileges\n")); + return WERR_ACCESS_DENIED; + } + + werr = decode_wkssvc_join_password_buffer(p->mem_ctx, + r->in.encrypted_password, + &p->session_key, + &cleartext_pwd); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + split_domain_user(p->mem_ctx, + r->in.account, + &admin_domain, + &admin_account); + + status = dsgetdcname(p->mem_ctx, + lp_realm(), + NULL, + NULL, + DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_RETURN_DNS_NAME, + &info); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + werr = libnet_init_UnjoinCtx(p->mem_ctx, &u); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + u->in.dc_name = info->dc_unc; + u->in.domain_name = lp_realm(); + u->in.unjoin_flags = r->in.unjoin_flags | + WKSSVC_JOIN_FLAGS_JOIN_TYPE; + u->in.admin_account = admin_account; + u->in.admin_password = cleartext_pwd; + u->in.debug = true; + + become_root(); + werr = libnet_Unjoin(p->mem_ctx, u); + unbecome_root(); + + TALLOC_FREE(u); + return werr; } /******************************************************************** |