From 4093bf7ff8c8861cf7b941945ede53a8ec5bb6c8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 9 Sep 2003 04:07:32 +0000 Subject: sync 3.0 into HEAD for the last time (This used to be commit c17a7dc9a190156a069da3e861c18fd3f81224ad) --- source3/rpc_server/srv_dfs.c | 16 ++- source3/rpc_server/srv_dfs_nt.c | 4 +- source3/rpc_server/srv_echo.c | 27 +++-- source3/rpc_server/srv_lsa.c | 43 +++++--- source3/rpc_server/srv_lsa_ds.c | 93 ++++++++++++++++ source3/rpc_server/srv_lsa_ds_nt.c | 127 ++++++++++++++++++++++ source3/rpc_server/srv_lsa_nt.c | 2 +- source3/rpc_server/srv_netlog.c | 13 ++- source3/rpc_server/srv_pipe.c | 209 ++++++++++++++++++++++++------------ source3/rpc_server/srv_pipe_hnd.c | 2 + source3/rpc_server/srv_reg.c | 18 ++-- source3/rpc_server/srv_samr.c | 49 +++++---- source3/rpc_server/srv_samr_nt.c | 112 ++++++++++++++++--- source3/rpc_server/srv_spoolss.c | 13 ++- source3/rpc_server/srv_spoolss_nt.c | 26 ++--- source3/rpc_server/srv_srvsvc.c | 16 ++- source3/rpc_server/srv_util.c | 11 +- source3/rpc_server/srv_wkssvc.c | 15 ++- 18 files changed, 624 insertions(+), 172 deletions(-) create mode 100644 source3/rpc_server/srv_lsa_ds.c create mode 100644 source3/rpc_server/srv_lsa_ds_nt.c (limited to 'source3/rpc_server') diff --git a/source3/rpc_server/srv_dfs.c b/source3/rpc_server/srv_dfs.c index 27bb0732b4..6c35917e61 100644 --- a/source3/rpc_server/srv_dfs.c +++ b/source3/rpc_server/srv_dfs.c @@ -157,17 +157,23 @@ static BOOL api_dfs_enum(pipes_struct *p) /******************************************************************* \pipe\netdfs commands ********************************************************************/ - -NTSTATUS rpc_dfs_init(void) +static struct api_struct api_netdfs_cmds[] = { - struct api_struct api_netdfs_cmds[] = - { {"DFS_EXIST", DFS_EXIST, api_dfs_exist }, {"DFS_ADD", DFS_ADD, api_dfs_add }, {"DFS_REMOVE", DFS_REMOVE, api_dfs_remove }, {"DFS_GET_INFO", DFS_GET_INFO, api_dfs_get_info }, {"DFS_ENUM", DFS_ENUM, api_dfs_enum } - }; +}; + +void netdfs_get_pipe_fns( struct api_struct **fns, int *n_fns ) +{ + *fns = api_netdfs_cmds; + *n_fns = sizeof(api_netdfs_cmds) / sizeof(struct api_struct); +} + +NTSTATUS rpc_dfs_init(void) +{ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "netdfs", "netdfs", api_netdfs_cmds, sizeof(api_netdfs_cmds) / sizeof(struct api_struct)); } diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index eba4eaec75..3470ad99b4 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -159,7 +159,7 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, { pstring refpath; pstrcpy(refpath,jn.referral_list[i].alternate_path); - trim_string(refpath, "\\", "\\"); + trim_char(refpath, '\\', '\\'); DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath)); if(strequal(refpath, altpath)) { @@ -257,7 +257,7 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, DFS_I struct referral* ref = &(j[i].referral_list[ii]); pstrcpy(path, ref->alternate_path); - trim_string(path,"\\",""); + trim_char(path,'\\','\0'); p = strrchr_m(path,'\\'); if(p==NULL) { diff --git a/source3/rpc_server/srv_echo.c b/source3/rpc_server/srv_echo.c index 166b6e939d..c6cfde07c1 100644 --- a/source3/rpc_server/srv_echo.c +++ b/source3/rpc_server/srv_echo.c @@ -120,18 +120,31 @@ static BOOL api_sink_data(pipes_struct *p) \pipe\rpcecho commands ********************************************************************/ -NTSTATUS rpc_echo_init(void) +struct api_struct api_echo_cmds[] = { + {"ADD_ONE", ECHO_ADD_ONE, api_add_one }, + {"ECHO_DATA", ECHO_DATA, api_echo_data }, + {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data }, + {"SINK_DATA", ECHO_SINK_DATA, api_sink_data }, +}; + + +void echo_get_pipe_fns( struct api_struct **fns, int *n_fns ) { - struct api_struct api_echo_cmds[] = { - {"ADD_ONE", ECHO_ADD_ONE, api_add_one }, - {"ECHO_DATA", ECHO_DATA, api_echo_data }, - {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data }, - {"SINK_DATA", ECHO_SINK_DATA, api_sink_data }, - }; + *fns = api_echo_cmds; + *n_fns = sizeof(api_echo_cmds) / sizeof(struct api_struct); +} +NTSTATUS rpc_echo_init(void) +{ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "rpcecho", "rpcecho", api_echo_cmds, sizeof(api_echo_cmds) / sizeof(struct api_struct)); } +#else /* DEVELOPER */ + +NTSTATUS rpc_echo_init(void) +{ + return NT_STATUS_OK; +} #endif /* DEVELOPER */ diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index 34812b15d9..138fb1d7ef 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -644,9 +644,8 @@ static BOOL api_lsa_query_info2(pipes_struct *p) /*************************************************************************** \PIPE\ntlsa commands ***************************************************************************/ -NTSTATUS rpc_lsa_init(void) -{ -static const struct api_struct api_lsa_cmds[] = + +static struct api_struct api_lsa_cmds[] = { { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, @@ -671,17 +670,33 @@ static const struct api_struct api_lsa_cmds[] = ADS DC capabilities */ { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 } }; -/* - * 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. - */ - int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct); - if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) { - funcs -= 1; - } +static int count_fns(void) +{ + int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct); + + /* + * 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; + } + + 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); + return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds, + funcs); } diff --git a/source3/rpc_server/srv_lsa_ds.c b/source3/rpc_server/srv_lsa_ds.c new file mode 100644 index 0000000000..1e75175c2c --- /dev/null +++ b/source3/rpc_server/srv_lsa_ds.c @@ -0,0 +1,93 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Gerald Carter 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* This is the interface for the registry functions. */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +#if 0 /* disabled */ +/******************************************************************* + api_reg_open_entry + ********************************************************************/ + +static BOOL api_dsrole_get_primary_dominfo(pipes_struct *p) +{ + DS_Q_GETPRIMDOMINFO q_u; + DS_R_GETPRIMDOMINFO 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 request */ + if ( !ds_io_q_getprimdominfo("", data, 0, &q_u) ) + return False; + + /* construct reply. */ + r_u.status = _dsrole_get_primary_dominfo( p, &q_u, &r_u ); + + if ( !ds_io_r_getprimdominfo("", rdata, 0, &r_u) ) + return False; + + return True; +} +#endif + +/******************************************************************* + stub functions for unimplemented RPC +*******************************************************************/ + +static BOOL api_dsrole_stub( pipes_struct *p ) +{ + DEBUG(0,("api_dsrole_stub: Hmmm....didn't know this RPC existed...\n")); + + return False; +} + + +/******************************************************************* + array of \PIPE\lsass (new windows 2000 UUID) operations +********************************************************************/ +static struct api_struct api_lsa_ds_cmds[] = { + { "DS_NOP", DS_NOP, api_dsrole_stub } + +#if 0 /* disabled due to breakage with viewing domain users and groups + on a Samba PDC from win2k clients --jerry CIFS 2003 */ + { "DS_GETPRIMDOMINFO", DS_GETPRIMDOMINFO, api_dsrole_get_primary_dominfo } +#endif + +}; + +void lsa_ds_get_pipe_fns( struct api_struct **fns, int *n_fns ) +{ + *fns = api_lsa_ds_cmds; + *n_fns = sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct); +} + + +NTSTATUS rpc_lsa_ds_init(void) +{ + return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsa_ds", "lsa_ds", api_lsa_ds_cmds, + sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct)); +} diff --git a/source3/rpc_server/srv_lsa_ds_nt.c b/source3/rpc_server/srv_lsa_ds_nt.c new file mode 100644 index 0000000000..37540a9668 --- /dev/null +++ b/source3/rpc_server/srv_lsa_ds_nt.c @@ -0,0 +1,127 @@ +/* + * 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) Gerald Carter 2002. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Implementation of registry functions. */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +/******************************************************************** + Fill in a DS_DOMINFO_CTR structure + ********************************************************************/ + +static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **info) +{ + DSROLE_PRIMARY_DOMAIN_INFO_BASIC *basic; + const char *netbios_domain; + fstring dnsdomain; + + DEBUG(10,("fill_dsrole_dominfo_basic: enter\n")); + + if ( !(basic = talloc_zero(ctx, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC))) ) { + DEBUG(0,("fill_dsrole_dominfo_basic: FATAL error! talloc_xero() failed\n")); + return NT_STATUS_NO_MEMORY; + } + + switch ( lp_server_role() ) { + case ROLE_STANDALONE: + basic->machine_role = DSROLE_STANDALONE_SRV; + break; + case ROLE_DOMAIN_MEMBER: + basic->machine_role = DSROLE_DOMAIN_MEMBER_SRV; + break; + case ROLE_DOMAIN_BDC: + basic->machine_role = DSROLE_BDC; + basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE; + if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) ) + basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT; + get_mydomname(dnsdomain); + strlower_m(dnsdomain); + break; + case ROLE_DOMAIN_PDC: + basic->machine_role = DSROLE_PDC; + basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE; + if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) ) + basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT; + get_mydomname(dnsdomain); + strlower_m(dnsdomain); + break; + } + + basic->unknown = 0x6173; /* seen on the wire; maybe padding */ + + /* always set netbios name */ + + basic->netbios_ptr = 1; + netbios_domain = get_global_sam_name(); + init_unistr2( &basic->netbios_domain, netbios_domain, strlen(netbios_domain) ); + + basic->dnsname_ptr = 1; + init_unistr2( &basic->dns_domain, dnsdomain, strlen(dnsdomain) ); + basic->forestname_ptr = 1; + init_unistr2( &basic->forest_domain, dnsdomain, strlen(dnsdomain) ); + + + /* fill in some additional fields if we are a member of an AD domain */ + + if ( lp_security() == SEC_ADS ) { + /* TODO */ + ;; + } + + *info = basic; + + return NT_STATUS_OK; +} + +/******************************************************************** + Implement the DsroleGetPrimaryDomainInfo() call + ********************************************************************/ + +NTSTATUS _dsrole_get_primary_dominfo(pipes_struct *p, DS_Q_GETPRIMDOMINFO *q_u, DS_R_GETPRIMDOMINFO *r_u) +{ + NTSTATUS result = NT_STATUS_OK; + uint32 level = q_u->level; + + switch ( level ) { + + case DsRolePrimaryDomainInfoBasic: + r_u->level = DsRolePrimaryDomainInfoBasic; + r_u->ptr = 1; + result = fill_dsrole_dominfo_basic( p->mem_ctx, &r_u->info.basic ); + break; + + default: + DEBUG(0,("_dsrole_get_primary_dominfo: Unsupported info level [%d]!\n", + level)); + result = NT_STATUS_INVALID_LEVEL; + } + + return result; +} + + + diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 9eafcb8dc3..330dd727ef 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -502,7 +502,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - nt_status = secrets_get_trusted_domains(p->mem_ctx, &enum_context, max_num_domains, &num_domains, &trust_doms); + nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms); if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) && diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index d1be2f3723..9c10d86379 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -320,10 +320,7 @@ static BOOL api_net_logon_ctrl(pipes_struct *p) /******************************************************************* array of \PIPE\NETLOGON operations ********************************************************************/ - -NTSTATUS rpc_net_init(void) -{ - static struct api_struct api_net_cmds [] = +static struct api_struct api_net_cmds [] = { { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal }, { "NET_AUTH" , NET_AUTH , api_net_auth }, @@ -336,6 +333,14 @@ NTSTATUS rpc_net_init(void) { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl } }; +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_pipe.c b/source3/rpc_server/srv_pipe.c index 594cb3a9ae..d1fb587d74 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -713,26 +713,19 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) Used to reject unknown binds from Win2k. *******************************************************************/ -BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, - RPC_IFACE* transfer) +BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, + RPC_IFACE* transfer, uint32 context_id) { extern struct pipe_id_info pipe_names[]; + char *pipe_name = p->name; int i=0; fstring pname; + fstrcpy(pname,"\\PIPE\\"); fstrcat(pname,pipe_name); DEBUG(3,("check_bind_req for %s\n", pname)); -#ifndef SUPPORT_NEW_LSARPC_UUID - - /* check for the first pipe matching the name */ - - for ( i=0; pipe_names[i].client_pipe; i++ ) { - if ( strequal(pipe_names[i].client_pipe, pname) ) - break; - } -#else /* 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++ ) @@ -743,29 +736,34 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, && (transfer->version == pipe_names[i].trans_syntax.version) && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) ) { + struct api_struct *fns = NULL; + int n_fns = 0; + PIPE_RPC_FNS *context_fns; + + if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) { + DEBUG(0,("check_bind_req: malloc() failed!\n")); + return False; + } + + /* save the RPC function table associated with this bind */ + + get_pipe_fns(i, &fns, &n_fns); + + context_fns->cmds = fns; + context_fns->n_cmds = n_fns; + context_fns->context_id = context_id; + + /* add to the list of open contexts */ + + DLIST_ADD( p->contexts, context_fns ); + break; } } -#endif if(pipe_names[i].client_pipe == NULL) return False; -#ifndef SUPPORT_NEW_LSARPC_UUID - /* check the abstract interface */ - if ( (abstract->version != pipe_names[i].abstr_syntax.version) - || (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) != 0) ) - { - return False; - } - - /* check the transfer interface */ - if ( (transfer->version != pipe_names[i].trans_syntax.version) - || (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) != 0) ) - { - return False; - } -#endif return True; } @@ -861,7 +859,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } if (i == rpc_lookup_size) { - if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { + if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", p->name )); if(!setup_bind_nak(p)) @@ -878,10 +876,10 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } } - if (i == rpc_lookup_size) { - DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); - return False; - } + if (i == rpc_lookup_size) { + DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); + return False; + } } /* decode the bind request */ @@ -1028,7 +1026,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ - if(check_bind_req(p->name, &hdr_rb.abstract, &hdr_rb.transfer)) { + if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id )) + { init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, @@ -1227,10 +1226,10 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) sizeof(p->ntlmssp_hash)); dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n", - data, data_len); + (const unsigned char *)data, data_len); NTLMSSPcalc_p(p, (uchar*)data, data_len); dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n", - data, data_len); + (const unsigned char *)data, data_len); crc32 = crc32_calc_buffer(data, data_len); } @@ -1391,6 +1390,48 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p return user; } +/**************************************************************************** + Find the set of RPC functions associated with this context_id +****************************************************************************/ + +static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id ) +{ + PIPE_RPC_FNS *fns = NULL; + PIPE_RPC_FNS *tmp = NULL; + + if ( !list ) { + DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n")); + return NULL; + } + + for (tmp=list; tmp; tmp=tmp->next ) { + if ( tmp->context_id == context_id ) + break; + } + + fns = tmp; + + return fns; +} + +/**************************************************************************** + memory cleanup +****************************************************************************/ + +void free_pipe_rpc_context( PIPE_RPC_FNS *list ) +{ + PIPE_RPC_FNS *tmp = list; + PIPE_RPC_FNS *tmp2; + + while (tmp) { + tmp2 = tmp->next; + SAFE_FREE(tmp); + tmp = tmp2; + } + + return; +} + /**************************************************************************** Find the correct RPC function to call for this request. If the pipe is authenticated then become the correct UNIX user @@ -1399,9 +1440,9 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p BOOL api_pipe_request(pipes_struct *p) { - int i = 0; BOOL ret = False; - + PIPE_RPC_FNS *pipe_fns; + if (p->ntlmssp_auth_validated) { if(!become_authenticated_pipe_user(p)) { @@ -1411,36 +1452,19 @@ BOOL api_pipe_request(pipes_struct *p) } DEBUG(5, ("Requested \\PIPE\\%s\n", p->name)); - - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { - DEBUG(3,("Doing \\PIPE\\%s\n", - rpc_lookup[i].pipe.clnt)); - set_current_rpc_talloc(p->mem_ctx); - ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt, - rpc_lookup[i].cmds, - rpc_lookup[i].n_cmds); - set_current_rpc_talloc(NULL); - break; - } + + /* get the set of RPC functions for this context */ + + pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id); + + if ( pipe_fns ) { + set_current_rpc_talloc(p->mem_ctx); + ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds); + set_current_rpc_talloc(NULL); } - - - if (i == rpc_lookup_size) { - smb_probe_module("rpc", p->name); - - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { - DEBUG(3,("Doing \\PIPE\\%s\n", - rpc_lookup[i].pipe.clnt)); - set_current_rpc_talloc(p->mem_ctx); - ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt, - rpc_lookup[i].cmds, - rpc_lookup[i].n_cmds); - set_current_rpc_talloc(NULL); - break; - } - } + else { + DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n", + p->hdr_req.context_id, p->name)); } if(p->ntlmssp_auth_validated) @@ -1529,3 +1553,56 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, return True; } + +/******************************************************************* +*******************************************************************/ + +void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) +{ + struct api_struct *cmds = NULL; + int n_cmds = 0; + + switch ( idx ) { + case PI_LSARPC: + lsa_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_LSARPC_DS: + lsa_ds_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_SAMR: + samr_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_NETLOGON: + netlog_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_SRVSVC: + srvsvc_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_WKSSVC: + wkssvc_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_WINREG: + reg_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_SPOOLSS: + spoolss_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_NETDFS: + netdfs_get_pipe_fns( &cmds, &n_cmds ); + break; +#ifdef DEVELOPER + case PI_ECHO: + echo_get_pipe_fns( &cmds, &n_cmds ); + break; +#endif + default: + DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); + } + + *fns = cmds; + *n_fns = n_cmds; + + return; +} + + diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 125f603771..55def97673 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1106,6 +1106,8 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn) if (p->mem_ctx) talloc_destroy(p->mem_ctx); + + free_pipe_rpc_context( p->contexts ); /* Free the handles database. */ close_policy_by_pipe(p); diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c index e1a02103f7..b780be0aff 100644 --- a/source3/rpc_server/srv_reg.c +++ b/source3/rpc_server/srv_reg.c @@ -367,16 +367,12 @@ static BOOL api_reg_save_key(pipes_struct *p) return True; } - - /******************************************************************* array of \PIPE\reg operations ********************************************************************/ -NTSTATUS rpc_reg_init(void) +static struct api_struct api_reg_cmds[] = { - static struct api_struct api_reg_cmds[] = - { { "REG_CLOSE" , REG_CLOSE , api_reg_close }, { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry }, { "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr }, @@ -390,7 +386,17 @@ NTSTATUS rpc_reg_init(void) { "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown }, { "REG_UNKNOWN_1A" , REG_UNKNOWN_1A , api_reg_unknown_1a }, { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key } - }; +}; + +void reg_get_pipe_fns( struct api_struct **fns, int *n_fns ) +{ + *fns = api_reg_cmds; + *n_fns = sizeof(api_reg_cmds) / sizeof(struct api_struct); +} + +NTSTATUS rpc_reg_init(void) +{ + return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "winreg", "winreg", api_reg_cmds, sizeof(api_reg_cmds) / sizeof(struct api_struct)); } diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 86ff039683..a0f62c20fc 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -386,7 +386,7 @@ static BOOL api_samr_chgpasswd_user(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - /* unknown 38 command */ + /* change password request */ if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) { DEBUG(0,("api_samr_chgpasswd_user: Failed to unmarshall SAMR_Q_CHGPASSWD_USER.\n")); return False; @@ -448,13 +448,12 @@ static BOOL api_samr_open_user(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - /* grab the samr unknown 22 */ if(!samr_io_q_open_user("", &q_u, data, 0)) { DEBUG(0,("api_samr_open_user: unable to unmarshall SAMR_Q_OPEN_USER.\n")); return False; } - r_u.status = _api_samr_open_user(p, &q_u, &r_u); + r_u.status = _samr_open_user(p, &q_u, &r_u); /* store the response in the SMB stream */ if(!samr_io_r_open_user("", &r_u, rdata, 0)) { @@ -479,7 +478,6 @@ static BOOL api_samr_query_userinfo(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - /* grab the samr unknown 24 */ if(!samr_io_q_query_userinfo("", &q_u, data, 0)){ DEBUG(0,("api_samr_query_userinfo: unable to unmarshall SAMR_Q_QUERY_USERINFO.\n")); return False; @@ -510,7 +508,6 @@ static BOOL api_samr_query_usergroups(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - /* grab the samr unknown 32 */ if(!samr_io_q_query_usergroups("", &q_u, data, 0)) { DEBUG(0,("api_samr_query_usergroups: unable to unmarshall SAMR_Q_QUERY_USERGROUPS.\n")); return False; @@ -541,7 +538,6 @@ static BOOL api_samr_query_dom_info(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - /* grab the samr unknown 8 command */ if(!samr_io_q_query_dom_info("", &q_u, data, 0)) { DEBUG(0,("api_samr_query_dom_info: unable to unmarshall SAMR_Q_QUERY_DOMAIN_INFO.\n")); return False; @@ -579,7 +575,7 @@ static BOOL api_samr_create_user(pipes_struct *p) return False; } - r_u.status=_api_samr_create_user(p, &q_u, &r_u); + r_u.status=_samr_create_user(p, &q_u, &r_u); /* store the response in the SMB stream */ if(!samr_io_r_create_user("", &r_u, rdata, 0)) { @@ -761,7 +757,7 @@ static BOOL api_samr_open_alias(pipes_struct *p) return False; } - r_u.status=_api_samr_open_alias(p, &q_u, &r_u); + r_u.status=_samr_open_alias(p, &q_u, &r_u); /* store the response in the SMB stream */ if(!samr_io_r_open_alias("", &r_u, rdata, 0)) { @@ -1347,13 +1343,13 @@ static BOOL api_samr_open_group(pipes_struct *p) } /******************************************************************* - api_samr_unknown_2d + api_samr_remove_user_foreign_domain ********************************************************************/ -static BOOL api_samr_unknown_2d(pipes_struct *p) +static BOOL api_samr_remove_user_foreign_domain(pipes_struct *p) { - SAMR_Q_UNKNOWN_2D q_u; - SAMR_R_UNKNOWN_2D r_u; + SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN q_u; + SAMR_R_REMOVE_USER_FOREIGN_DOMAIN r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; @@ -1361,15 +1357,15 @@ static BOOL api_samr_unknown_2d(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - if (!samr_io_q_unknown_2d("", &q_u, data, 0)) { - DEBUG(0,("api_samr_unknown_2d: unable to unmarshall SAMR_Q_UNKNOWN_2D.\n")); + if (!samr_io_q_remove_user_foreign_domain("", &q_u, data, 0)) { + DEBUG(0,("api_samr_remove_user_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN.\n")); return False; } - r_u.status = _samr_unknown_2d(p, &q_u, &r_u); + r_u.status = _samr_remove_user_foreign_domain(p, &q_u, &r_u); - if (!samr_io_r_unknown_2d("", &r_u, rdata, 0)) { - DEBUG(0,("api_samr_unknown_2d: unable to marshall SAMR_R_UNKNOWN_2D.\n")); + if (!samr_io_r_remove_user_foreign_domain("", &r_u, rdata, 0)) { + DEBUG(0,("api_samr_remove_user_foreign_domain: unable to marshall SAMR_R_REMOVE_USER_FOREIGN_DOMAIN.\n")); return False; } @@ -1421,7 +1417,6 @@ static BOOL api_samr_set_dom_info(pipes_struct *p) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - /* grab the samr unknown 8 command */ if(!samr_io_q_set_domain_info("", &q_u, data, 0)) { DEBUG(0,("api_samr_set_dom_info: unable to unmarshall SAMR_Q_SET_DOMAIN_INFO.\n")); return False; @@ -1442,10 +1437,8 @@ static BOOL api_samr_set_dom_info(pipes_struct *p) array of \PIPE\samr operations ********************************************************************/ -NTSTATUS rpc_samr_init(void) +static struct api_struct api_samr_cmds [] = { - static struct api_struct api_samr_cmds [] = - { {"SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd }, {"SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect }, {"SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon }, @@ -1490,7 +1483,7 @@ NTSTATUS rpc_samr_init(void) {"SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias }, {"SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group }, {"SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain }, - {"SAMR_UNKNOWN_2D" , SAMR_UNKNOWN_2D , api_samr_unknown_2d }, + {"SAMR_REMOVE_USER_FOREIGN_DOMAIN" , SAMR_REMOVE_USER_FOREIGN_DOMAIN , api_samr_remove_user_foreign_domain }, {"SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain }, {"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj }, @@ -1499,7 +1492,17 @@ NTSTATUS rpc_samr_init(void) {"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e }, {"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info }, {"SAMR_CONNECT4" , SAMR_CONNECT4 , api_samr_connect4 } - }; +}; + +void samr_get_pipe_fns( struct api_struct **fns, int *n_fns ) +{ + *fns = api_samr_cmds; + *n_fns = sizeof(api_samr_cmds) / sizeof(struct api_struct); +} + + +NTSTATUS rpc_samr_init(void) +{ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "samr", "lsass", api_samr_cmds, sizeof(api_samr_cmds) / sizeof(struct api_struct)); } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 14aad5d6f8..7f7b5e8d5e 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -8,6 +8,7 @@ * Copyright (C) Jeremy Allison 2001-2002, * Copyright (C) Jean François Micouleau 1998-2001, * Copyright (C) Jim McDonough 2002. + * Copyright (C) Gerald (Jerry) Carter 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 @@ -913,7 +914,6 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) { struct sys_grent *glist; struct sys_grent *grp; - struct passwd *pw; gid_t winbind_gid_low, winbind_gid_high; BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high); @@ -952,7 +952,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM /* Don't return user private groups... */ - if ((pw = Get_Pwnam(smap.nt_name)) != 0) { + if (Get_Pwnam(smap.nt_name) != 0) { DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name )); continue; } @@ -1013,8 +1013,13 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO *p_num_entries = 0; + /* access checks for the users were performed higher up. become/unbecome_root() + needed for some passdb backends to enumerate groups */ + + become_root(); pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); - + unbecome_root(); + num_entries=group_entries-start_idx; /* limit the number of entries */ @@ -1659,10 +1664,10 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK } /******************************************************************* - _api_samr_open_user. Safe - gives out no passwd info. + _samr_open_user. Safe - gives out no passwd info. ********************************************************************/ -NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u) +NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u) { SAM_ACCOUNT *sampass=NULL; DOM_SID sid; @@ -2140,7 +2145,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA num_users, num_groups, num_aliases); break; case 0x03: - account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout); + account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout); unix_to_nt_time_abs(&nt_logout, u_logout); init_unk_info3(&ctr->info.inf3, nt_logout); @@ -2181,12 +2186,12 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA } /******************************************************************* - _api_samr_create_user + _samr_create_user Create an account, can be either a normal user or a machine. This funcion will need to be updated for bdc/domain trusts. ********************************************************************/ -NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u) +NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u) { SAM_ACCOUNT *sam_pass=NULL; fstring account; @@ -2300,12 +2305,12 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ int add_ret; all_string_sub(add_script, "%u", account, sizeof(account)); add_ret = smbrun(add_script,NULL); - DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret)); + DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret)); } else /* no add user script -- ask winbindd to do it */ { if ( !winbind_create_user( account, &new_rid ) ) { - DEBUG(3,("_api_samr_create_user: winbind_create_user(%s) failed\n", + DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n", account)); } } @@ -2369,6 +2374,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u) { struct samr_info *info = NULL; + uint32 des_access = q_u->access_mask; /* Access check */ @@ -2386,6 +2392,13 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO if ((info = get_samr_info_by_sid(NULL)) == NULL) return NT_STATUS_NO_MEMORY; + /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS + was observed from a win98 client trying to enumerate users (when configured + user level access control on shares) --jerry */ + + se_map_generic( &des_access, &sam_generic_mapping ); + info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN); + info->status = q_u->unknown_0; /* get a (unique) handle. open a policy on it. */ @@ -2510,7 +2523,9 @@ NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_ if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info)) return NT_STATUS_INVALID_HANDLE; - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) { + if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, + SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain"))) + { return r_u->status; } @@ -2605,7 +2620,7 @@ NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_EN api_samr_open_alias ********************************************************************/ -NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u) +NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u) { DOM_SID sid; POLICY_HND domain_pol = q_u->dom_pol; @@ -3773,7 +3788,8 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM /* check if the user exists before trying to delete */ pdb_init_sam(&sam_pass); if(!pdb_getsampwsid(sam_pass, &user_sid)) { - DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass))); + DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", + sid_string_static(&user_sid))); pdb_free_sam(&sam_pass); return NT_STATUS_NO_SUCH_USER; } @@ -4269,13 +4285,75 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G } /********************************************************************* - _samr_unknown_2d + _samr_remove_user_foreign_domain *********************************************************************/ -NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u) +NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p, + SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u, + SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u) { - DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n")); - return NT_STATUS_NOT_IMPLEMENTED; + DOM_SID user_sid, dom_sid; + SAM_ACCOUNT *sam_pass=NULL; + uint32 acc_granted; + + sid_copy( &user_sid, &q_u->sid.sid ); + + DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n", + sid_string_static(&user_sid))); + + /* Find the policy handle. Open a policy on it. */ + + if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) + return NT_STATUS_INVALID_HANDLE; + + if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, + STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain"))) + { + return r_u->status; + } + + if ( !sid_check_is_in_our_domain(&user_sid) ) { + DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n")); + return NT_STATUS_NO_SUCH_USER; + } + + /* check if the user exists before trying to delete */ + + pdb_init_sam(&sam_pass); + + if ( !pdb_getsampwsid(sam_pass, &user_sid) ) { + + DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n", + sid_string_static(&user_sid))); + + pdb_free_sam(&sam_pass); + + return NT_STATUS_NO_SUCH_USER; + } + + /* + * delete the unix side + * + * note: we don't check if the delete really happened + * as the script is not necessary present + * and maybe the sysadmin doesn't want to delete the unix side + */ + + smb_delete_user(pdb_get_username(sam_pass)); + + /* and delete the samba side */ + + if ( !pdb_delete_sam_account(sam_pass) ) { + + DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass))); + pdb_free_sam(&sam_pass); + + return NT_STATUS_CANNOT_DELETE; + } + + pdb_free_sam(&sam_pass); + + return NT_STATUS_OK; } /******************************************************************* diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index fa0ca8478c..f846813a40 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -141,7 +141,7 @@ static BOOL api_spoolss_deleteprinterdata(pipes_struct *p) return False; } - r_u.status = _spoolss_deleteprinterdata( p, &q_u, &r_u); + r_u.status = _spoolss_deleteprinterdata( p, &q_u, &r_u ); if (!spoolss_io_r_deleteprinterdata("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_deleteprinterdata: unable to marshall SPOOL_R_DELETEPRINTERDATA.\n")); @@ -1580,8 +1580,6 @@ static BOOL api_spoolss_replycloseprinter(pipes_struct *p) \pipe\spoolss commands ********************************************************************/ -NTSTATUS rpc_spoolss_init(void) -{ struct api_struct api_spoolss_cmds[] = { {"SPOOLSS_OPENPRINTER", SPOOLSS_OPENPRINTER, api_spoolss_open_printer }, @@ -1640,6 +1638,15 @@ NTSTATUS rpc_spoolss_init(void) {"SPOOLSS_REPLYCLOSEPRINTER", SPOOLSS_REPLYCLOSEPRINTER, api_spoolss_replycloseprinter } #endif }; + +void spoolss_get_pipe_fns( struct api_struct **fns, int *n_fns ) +{ + *fns = api_spoolss_cmds; + *n_fns = sizeof(api_spoolss_cmds) / sizeof(struct api_struct); +} + +NTSTATUS rpc_spoolss_init(void) +{ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "spoolss", "spoolss", api_spoolss_cmds, sizeof(api_spoolss_cmds) / sizeof(struct api_struct)); } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 8237298ebb..7159527a7d 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -387,7 +387,6 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) char *cmd = lp_deleteprinter_cmd(); pstring command; int ret; - int i; /* Printer->dev.handlename equals portname equals sharename */ slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd, @@ -406,7 +405,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) /* go ahead and re-read the services immediately */ reload_services( False ); - if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) < 0 ) + if ( lp_servicenumber( Printer->dev.handlename ) < 0 ) return WERR_ACCESS_DENIED; } @@ -957,7 +956,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) SPOOL_NOTIFY_INFO_DATA *data; uint32 data_len = 0; uint32 id; - int i, event_index; + int i; /* Is there notification on this handle? */ @@ -980,8 +979,6 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) ); ZERO_STRUCTP(data); - event_index = 0; - /* build the array of change notifications */ sending_msg_count = 0; @@ -2671,6 +2668,8 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer, fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */ + ZERO_STRUCT(notify_cli); + if(!spoolss_connect_to_client(¬ify_cli, client_ip, unix_printer)) return False; @@ -3753,7 +3752,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, Printer_entry *Printer=find_printer_index_by_hnd(p, hnd); int n_services=lp_numservices(); int i; - uint32 id; SPOOL_NOTIFY_OPTION *option; SPOOL_NOTIFY_OPTION_TYPE *option_type; @@ -3763,7 +3761,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, return WERR_BADFID; option=Printer->notify.option; - id=1; info->version=2; info->data=NULL; info->count=0; @@ -6192,12 +6189,9 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle, SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7; int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); - WERROR result; DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action)); - result = WERR_OK; - if (!Printer) return WERR_BADFID; @@ -7100,7 +7094,6 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name) init_unistr(&port->port_name, name); init_unistr(&port->monitor_name, "Local Monitor"); init_unistr(&port->description, "Local Port"); -#define PORT_TYPE_WRITE 1 port->port_type=PORT_TYPE_WRITE; port->reserved=0x0; } @@ -7723,7 +7716,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S NT_PRINTER_INFO_LEVEL *printer = NULL; - uint32 param_index; uint32 biggest_valuesize; uint32 biggest_datasize; uint32 data_len; @@ -7772,7 +7764,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S { DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); - param_index = 0; biggest_valuesize = 0; biggest_datasize = 0; @@ -8032,6 +8023,9 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_ unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename ); + + if ( W_ERROR_IS_OK(status) ) + mod_a_printer( *printer, 2 ); free_a_printer(&printer, 2); @@ -8895,6 +8889,9 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX status = delete_printer_dataex( printer, keyname, valuename ); + if ( W_ERROR_IS_OK(status) ) + mod_a_printer( *printer, 2 ); + free_a_printer(&printer, 2); return status; @@ -9186,12 +9183,11 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, { pstring path; pstring long_archi; - const char *short_archi; PRINTPROCESSOR_DIRECTORY_1 *info=NULL; unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1); - if (!(short_archi = get_short_archi(long_archi))) + if (!get_short_archi(long_archi)) return WERR_INVALID_ENVIRONMENT; if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL) diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c index 0da3cf70dd..9d85088e56 100644 --- a/source3/rpc_server/srv_srvsvc.c +++ b/source3/rpc_server/srv_srvsvc.c @@ -526,10 +526,8 @@ static BOOL api_srv_net_file_set_secdesc(pipes_struct *p) \PIPE\srvsvc commands ********************************************************************/ -NTSTATUS rpc_srv_init(void) +static struct api_struct api_srv_cmds[] = { - static const struct api_struct api_srv_cmds[] = - { { "SRV_NET_CONN_ENUM" , SRV_NET_CONN_ENUM , api_srv_net_conn_enum }, { "SRV_NET_SESS_ENUM" , SRV_NET_SESS_ENUM , api_srv_net_sess_enum }, { "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all }, @@ -547,7 +545,17 @@ NTSTATUS rpc_srv_init(void) { "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate }, { "SRV_NET_FILE_QUERY_SECDESC", SRV_NET_FILE_QUERY_SECDESC, api_srv_net_file_query_secdesc }, { "SRV_NET_FILE_SET_SECDESC" , SRV_NET_FILE_SET_SECDESC , api_srv_net_file_set_secdesc } - }; +}; + +void srvsvc_get_pipe_fns( struct api_struct **fns, int *n_fns ) +{ + *fns = api_srv_cmds; + *n_fns = sizeof(api_srv_cmds) / sizeof(struct api_struct); +} + + +NTSTATUS rpc_srv_init(void) +{ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "srvsvc", "ntsvcs", api_srv_cmds, sizeof(api_srv_cmds) / sizeof(struct api_struct)); } diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index 03e53118a8..632d381503 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -307,8 +307,17 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA */ gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * num_entries); - /* for each group, check if the user is a member of*/ + /* for each group, check if the user is a member of. Only include groups + from this domain */ + for(i=0; i