diff options
author | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 15:34:30 -0500 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 15:34:30 -0500 |
commit | e5a951325a6cac8567af3a66de6d2df577508ae4 (patch) | |
tree | 34da9fe59f3c2d7f8edb072144443a9704197831 /source3/rpc_server | |
parent | 57482469b32645250e92a7ffd003aeeb4a42235e (diff) | |
download | samba-e5a951325a6cac8567af3a66de6d2df577508ae4.tar.gz samba-e5a951325a6cac8567af3a66de6d2df577508ae4.tar.xz samba-e5a951325a6cac8567af3a66de6d2df577508ae4.zip |
[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
(This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab)
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_echo_nt.c | 52 | ||||
-rw-r--r-- | source3/rpc_server/srv_epmapper_nt.c | 70 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 67 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 111 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 261 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc.c | 616 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 2152 | ||||
-rw-r--r-- | source3/rpc_server/srv_svcctl_nt.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_unixinfo_nt.c | 130 |
11 files changed, 1889 insertions, 1576 deletions
diff --git a/source3/rpc_server/srv_echo_nt.c b/source3/rpc_server/srv_echo_nt.c index 58c59aa506..1179a162b0 100644 --- a/source3/rpc_server/srv_echo_nt.c +++ b/source3/rpc_server/srv_echo_nt.c @@ -35,7 +35,7 @@ void _echo_AddOne(pipes_struct *p, struct echo_AddOne *r ) { DEBUG(10, ("_echo_AddOne\n")); - *r->out.out_data = r->in.in_data + 1; + *r->out.out_data = r->in.in_data + 1; } /* Echo back an array of data */ @@ -88,66 +88,38 @@ void _echo_SourceData(pipes_struct *p, struct echo_SourceData *r) void _echo_TestCall(pipes_struct *p, struct echo_TestCall *r) { - *r->out.s2 = talloc_strdup(p->mem_ctx, r->in.s1); + p->rng_fault_state = True; + return; } NTSTATUS _echo_TestCall2(pipes_struct *p, struct echo_TestCall2 *r) { - switch (r->in.level) { - case 1: - r->out.info->info1.v = 10; - break; - case 2: - r->out.info->info2.v = 20; - break; - case 3: - r->out.info->info3.v = 30; - break; - case 4: - r->out.info->info4.v = 40; - break; - case 5: - r->out.info->info5.v1 = 50; - r->out.info->info5.v2 = 60; - break; - case 6: - r->out.info->info6.v1 = 70; - r->out.info->info6.info1.v= 80; - break; - case 7: - r->out.info->info7.v1 = 80; - r->out.info->info7.info4.v = 90; - break; - default: - return NT_STATUS_INVALID_LEVEL; - } - + p->rng_fault_state = True; return NT_STATUS_OK; } uint32 _echo_TestSleep(pipes_struct *p, struct echo_TestSleep *r) { - sleep(r->in.seconds); - return r->in.seconds; + p->rng_fault_state = True; + return 0; } void _echo_TestEnum(pipes_struct *p, struct echo_TestEnum *r) { + p->rng_fault_state = True; + return; } void _echo_TestSurrounding(pipes_struct *p, struct echo_TestSurrounding *r) { - r->out.data->x *= 2; - r->out.data->surrounding = TALLOC_ZERO_ARRAY(p->mem_ctx, uint16_t, r->in.data->x); + p->rng_fault_state = True; + return; } uint16 _echo_TestDoublePointer(pipes_struct *p, struct echo_TestDoublePointer *r) { - if (!*r->in.data) - return 0; - if (!**r->in.data) - return 0; - return ***r->in.data; + p->rng_fault_state = True; + return 0; } #endif /* DEVELOPER */ diff --git a/source3/rpc_server/srv_epmapper_nt.c b/source3/rpc_server/srv_epmapper_nt.c deleted file mode 100644 index 405769072b..0000000000 --- a/source3/rpc_server/srv_epmapper_nt.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines for the endpoint mapper - * Copyright (C) Jelmer Vernooij 2007. - * - * 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 implementation of the dfs pipe. */ - -#include "includes.h" - -uint32 _epm_MapAuth(pipes_struct *p, struct epm_MapAuth *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_MgmtDelete(pipes_struct *p, struct epm_MgmtDelete *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_InqObject(pipes_struct *p, struct epm_InqObject *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_LookupHandleFree(pipes_struct *p, struct epm_LookupHandleFree *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_Map(pipes_struct *p, struct epm_Map *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_Lookup(pipes_struct *p, struct epm_Lookup *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_Delete(pipes_struct *p, struct epm_Delete *r) -{ - /* FIXME */ - return 0; -} - -uint32 _epm_Insert(pipes_struct *p, struct epm_Insert *r) -{ - /* FIXME */ - return 0; -} diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 4bd6a634d8..c513d8489c 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -996,33 +996,41 @@ NTSTATUS _lsa_lookup_sids2(pipes_struct *p, /*************************************************************************** _lsa_lookup_sida3 - - Before someone actually re-activates this, please present a sniff showing - this call against some Windows server. I (vl) could not make it work against - w2k3 at all. ***************************************************************************/ NTSTATUS _lsa_lookup_sids3(pipes_struct *p, LSA_Q_LOOKUP_SIDS3 *q_u, LSA_R_LOOKUP_SIDS3 *r_u) { + int num_sids = q_u->sids.num_entries; uint32 mapped_count = 0; - DOM_R_REF *ref; + DOM_R_REF *ref = NULL; if ((q_u->level < 1) || (q_u->level > 6)) { return NT_STATUS_INVALID_PARAMETER; } - r_u->status = NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED; - - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); + /* 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", + get_remote_machine_name() )); + return NT_STATUS_INVALID_PARAMETER; + } - if (ref == NULL) { - /* We would segfault later on in lsa_io_r_lookup_sids3 anyway, - * so do a planned exit here. We NEEEED pidl! */ - smb_panic("talloc failed"); + 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; } + r_u->status = _lsa_lookup_sids_internal(p, + q_u->level, + num_sids, + q_u->sids.sid, + &ref, + &r_u->names, + &mapped_count); + init_reply_lookup_sids3(r_u, ref, mapped_count); return r_u->status; } @@ -1537,26 +1545,14 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u) { - const char *username, *domname; + fstring username, domname; user_struct *vuser = get_valid_user_struct(p->vuid); if (vuser == NULL) return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - - if (vuser->guest) { - /* - * I'm 99% sure this is not the right place to do this, - * global_sid_Anonymous should probably be put into the token - * instead of the guest id -- vl - */ - if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous, - &domname, &username, NULL)) { - return NT_STATUS_NO_MEMORY; - } - } else { - username = vuser->user.smb_name; - domname = vuser->user.domain; - } + + fstrcpy(username, vuser->user.smb_name); + fstrcpy(domname, vuser->user.domain); r_u->ptr_user_name = 1; init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE); @@ -1592,23 +1588,17 @@ NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CR * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ - if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) { - DEBUG(10, ("_lsa_create_account: No POLICY_GET_PRIVATE_INFORMATION access right!\n")); + if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - } /* 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 ) ) { - DEBUG(10, ("_lsa_create_account: The use is not a Domain Admin, deny access!\n")); + 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( &q_u->sid.sid ) ) { - DEBUG(10, ("_lsa_create_account: Policy account already exists!\n")); + if ( is_privileged_sid( &q_u->sid.sid ) ) return NT_STATUS_OBJECT_NAME_COLLISION; - } /* associate the user/group SID with the (unique) handle. */ @@ -1623,7 +1613,6 @@ NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CR if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; - DEBUG(10, ("_lsa_create_account: call privileges code to create an account\n")); return privilege_create_account( &info->sid ); } @@ -1718,7 +1707,7 @@ NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA return NT_STATUS_INVALID_HANDLE; if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL)) - return NT_STATUS_OK; + return NT_STATUS_ACCESS_DENIED; /* 0x01 -> Log on locally diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index fefdb529b2..72ce72fb28 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -45,11 +45,6 @@ static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) auth->a_u.auth_ntlmssp_state = NULL; } -static DATA_BLOB generic_session_key(void) -{ - return data_blob("SystemLibraryDTC", 16); -} - /******************************************************************* Generate the next PDU to be returned from the data in p->rdata. Handle NTLMSSP. @@ -614,6 +609,16 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) ZERO_STRUCT(reply); + memset(p->user_name, '\0', sizeof(p->user_name)); + memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); + memset(p->domain, '\0', sizeof(p->domain)); + memset(p->wks, '\0', sizeof(p->wks)); + + /* Set up for non-authenticated user. */ + TALLOC_FREE(p->pipe_user.nt_user_token); + p->pipe_user.ut.ngroups = 0; + SAFE_FREE( p->pipe_user.ut.groups); + /* this has to be done as root in order to verify the password */ become_root(); status = auth_ntlmssp_update(a, *p_resp_blob, &reply); @@ -626,12 +631,6 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } - if (a->server_info->ptok == NULL) { - DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); - p->pipe_user.nt_user_token = NULL; - return False; - } - /* Finally - if the pipe negotiated integrity (sign) or privacy (seal) ensure the underlying NTLMSSP flags are also set. If not we should refuse the bind. */ @@ -653,9 +652,13 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) } } + fstrcpy(p->user_name, a->ntlmssp_state->user); + fstrcpy(p->pipe_user_name, a->server_info->unix_name); + fstrcpy(p->domain, a->ntlmssp_state->domain); + fstrcpy(p->wks, a->ntlmssp_state->workstation); + DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n", - a->ntlmssp_state->user, a->ntlmssp_state->domain, - a->ntlmssp_state->workstation)); + p->user_name, p->domain, p->wks)); /* * Store the UNIX credential data (uid/gid pair) in the pipe structure. @@ -665,40 +668,30 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.gid = a->server_info->gid; /* - * We're an authenticated bind over smb, so the session key needs to - * be set to "SystemLibraryDTC". Weird, but this is what Windows - * does. See the RPC-SAMBA3SESSIONKEY. + * Copy the session key from the ntlmssp state. */ data_blob_free(&p->session_key); - p->session_key = generic_session_key(); + p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length); if (!p->session_key.data) { return False; } p->pipe_user.ut.ngroups = a->server_info->n_groups; if (p->pipe_user.ut.ngroups) { - if (!(p->pipe_user.ut.groups = (gid_t *) - memdup(a->server_info->groups, - sizeof(gid_t) * p->pipe_user.ut.ngroups))) { - DEBUG(0,("pipe_ntlmssp_verify_final: failed to memdup group list to p->pipe_user.groups\n")); - data_blob_free(&p->session_key); + if (!(p->pipe_user.ut.groups = (gid_t *)memdup(a->server_info->groups, + sizeof(gid_t) * p->pipe_user.ut.ngroups))) { + DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); return False; } } - if (!a->server_info->ptok) { - DEBUG(1,("pipe_ntlmssp_verify_final: Error: Authmodule failed to provide nt_user_token\n")); - data_blob_free(&p->session_key); - SAFE_FREE(p->pipe_user.ut.groups); - return False; - } - - p->pipe_user.nt_user_token = dup_nt_token(NULL, a->server_info->ptok); - if (!p->pipe_user.nt_user_token) { - DEBUG(1,("pipe_ntlmssp_verify_final: dup_nt_token failed.\n")); - data_blob_free(&p->session_key); - SAFE_FREE(p->pipe_user.ut.groups); + if (a->server_info->ptok) { + p->pipe_user.nt_user_token = + dup_nt_token(NULL, a->server_info->ptok); + } else { + DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); + p->pipe_user.nt_user_token = NULL; return False; } @@ -1358,21 +1351,8 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, * JRA. Should we also copy the schannel session key into the pipe session key p->session_key * here ? We do that for NTLMSSP, but the session key is already set up from the vuser * struct of the person who opened the pipe. I need to test this further. JRA. - * - * VL. As we are mapping this to guest set the generic key - * "SystemLibraryDTC" key here. It's a bit difficult to test against - * W2k3, as it does not allow schannel binds against SAMR and LSA - * anymore. */ - data_blob_free(&p->session_key); - p->session_key = generic_session_key(); - if (p->session_key.data == NULL) { - DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session" - " key\n")); - return False; - } - init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); @@ -1401,12 +1381,6 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, p->auth.auth_data_free_func = NULL; p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL; - if (!set_current_user_guest(&p->pipe_user)) { - DEBUG(1, ("pipe_schannel_auth_bind: Could not set guest " - "token\n")); - return False; - } - p->pipe_bound = True; return True; @@ -2172,6 +2146,23 @@ BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss } /**************************************************************************** + Return a user struct for a pipe user. +****************************************************************************/ + +struct current_user *get_current_user(struct current_user *user, pipes_struct *p) +{ + if (p->pipe_bound && + (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP || + (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { + memcpy(user, &p->pipe_user, sizeof(struct current_user)); + } else { + memcpy(user, ¤t_user, sizeof(struct current_user)); + } + + return user; +} + +/**************************************************************************** Find the set of RPC functions associated with this context_id ****************************************************************************/ @@ -2225,7 +2216,9 @@ BOOL api_pipe_request(pipes_struct *p) BOOL changed_user = False; PIPE_RPC_FNS *pipe_fns; - if (p->pipe_bound) { + if (p->pipe_bound && + ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) || + (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { if(!become_authenticated_pipe_user(p)) { prs_mem_free(&p->out_data.rdata); return False; @@ -2364,7 +2357,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) netlog_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SRVSVC: - srvsvc_get_pipe_fns( &cmds, &n_cmds ); + srvsvc2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_WKSSVC: wkssvc_get_pipe_fns( &cmds, &n_cmds ); @@ -2381,12 +2374,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_SVCCTL: svcctl2_get_pipe_fns( &cmds, &n_cmds ); break; - case PI_EVENTLOG: + case PI_EVENTLOG: eventlog2_get_pipe_fns( &cmds, &n_cmds ); break; - case PI_UNIXINFO: - unixinfo_get_pipe_fns( &cmds, &n_cmds ); - break; case PI_NTSVCS: ntsvcs_get_pipe_fns( &cmds, &n_cmds ); break; @@ -2395,9 +2385,6 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) rpcecho_get_pipe_fns( &cmds, &n_cmds ); break; #endif - case PI_EPMAPPER: - epmapper_get_pipe_fns( &cmds, &n_cmds ); - break; default: DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); } diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 0dd3ee82a7..91814979c5 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -350,6 +350,8 @@ static void *make_internal_rpc_pipe_p(const char *pipe_name, /* Store the session key and NT_TOKEN */ if (vuser) { p->session_key = data_blob(vuser->session_key.data, vuser->session_key.length); + p->pipe_user.nt_user_token = dup_nt_token( + NULL, vuser->nt_user_token); } /* diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index d717bb6bb8..bdc082f647 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -1530,8 +1530,8 @@ static struct api_struct api_samr_cmds [] = {"SAMR_QUERY_DOMAIN_INFO" , SAMR_QUERY_DOMAIN_INFO, api_samr_query_domain_info}, {"SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups }, {"SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo }, - {"SAMR_QUERY_DISPINFO2" , SAMR_QUERY_DISPINFO2 , api_samr_query_dispinfo }, {"SAMR_QUERY_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo }, + {"SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo }, {"SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo }, {"SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo }, diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index d5795cca25..11827c223b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -328,7 +328,7 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename ) /* go ahead and re-read the services immediately */ reload_services( False ); - if ( share_defined( sharename ) ) + if ( lp_servicenumber( sharename ) < 0 ) return WERR_ACCESS_DENIED; return WERR_OK; @@ -388,13 +388,6 @@ static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number, case SPLHND_PRINTER: DEBUG(4,("short name:%s\n", Printer->sharename)); *number = print_queue_snum(Printer->sharename); - if ((*number != -1) && (params != NULL)) { - *params = get_share_params(talloc_tos(), - Printer->sharename); - if (*params == NULL) { - return False; - } - } return (*number != -1); case SPLHND_SERVER: return False; @@ -3953,9 +3946,7 @@ done: * fill a printer_info_0 struct ********************************************************************/ -static BOOL construct_printer_info_0(Printer_entry *print_hnd, - PRINTER_INFO_0 *printer, - const struct share_params *params) +static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum) { pstring chaine; int count; @@ -3966,15 +3957,14 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, time_t setuptime; print_status_struct status; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; - count = print_queue_length(params->service, &status); + count = print_queue_length(snum, &status); /* check if we already have a counter for this printer */ for(session_counter = counter_list; session_counter; session_counter = session_counter->next) { - if (session_counter->snum == params->service) + if (session_counter->snum == snum) break; } @@ -3985,7 +3975,7 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, return False; } ZERO_STRUCTP(session_counter); - session_counter->snum=params->service; + session_counter->snum=snum; session_counter->counter=0; DLIST_ADD(counter_list, session_counter); } @@ -4061,25 +4051,21 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, * construct_printer_info_1 * fill a printer_info_1 struct ********************************************************************/ -static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, - PRINTER_INFO_1 *printer, - const struct share_params *params) +static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum) { pstring chaine; pstring chaine2; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; printer->flags=flags; if (*ntprinter->info_2->comment == '\0') { - init_unistr(&printer->comment, lp_comment(params->service)); + init_unistr(&printer->comment, lp_comment(snum)); slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername, - ntprinter->info_2->drivername, - lp_comment(params->service)); + ntprinter->info_2->drivername, lp_comment(snum)); } else { init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ @@ -4170,7 +4156,7 @@ DEVICEMODE *construct_dev_mode(const char *servicename) DEBUGADD(8,("getting printer characteristics\n")); - if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) return NULL; if ( !printer->info_2->devmode ) { @@ -4203,29 +4189,26 @@ done: * fill a printer_info_2 struct ********************************************************************/ -static BOOL construct_printer_info_2(Printer_entry *print_hnd, - PRINTER_INFO_2 *printer, - const struct share_params *params) +static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum) { int count; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; print_status_struct status; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; - count = print_queue_length(params->service, &status); + count = print_queue_length(snum, &status); init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/ init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ - init_unistr(&printer->sharename, lp_servicename(params->service)); /* sharename */ + init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */ init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */ init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */ if (*ntprinter->info_2->comment == '\0') - init_unistr(&printer->comment, lp_comment(params->service)); /* comment */ + init_unistr(&printer->comment, lp_comment(snum)); /* comment */ else init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ @@ -4246,7 +4229,7 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */ if ( !(printer->devmode = construct_dev_mode( - lp_const_servicename(params->service))) ) + lp_const_servicename(snum))) ) DEBUG(8, ("Returning NULL Devicemode!\n")); printer->secdesc = NULL; @@ -4271,15 +4254,12 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, * fill a printer_info_3 struct ********************************************************************/ -static BOOL construct_printer_info_3(Printer_entry *print_hnd, - PRINTER_INFO_3 **pp_printer, - const struct share_params *params) +static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; PRINTER_INFO_3 *printer = NULL; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; *pp_printer = NULL; @@ -4312,14 +4292,11 @@ static BOOL construct_printer_info_3(Printer_entry *print_hnd, * fill a printer_info_4 struct ********************************************************************/ -static BOOL construct_printer_info_4(Printer_entry *print_hnd, - PRINTER_INFO_4 *printer, - const struct share_params *params) +static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ @@ -4335,14 +4312,11 @@ static BOOL construct_printer_info_4(Printer_entry *print_hnd, * fill a printer_info_5 struct ********************************************************************/ -static BOOL construct_printer_info_5(Printer_entry *print_hnd, - PRINTER_INFO_5 *printer, - const struct share_params *params) +static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; init_unistr(&printer->printername, ntprinter->info_2->printername); @@ -4366,17 +4340,17 @@ static BOOL construct_printer_info_5(Printer_entry *print_hnd, static BOOL construct_printer_info_6(Printer_entry *print_hnd, PRINTER_INFO_6 *printer, - const struct share_params *params) + int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; int count; print_status_struct status; if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, - lp_const_servicename(params->service)))) + lp_const_servicename(snum)))) return False; - count = print_queue_length(params->service, &status); + count = print_queue_length(snum, &status); printer->status = nt_printq_status(status.status); @@ -4390,14 +4364,12 @@ static BOOL construct_printer_info_6(Printer_entry *print_hnd, * fill a printer_info_7 struct ********************************************************************/ -static BOOL construct_printer_info_7(Printer_entry *print_hnd, - PRINTER_INFO_7 *printer, - const struct share_params *params) +static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum) { char *guid_str = NULL; struct GUID guid; - if (is_printer_published(print_hnd, params->service, &guid)) { + if (is_printer_published(print_hnd, snum, &guid)) { asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid)); strupper_m(guid_str); init_unistr(&printer->guid, guid_str); @@ -4416,45 +4388,31 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { + int snum; int i; - struct share_iterator *shares; - struct share_params *printer; + int n_services=lp_numservices(); PRINTER_INFO_1 *printers=NULL; + PRINTER_INFO_1 current_prt; WERROR result = WERR_OK; DEBUG(4,("enum_all_printers_info_1\n")); - if (!(shares = share_list_all(NULL))) { - DEBUG(5, ("Could not list printers\n")); - return WERR_ACCESS_DENIED; - } + for (snum=0; snum<n_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { + DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - while ((printer = next_printer(shares)) != NULL) { - PRINTER_INFO_1 current_prt; - - DEBUG(4,("Found a printer in smb.conf: %s\n", - lp_servicename(printer->service))); - - if (!construct_printer_info_1(NULL, flags, ¤t_prt, - printer)) { - continue; - } + if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) { + if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) { + DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n")); + *returned=0; + return WERR_NOMEM; + } + DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned)); - if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, - *returned +1)) == NULL) { - DEBUG(2,("enum_all_printers_info_1: failed to enlarge " - "printers buffer!\n")); - *returned=0; - TALLOC_FREE(shares); - return WERR_NOMEM; + memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1)); + (*returned)++; + } } - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", - *returned)); - - memcpy(&printers[*returned], ¤t_prt, - sizeof(PRINTER_INFO_1)); - (*returned)++; - TALLOC_FREE(printer); } /* check the required size. */ @@ -4479,7 +4437,6 @@ out: /* clear memory */ SAFE_FREE(printers); - TALLOC_FREE(shares); if ( !W_ERROR_IS_OK(result) ) *returned = 0; @@ -4617,45 +4574,33 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { + int snum; int i; - struct share_iterator *shares; - struct share_params *printer; + int n_services=lp_numservices(); PRINTER_INFO_2 *printers=NULL; + PRINTER_INFO_2 current_prt; WERROR result = WERR_OK; *returned = 0; - if (!(shares = share_list_all(NULL))) { - DEBUG(5, ("Could not list printers\n")); - return WERR_ACCESS_DENIED; - } + for (snum=0; snum<n_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { + DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); + + if (construct_printer_info_2(NULL, ¤t_prt, snum)) { + if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) { + DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n")); + *returned = 0; + return WERR_NOMEM; + } - while ((printer = next_printer(shares)) != NULL) { - PRINTER_INFO_2 current_prt; + DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1)); - DEBUG(4,("Found a printer in smb.conf: %s\n", - lp_servicename(printer->service))); + memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2)); - if (!construct_printer_info_2(NULL, ¤t_prt, - printer)) { - continue; - } - if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, - *returned +1)) ) { - DEBUG(2,("enum_all_printers_info_2: failed to enlarge " - "printers buffer!\n")); - *returned = 0; - TALLOC_FREE(shares); - return WERR_NOMEM; + (*returned)++; + } } - - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", - *returned + 1)); - - memcpy(&printers[*returned], ¤t_prt, - sizeof(PRINTER_INFO_2)); - (*returned)++; - TALLOC_FREE(printer); } /* check the required size. */ @@ -4683,7 +4628,6 @@ out: free_devmode(printers[i].devmode); SAFE_FREE(printers); - TALLOC_FREE(shares); if ( !W_ERROR_IS_OK(result) ) *returned = 0; @@ -4824,10 +4768,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_ /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_0(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_0 *printer=NULL; WERROR result = WERR_OK; @@ -4835,7 +4776,7 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL) return WERR_NOMEM; - construct_printer_info_0(print_hnd, printer, params); + construct_printer_info_0(print_hnd, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_0(printer); @@ -4864,10 +4805,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_1(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_1 *printer=NULL; WERROR result = WERR_OK; @@ -4875,8 +4813,7 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL) return WERR_NOMEM; - construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, - params); + construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_1(printer); @@ -4904,10 +4841,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_2(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_2 *printer=NULL; WERROR result = WERR_OK; @@ -4915,7 +4849,7 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL) return WERR_NOMEM; - construct_printer_info_2(print_hnd, printer, params); + construct_printer_info_2(print_hnd, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_2(printer); @@ -4944,15 +4878,12 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_3(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_3 *printer=NULL; WERROR result = WERR_OK; - if (!construct_printer_info_3(print_hnd, &printer, params)) + if (!construct_printer_info_3(print_hnd, &printer, snum)) return WERR_NOMEM; /* check the required size. */ @@ -4981,10 +4912,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_4(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_4 *printer=NULL; WERROR result = WERR_OK; @@ -4992,7 +4920,7 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL) return WERR_NOMEM; - if (!construct_printer_info_4(print_hnd, printer, params)) { + if (!construct_printer_info_4(print_hnd, printer, snum)) { SAFE_FREE(printer); return WERR_NOMEM; } @@ -5023,10 +4951,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_5(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_5 *printer=NULL; WERROR result = WERR_OK; @@ -5034,7 +4959,7 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL) return WERR_NOMEM; - if (!construct_printer_info_5(print_hnd, printer, params)) { + if (!construct_printer_info_5(print_hnd, printer, snum)) { free_printer_info_5(printer); return WERR_NOMEM; } @@ -5063,7 +4988,7 @@ out: } static WERROR getprinter_level_6(Printer_entry *print_hnd, - const struct share_params *params, + int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { @@ -5074,7 +4999,7 @@ static WERROR getprinter_level_6(Printer_entry *print_hnd, return WERR_NOMEM; } - if (!construct_printer_info_6(print_hnd, printer, params)) { + if (!construct_printer_info_6(print_hnd, printer, snum)) { free_printer_info_6(printer); return WERR_NOMEM; } @@ -5102,10 +5027,7 @@ out: return result; } -static WERROR getprinter_level_7(Printer_entry *print_hnd, - const struct share_params *params, - RPC_BUFFER *buffer, uint32 offered, - uint32 *needed) +static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_7 *printer=NULL; WERROR result = WERR_OK; @@ -5113,7 +5035,7 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL) return WERR_NOMEM; - if (!construct_printer_info_7(print_hnd, printer, params)) + if (!construct_printer_info_7(print_hnd, printer, snum)) return WERR_NOMEM; /* check the required size. */ @@ -5151,7 +5073,6 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); - struct share_params *params; int snum; @@ -5166,34 +5087,26 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET *needed=0; - if (!get_printer_snum(p, handle, &snum, ¶ms)) + if (!get_printer_snum(p, handle, &snum, NULL)) return WERR_BADFID; switch (level) { case 0: - return getprinter_level_0(Printer, params, buffer, offered, - needed); + return getprinter_level_0(Printer, snum, buffer, offered, needed); case 1: - return getprinter_level_1(Printer, params, buffer, offered, - needed); + return getprinter_level_1(Printer, snum, buffer, offered, needed); case 2: - return getprinter_level_2(Printer, params, buffer, offered, - needed); + return getprinter_level_2(Printer, snum, buffer, offered, needed); case 3: - return getprinter_level_3(Printer, params, buffer, offered, - needed); + return getprinter_level_3(Printer, snum, buffer, offered, needed); case 4: - return getprinter_level_4(Printer, params, buffer, offered, - needed); + return getprinter_level_4(Printer, snum, buffer, offered, needed); case 5: - return getprinter_level_5(Printer, params, buffer, offered, - needed); - case 6: - return getprinter_level_6(Printer, params, buffer, offered, - needed); + return getprinter_level_5(Printer, snum, buffer, offered, needed); + case 6: + return getprinter_level_6(Printer, snum, buffer, offered, needed); case 7: - return getprinter_level_7(Printer, params, buffer, offered, - needed); + return getprinter_level_7(Printer, snum, buffer, offered, needed); } return WERR_UNKNOWN_LEVEL; } diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c new file mode 100644 index 0000000000..92ed7274cc --- /dev/null +++ b/source3/rpc_server/srv_srvsvc.c @@ -0,0 +1,616 @@ +/* + * 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> 2003. + * Copyright (C) Gera;d (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/>. + */ + +/* This is the interface to the srvsvc pipe. */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +static BOOL proxy_srvsvc_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\n"); + } + + return fns[opnum].fn(p); +} + +/******************************************************************* + api_srv_net_srv_get_info +********************************************************************/ + +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; +} + +/******************************************************************* + api_srv_net_srv_get_info +********************************************************************/ + +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; +} + +/******************************************************************* + api_srv_net_file_enum +********************************************************************/ + +static BOOL api_srv_net_file_enum(pipes_struct *p) +{ + SRV_Q_NET_FILE_ENUM q_u; + SRV_R_NET_FILE_ENUM 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 file enum */ + if (!srv_io_q_net_file_enum("", &q_u, data, 0)) + return False; + + r_u.status = _srv_net_file_enum(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if(!srv_io_r_net_file_enum("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* + api_srv_net_conn_enum +********************************************************************/ + +static BOOL api_srv_net_conn_enum(pipes_struct *p) +{ + SRV_Q_NET_CONN_ENUM q_u; + SRV_R_NET_CONN_ENUM 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_conn_enum("", &q_u, data, 0)) + return False; + + r_u.status = _srv_net_conn_enum(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if (!srv_io_r_net_conn_enum("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* + Enumerate sessions. +********************************************************************/ + +static BOOL api_srv_net_sess_enum(pipes_struct *p) +{ + SRV_Q_NET_SESS_ENUM q_u; + SRV_R_NET_SESS_ENUM 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_sess_enum("", &q_u, data, 0)) + return False; + + /* construct reply. always indicate success */ + r_u.status = _srv_net_sess_enum(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if (!srv_io_r_net_sess_enum("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* + Delete session. +********************************************************************/ + +static BOOL api_srv_net_sess_del(pipes_struct *p) +{ + SRV_Q_NET_SESS_DEL q_u; + SRV_R_NET_SESS_DEL 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_sess_del("", &q_u, data, 0)) + return False; + + /* construct reply. always indicate success */ + r_u.status = _srv_net_sess_del(p, &q_u, &r_u); + + /* store the response in the SMB stream */ + if (!srv_io_r_net_sess_del("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* + RPC to enumerate shares. +********************************************************************/ + +static BOOL api_srv_net_share_enum_all(pipes_struct *p) +{ + SRV_Q_NET_SHARE_ENUM q_u; + SRV_R_NET_SHARE_ENUM 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 get enum. */ + if(!srv_io_q_net_share_enum("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_enum_all: Failed to unmarshall SRV_Q_NET_SHARE_ENUM.\n")); + return False; + } + + r_u.status = _srv_net_share_enum_all(p, &q_u, &r_u); + + if (!srv_io_r_net_share_enum("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_enum_all: Failed to marshall SRV_R_NET_SHARE_ENUM.\n")); + return False; + } + + return True; +} + +/******************************************************************* + RPC to enumerate shares. +********************************************************************/ + +static BOOL api_srv_net_share_enum(pipes_struct *p) +{ + SRV_Q_NET_SHARE_ENUM q_u; + SRV_R_NET_SHARE_ENUM 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 get enum. */ + if(!srv_io_q_net_share_enum("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_enum: Failed to unmarshall SRV_Q_NET_SHARE_ENUM.\n")); + return False; + } + + r_u.status = _srv_net_share_enum(p, &q_u, &r_u); + + if (!srv_io_r_net_share_enum("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_enum: Failed to marshall SRV_R_NET_SHARE_ENUM.\n")); + return False; + } + + return True; +} + +/******************************************************************* + RPC to return share information. +********************************************************************/ + +static BOOL api_srv_net_share_get_info(pipes_struct *p) +{ + SRV_Q_NET_SHARE_GET_INFO q_u; + SRV_R_NET_SHARE_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); + + /* Unmarshall the net server get info. */ + if(!srv_io_q_net_share_get_info("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_get_info: Failed to unmarshall SRV_Q_NET_SHARE_GET_INFO.\n")); + return False; + } + + r_u.status = _srv_net_share_get_info(p, &q_u, &r_u); + + if(!srv_io_r_net_share_get_info("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_get_info: Failed to marshall SRV_R_NET_SHARE_GET_INFO.\n")); + return False; + } + + return True; +} + +/******************************************************************* + RPC to set share information. +********************************************************************/ + +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; +} + +/******************************************************************* + RPC to add share information. +********************************************************************/ + +static BOOL api_srv_net_share_add(pipes_struct *p) +{ + SRV_Q_NET_SHARE_ADD q_u; + SRV_R_NET_SHARE_ADD 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 add info. */ + if(!srv_io_q_net_share_add("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_add: Failed to unmarshall SRV_Q_NET_SHARE_ADD.\n")); + return False; + } + + r_u.status = _srv_net_share_add(p, &q_u, &r_u); + + if(!srv_io_r_net_share_add("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_add: Failed to marshall SRV_R_NET_SHARE_ADD.\n")); + return False; + } + + return True; +} + +/******************************************************************* + RPC to delete share information. +********************************************************************/ + +static BOOL api_srv_net_share_del(pipes_struct *p) +{ + SRV_Q_NET_SHARE_DEL q_u; + SRV_R_NET_SHARE_DEL 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 del info. */ + if(!srv_io_q_net_share_del("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_del: Failed to unmarshall SRV_Q_NET_SHARE_DEL.\n")); + return False; + } + + r_u.status = _srv_net_share_del(p, &q_u, &r_u); + + if(!srv_io_r_net_share_del("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_del: Failed to marshall SRV_R_NET_SHARE_DEL.\n")); + return False; + } + + return True; +} + +/******************************************************************* + RPC to delete share information. +********************************************************************/ + +static BOOL api_srv_net_share_del_sticky(pipes_struct *p) +{ + SRV_Q_NET_SHARE_DEL q_u; + SRV_R_NET_SHARE_DEL 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 del info. */ + if(!srv_io_q_net_share_del("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_del_sticky: Failed to unmarshall SRV_Q_NET_SHARE_DEL.\n")); + return False; + } + + r_u.status = _srv_net_share_del_sticky(p, &q_u, &r_u); + + if(!srv_io_r_net_share_del("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_del_sticky: Failed to marshall SRV_R_NET_SHARE_DEL.\n")); + return False; + } + + return True; +} + +/******************************************************************* + api_srv_net_remote_tod +********************************************************************/ + +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; +} + +/******************************************************************* + RPC to enumerate disks available on a server e.g. C:, D: ... +*******************************************************************/ + +static BOOL api_srv_net_disk_enum(pipes_struct *p) +{ + SRV_Q_NET_DISK_ENUM q_u; + SRV_R_NET_DISK_ENUM 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 disk enum. */ + if(!srv_io_q_net_disk_enum("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_disk_enum: Failed to unmarshall SRV_Q_NET_DISK_ENUM.\n")); + return False; + } + + r_u.status = _srv_net_disk_enum(p, &q_u, &r_u); + + if(!srv_io_r_net_disk_enum("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_disk_enum: Failed to marshall SRV_R_NET_DISK_ENUM.\n")); + return False; + } + + return True; +} + +/******************************************************************* + NetValidateName (opnum 0x21) +*******************************************************************/ + +static BOOL api_srv_net_name_validate(pipes_struct *p) +{ + SRV_Q_NET_NAME_VALIDATE q_u; + SRV_R_NET_NAME_VALIDATE 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 disk enum. */ + if(!srv_io_q_net_name_validate("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_name_validate: Failed to unmarshall SRV_Q_NET_NAME_VALIDATE.\n")); + return False; + } + + r_u.status = _srv_net_name_validate(p, &q_u, &r_u); + + if(!srv_io_r_net_name_validate("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_name_validate: Failed to marshall SRV_R_NET_NAME_VALIDATE.\n")); + return False; + } + + return True; +} + +/******************************************************************* + NetFileQuerySecdesc (opnum 0x27) +*******************************************************************/ + +static BOOL api_srv_net_file_query_secdesc(pipes_struct *p) +{ + SRV_Q_NET_FILE_QUERY_SECDESC q_u; + SRV_R_NET_FILE_QUERY_SECDESC 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 file get info from Win9x */ + if(!srv_io_q_net_file_query_secdesc("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_file_query_secdesc: Failed to unmarshall SRV_Q_NET_FILE_QUERY_SECDESC.\n")); + return False; + } + + r_u.status = _srv_net_file_query_secdesc(p, &q_u, &r_u); + + if(!srv_io_r_net_file_query_secdesc("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_file_query_secdesc: Failed to marshall SRV_R_NET_FILE_QUERY_SECDESC.\n")); + return False; + } + + return True; +} + +/******************************************************************* + NetFileSetSecdesc (opnum 0x28) +*******************************************************************/ + +static BOOL api_srv_net_file_set_secdesc(pipes_struct *p) +{ + SRV_Q_NET_FILE_SET_SECDESC q_u; + SRV_R_NET_FILE_SET_SECDESC 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 file set info from Win9x */ + if(!srv_io_q_net_file_set_secdesc("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_file_set_secdesc: Failed to unmarshall SRV_Q_NET_FILE_SET_SECDESC.\n")); + return False; + } + + r_u.status = _srv_net_file_set_secdesc(p, &q_u, &r_u); + + if(!srv_io_r_net_file_set_secdesc("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_file_set_secdesc: Failed to marshall SRV_R_NET_FILE_SET_SECDESC.\n")); + return False; + } + + return True; +} + +/******************************************************************* +*******************************************************************/ + +static BOOL api_srv_net_file_close(pipes_struct *p) +{ + return proxy_srvsvc_call( p, NDR_SRVSVC_NETFILECLOSE ); +} + +/******************************************************************* +\PIPE\srvsvc commands +********************************************************************/ + +static 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_SESS_DEL" , SRV_NET_SESS_DEL , api_srv_net_sess_del }, + { "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all }, + { "SRV_NET_SHARE_ENUM" , SRV_NET_SHARE_ENUM , api_srv_net_share_enum }, + { "SRV_NET_SHARE_ADD" , SRV_NET_SHARE_ADD , api_srv_net_share_add }, + { "SRV_NET_SHARE_DEL" , SRV_NET_SHARE_DEL , api_srv_net_share_del }, + { "SRV_NET_SHARE_DEL_STICKY" , SRV_NET_SHARE_DEL_STICKY , api_srv_net_share_del_sticky }, + { "SRV_NET_SHARE_GET_INFO" , SRV_NET_SHARE_GET_INFO , api_srv_net_share_get_info }, + { "SRV_NET_SHARE_SET_INFO" , SRV_NET_SHARE_SET_INFO , api_srv_net_share_set_info }, + { "SRV_NET_FILE_ENUM" , SRV_NET_FILE_ENUM , api_srv_net_file_enum }, + { "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info }, + { "SRV_NET_SRV_SET_INFO" , SRV_NET_SRV_SET_INFO , api_srv_net_srv_set_info }, + { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod }, + { "SRV_NET_DISK_ENUM" , SRV_NET_DISK_ENUM , api_srv_net_disk_enum }, + { "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 }, + { "SRV_NET_FILE_CLOSE" , SRV_NET_FILE_CLOSE , api_srv_net_file_close } +}; + +void srvsvc2_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_srvsvc2_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_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 2af4c79002..f23d6dfcb9 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -5,7 +5,6 @@ * Copyright (C) Jeremy Allison 2001. * Copyright (C) Nigel Williams 2001. * Copyright (C) Gerald (Jerry) Carter 2006. - * Copyright (C) Jelmer Vernooij 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 @@ -25,10 +24,7 @@ #include "includes.h" -#define MAX_SERVER_DISK_ENTRIES 15 - extern const struct generic_mapping file_generic_mapping; -extern userdom_struct current_user_info; #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -38,8 +34,8 @@ extern userdom_struct current_user_info; struct file_enum_count { TALLOC_CTX *ctx; const char *username; - uint32 count; - struct srvsvc_NetFileInfo3 *info; + int count; + FILE_INFO_3 *info; }; struct sess_file_count { @@ -56,7 +52,7 @@ static int pipe_enum_fn( struct db_record *rec, void *p) { struct pipe_open_rec prec; struct file_enum_count *fenum = (struct file_enum_count *)p; - struct srvsvc_NetFileInfo3 *f; + FILE_INFO_3 *f; int i = fenum->count; pstring fullpath; const char *username; @@ -79,25 +75,19 @@ static int pipe_enum_fn( struct db_record *rec, void *p) snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name ); - f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, - struct srvsvc_NetFileInfo3, i+1 ); + f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 ); if ( !f ) { DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1)); return 1; } - fenum->info = f; - fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum); - fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA); - fenum->info[i].num_locks = 0; - fenum->info[i].user = talloc_move(fenum->ctx, &username); - if (!(fenum->info[i].path = talloc_strdup( - fenum->ctx, fullpath))) { - /* There's not much we can do here. */ - fenum->info[i].path = ""; - } - + init_srv_file_info3( + &fenum->info[i], + (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum), + (FILE_READ_DATA|FILE_WRITE_DATA), + 0, username, fullpath); + fenum->count++; return 0; @@ -107,15 +97,15 @@ static int pipe_enum_fn( struct db_record *rec, void *p) ********************************************************************/ static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username, - struct srvsvc_NetFileInfo3 **info, - uint32 *count, uint32 *resume ) + FILE_INFO_3 **info, + uint32 *count, uint32 resume ) { struct file_enum_count fenum; - + fenum.ctx = ctx; fenum.username = username; - fenum.info = *info; fenum.count = *count; + fenum.info = *info; if (connections_traverse(pipe_enum_fn, &fenum) == -1) { DEBUG(0,("net_enum_pipes: traverse of connections.tdb " @@ -136,10 +126,10 @@ static void enum_file_fn( const struct share_mode_entry *e, const char *sharepath, const char *fname, void *private_data ) { - struct file_enum_count *fenum = - (struct file_enum_count *)private_data; + struct file_enum_count *fenum = + (struct file_enum_count *)private_data; - struct srvsvc_NetFileInfo3 *f; + FILE_INFO_3 *f; int i = fenum->count; files_struct fsp; struct byte_range_lock *brl; @@ -150,7 +140,7 @@ static void enum_file_fn( const struct share_mode_entry *e, /* If the pid was not found delete the entry from connections.tdb */ - if (!process_exists(e->pid)) { + if ( !process_exists(e->pid) ) { return; } @@ -161,8 +151,7 @@ static void enum_file_fn( const struct share_mode_entry *e, return; } - f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, - struct srvsvc_NetFileInfo3, i+1 ); + f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 ); if ( !f ) { DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1)); return; @@ -174,7 +163,7 @@ static void enum_file_fn( const struct share_mode_entry *e, ZERO_STRUCT( fsp ); fsp.file_id = e->id; - if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) { + if ( (brl = brl_get_locks(NULL,&fsp)) != NULL ) { num_locks = brl->num_locks; TALLOC_FREE( brl ); } @@ -189,15 +178,13 @@ static void enum_file_fn( const struct share_mode_entry *e, /* mask out create (what ever that is) */ permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA); - fenum->info[i].fid = e->share_file_id; - fenum->info[i].permissions = permissions; - fenum->info[i].num_locks = num_locks; - fenum->info[i].user = talloc_move(fenum->ctx, &username); - if (!(fenum->info[i].path = talloc_strdup( - fenum->ctx, fullpath))) { - /* There's not much we can do here. */ - fenum->info[i].path = ""; - } + /* now fill in the FILE_INFO_3 struct */ + init_srv_file_info3( &fenum->info[i], + e->share_file_id, + permissions, + num_locks, + username, + fullpath ); fenum->count++; } @@ -206,8 +193,8 @@ static void enum_file_fn( const struct share_mode_entry *e, ********************************************************************/ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, - struct srvsvc_NetFileInfo3 **info, - uint32 *count, uint32 *resume ) + FILE_INFO_3 **info, + uint32 *count, uint32 resume ) { struct file_enum_count f_enum_cnt; @@ -225,19 +212,19 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, } /******************************************************************* - Utility function to get the 'type' of a share from a share definition. + Utility function to get the 'type' of a share from an snum. ********************************************************************/ -static uint32 get_share_type(const struct share_params *params) +static uint32 get_share_type(int snum) { - char *net_name = lp_servicename(params->service); + char *net_name = lp_servicename(snum); int len_net_name = strlen(net_name); /* work out the share type */ uint32 type = STYPE_DISKTREE; - if (lp_print_ok(params->service)) + if (lp_print_ok(snum)) type = STYPE_PRINTQ; - if (strequal(lp_fstype(params->service), "IPC")) + if (strequal(lp_fstype(snum), "IPC")) type = STYPE_IPC; if (net_name[len_net_name-1] == '$') type |= STYPE_HIDDEN; @@ -249,70 +236,65 @@ static uint32 get_share_type(const struct share_params *params) Fill in a share info level 0 structure. ********************************************************************/ -static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0, - const struct share_params *params) +static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum) { - sh0->name = lp_servicename(params->service); + pstring net_name; + + pstrcpy(net_name, lp_servicename(snum)); + + init_srv_share_info0(&sh0->info_0, net_name); + init_srv_share_info0_str(&sh0->info_0_str, net_name); } /******************************************************************* Fill in a share info level 1 structure. ********************************************************************/ -static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1, - const struct share_params *params) +static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum) { - connection_struct *conn = p->conn; + pstring remark; - sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); + char *net_name = lp_servicename(snum); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark,sizeof(remark)); - sh1->name = lp_servicename(params->service); - sh1->type = get_share_type(params); + init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark); + init_srv_share_info1_str(&sh1->info_1_str, net_name, remark); } /******************************************************************* Fill in a share info level 2 structure. ********************************************************************/ -static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2, - const struct share_params *params) +static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum) { - connection_struct *conn = p->conn; - char *remark; - char *path; - int max_connections = lp_max_connections(params->service); + pstring remark; + pstring path; + pstring passwd; + int max_connections = lp_max_connections(snum); uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff; int count = 0; - char *net_name = lp_servicename(params->service); + char *net_name = lp_servicename(snum); - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); - path = talloc_asprintf(p->mem_ctx, "C:%s", - lp_pathname(params->service)); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark,sizeof(remark)); + pstrcpy(path, "C:"); + pstrcat(path, lp_pathname(snum)); /* - * Change / to \\ so that win2k will see it as a valid path. This was - * added to enable use of browsing in win2k add share dialog. + * Change / to \\ so that win2k will see it as a valid path. This was added to + * enable use of browsing in win2k add share dialog. */ string_replace(path, '/', '\\'); + pstrcpy(passwd, ""); + count = count_current_connections( net_name, False ); - sh2->name = net_name; - sh2->type = get_share_type(params); - sh2->comment = remark; - sh2->permissions = 0; - sh2->max_users = max_uses; - sh2->current_users = count; - sh2->path = path; - sh2->password = ""; + init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), + remark, 0, max_uses, count, path, passwd); + + init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd); } /******************************************************************* @@ -344,40 +326,28 @@ static void map_generic_share_sd_bits(SEC_DESC *psd) Fill in a share info level 501 structure. ********************************************************************/ -static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501, - const struct share_params *params) +static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum) { - connection_struct *conn = p->conn; - char *remark; - const char *net_name = lp_servicename(params->service); + pstring remark; - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); + const char *net_name = lp_servicename(snum); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark, sizeof(remark)); - - sh501->name = net_name; - sh501->type = get_share_type(params); - sh501->comment = remark; - sh501->csc_policy = (lp_csc_policy(params->service) << 4); + init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4)); + init_srv_share_info501_str(&sh501->info_501_str, net_name, remark); } /******************************************************************* Fill in a share info level 502 structure. ********************************************************************/ -static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502, - const struct share_params *params) +static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum) { - int max_connections = lp_max_connections(params->service); - uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff; - connection_struct *conn = p->conn; - int count; - char *net_name; - char *remark; - char *path; + pstring net_name; + pstring remark; + pstring path; + pstring passwd; SEC_DESC *sd; size_t sd_size; TALLOC_CTX *ctx = p->mem_ctx; @@ -385,112 +355,87 @@ static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo5 ZERO_STRUCTP(sh502); - net_name = lp_servicename(params->service); - count = count_current_connections( net_name, False ); - - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); - - path = talloc_asprintf(p->mem_ctx, "C:%s", - lp_pathname(params->service)); + pstrcpy(net_name, lp_servicename(snum)); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark,sizeof(remark)); + pstrcpy(path, "C:"); + pstrcat(path, lp_pathname(snum)); /* - * Change / to \\ so that win2k will see it as a valid path. This was - * added to enable use of browsing in win2k add share dialog. + * Change / to \\ so that win2k will see it as a valid path. This was added to + * enable use of browsing in win2k add share dialog. */ string_replace(path, '/', '\\'); - sd = get_share_security(ctx, lp_servicename(params->service), - &sd_size); + pstrcpy(passwd, ""); + + sd = get_share_security(ctx, lp_servicename(snum), &sd_size); - sh502->name = net_name; - sh502->type = get_share_type(params); - sh502->comment = remark; - sh502->path = path; - sh502->password = ""; - sh502->sd = sd; - sh502->permissions = 0; - sh502->max_users = max_uses; - sh502->current_users = count; - sh502->unknown = 1; + init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size); + init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size); } /*************************************************************************** Fill in a share info level 1004 structure. ***************************************************************************/ -static void init_srv_share_info_1004(pipes_struct *p, - struct srvsvc_NetShareInfo1004* sh1004, - const struct share_params *params) +static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum) { - connection_struct *conn = p->conn; - char *remark; + pstring remark; - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark, sizeof(remark)); ZERO_STRUCTP(sh1004); - - sh1004->comment = remark; + + init_srv_share_info1004(&sh1004->info_1004, remark); + init_srv_share_info1004_str(&sh1004->info_1004_str, remark); } /*************************************************************************** Fill in a share info level 1005 structure. ***************************************************************************/ -static void init_srv_share_info_1005(pipes_struct *p, - struct srvsvc_NetShareInfo1005* sh1005, - const struct share_params *params) +static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum) { - sh1005->dfs_flags = 0; + sh1005->share_info_flags = 0; - if(lp_host_msdfs() && lp_msdfs_root(params->service)) - sh1005->dfs_flags |= + if(lp_host_msdfs() && lp_msdfs_root(snum)) + sh1005->share_info_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT; - sh1005->dfs_flags |= - lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT; + sh1005->share_info_flags |= + lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT; } /*************************************************************************** Fill in a share info level 1006 structure. ***************************************************************************/ -static void init_srv_share_info_1006(pipes_struct *p, - struct srvsvc_NetShareInfo1006* sh1006, - const struct share_params *params) +static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum) { - sh1006->max_users = -1; + sh1006->max_uses = -1; } /*************************************************************************** Fill in a share info level 1007 structure. ***************************************************************************/ -static void init_srv_share_info_1007(pipes_struct *p, - struct srvsvc_NetShareInfo1007* sh1007, - const struct share_params *params) +static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum) { + pstring alternate_directory_name = ""; uint32 flags = 0; ZERO_STRUCTP(sh1007); - sh1007->flags = flags; - sh1007->alternate_directory_name = ""; + init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name); + init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name); } /******************************************************************* Fill in a share info level 1501 structure. ********************************************************************/ -static void init_srv_share_info_1501(pipes_struct *p, - struct sec_desc_buf *sh1501, - const struct share_params *params) +static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum) { SEC_DESC *sd; size_t sd_size; @@ -498,282 +443,350 @@ static void init_srv_share_info_1501(pipes_struct *p, ZERO_STRUCTP(sh1501); - sd = get_share_security(ctx, lp_servicename(params->service), - &sd_size); + sd = get_share_security(ctx, lp_servicename(snum), &sd_size); - sh1501->sd = sd; + sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd); } /******************************************************************* True if it ends in '$'. ********************************************************************/ -static BOOL is_hidden_share(const struct share_params *params) +static BOOL is_hidden_share(int snum) { - const char *net_name = lp_servicename(params->service); + const char *net_name = lp_servicename(snum); - return (net_name[strlen(net_name) - 1] == '$'); + return (net_name[strlen(net_name) - 1] == '$') ? True : False; } /******************************************************************* Fill in a share info structure. ********************************************************************/ -static WERROR init_srv_share_info_ctr(pipes_struct *p, - union srvsvc_NetShareCtr *ctr, - uint32 info_level, uint32 *resume_hnd, - uint32 *total_entries, BOOL all_shares) +static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, + uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares) { + int num_entries = 0; + int num_services = 0; + int snum; TALLOC_CTX *ctx = p->mem_ctx; - struct share_iterator *shares; - struct share_params *share; - WERROR result = WERR_NOMEM; DEBUG(5,("init_srv_share_info_ctr\n")); - ZERO_STRUCTP(ctr); + ZERO_STRUCTPN(ctr); - if (resume_hnd) { - *resume_hnd = 0; - } + ctr->info_level = ctr->switch_value = info_level; + *resume_hnd = 0; /* Ensure all the usershares are loaded. */ become_root(); - load_usershare_shares(); + num_services = load_usershare_shares(); load_registry_shares(); unbecome_root(); - *total_entries = 0; - - if (!(shares = share_list_all(ctx))) { - DEBUG(5, ("Could not list shares\n")); - return WERR_ACCESS_DENIED; + /* Count the number of entries. */ + for (snum = 0; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) + num_entries++; } + *total_entries = num_entries; + ctr->num_entries2 = ctr->num_entries = num_entries; + ctr->ptr_share_info = ctr->ptr_entries = 1; + + if (!num_entries) + return True; + switch (info_level) { case 0: - if (!(ctr->ctr0 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr0))) { - goto done; + { + SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries); + int i = 0; + + if (!info0) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_0(p, &info0[i++], snum); + } } + + ctr->share.info0 = info0; break; + + } + case 1: - if (!(ctr->ctr1 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1))) { - goto done; + { + SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries); + int i = 0; + + if (!info1) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1(p, &info1[i++], snum); + } } + + ctr->share.info1 = info1; break; + } + case 2: - if (!(ctr->ctr2 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr2))) { - goto done; + { + SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries); + int i = 0; + + if (!info2) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_2(p, &info2[i++], snum); + } } + + ctr->share.info2 = info2; break; + } + case 501: - if (!(ctr->ctr501 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr501))) { - goto done; + { + SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries); + int i = 0; + + if (!info501) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_501(p, &info501[i++], snum); + } + } + + ctr->share.info501 = info501; break; + } + case 502: - if (!(ctr->ctr502 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr502))) { - goto done; + { + SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries); + int i = 0; + + if (!info502) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_502(p, &info502[i++], snum); + } + } + + ctr->share.info502 = info502; break; + } + + /* here for completeness but not currently used with enum (1004 - 1501)*/ + case 1004: - if (!(ctr->ctr1004 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1004))) { - goto done; + { + SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries); + int i = 0; + + if (!info1004) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1004(p, &info1004[i++], snum); + } } + + ctr->share.info1004 = info1004; break; + } + case 1005: - if (!(ctr->ctr1005 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1005))) { - goto done; + { + SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries); + int i = 0; + + if (!info1005) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1005(p, &info1005[i++], snum); + } + } + + ctr->share.info1005 = info1005; break; + } + case 1006: - if (!(ctr->ctr1006 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1006))) { - goto done; + { + SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries); + int i = 0; + + if (!info1006) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1006(p, &info1006[i++], snum); + } } + + ctr->share.info1006 = info1006; break; + } + case 1007: - if (!(ctr->ctr1007 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1007))) { - goto done; + { + SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries); + int i = 0; + + if (!info1007) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1007(p, &info1007[i++], snum); + } + } + + ctr->share.info1007 = info1007; break; + } + case 1501: - if (!(ctr->ctr1501 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1501))) { - goto done; + { + SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries); + int i = 0; + + if (!info1501) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1501(p, &info1501[i++], snum); + } } + + ctr->share.info1501 = info1501; break; + } default: - DEBUG(5,("init_srv_share_info_ctr: unsupported switch " - "value %d\n", info_level)); - return WERR_UNKNOWN_LEVEL; + DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level)); + return False; } - while ((share = next_share(shares)) != NULL) { - if (!lp_browseable(share->service)) { - continue; - } - if (!all_shares && is_hidden_share(share)) { - continue; - } + return True; +} + +/******************************************************************* + Inits a SRV_R_NET_SHARE_ENUM structure. +********************************************************************/ + +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) +{ + DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__)); + + if (init_srv_share_info_ctr(p, &r_n->ctr, info_level, + &resume_hnd, &r_n->total_entries, all)) { + r_n->status = WERR_OK; + } else { + r_n->status = WERR_UNKNOWN_LEVEL; + } + init_enum_hnd(&r_n->enum_hnd, resume_hnd); +} + +/******************************************************************* + Inits a SRV_R_NET_SHARE_GET_INFO structure. +********************************************************************/ + +static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n, + char *share_name, uint32 info_level) +{ + WERROR status = WERR_OK; + int snum; + + DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__)); + + r_n->info.switch_value = info_level; + + snum = find_service(share_name); + + if (snum >= 0) { switch (info_level) { case 0: - { - struct srvsvc_NetShareInfo0 i; - init_srv_share_info_0(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i, - &ctr->ctr0->array, &ctr->ctr0->count); - if (ctr->ctr0->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr0->count; + init_srv_share_info_0(p, &r_n->info.share.info0, snum); break; - } - case 1: - { - struct srvsvc_NetShareInfo1 i; - init_srv_share_info_1(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i, - &ctr->ctr1->array, &ctr->ctr1->count); - if (ctr->ctr1->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1->count; + init_srv_share_info_1(p, &r_n->info.share.info1, snum); break; - } - case 2: - { - struct srvsvc_NetShareInfo2 i; - init_srv_share_info_2(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i, - &ctr->ctr2->array, &ctr->ctr2->count); - if (ctr->ctr2->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr2->count; + init_srv_share_info_2(p, &r_n->info.share.info2, snum); break; - } - case 501: - { - struct srvsvc_NetShareInfo501 i; - init_srv_share_info_501(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i, - &ctr->ctr501->array, &ctr->ctr501->count); - if (ctr->ctr501->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr501->count; + init_srv_share_info_501(p, &r_n->info.share.info501, snum); break; - } - case 502: - { - struct srvsvc_NetShareInfo502 i; - init_srv_share_info_502(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i, - &ctr->ctr502->array, &ctr->ctr502->count); - if (ctr->ctr502->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr502->count; + init_srv_share_info_502(p, &r_n->info.share.info502, snum); break; - } - /* here for completeness but not currently used with enum - * (1004 - 1501)*/ - + /* here for completeness */ case 1004: - { - struct srvsvc_NetShareInfo1004 i; - init_srv_share_info_1004(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i, - &ctr->ctr1004->array, &ctr->ctr1004->count); - if (ctr->ctr1004->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1004->count; + init_srv_share_info_1004(p, &r_n->info.share.info1004, snum); break; - } - case 1005: - { - struct srvsvc_NetShareInfo1005 i; - init_srv_share_info_1005(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i, - &ctr->ctr1005->array, &ctr->ctr1005->count); - if (ctr->ctr1005->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1005->count; + init_srv_share_info_1005(p, &r_n->info.share.info1005, snum); break; - } + /* here for completeness 1006 - 1501 */ case 1006: - { - struct srvsvc_NetShareInfo1006 i; - init_srv_share_info_1006(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i, - &ctr->ctr1006->array, &ctr->ctr1006->count); - if (ctr->ctr1006->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1006->count; + init_srv_share_info_1006(p, &r_n->info.share.info1006, snum); break; - } - case 1007: - { - struct srvsvc_NetShareInfo1007 i; - init_srv_share_info_1007(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i, - &ctr->ctr1007->array, &ctr->ctr1007->count); - if (ctr->ctr1007->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1007->count; + init_srv_share_info_1007(p, &r_n->info.share.info1007, snum); break; - } - case 1501: - { - struct sec_desc_buf i; - init_srv_share_info_1501(p, &i, share); - ADD_TO_ARRAY(ctx, struct sec_desc_buf, i, - &ctr->ctr1501->array, &ctr->ctr1501->count); - if (ctr->ctr1501->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1501->count; + init_srv_share_info_1501(p, &r_n->info.share.info1501, snum); + break; + default: + DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level)); + status = WERR_UNKNOWN_LEVEL; break; } - } - - TALLOC_FREE(share); + } else { + status = WERR_INVALID_NAME; } - result = WERR_OK; - done: - TALLOC_FREE(shares); - return result; + r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0; + r_n->status = status; } /******************************************************************* fill in a sess info level 0 structure. ********************************************************************/ -static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot) +static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot) { struct sessionid *session_list; uint32 num_entries = 0; @@ -788,34 +801,37 @@ static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0 DEBUG(5,("init_srv_sess_0_ss0\n")); - ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot); - if (snum) { - for (; (*snum) < (*stot); (*snum)++) { - ss0->array[num_entries].client = session_list[(*snum)].remote_machine; + for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) { + init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine); num_entries++; } - ss0->count = num_entries; + 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; } } else { - ss0->array = NULL; - ss0->count = 0; + ss0->num_entries_read = 0; + ss0->ptr_sess_info = 0; + ss0->num_entries_read2 = 0; } } /******************************************************************* ********************************************************************/ +/* global needed to make use of the share_mode_forall() callback */ +static struct sess_file_count s_file_cnt; + static void sess_file_fn( const struct share_mode_entry *e, - const char *sharepath, const char *fname, - void *private_data ) + const char *sharepath, const char *fname, void *state ) { - struct sess_file_count *sess = (struct sess_file_count *)private_data; + struct sess_file_count *sess = &s_file_cnt; if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) { sess->count++; @@ -829,13 +845,11 @@ static void sess_file_fn( const struct share_mode_entry *e, static int net_count_files( uid_t uid, struct server_id pid ) { - struct sess_file_count s_file_cnt; - s_file_cnt.count = 0; s_file_cnt.uid = uid; s_file_cnt.pid = pid; - share_mode_forall( sess_file_fn, (void *)&s_file_cnt ); + share_mode_forall( sess_file_fn, NULL ); return s_file_cnt.count; } @@ -844,15 +858,16 @@ static int net_count_files( uid_t uid, struct server_id pid ) fill in a sess info level 1 structure. ********************************************************************/ -static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot) +static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot) { struct sessionid *session_list; uint32 num_entries = 0; time_t now = time(NULL); if ( !snum ) { - ss1->count = 0; - ss1->array = NULL; + ss1->num_entries_read = 0; + ss1->ptr_sess_info = 0; + ss1->num_entries_read2 = 0; (*stot) = 0; @@ -860,16 +875,14 @@ static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1 } if (ss1 == NULL) { - if (snum != NULL) - (*snum) = 0; + (*snum) = 0; return; } (*stot) = list_sessions(p->mem_ctx, &session_list); - - ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot); - for (; (*snum) < (*stot); (*snum)++) { + + for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) { uint32 num_files; uint32 connect_time; struct passwd *pw = sys_getpwnam(session_list[*snum].username); @@ -885,54 +898,52 @@ static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid); guest = strequal( session_list[*snum].username, lp_guestaccount() ); - if (!(ss1->array[num_entries].client = talloc_strdup( - ss1->array, session_list[*snum].remote_machine))) { - ss1->array[num_entries].client = ""; - } - if (!(ss1->array[num_entries].user = talloc_strdup( - ss1->array, session_list[*snum].username))) { - ss1->array[num_entries].user = ""; - } - ss1->array[num_entries].num_open = num_files; - ss1->array[num_entries].time = connect_time; - ss1->array[num_entries].idle_time = 0; - ss1->array[num_entries].user_flags = guest; - + init_srv_sess_info1( &ss1->info_1[num_entries], + session_list[*snum].remote_machine, + session_list[*snum].username, + num_files, + connect_time, + 0, + guest); num_entries++; } - ss1->count = num_entries; + 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; } + } /******************************************************************* makes a SRV_R_NET_SESS_ENUM structure. ********************************************************************/ -static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr, +static WERROR init_srv_sess_info_ctr(pipes_struct *p, SRV_SESS_INFO_CTR *ctr, int switch_value, uint32 *resume_hnd, uint32 *total_entries) { WERROR status = WERR_OK; DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__)); + ctr->switch_value = switch_value; + switch (switch_value) { case 0: - ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0); - init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries); + init_srv_sess_info_0(p, &(ctr->sess.info0), resume_hnd, total_entries); + ctr->ptr_sess_ctr = 1; break; case 1: - ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1); - init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries); + init_srv_sess_info_1(p, &(ctr->sess.info1), resume_hnd, total_entries); + ctr->ptr_sess_ctr = 1; break; default: DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value)); - if (resume_hnd != NULL) - (*resume_hnd) = 0; + (*resume_hnd) = 0; (*total_entries) = 0; - ctr->ctr0 = NULL; + ctr->ptr_sess_ctr = 0; status = WERR_UNKNOWN_LEVEL; break; } @@ -941,42 +952,65 @@ static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *c } /******************************************************************* + makes a SRV_R_NET_SESS_ENUM structure. +********************************************************************/ + +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) +{ + DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__)); + + r_n->sess_level = sess_level; + + if (sess_level == -1) + r_n->status = WERR_UNKNOWN_LEVEL; + else + r_n->status = init_srv_sess_info_ctr(p, r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries); + + if (!W_ERROR_IS_OK(r_n->status)) + resume_hnd = 0; + + init_enum_hnd(&r_n->enum_hnd, resume_hnd); +} + +/******************************************************************* fill in a conn info level 0 structure. ********************************************************************/ -static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot) +static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot) { uint32 num_entries = 0; (*stot) = 1; if (ss0 == NULL) { - if (snum != NULL) - (*snum) = 0; + (*snum) = 0; return; } DEBUG(5,("init_srv_conn_0_ss0\n")); if (snum) { - ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot); - for (; (*snum) < (*stot); (*snum)++) { + for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) { - ss0->array[num_entries].conn_id = (*stot); + init_srv_conn_info0(&ss0->info_0[num_entries], (*stot)); /* move on to creating next connection */ /* move on to creating next conn */ num_entries++; } - ss0->count = num_entries; + 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; } } else { - ss0->array = NULL; - ss0->count = 0; + ss0->num_entries_read = 0; + ss0->ptr_conn_info = 0; + ss0->num_entries_read2 = 0; (*stot) = 0; } @@ -986,44 +1020,55 @@ static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0 fill in a conn info level 1 structure. ********************************************************************/ -static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot) +static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1, + uint32 id, uint32 type, + uint32 num_opens, uint32 num_users, uint32 open_time, + const char *usr_name, const char *net_name) +{ + init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name); + init_srv_conn_info1_str(str1, usr_name, net_name); +} + +/******************************************************************* + fill in a conn info level 1 structure. + ********************************************************************/ + +static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot) { uint32 num_entries = 0; (*stot) = 1; if (ss1 == NULL) { - if (snum != NULL) - (*snum) = 0; + (*snum) = 0; return; } DEBUG(5,("init_srv_conn_1_ss1\n")); if (snum) { - ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot); - for (; (*snum) < (*stot); (*snum)++) { - ss1->array[num_entries].conn_id = (*stot); - ss1->array[num_entries].conn_type = 0x3; - ss1->array[num_entries].num_open = 1; - ss1->array[num_entries].num_users = 1; - ss1->array[num_entries].conn_time = 3; - ss1->array[num_entries].user = "dummy_user"; - ss1->array[num_entries].share = "IPC$"; + for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) { + init_srv_conn_1_info(&ss1->info_1[num_entries], + &ss1->info_1_str[num_entries], + (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$"); /* move on to creating next connection */ /* move on to creating next conn */ num_entries++; } - ss1->count = num_entries; + 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; } } else { - ss1->count = 0; - ss1->array = NULL; + ss1->num_entries_read = 0; + ss1->ptr_conn_info = 0; + ss1->num_entries_read2 = 0; (*stot) = 0; } @@ -1033,24 +1078,28 @@ static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1 makes a SRV_R_NET_CONN_ENUM structure. ********************************************************************/ -static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr, +static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr, int switch_value, uint32 *resume_hnd, uint32 *total_entries) { WERROR status = WERR_OK; DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__)); + ctr->switch_value = switch_value; + switch (switch_value) { case 0: - init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries); + init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries); + ctr->ptr_conn_ctr = 1; break; case 1: - init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries); + init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries); + ctr->ptr_conn_ctr = 1; break; default: DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value)); - ctr->ctr0 = NULL; - (*resume_hnd) = 0; + (*resume_hnd = 0); (*total_entries) = 0; + ctr->ptr_conn_ctr = 0; status = WERR_UNKNOWN_LEVEL; break; } @@ -1059,45 +1108,83 @@ static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *c } /******************************************************************* + makes a SRV_R_NET_CONN_ENUM structure. +********************************************************************/ + +static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n, + uint32 resume_hnd, int conn_level, int switch_value) +{ + DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__)); + + r_n->conn_level = conn_level; + if (conn_level == -1) + r_n->status = WERR_UNKNOWN_LEVEL; + else + r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries); + + if (!W_ERROR_IS_OK(r_n->status)) + resume_hnd = 0; + + init_enum_hnd(&r_n->enum_hnd, resume_hnd); +} + +/******************************************************************* makes a SRV_R_NET_FILE_ENUM structure. ********************************************************************/ -static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, - uint32 *resume_hnd, const char *username, - uint32 *num_entries ) +static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, + uint32 resume_hnd ) { - WERROR status; + TALLOC_CTX *ctx = talloc_tos(); + SRV_FILE_INFO_CTR *ctr = &r->ctr; /* TODO -- Windows enumerates (b) active pipes (c) open directories and files */ - ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3); - - status = net_enum_files(p->mem_ctx, username, &ctr->ctr3->array, - num_entries, resume_hnd ); - if ( !W_ERROR_IS_OK(status)) - return status; + r->status = net_enum_files( ctx, username, &ctr->file.info3, + &ctr->num_entries, resume_hnd ); + if ( !W_ERROR_IS_OK(r->status)) + goto done; - status = net_enum_pipes(p->mem_ctx, username, &ctr->ctr3->array, - num_entries, resume_hnd ); - if ( !W_ERROR_IS_OK(status)) - return status; - - ctr->ctr3->count = *num_entries; + r->status = net_enum_pipes( ctx, username, &ctr->file.info3, + &ctr->num_entries, resume_hnd ); + if ( !W_ERROR_IS_OK(r->status)) + goto done; - return WERR_OK; + r->level = ctr->level = 3; + r->total_entries = ctr->num_entries; + /* ctr->num_entries = r->total_entries - resume_hnd; */ + ctr->num_entries2 = ctr->num_entries; + ctr->ptr_file_info = 1; + + r->status = WERR_OK; + +done: + if ( ctr->num_entries > 0 ) + ctr->ptr_entries = 1; + + init_enum_hnd(&r->enum_hnd, 0); + + return r->status; } /******************************************************************* *******************************************************************/ -WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r) +WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u) { - switch ( *r->in.level ) { - case 3: - return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, - r->in.user, r->out.totalentries ); + switch ( q_u->level ) { + case 3: { + char *username; + if (!(username = rpcstr_pull_unistr2_talloc( + p->mem_ctx, q_u->username))) { + return WERR_NOMEM; + } + + return net_file_enum_3(username, r_u, + get_enum_hnd(&q_u->enum_hnd)); + } default: return WERR_UNKNOWN_LEVEL; } @@ -1109,11 +1196,15 @@ WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r) net server get info ********************************************************************/ -WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) +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 status = WERR_OK; + SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR); - ZERO_STRUCTP(r->out.info); + if (!ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(ctr); DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); @@ -1122,108 +1213,133 @@ WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) return WERR_ACCESS_DENIED; } - switch (r->in.level) { + switch (q_u->switch_value) { /* 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: - r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102); - - r->out.info->info102->platform_id = 500; - r->out.info->info102->version_major = lp_major_announce_version(); - r->out.info->info102->version_minor = lp_minor_announce_version(); - r->out.info->info102->server_name = global_myname(); - r->out.info->info102->server_type = lp_default_server_announce(); - r->out.info->info102->userpath = "C:\\"; - r->out.info->info102->licenses = 10000; - r->out.info->info102->anndelta = 3000; - r->out.info->info102->disc = 0xf; - r->out.info->info102->users = 0xffffffff; - r->out.info->info102->hidden = 0; - r->out.info->info102->announce = 240; - r->out.info->info102->comment = lp_serverstring(); + 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 */ break; case 101: - r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101); - r->out.info->info101->platform_id = 500; - r->out.info->info101->server_name = global_myname(); - r->out.info->info101->version_major = lp_major_announce_version(); - r->out.info->info101->version_minor = lp_minor_announce_version(); - r->out.info->info101->server_type = lp_default_server_announce(); - r->out.info->info101->comment = lp_serverstring(); + 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)); break; case 100: - r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100); - r->out.info->info100->platform_id = 500; - r->out.info->info100->server_name = global_myname(); + init_srv_info_100(&ctr->srv.sv100, 500, global_myname()); break; default: - return WERR_UNKNOWN_LEVEL; + 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__)); - return status; + return r_u->status; } /******************************************************************* net server set info ********************************************************************/ -WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r) +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 status = WERR_OK; + + DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + /* Set up the net server set info structure. */ - if (r->out.parm_error) { - *r->out.parm_error = 0; - } - return WERR_OK; + + init_srv_r_net_srv_set_info(r_u, 0x0, status); + + DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* net conn enum ********************************************************************/ -WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r) +WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u) { DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__)); - ZERO_STRUCTP(r->out.ctr); + r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR); + if (!r_u->ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(r_u->ctr); /* set up the */ - return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries); + init_srv_r_net_conn_enum(r_u, + get_enum_hnd(&q_u->enum_hnd), + q_u->conn_level, + q_u->ctr->switch_value); + + DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* net sess enum ********************************************************************/ -WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r) +WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u) { DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__)); - ZERO_STRUCTP(r->out.ctr); + r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR); + if (!r_u->ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(r_u->ctr); /* set up the */ - return init_srv_sess_info_ctr(p, r->out.ctr, - *r->in.level, - r->in.resume_handle, - r->out.totalentries); + init_srv_r_net_sess_enum(p, r_u, + get_enum_hnd(&q_u->enum_hnd), + q_u->sess_level, + q_u->ctr->switch_value); + + DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* net sess del ********************************************************************/ -WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) +WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u) { struct sessionid *session_list; + struct current_user user; int num_sessions, snum; - WERROR status; + fstring username; + fstring machine; + BOOL not_root = False; - char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc); + rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name); + rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name); /* strip leading backslashes if any */ while (machine[0] == '\\') { @@ -1234,11 +1350,13 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__)); - status = WERR_ACCESS_DENIED; + r_u->status = WERR_ACCESS_DENIED; + + get_current_user(&user, p); /* fail out now if you are not root or not a domain admin */ - if ((p->pipe_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; @@ -1246,30 +1364,41 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) for (snum = 0; snum < num_sessions; snum++) { - if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) && - strequal(session_list[snum].remote_machine, machine)) { + if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) && + strequal(session_list[snum].remote_machine, machine)) { + NTSTATUS ntstat; + + if (user.ut.uid != sec_initial_uid()) { + not_root = True; + become_root(); + } ntstat = messaging_send(smbd_messaging_context(), session_list[snum].pid, MSG_SHUTDOWN, &data_blob_null); - + if (NT_STATUS_IS_OK(ntstat)) - status = WERR_OK; + r_u->status = WERR_OK; + + if (not_root) + unbecome_root(); } } DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__)); + done: - return status; + + return r_u->status; } /******************************************************************* Net share enum all. ********************************************************************/ -WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r) +WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u) { DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); @@ -1279,15 +1408,20 @@ WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r } /* Create the list of shares for the response. */ - return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level, - r->in.resume_handle, r->out.totalentries, True); + init_srv_r_net_share_enum(p, r_u, + q_u->ctr.info_level, + get_enum_hnd(&q_u->enum_hnd), True); + + DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* Net share enum. ********************************************************************/ -WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r) +WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u) { DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); @@ -1297,80 +1431,32 @@ WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r) } /* Create the list of shares for the response. */ - return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level, - r->in.resume_handle, r->out.totalentries, False); + init_srv_r_net_share_enum(p, r_u, + q_u->ctr.info_level, + get_enum_hnd(&q_u->enum_hnd), False); + + DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* Net share get info. ********************************************************************/ -WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r) +WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u) { - const struct share_params *params; - - params = get_share_params(p->mem_ctx, r->in.share_name); + fstring share_name; - if (params != NULL) { - switch (r->in.level) { - case 0: - r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0); - init_srv_share_info_0(p, r->out.info->info0, params); - break; - case 1: - r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1); - init_srv_share_info_1(p, r->out.info->info1, params); - break; - case 2: - r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2); - init_srv_share_info_2(p, r->out.info->info2, params); - break; - case 501: - r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501); - init_srv_share_info_501(p, r->out.info->info501, params); - break; - case 502: - r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502); - init_srv_share_info_502(p, r->out.info->info502, params); - break; + DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__)); - /* here for completeness */ - case 1004: - r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004); - init_srv_share_info_1004(p, r->out.info->info1004, params); - break; - case 1005: - r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005); - init_srv_share_info_1005(p, r->out.info->info1005, params); - break; + /* Create the list of shares for the response. */ + unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); + init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level); - /* here for completeness 1006 - 1501 */ - case 1006: - r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006); - init_srv_share_info_1006(p, r->out.info->info1006, - params); - break; - case 1007: - r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007); - init_srv_share_info_1007(p, r->out.info->info1007, - params); - break; - case 1501: - r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf); - init_srv_share_info_1501(p, r->out.info->info1501, - params); - break; - default: - DEBUG(5,("init_srv_net_share_get_info: unsupported " - "switch value %d\n", r->in.level)); - return WERR_UNKNOWN_LEVEL; - break; - } - } else { - return WERR_INVALID_NAME; - } + DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__)); - return WERR_OK; + return r_u->status; } /******************************************************************* @@ -1397,295 +1483,40 @@ char *valid_share_pathname(char *dos_pathname) return ptr; } -static void setval_helper(struct registry_key *key, const char *name, - const char *value, WERROR *err) -{ - struct registry_value val; - - if (!W_ERROR_IS_OK(*err)) { - return; - } - - ZERO_STRUCT(val); - val.type = REG_SZ; - val.v.sz.str = CONST_DISCARD(char *, value); - val.v.sz.len = strlen(value)+1; - - *err = reg_setvalue(key, name, &val); -} - -static WERROR add_share(const char *share_name, const char *path, - const char *comment, uint32 max_connections, - const struct nt_user_token *token, - BOOL is_disk_op) -{ - if (lp_add_share_cmd() && *lp_add_share_cmd()) { - char *command; - int ret; - - if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", - lp_add_share_cmd(), dyn_CONFIGFILE, share_name, - path, comment, max_connections) == -1) { - return WERR_NOMEM; - } - - DEBUG(10,("add_share: Running [%s]\n", command )); - - /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ - - if ( is_disk_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(smbd_messaging_context(), - MSG_SMB_CONF_UPDATED, - NULL, 0, NULL); - } - - if ( is_disk_op ) - unbecome_root(); - - /********* END SeDiskOperatorPrivilege BLOCK *********/ - - DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", - command, ret )); - - /* - * No fallback to registry shares, the user did define a add - * share command, so fail here. - */ - - SAFE_FREE(command); - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; - } - - if (lp_registry_shares()) { - char *keyname; - struct registry_key *key; - enum winreg_CreateAction action; - WERROR err; - TALLOC_CTX *mem_ctx; - - if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF, - share_name))) { - return WERR_NOMEM; - } - - mem_ctx = (TALLOC_CTX *)keyname; - - err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE, - is_disk_op ? get_root_nt_token():token, - &action, &key); - - if (action != REG_CREATED_NEW_KEY) { - err = WERR_ALREADY_EXISTS; - } - - if (!W_ERROR_IS_OK(err)) { - TALLOC_FREE(mem_ctx); - return err; - } - - setval_helper(key, "path", path, &err); - if ((comment != NULL) && (comment[0] != '\0')) { - setval_helper(key, "comment", comment, &err); - } - if (max_connections != 0) { - char tmp[16]; - snprintf(tmp, sizeof(tmp), "%d", max_connections); - setval_helper(key, "max connections", tmp, &err); - } - - if (!W_ERROR_IS_OK(err)) { - /* - * Hmmmm. We'd need transactions on the registry to - * get this right.... - */ - reg_delete_path(is_disk_op ? get_root_nt_token():token, - keyname); - } - TALLOC_FREE(mem_ctx); - return err; - } - - return WERR_ACCESS_DENIED; -} - -static WERROR delete_share(const char *sharename, - const struct nt_user_token *token, - BOOL is_disk_op) -{ - if (lp_delete_share_cmd() && *lp_delete_share_cmd()) { - char *command; - int ret; - - if (asprintf(&command, "%s \"%s\" \"%s\"", - lp_delete_share_cmd(), dyn_CONFIGFILE, - sharename)) { - return WERR_NOMEM; - } - - DEBUG(10,("delete_share: Running [%s]\n", command )); - - /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ - - if ( is_disk_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(smbd_messaging_context(), - MSG_SMB_CONF_UPDATED, - NULL, 0, NULL); - } - - if ( is_disk_op ) - unbecome_root(); - - /********* END SeDiskOperatorPrivilege BLOCK *********/ - - SAFE_FREE(command); - - DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", - command, ret )); - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; - } - - if (lp_registry_shares()) { - char *keyname; - WERROR err; - - if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF, - sharename) == -1) { - return WERR_NOMEM; - } - - err = reg_delete_path(is_disk_op ? get_root_nt_token():token, - keyname); - SAFE_FREE(keyname); - return err; - } - - return WERR_ACCESS_DENIED; -} - -static WERROR change_share(const char *share_name, const char *path, - const char *comment, uint32 max_connections, - const struct nt_user_token *token, - BOOL is_disk_op) -{ - if (lp_change_share_cmd() && *lp_change_share_cmd()) { - char *command; - int ret; - - if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", - lp_change_share_cmd(), dyn_CONFIGFILE, share_name, - path, comment, max_connections) == -1) { - return WERR_NOMEM; - } - - DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command)); - - /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ - - if ( is_disk_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(smbd_messaging_context(), - MSG_SMB_CONF_UPDATED, - NULL, 0, NULL); - } - - if ( is_disk_op ) - unbecome_root(); - - /********* END SeDiskOperatorPrivilege BLOCK *********/ - - DEBUG(3,("_srv_net_share_set_info: Running [%s] returned " - "(%d)\n", command, ret )); - - SAFE_FREE(command); - - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; - } - - if (lp_registry_shares()) { - char *keyname; - struct registry_key *key; - WERROR err; - TALLOC_CTX *mem_ctx; - - if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF, - share_name))) { - return WERR_NOMEM; - } - - mem_ctx = (TALLOC_CTX *)keyname; - - err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE, - is_disk_op ? get_root_nt_token():token, - &key); - if (!W_ERROR_IS_OK(err)) { - TALLOC_FREE(mem_ctx); - return err; - } - - setval_helper(key, "path", path, &err); - - reg_deletevalue(key, "comment"); - if ((comment != NULL) && (comment[0] != '\0')) { - setval_helper(key, "comment", comment, &err); - } - - reg_deletevalue(key, "max connections"); - if (max_connections != 0) { - char tmp[16]; - snprintf(tmp, sizeof(tmp), "%d", max_connections); - setval_helper(key, "max connections", tmp, &err); - } - - TALLOC_FREE(mem_ctx); - return err; - } - - return WERR_ACCESS_DENIED; -} - /******************************************************************* Net share set info. Modify share details. ********************************************************************/ -WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r) +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) { - pstring comment; + struct current_user user; + pstring command; + fstring share_name; + fstring comment; pstring pathname; int type; int snum; + int ret; char *path; SEC_DESC *psd = NULL; SE_PRIV se_diskop = SE_DISK_OPERATOR; BOOL is_disk_op = False; int max_connections = 0; - fstring tmp_share_name; DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); - if (r->out.parm_error) { - *r->out.parm_error = 0; - } + unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); + + r_u->parm_error = 0; - if ( strequal(r->in.share_name,"IPC$") - || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") ) - || strequal(r->in.share_name,"global") ) + if ( strequal(share_name,"IPC$") + || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) + || strequal(share_name,"global") ) { return WERR_ACCESS_DENIED; } - fstrcpy(tmp_share_name, r->in.share_name); - snum = find_service(tmp_share_name); + snum = find_service(share_name); /* Does this share exist ? */ if (snum < 0) @@ -1695,39 +1526,47 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r if (lp_print_ok(snum)) return WERR_ACCESS_DENIED; - is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, - &se_diskop ); + get_current_user(&user,p); + + is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); /* fail out now if you are not root and not a disk op */ - if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op ) + if ( user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - switch (r->in.level) { + switch (q_u->info_level) { case 1: pstrcpy(pathname, lp_pathname(snum)); - pstrcpy(comment, r->in.info.info1->comment); - type = r->in.info.info1->type; + unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment)); + type = q_u->info.share.info2.info_2.type; psd = NULL; break; case 2: - pstrcpy(comment, r->in.info.info2->comment); - pstrcpy(pathname, r->in.info.info2->path); - type = r->in.info.info2->type; - max_connections = (r->in.info.info2->max_users == 0xffffffff) ? - 0 : r->in.info.info2->max_users; + unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment)); + unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname)); + 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; 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; + psd = NULL; + break; +#endif case 502: - pstrcpy(comment, r->in.info.info502->comment); - pstrcpy(pathname, r->in.info.info502->path); - type = r->in.info.info502->type; - psd = r->in.info.info502->sd; + unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment)); + unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname)); + type = q_u->info.share.info502.info_502.type; + psd = q_u->info.share.info502.info_502_str.sd; map_generic_share_sd_bits(psd); break; case 1004: pstrcpy(pathname, lp_pathname(snum)); - pstrcpy(comment, r->in.info.info1004->comment); + unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment)); type = STYPE_DISKTREE; break; case 1005: @@ -1735,14 +1574,12 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r 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 (((r->in.info.info1005->dfs_flags & + if (((q_u->info.share.info1005.share_info_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, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n")); return WERR_ACCESS_DENIED; } case 1006: @@ -1750,14 +1587,13 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r return WERR_ACCESS_DENIED; case 1501: pstrcpy(pathname, lp_pathname(snum)); - pstrcpy(comment, lp_comment(snum)); - psd = r->in.info.info1501->sd; + fstrcpy(comment, lp_comment(snum)); + psd = q_u->info.share.info1501.sdb->sd; map_generic_share_sd_bits(psd); type = STYPE_DISKTREE; break; default: - DEBUG(5,("_srv_net_share_set_info: unsupported switch value " - "%d\n", r->in.level)); + DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level)); return WERR_UNKNOWN_LEVEL; } @@ -1769,29 +1605,52 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r if (!(path = valid_share_pathname( pathname ))) return WERR_OBJECT_PATH_INVALID; - /* Ensure share name, pathname and comment don't contain '"' - * characters. */ - string_replace(tmp_share_name, '"', ' '); + /* Ensure share name, pathname and comment don't contain '"' characters. */ + string_replace(share_name, '"', ' '); string_replace(path, '"', ' '); string_replace(comment, '"', ' '); DEBUG(10,("_srv_net_share_set_info: change share command = %s\n", - lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" )); + lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" )); /* Only call modify function if something changed. */ - if (strcmp(path, lp_pathname(snum)) - || strcmp(comment, lp_comment(snum)) - || (lp_max_connections(snum) != max_connections) ) { - WERROR err; + 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")); + return WERR_ACCESS_DENIED; + } - err = change_share(tmp_share_name, path, comment, - max_connections, p->pipe_user.nt_user_token, - is_disk_op); + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", + lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections ); - if (!W_ERROR_IS_OK(err)) { - return err; + DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command )); + + /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ + + if ( is_disk_op ) + become_root(); + + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(smbd_messaging_context(), + MSG_SMB_CONF_UPDATED, NULL, 0, + NULL); } + + if ( is_disk_op ) + unbecome_root(); + + /********* END SeDiskOperatorPrivilege BLOCK *********/ + + DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret )); + + if ( ret != 0 ) + return WERR_ACCESS_DENIED; + } else { + DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name )); } /* Replace SD if changed. */ @@ -1799,15 +1658,12 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r SEC_DESC *old_sd; size_t sd_size; - old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), - &sd_size); + old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size); if (old_sd && !sec_desc_equal(old_sd, psd)) { - if (!set_share_security(r->in.share_name, psd)) { - DEBUG(0,("_srv_net_share_set_info: Failed to " - "change security info in share %s.\n", - r->in.share_name )); - } + if (!set_share_security(share_name, psd)) + DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n", + share_name )); } } @@ -1816,38 +1672,44 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r return WERR_OK; } - /******************************************************************* Net share add. Call 'add_share_command "sharename" "pathname" "comment" "max connections = " ********************************************************************/ -WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) +WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u) { - pstring share_name; - pstring comment; + struct current_user user; + pstring command; + fstring share_name; + fstring comment; pstring pathname; - char *path; int type; + int snum; + int ret; + char *path; SEC_DESC *psd = NULL; SE_PRIV se_diskop = SE_DISK_OPERATOR; BOOL is_disk_op; - uint32 max_connections = 0; - WERROR err; + int max_connections = 0; DEBUG(5,("_srv_net_share_add: %d\n", __LINE__)); - if (r->out.parm_error) { - *r->out.parm_error = 0; - } + r_u->parm_error = 0; - is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, - &se_diskop ); + get_current_user(&user,p); - if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op ) + is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); + + if (user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - switch (r->in.level) { + if (!lp_add_share_cmd() || !*lp_add_share_cmd()) { + DEBUG(10,("_srv_net_share_add: No add share command\n")); + return WERR_ACCESS_DENIED; + } + + switch (q_u->info_level) { case 0: /* No path. Not enough info in a level 0 to do anything. */ return WERR_ACCESS_DENIED; @@ -1855,27 +1717,25 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) /* Not enough info in a level 1 to do anything. */ return WERR_ACCESS_DENIED; case 2: - pstrcpy(share_name, r->in.info.info2->name); - pstrcpy(comment, r->in.info.info2->comment); - pstrcpy(pathname, r->in.info.info2->path); - max_connections = (r->in.info.info2->max_users == 0xffffffff) ? - 0 : r->in.info.info2->max_users; - type = r->in.info.info2->type; + unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name)); + unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name)); + unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name)); + max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses; + type = q_u->info.share.info2.info_2.type; break; case 501: /* No path. Not enough info in a level 501 to do anything. */ return WERR_ACCESS_DENIED; case 502: - pstrcpy(share_name, r->in.info.info502->name); - pstrcpy(comment, r->in.info.info502->comment); - pstrcpy(pathname, r->in.info.info502->path); - type = r->in.info.info502->type; - psd = r->in.info.info502->sd; + unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name)); + unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name)); + unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name)); + type = q_u->info.share.info502.info_502.type; + psd = q_u->info.share.info502.info_502_str.sd; 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: @@ -1886,30 +1746,28 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) /* DFS only level. */ return WERR_ACCESS_DENIED; default: - DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", - r->in.level)); + DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level)); return WERR_UNKNOWN_LEVEL; } /* check for invalid share names */ - if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, - sizeof(share_name) ) ) { - DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", - share_name)); + if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) { + DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name)); return WERR_INVALID_NAME; } if ( strequal(share_name,"IPC$") || strequal(share_name,"global") - || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) ) + || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) ) { return WERR_ACCESS_DENIED; } - if (get_share_params(p->mem_ctx, share_name) != NULL) { - /* Share already exists. */ + snum = find_service(share_name); + + /* Share already exists. */ + if (snum >= 0) return WERR_ALREADY_EXISTS; - } /* We can only add disk shares. */ if (type != STYPE_DISKTREE) @@ -1919,24 +1777,45 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) if (!(path = valid_share_pathname( pathname ))) return WERR_OBJECT_PATH_INVALID; - /* Ensure share name, pathname and comment don't contain '"' - * characters. */ - + /* Ensure share name, pathname and comment don't contain '"' characters. */ string_replace(share_name, '"', ' '); string_replace(path, '"', ' '); string_replace(comment, '"', ' '); - err = add_share(share_name, path, comment, max_connections, - p->pipe_user.nt_user_token, is_disk_op); + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", + lp_add_share_cmd(), + dyn_CONFIGFILE, + share_name, + path, + comment, + max_connections); + + DEBUG(10,("_srv_net_share_add: Running [%s]\n", command )); + + /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ + + if ( is_disk_op ) + become_root(); - if (!W_ERROR_IS_OK(err)) { - return err; + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(smbd_messaging_context(), + MSG_SMB_CONF_UPDATED, NULL, 0, NULL); } + if ( is_disk_op ) + unbecome_root(); + + /********* END SeDiskOperatorPrivilege BLOCK *********/ + + DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret )); + + if ( ret != 0 ) + return WERR_ACCESS_DENIED; + if (psd) { if (!set_share_security(share_name, psd)) { - DEBUG(0,("_srv_net_share_add: Failed to add security " - "info to share %s.\n", share_name )); + DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name )); } } @@ -1956,43 +1835,76 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) a parameter. ********************************************************************/ -WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) +WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u) { - struct share_params *params; + struct current_user user; + pstring command; + fstring share_name; + int ret; + int snum; SE_PRIV se_diskop = SE_DISK_OPERATOR; BOOL is_disk_op; - WERROR err; + struct share_params *params; DEBUG(5,("_srv_net_share_del: %d\n", __LINE__)); - if ( strequal(r->in.share_name, "IPC$") - || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") ) - || strequal(r->in.share_name, "global") ) + unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); + + if ( strequal(share_name,"IPC$") + || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) + || strequal(share_name,"global") ) { return WERR_ACCESS_DENIED; } - if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) { - return WERR_NO_SUCH_SHARE; - } + if (!(params = get_share_params(p->mem_ctx, share_name))) { + return WERR_NO_SUCH_SHARE; + } + + snum = find_service(share_name); /* No change to printer shares. */ - if (lp_print_ok(params->service)) + if (lp_print_ok(snum)) return WERR_ACCESS_DENIED; - is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, - &se_diskop ); + get_current_user(&user,p); + + is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); - if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op ) + if (user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - err = delete_share(lp_servicename(params->service), - p->pipe_user.nt_user_token, is_disk_op); + if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) { + DEBUG(10,("_srv_net_share_del: No delete share command\n")); + return WERR_ACCESS_DENIED; + } + + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", + lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum)); + + DEBUG(10,("_srv_net_share_del: Running [%s]\n", command )); + + /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ + + if ( is_disk_op ) + become_root(); - if (!W_ERROR_IS_OK(err)) { - return err; + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(smbd_messaging_context(), + MSG_SMB_CONF_UPDATED, NULL, 0, NULL); } + if ( is_disk_op ) + unbecome_root(); + + /********* END SeDiskOperatorPrivilege BLOCK *********/ + + DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret )); + + if ( ret != 0 ) + return WERR_ACCESS_DENIED; + /* Delete the SD in the database. */ delete_share_security(lp_servicename(params->service)); @@ -2001,28 +1913,22 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) return WERR_OK; } -WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r) +WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u) { - struct srvsvc_NetShareDel s; - DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__)); - s.in.server_unc = r->in.server_unc; - s.in.share_name = r->in.share_name; - s.in.reserved = r->in.reserved; - - return _srvsvc_NetShareDel(p, &s); + return _srv_net_share_del(p, q_u, r_u); } /******************************************************************* time of day ********************************************************************/ -WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) +WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u) { + TIME_OF_DAY_INFO *tod; struct tm *t; time_t unixdate = time(NULL); - WERROR status = WERR_OK; /* We do this call first as if we do it *after* the gmtime call it overwrites the pointed-to values. JRA */ @@ -2031,91 +1937,106 @@ WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) ) + return WERR_NOMEM; + + r_u->tod = tod; + r_u->ptr_srv_tod = 0x1; + r_u->status = WERR_OK; + + DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + t = gmtime(&unixdate); /* set up the */ - r->out.info->elapsed = unixdate; - r->out.info->msecs = 0; - r->out.info->hours = t->tm_hour; - r->out.info->mins = t->tm_min; - r->out.info->secs = t->tm_sec; - r->out.info->hunds = 0; - r->out.info->timezone = zone; - r->out.info->tinterval = 10000; - r->out.info->day = t->tm_mday; - r->out.info->month = t->tm_mon + 1; - r->out.info->year = 1900+t->tm_year; - r->out.info->weekday = t->tm_wday; + 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__)); - return status; + return r_u->status; } /*********************************************************************************** Win9x NT tools get security descriptor. ***********************************************************************************/ -WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r) +WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u, + SRV_R_NET_FILE_QUERY_SECDESC *r_u) { SEC_DESC *psd = NULL; size_t sd_size; DATA_BLOB null_pw; + pstring filename_in; + char *filename = NULL; + pstring qualname; files_struct *fsp = NULL; SMB_STRUCT_STAT st; NTSTATUS nt_status; + struct current_user user; connection_struct *conn = NULL; - BOOL became_user = False; - WERROR status = WERR_OK; - char *tmp_file = NULL; + BOOL became_user = False; TALLOC_CTX *ctx = talloc_tos(); ZERO_STRUCT(st); + r_u->status = WERR_OK; + + unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); /* Null password is ok - we are already an authenticated user... */ null_pw = data_blob_null; + get_current_user(&user, p); + become_root(); - conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status); + conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status); unbecome_root(); if (conn == NULL) { - DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share)); - status = ntstatus_to_werror(nt_status); + DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } if (!become_user(conn, conn->vuid)) { DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n")); - status = WERR_ACCESS_DENIED; + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } became_user = True; - if (!r->in.file) { - status = WERR_INVALID_PARAM; - goto error_exit; - } - nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st); + unistr2_to_ascii(filename_in, &q_u->uni_file_name, sizeof(filename_in)); + nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = check_name(conn, tmp_file); + nt_status = check_name(conn, filename); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp); - if (!NT_STATUS_IS_OK(nt_status)) { + nt_status = open_file_stat(conn, NULL, filename, &st, &fsp); + if ( !NT_STATUS_IS_OK(nt_status)) { /* Perhaps it is a directory */ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY)) - nt_status = open_directory(conn, NULL, tmp_file, &st, + nt_status = open_directory(conn, NULL, filename, &st, READ_CONTROL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, @@ -2124,8 +2045,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur NULL, &fsp); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } } @@ -2133,20 +2054,23 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); if (sd_size == 0) { - DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - r->out.sd_buf->sd_size= sd_size; - r->out.sd_buf->sd = psd; + r_u->ptr_response = 1; + r_u->size_response = sd_size; + r_u->ptr_secdesc = 1; + r_u->size_secdesc = sd_size; + r_u->sec_desc = psd; psd->dacl->revision = (uint16) NT4_ACL_REVISION; close_file(fsp, NORMAL_CLOSE); unbecome_user(); - close_cnum(conn, p->pipe_user.vuid); - return status; + close_cnum(conn, user.vuid); + return r_u->status; error_exit: @@ -2158,74 +2082,80 @@ error_exit: unbecome_user(); if (conn) - close_cnum(conn, p->pipe_user.vuid); + close_cnum(conn, user.vuid); - return status; + return r_u->status; } /*********************************************************************************** Win9x NT tools set security descriptor. ***********************************************************************************/ -WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) +WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u, + SRV_R_NET_FILE_SET_SECDESC *r_u) { + pstring filename_in; + char *filename = NULL; + pstring qualname; DATA_BLOB null_pw; files_struct *fsp = NULL; SMB_STRUCT_STAT st; NTSTATUS nt_status; + struct current_user user; connection_struct *conn = NULL; BOOL became_user = False; - WERROR status = WERR_OK; - char *tmp_file = NULL; TALLOC_CTX *ctx = talloc_tos(); ZERO_STRUCT(st); + r_u->status = WERR_OK; + + unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); + /* Null password is ok - we are already an authenticated user... */ null_pw = data_blob_null; + get_current_user(&user, p); + become_root(); - conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status); + conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status); unbecome_root(); if (conn == NULL) { - DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share)); - status = ntstatus_to_werror(nt_status); + DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } if (!become_user(conn, conn->vuid)) { DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n")); - status = WERR_ACCESS_DENIED; + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } became_user = True; - if (!r->in.file) { - status = WERR_INVALID_PARAM; - goto error_exit; - } - nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st); + unistr2_to_ascii(filename_in, &q_u->uni_file_name, sizeof(filename_in)); + nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = check_name(conn, tmp_file); + nt_status = check_name(conn, filename); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp); + nt_status = open_file_stat(conn, NULL, filename, &st, &fsp); - if (!NT_STATUS_IS_OK(nt_status)) { + if ( !NT_STATUS_IS_OK(nt_status) ) { /* Perhaps it is a directory */ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY)) - nt_status = open_directory(conn, NULL, tmp_file, &st, + nt_status = open_directory(conn, NULL, filename, &st, FILE_READ_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, @@ -2233,25 +2163,25 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur FILE_ATTRIBUTE_DIRECTORY, NULL, &fsp); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + if ( !NT_STATUS_IS_OK(nt_status) ) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } } - nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd); + nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + if (!NT_STATUS_IS_OK(nt_status) ) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } close_file(fsp, NORMAL_CLOSE); unbecome_user(); - close_cnum(conn, p->pipe_user.vuid); - return status; + close_cnum(conn, user.vuid); + return r_u->status; error_exit: @@ -2264,10 +2194,10 @@ error_exit: } if (conn) { - close_cnum(conn, p->pipe_user.vuid); + close_cnum(conn, user.vuid); } - return status; + return r_u->status; } /*********************************************************************************** @@ -2316,68 +2246,59 @@ static const char *next_server_disk_enum(uint32 *resume) return disk; } -WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r) +WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u) { uint32 i; const char *disk_name; + TALLOC_CTX *ctx = p->mem_ctx; + uint32 resume=get_enum_hnd(&q_u->enum_hnd); - WERROR status = WERR_OK; + r_u->status=WERR_OK; + + r_u->total_entries = init_server_disk_enum(&resume); - *r->out.totalentries = init_server_disk_enum(r->in.resume_handle); - r->out.info->count = 0; + r_u->disk_enum_ctr.unknown = 0; - if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) { + if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) { return WERR_NOMEM; } - /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/ + r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0; - for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) { + /*allow one DISK_INFO for null terminator*/ - r->out.info->count++; - (*r->out.totalentries)++; + for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) { + + r_u->disk_enum_ctr.entries_read++; /*copy disk name into a unicode string*/ - r->out.info->disks[i].disk = 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? */ - r->out.info->count++; - (*r->out.totalentries)++; + r_u->disk_enum_ctr.entries_read++; - r->out.info->disks[i].disk = ""; + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, ""); - return status; + init_enum_hnd(&r_u->enum_hnd, resume); + + return r_u->status; } /******************************************************************** ********************************************************************/ -WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r) +WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u) { - int len; - - if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) { - return WERR_INVALID_PARAM; - } + fstring sharename; - switch ( r->in.name_type ) { + switch ( q_u->type ) { case 0x9: - len = strlen_m(r->in.name); - - if ((r->in.flags == 0x0) && (len > 81)) { - DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name)); - return WERR_INVALID_NAME; - } - if ((r->in.flags == 0x80000000) && (len > 13)) { - DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name)); - return WERR_INVALID_NAME; - } - - if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) { - DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name)); + rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0); + if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) { + DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename)); return WERR_INVALID_NAME; } break; @@ -2398,6 +2319,10 @@ WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r) return WERR_ACCESS_DENIED; } + +/******************************************************************** +********************************************************************/ + WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r) { p->rng_fault_state = True; @@ -2446,18 +2371,96 @@ WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPu return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r) +{ + p->rng_fault_state = True; + 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; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r) { p->rng_fault_state = True; 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; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r) { p->rng_fault_state = True; @@ -2482,6 +2485,12 @@ 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; @@ -2506,6 +2515,12 @@ WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r) return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r) { p->rng_fault_state = True; @@ -2518,6 +2533,12 @@ WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r) { p->rng_fault_state = True; @@ -2530,6 +2551,18 @@ WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommi return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r) { p->rng_fault_state = True; @@ -2560,7 +2593,7 @@ WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDF return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R) +WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; @@ -2584,26 +2617,27 @@ WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELE return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r) +WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r) +WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r) +WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r) +WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } + diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index dba209eb07..c868f94f76 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -626,7 +626,7 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG the client from showing the "Start" button (if of course the services are not running */ - if ( strequal( name, "NETLOGON" ) && ( !share_defined(name) ) ) + if ( strequal( name, "NETLOGON" ) && ( lp_servicenumber(name) == -1 ) ) config->start_type = SVCCTL_DISABLED; else if ( strequal( name, "WINS" ) && ( !lp_wins_support() )) config->start_type = SVCCTL_DISABLED; diff --git a/source3/rpc_server/srv_unixinfo_nt.c b/source3/rpc_server/srv_unixinfo_nt.c deleted file mode 100644 index e9680247ae..0000000000 --- a/source3/rpc_server/srv_unixinfo_nt.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines for unixinfo-pipe - * Copyright (C) Volker Lendecke 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 rpcunixinfo pipe. */ - -#include "includes.h" -#include "nterr.h" - - - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -/* Map a sid to a uid */ - -NTSTATUS _unixinfo_SidToUid(pipes_struct *p, struct unixinfo_SidToUid *r) -{ - uid_t real_uid; - NTSTATUS status; - *r->out.uid = 0; - - status = sid_to_uid(&r->in.sid, &real_uid) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED; - if (NT_STATUS_IS_OK(status)) - *r->out.uid = real_uid; - - return status; -} - -/* Map a uid to a sid */ - -NTSTATUS _unixinfo_UidToSid(pipes_struct *p, struct unixinfo_UidToSid *r) -{ - NTSTATUS status = NT_STATUS_NO_SUCH_USER; - - uid_to_sid(r->out.sid, (uid_t)r->in.uid); - status = NT_STATUS_OK; - - return status; -} - -/* Map a sid to a gid */ - -NTSTATUS _unixinfo_SidToGid(pipes_struct *p, struct unixinfo_SidToGid *r) -{ - gid_t real_gid; - NTSTATUS status; - - *r->out.gid = 0; - - status = sid_to_gid(&r->in.sid, &real_gid) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED; - if (NT_STATUS_IS_OK(status)) - *r->out.gid = real_gid; - - return status; -} - -/* Map a gid to a sid */ - -NTSTATUS _unixinfo_GidToSid(pipes_struct *p, struct unixinfo_GidToSid *r) -{ - NTSTATUS status = NT_STATUS_NO_SUCH_GROUP; - - gid_to_sid(r->out.sid, (gid_t)r->in.gid); - status = NT_STATUS_OK; - - return status; -} - -/* Get unix struct passwd information */ - -NTSTATUS _unixinfo_GetPWUid(pipes_struct *p, struct unixinfo_GetPWUid *r) -{ - int i; - NTSTATUS status; - - if (*r->in.count > 1023) - return NT_STATUS_INVALID_PARAMETER; - - status = NT_STATUS_OK; - - for (i=0; i<*r->in.count; i++) { - struct passwd *pw; - char *homedir, *shell; - ssize_t len1, len2; - - r->out.infos[i].status = NT_STATUS_NO_SUCH_USER; - r->out.infos[i].homedir = ""; - r->out.infos[i].shell = ""; - - pw = getpwuid(r->in.uids[i]); - - if (pw == NULL) { - DEBUG(10, ("Did not find uid %lld\n", - (long long int)r->in.uids[i])); - continue; - } - - len1 = push_utf8_talloc(p->mem_ctx, &homedir, pw->pw_dir); - len2 = push_utf8_talloc(p->mem_ctx, &shell, pw->pw_shell); - - if ((len1 < 0) || (len2 < 0) || (homedir == NULL) || - (shell == NULL)) { - DEBUG(3, ("push_utf8_talloc failed\n")); - r->out.infos[i].status = NT_STATUS_NO_MEMORY; - continue; - } - - r->out.infos[i].status = NT_STATUS_OK; - r->out.infos[i].homedir = homedir; - r->out.infos[i].shell = shell; - } - - return status; -} |