summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_lsa.c789
-rw-r--r--source3/rpc_server/srv_lsa_nt.c1277
-rw-r--r--source3/rpc_server/srv_netlog.c363
-rw-r--r--source3/rpc_server/srv_netlog_nt.c859
-rw-r--r--source3/rpc_server/srv_ntsvcs.c107
-rw-r--r--source3/rpc_server/srv_ntsvcs_nt.c636
-rw-r--r--source3/rpc_server/srv_pipe.c63
-rw-r--r--source3/rpc_server/srv_samr_nt.c19
-rw-r--r--source3/rpc_server/srv_samr_util.c1
-rw-r--r--source3/rpc_server/srv_srvsvc.c87
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c376
-rw-r--r--source3/rpc_server/srv_svcctl.c180
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c502
-rw-r--r--source3/rpc_server/srv_winreg_nt.c297
-rw-r--r--source3/rpc_server/srv_wkssvc_nt.c91
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( &registry_key, values )
- || !store_reg_keys( &registry_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( &registry_key, subkeys );
- fetch_reg_values( &registry_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;
}
/********************************************************************