summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-07-11 18:01:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:19:14 -0500
commitfbdcf2663b56007a438ac4f0d8d82436b1bfe688 (patch)
tree4e42c1f061391cea3d640152fd240682cbf4fd9a /source3/rpc_server
parent5bf62a0c3cc95abe918f3e772bb10e0a90fdce22 (diff)
downloadsamba-fbdcf2663b56007a438ac4f0d8d82436b1bfe688.tar.gz
samba-fbdcf2663b56007a438ac4f0d8d82436b1bfe688.tar.bz2
samba-fbdcf2663b56007a438ac4f0d8d82436b1bfe688.zip
r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8)
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_dfs_nt.c10
-rw-r--r--source3/rpc_server/srv_lsa_nt.c31
-rw-r--r--source3/rpc_server/srv_pipe.c105
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c9
-rw-r--r--source3/rpc_server/srv_samr_nt.c17
-rw-r--r--source3/rpc_server/srv_samr_util.c35
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c98
-rw-r--r--source3/rpc_server/srv_srvsvc.c33
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c520
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c2
-rw-r--r--source3/rpc_server/srv_unixinfo.c163
-rw-r--r--source3/rpc_server/srv_unixinfo_nt.c166
12 files changed, 856 insertions, 333 deletions
diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c
index 8239584522..c7f8e05d91 100644
--- a/source3/rpc_server/srv_dfs_nt.c
+++ b/source3/rpc_server/srv_dfs_nt.c
@@ -40,7 +40,6 @@ uint32 _dfs_GetManagerVersion(pipes_struct *p, NETDFS_Q_DFS_GETMANAGERVERSION *q
WERROR _dfs_Add(pipes_struct *p, NETDFS_Q_DFS_ADD* q_u, NETDFS_R_DFS_ADD *r_u)
{
- struct current_user user;
struct junction_map jn;
struct referral* old_referral_list = NULL;
BOOL exists = False;
@@ -48,9 +47,7 @@ WERROR _dfs_Add(pipes_struct *p, NETDFS_Q_DFS_ADD* q_u, NETDFS_R_DFS_ADD *r_u)
pstring dfspath, servername, sharename;
pstring altpath;
- get_current_user(&user,p);
-
- if (user.ut.uid != 0) {
+ if (p->pipe_user.ut.uid != 0) {
DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
@@ -104,16 +101,13 @@ WERROR _dfs_Add(pipes_struct *p, NETDFS_Q_DFS_ADD* q_u, NETDFS_R_DFS_ADD *r_u)
WERROR _dfs_Remove(pipes_struct *p, NETDFS_Q_DFS_REMOVE *q_u,
NETDFS_R_DFS_REMOVE *r_u)
{
- struct current_user user;
struct junction_map jn;
BOOL found = False;
pstring dfspath, servername, sharename;
pstring altpath;
- get_current_user(&user,p);
-
- if (user.ut.uid != 0) {
+ if (p->pipe_user.ut.uid != 0) {
DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index efa7156eea..2cc5ef6110 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -1557,17 +1557,23 @@ 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))
+ if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) {
+ DEBUG(10, ("_lsa_create_account: No POLICY_GET_PRIVATE_INFORMATION access right!\n"));
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 ) )
+ 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"));
return NT_STATUS_ACCESS_DENIED;
+ }
- if ( is_privileged_sid( &q_u->sid.sid ) )
+ if ( is_privileged_sid( &q_u->sid.sid ) ) {
+ DEBUG(10, ("_lsa_create_account: Policy account already exists!\n"));
return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
/* associate the user/group SID with the (unique) handle. */
@@ -1582,6 +1588,7 @@ 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 );
}
@@ -1676,7 +1683,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_ACCESS_DENIED;
+ return NT_STATUS_OK;
/*
0x01 -> Log on locally
@@ -1727,7 +1734,6 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
struct lsa_info *info = NULL;
SE_PRIV mask;
PRIVILEGE_SET *set = NULL;
- struct current_user user;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
@@ -1736,8 +1742,7 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
/* check to see if the pipe_user is root or a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- get_current_user( &user, p );
- if ( user.ut.uid != sec_initial_uid()
+ if ( p->pipe_user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1768,7 +1773,6 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
struct lsa_info *info = NULL;
SE_PRIV mask;
PRIVILEGE_SET *set = NULL;
- struct current_user user;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
@@ -1777,8 +1781,7 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
/* check to see if the pipe_user is root or a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- get_current_user( &user, p );
- if ( user.ut.uid != sec_initial_uid()
+ if ( p->pipe_user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1929,7 +1932,6 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
DOM_SID sid;
fstring privname;
UNISTR4_ARRAY *uni_privnames = q_u->rights;
- struct current_user user;
/* find the connection policy handle. */
@@ -1939,8 +1941,7 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
/* 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 */
- get_current_user( &user, p );
- if ( user.ut.uid != sec_initial_uid()
+ if ( p->pipe_user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
@@ -1987,7 +1988,6 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
DOM_SID sid;
fstring privname;
UNISTR4_ARRAY *uni_privnames = q_u->rights;
- struct current_user user;
/* find the connection policy handle. */
@@ -1997,8 +1997,7 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
/* 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 */
- get_current_user( &user, p );
- if ( user.ut.uid != sec_initial_uid()
+ if ( p->pipe_user.ut.uid != sec_initial_uid()
&& !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 812a720d90..e2c5e865ed 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -46,6 +46,11 @@ 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.
@@ -610,16 +615,6 @@ 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);
@@ -632,6 +627,12 @@ 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,13 +654,9 @@ 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",
- p->user_name, p->domain, p->wks));
+ a->ntlmssp_state->user, a->ntlmssp_state->domain,
+ a->ntlmssp_state->workstation));
/*
* Store the UNIX credential data (uid/gid pair) in the pipe structure.
@@ -669,11 +666,13 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
p->pipe_user.ut.gid = a->server_info->gid;
/*
- * Copy the session key from the ntlmssp state.
+ * 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.
*/
data_blob_free(&p->session_key);
- p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length);
+ p->session_key = generic_session_key();
if (!p->session_key.data) {
return False;
}
@@ -688,23 +687,21 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
}
}
- if (a->server_info->ptok) {
- 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);
- return False;
- }
-
- } else {
+ 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);
+ return False;
+ }
+
return True;
}
@@ -1361,8 +1358,21 @@ 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"));
@@ -1391,6 +1401,12 @@ 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;
@@ -1641,11 +1657,18 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
case RPC_ANONYMOUS_AUTH_TYPE:
/* Unauthenticated bind request. */
+ /* Get the authenticated pipe user from current_user */
+ if (!copy_current_user(&p->pipe_user, &current_user)) {
+ DEBUG(10, ("Could not copy current user\n"));
+ goto err_exit;
+ }
/* We're finished - no more packets. */
p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
/* We must set the pipe auth_level here also. */
p->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
p->pipe_bound = True;
+ /* The session key was initialized from the SMB
+ * session in make_internal_rpc_pipe_p */
break;
default:
@@ -2149,23 +2172,6 @@ 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, &current_user, sizeof(struct current_user));
- }
-
- return user;
-}
-
-/****************************************************************************
Find the set of RPC functions associated with this context_id
****************************************************************************/
@@ -2219,9 +2225,7 @@ BOOL api_pipe_request(pipes_struct *p)
BOOL changed_user = False;
PIPE_RPC_FNS *pipe_fns;
- if (p->pipe_bound &&
- ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) ||
- (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
+ if (p->pipe_bound) {
if(!become_authenticated_pipe_user(p)) {
prs_mem_free(&p->out_data.rdata);
return False;
@@ -2373,6 +2377,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
case PI_EVENTLOG:
eventlog_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;
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 9cc8b72546..8aa5bb3e6d 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -351,8 +351,6 @@ static void *make_internal_rpc_pipe_p(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);
}
/*
@@ -1169,6 +1167,13 @@ BOOL close_rpc_pipe_hnd(smb_np_struct *p)
p->name, p->pnum, pipes_open));
DLIST_REMOVE(Pipes, p);
+
+ /* TODO: Remove from pipe open db */
+
+ if ( !delete_pipe_opendb( p ) ) {
+ DEBUG(3,("close_rpc_pipe_hnd: failed to delete %s "
+ "pipe from open db.\n", p->name));
+ }
ZERO_STRUCTP(p);
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index e045de5639..2e0b355db5 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -1435,7 +1435,7 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
}
}
- init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
+ init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, type, r_u->status);
DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
@@ -2508,7 +2508,8 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
}
DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
- p->pipe_user_name, can_add_account ? "True":"False" ));
+ uidtoname(p->pipe_user.ut.uid),
+ can_add_account ? "True":"False" ));
/********** BEGIN Admin BLOCK **********/
@@ -3110,9 +3111,11 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
}
/* we need to separately check for an account rename first */
+
if (rpcstr_pull(new_name, id21->uni_user_name.buffer,
- sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0) &&
- (!strequal(new_name, pdb_get_username(pwd)))) {
+ sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0)
+ && (!strequal(new_name, pdb_get_username(pwd))))
+ {
/* check to see if the new username already exists. Note: we can't
reliably lock all backends, so there is potentially the
@@ -3435,7 +3438,8 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
}
DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
- p->pipe_user_name, has_enough_rights ? "" : " not"));
+ uidtoname(p->pipe_user.ut.uid),
+ has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
@@ -3593,7 +3597,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
}
DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
- p->pipe_user_name, has_enough_rights ? "" : " not"));
+ uidtoname(p->pipe_user.ut.uid),
+ has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index 2b65eb210f..c4bec79c9c 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -195,14 +195,13 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from)
pdb_set_workstations(to , new_string, PDB_CHANGED);
}
- /* is this right? */
- if ((from->fields_present & ACCT_ADMIN_DESC) &&
- (from->hdr_unknown_str.buffer)) {
- old_string = pdb_get_unknown_str(to);
- new_string = unistr2_static(&from->uni_unknown_str);
- DEBUG(10,("INFO_21 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
+ if ((from->fields_present & ACCT_COMMENT) &&
+ (from->hdr_comment.buffer)) {
+ old_string = pdb_get_comment(to);
+ new_string = unistr2_static(&from->uni_comment);
+ DEBUG(10,("INFO_21 UNI_COMMENT: %s -> %s\n",old_string, new_string));
if (STRING_CHANGED)
- pdb_set_unknown_str(to , new_string, PDB_CHANGED);
+ pdb_set_comment(to, new_string, PDB_CHANGED);
}
if ((from->fields_present & ACCT_CALLBACK) &&
@@ -445,14 +444,13 @@ void copy_id23_to_sam_passwd(struct samu *to, SAM_USER_INFO_23 *from)
pdb_set_workstations(to , new_string, PDB_CHANGED);
}
- /* is this right? */
- if ((from->fields_present & ACCT_ADMIN_DESC) &&
- (from->hdr_unknown_str.buffer)) {
- old_string = pdb_get_unknown_str(to);
- new_string = unistr2_static(&from->uni_unknown_str);
+ if ((from->fields_present & ACCT_COMMENT) &&
+ (from->hdr_comment.buffer)) {
+ old_string = pdb_get_comment(to);
+ new_string = unistr2_static(&from->uni_comment);
DEBUG(10,("INFO_23 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
if (STRING_CHANGED)
- pdb_set_unknown_str(to , new_string, PDB_CHANGED);
+ pdb_set_comment(to , new_string, PDB_CHANGED);
}
if ((from->fields_present & ACCT_CALLBACK) &&
@@ -683,14 +681,13 @@ void copy_id25_to_sam_passwd(struct samu *to, SAM_USER_INFO_25 *from)
pdb_set_workstations(to , new_string, PDB_CHANGED);
}
- /* is this right? */
- if ((from->fields_present & ACCT_ADMIN_DESC) &&
- (from->hdr_unknown_str.buffer)) {
- old_string = pdb_get_unknown_str(to);
- new_string = unistr2_static(&from->uni_unknown_str);
+ if ((from->fields_present & ACCT_COMMENT) &&
+ (from->hdr_comment.buffer)) {
+ old_string = pdb_get_comment(to);
+ new_string = unistr2_static(&from->uni_comment);
DEBUG(10,("INFO_25 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
if (STRING_CHANGED)
- pdb_set_unknown_str(to , new_string, PDB_CHANGED);
+ pdb_set_comment(to , new_string, PDB_CHANGED);
}
if ((from->fields_present & ACCT_CALLBACK) &&
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 0281e3da0c..3dbad208cc 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -331,7 +331,7 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
/* go ahead and re-read the services immediately */
reload_services( False );
- if ( lp_servicenumber( sharename ) < 0 )
+ if ( !share_defined( sharename ) )
return WERR_ACCESS_DENIED;
return WERR_OK;
@@ -1509,7 +1509,6 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
fstring name;
int snum;
- struct current_user user;
Printer_entry *Printer=NULL;
if ( !q_u->printername )
@@ -1533,8 +1532,6 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
return WERR_INVALID_PRINTER_NAME;
}
- get_current_user(&user, p);
-
/*
* First case: the user is opening the print server:
*
@@ -1599,12 +1596,12 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ((user.ut.uid != 0) &&
- !user_has_privileges(user.nt_user_token,
+ if ((p->pipe_user.ut.uid != 0) &&
+ !user_has_privileges(p->pipe_user.nt_user_token,
&se_printop ) &&
!token_contains_name_in_list(
- uidtoname(user.ut.uid), NULL,
- user.nt_user_token,
+ uidtoname(p->pipe_user.ut.uid), NULL,
+ p->pipe_user.nt_user_token,
lp_printer_admin(snum))) {
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1657,9 +1654,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
return WERR_ACCESS_DENIED;
}
- if (!user_ok_token(uidtoname(user.ut.uid), user.nt_user_token,
- snum) ||
- !print_access_check(&user, snum,
+ if (!user_ok_token(uidtoname(p->pipe_user.ut.uid),
+ p->pipe_user.nt_user_token, snum) ||
+ !print_access_check(&p->pipe_user, snum,
printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
@@ -1953,20 +1950,17 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
NT_PRINTER_DRIVER_INFO_LEVEL info;
NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
int version;
- struct current_user user;
WERROR status;
WERROR status_win2k = WERR_ACCESS_DENIED;
SE_PRIV se_printop = SE_PRINT_OPERATOR;
- get_current_user(&user, p);
-
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( (user.ut.uid != 0)
- && !user_has_privileges(user.nt_user_token, &se_printop )
- && !token_contains_name_in_list( uidtoname(user.ut.uid),
- NULL, user.nt_user_token, lp_printer_admin(-1)) )
+ if ( (p->pipe_user.ut.uid != 0)
+ && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop )
+ && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid),
+ NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) )
{
return WERR_ACCESS_DENIED;
}
@@ -2013,7 +2007,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
- status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False );
+ status_win2k = delete_printer_driver(info_win2k.info_3, &p->pipe_user, 3, False );
free_a_printer_driver( info_win2k, 3 );
/* this should not have failed---if it did, report to client */
@@ -2025,7 +2019,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
}
}
- status = delete_printer_driver(info.info_3, &user, version, False);
+ status = delete_printer_driver(info.info_3, &p->pipe_user, version, False);
/* if at least one of the deletes succeeded return OK */
@@ -2051,20 +2045,17 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
int version;
uint32 flags = q_u->delete_flags;
BOOL delete_files;
- struct current_user user;
WERROR status;
WERROR status_win2k = WERR_ACCESS_DENIED;
SE_PRIV se_printop = SE_PRINT_OPERATOR;
- get_current_user(&user, p);
-
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( (user.ut.uid != 0)
- && !user_has_privileges(user.nt_user_token, &se_printop )
- && !token_contains_name_in_list( uidtoname(user.ut.uid),
- NULL, user.nt_user_token, lp_printer_admin(-1)) )
+ if ( (p->pipe_user.ut.uid != 0)
+ && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop )
+ && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid),
+ NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) )
{
return WERR_ACCESS_DENIED;
}
@@ -2150,7 +2141,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
- status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files);
+ status_win2k = delete_printer_driver(info_win2k.info_3, &p->pipe_user, 3, delete_files);
free_a_printer_driver( info_win2k, 3 );
/* this should not have failed---if it did, report to client */
@@ -2160,7 +2151,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
}
}
- status = delete_printer_driver(info.info_3, &user, version, delete_files);
+ status = delete_printer_driver(info.info_3, &p->pipe_user, version, delete_files);
if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
status = WERR_OK;
@@ -4073,7 +4064,7 @@ static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode
Create a DEVMODE struct. Returns malloced memory.
****************************************************************************/
-DEVICEMODE *construct_dev_mode(int snum)
+DEVICEMODE *construct_dev_mode(const char *servicename)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
DEVICEMODE *devmode = NULL;
@@ -4082,7 +4073,7 @@ DEVICEMODE *construct_dev_mode(int snum)
DEBUGADD(8,("getting printer characteristics\n"));
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
return NULL;
if ( !printer->info_2->devmode ) {
@@ -4154,7 +4145,7 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *p
printer->cjobs = count; /* jobs */
printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
- if ( !(printer->devmode = construct_dev_mode(snum)) )
+ if ( !(printer->devmode = construct_dev_mode(lp_const_servicename(snum))) )
DEBUG(8, ("Returning NULL Devicemode!\n"));
printer->secdesc = NULL;
@@ -5640,15 +5631,12 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
pstring jobname;
fstring datatype;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- struct current_user user;
if (!Printer) {
DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
- get_current_user(&user, p);
-
/*
* a nice thing with NT is it doesn't listen to what you tell it.
* when asked to send _only_ RAW datas, it tries to send datas
@@ -5672,7 +5660,7 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
- Printer->jobid = print_job_start(&user, snum, jobname, Printer->nt_devmode);
+ Printer->jobid = print_job_start(&p->pipe_user, snum, jobname, Printer->nt_devmode);
/* An error occured in print_job_start() so return an appropriate
NT error code. */
@@ -5745,13 +5733,10 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
static WERROR control_printer(POLICY_HND *handle, uint32 command,
pipes_struct *p)
{
- struct current_user user;
int snum;
WERROR errcode = WERR_BADFUNC;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- get_current_user(&user, p);
-
if (!Printer) {
DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
return WERR_BADFID;
@@ -5762,18 +5747,18 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command,
switch (command) {
case PRINTER_CONTROL_PAUSE:
- if (print_queue_pause(&user, snum, &errcode)) {
+ if (print_queue_pause(&p->pipe_user, snum, &errcode)) {
errcode = WERR_OK;
}
break;
case PRINTER_CONTROL_RESUME:
case PRINTER_CONTROL_UNPAUSE:
- if (print_queue_resume(&user, snum, &errcode)) {
+ if (print_queue_resume(&p->pipe_user, snum, &errcode)) {
errcode = WERR_OK;
}
break;
case PRINTER_CONTROL_PURGE:
- if (print_queue_purge(&user, snum, &errcode)) {
+ if (print_queue_purge(&p->pipe_user, snum, &errcode)) {
errcode = WERR_OK;
}
break;
@@ -5795,7 +5780,6 @@ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R
POLICY_HND *handle = &q_u->handle;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
int snum;
- struct current_user user;
WERROR errcode = WERR_OK;
if (!Printer) {
@@ -5806,9 +5790,7 @@ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R
if (!get_printer_snum(p, handle, &snum))
return WERR_BADFID;
- get_current_user( &user, p );
-
- print_job_delete( &user, snum, Printer->jobid, &errcode );
+ print_job_delete( &p->pipe_user, snum, Printer->jobid, &errcode );
return errcode;
}
@@ -6018,7 +6000,9 @@ BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
SE_PRIV se_printop = SE_PRINT_OPERATOR;
BOOL is_print_op = False;
- standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
+ standard_sub_basic(current_user_info.smb_name,
+ current_user_info.domain,
+ remote_machine,sizeof(remote_machine));
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
cmd, printer->info_2->printername, printer->info_2->sharename,
@@ -6544,7 +6528,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
/* this should not be a failure condition if the devmode is NULL */
- devmode = construct_dev_mode(snum);
+ devmode = construct_dev_mode(lp_const_servicename(snum));
for (i=0; i<*returned; i++)
fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
@@ -6664,7 +6648,6 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
uint32 jobid = q_u->jobid;
uint32 command = q_u->command;
- struct current_user user;
int snum;
WERROR errcode = WERR_BADFUNC;
@@ -6676,23 +6659,21 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
return WERR_INVALID_PRINTER_NAME;
}
- get_current_user(&user, p);
-
switch (command) {
case JOB_CONTROL_CANCEL:
case JOB_CONTROL_DELETE:
- if (print_job_delete(&user, snum, jobid, &errcode)) {
+ if (print_job_delete(&p->pipe_user, snum, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
case JOB_CONTROL_PAUSE:
- if (print_job_pause(&user, snum, jobid, &errcode)) {
+ if (print_job_pause(&p->pipe_user, snum, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
case JOB_CONTROL_RESTART:
case JOB_CONTROL_RESUME:
- if (print_job_resume(&user, snum, jobid, &errcode)) {
+ if (print_job_resume(&p->pipe_user, snum, jobid, &errcode)) {
errcode = WERR_OK;
}
break;
@@ -7618,26 +7599,23 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
WERROR err = WERR_OK;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- struct current_user user;
fstring driver_name;
uint32 version;
ZERO_STRUCT(driver);
- get_current_user(&user, p);
-
if (!convert_printer_driver_info(info, &driver, level)) {
err = WERR_NOMEM;
goto done;
}
DEBUG(5,("Cleaning driver's information\n"));
- err = clean_up_driver_struct(driver, level, &user);
+ err = clean_up_driver_struct(driver, level, &p->pipe_user);
if (!W_ERROR_IS_OK(err))
goto done;
DEBUG(5,("Moving driver to final destination\n"));
- if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &user, &err)) ) {
+ if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &p->pipe_user, &err)) ) {
goto done;
}
@@ -8777,7 +8755,7 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
*/
if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
- devmode = construct_dev_mode(snum);
+ devmode = construct_dev_mode(lp_const_servicename(snum));
else {
if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
ZERO_STRUCTP( devmode );
diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c
index 0b4eac5cc7..e4f85d0bdb 100644
--- a/source3/rpc_server/srv_srvsvc.c
+++ b/source3/rpc_server/srv_srvsvc.c
@@ -6,6 +6,7 @@
* 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
@@ -551,6 +552,35 @@ static BOOL api_srv_net_file_set_secdesc(pipes_struct *p)
}
/*******************************************************************
+*******************************************************************/
+
+static BOOL api_srv_net_file_close(pipes_struct *p)
+{
+ SRV_Q_NET_FILE_CLOSE q_u;
+ SRV_R_NET_FILE_CLOSE 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_close("", &q_u, data, 0)) {
+ DEBUG(0,("api_srv_net_file_close: Failed to unmarshall SRV_Q_NET_FILE_SET_SECDESC.\n"));
+ return False;
+ }
+
+ r_u.status = _srv_net_file_close(p, &q_u, &r_u);
+
+ if(!srv_io_r_net_file_close("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_srv_net_file_close: Failed to marshall SRV_R_NET_FILE_SET_SECDESC.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
\PIPE\srvsvc commands
********************************************************************/
@@ -573,7 +603,8 @@ static struct api_struct api_srv_cmds[] =
{ "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_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 srvsvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index a936ef5870..12a86ce9f3 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -4,6 +4,7 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Jeremy Allison 2001.
* Copyright (C) Nigel Williams 2001.
+ * Copyright (C) Gerald (Jerry) Carter 2006.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,10 +26,179 @@
#include "includes.h"
extern struct generic_mapping file_generic_mapping;
+extern userdom_struct current_user_info;
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+/* Use for enumerating connections, pipes, & files */
+
+struct file_enum_count {
+ TALLOC_CTX *ctx;
+ int count;
+ FILE_INFO_3 *info;
+};
+
+struct sess_file_count {
+ pid_t pid;
+ uid_t uid;
+ int count;
+};
+
+/****************************************************************************
+ Count the entries belonging to a service in the connection db.
+****************************************************************************/
+
+static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
+{
+ struct pipe_open_rec prec;
+ struct file_enum_count *fenum = (struct file_enum_count *)p;
+
+ if (dbuf.dsize != sizeof(struct pipe_open_rec))
+ return 0;
+
+ memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
+
+ if ( process_exists(prec.pid) ) {
+ FILE_INFO_3 *f;
+ int i = fenum->count;
+ pstring fullpath;
+
+ snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
+
+ 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;
+
+
+ init_srv_file_info3( &fenum->info[i],
+ (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
+ (FILE_READ_DATA|FILE_WRITE_DATA),
+ 0,
+ uidtoname( prec.uid ),
+ fullpath );
+
+ fenum->count++;
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+********************************************************************/
+
+static WERROR net_enum_pipes( TALLOC_CTX *ctx, FILE_INFO_3 **info,
+ uint32 *count, uint32 resume )
+{
+ struct file_enum_count fenum;
+ TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
+
+ if ( !conn_tdb ) {
+ DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
+ fenum.ctx = ctx;
+ fenum.count = *count;
+ fenum.info = *info;
+
+ if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
+ DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
+ tdb_errorstr(conn_tdb) ));
+ return WERR_NOMEM;
+ }
+
+ *info = fenum.info;
+ *count = fenum.count;
+
+ return WERR_OK;}
+
+/*******************************************************************
+********************************************************************/
+
+/* global needed to make use of the share_mode_forall() callback */
+static struct file_enum_count f_enum_cnt;
+
+static void enum_file_fn( const struct share_mode_entry *e,
+ const char *sharepath, const char *fname )
+{
+ struct file_enum_count *fenum = &f_enum_cnt;
+
+ /* If the pid was not found delete the entry from connections.tdb */
+
+ if ( process_exists(e->pid) ) {
+ FILE_INFO_3 *f;
+ int i = fenum->count;
+ files_struct fsp;
+ struct byte_range_lock *brl;
+ int num_locks = 0;
+ pstring fullpath;
+ uint32 permissions;
+
+ 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;
+ }
+ fenum->info = f;
+
+ /* need to count the number of locks on a file */
+
+ ZERO_STRUCT( fsp );
+ fsp.dev = e->dev;
+ fsp.inode = e->inode;
+
+ if ( (brl = brl_get_locks(NULL,&fsp)) != NULL ) {
+ num_locks = brl->num_locks;
+ TALLOC_FREE( brl );
+ }
+
+ if ( strcmp( fname, "." ) == 0 ) {
+ pstr_sprintf( fullpath, "C:%s", sharepath );
+ } else {
+ pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
+ }
+ string_replace( fullpath, '/', '\\' );
+
+ /* mask out create (what ever that is) */
+ permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
+
+ /* now fill in the FILE_INFO_3 struct */
+ init_srv_file_info3( &fenum->info[i],
+ e->share_file_id,
+ permissions,
+ num_locks,
+ uidtoname(e->uid),
+ fullpath );
+
+ fenum->count++;
+ }
+
+ return;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+static WERROR net_enum_files( TALLOC_CTX *ctx, FILE_INFO_3 **info,
+ uint32 *count, uint32 resume )
+{
+ f_enum_cnt.ctx = ctx;
+ f_enum_cnt.count = *count;
+ f_enum_cnt.info = *info;
+
+ share_mode_forall( enum_file_fn );
+
+ *info = f_enum_cnt.info;
+ *count = f_enum_cnt.count;
+
+ return WERR_OK;
+}
+
/*******************************************************************
Utility function to get the 'type' of a share from an snum.
********************************************************************/
@@ -70,11 +240,16 @@ static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int sn
static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
{
+ connection_struct *conn = p->conn;
pstring remark;
char *net_name = lp_servicename(snum);
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark,sizeof(remark));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ remark, sizeof(remark));
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);
@@ -86,15 +261,21 @@ static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int sn
static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
{
+ connection_struct *conn = p->conn;
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(snum);
+
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark,sizeof(remark));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ remark, sizeof(remark));
pstrcpy(path, "C:");
pstrcat(path, lp_pathname(snum));
@@ -107,7 +288,10 @@ static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int sn
pstrcpy(passwd, "");
- init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, max_uses, 1, path, passwd);
+ count = count_current_connections( net_name, False );
+ 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);
}
@@ -179,11 +363,16 @@ out:
static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
{
+ connection_struct *conn = p->conn;
pstring remark;
const char *net_name = lp_servicename(snum);
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark, sizeof(remark));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ remark, sizeof(remark));
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);
@@ -195,6 +384,7 @@ static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501,
static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
{
+ connection_struct *conn = p->conn;
pstring net_name;
pstring remark;
pstring path;
@@ -208,7 +398,11 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502,
pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark,sizeof(remark));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ remark, sizeof(remark));
pstrcpy(path, "C:");
pstrcat(path, lp_pathname(snum));
@@ -233,10 +427,15 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502,
static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum)
{
+ connection_struct *conn = p->conn;
pstring remark;
pstrcpy(remark, lp_comment(snum));
- standard_sub_conn(p->conn, remark, sizeof(remark));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ remark, sizeof(remark));
ZERO_STRUCTP(sh1004);
@@ -633,16 +832,6 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I
}
/*******************************************************************
- fill in a sess info level 1 structure.
- ********************************************************************/
-
-static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char *name)
-{
- init_srv_sess_info0(se0, name);
- init_srv_sess_info0_str(str0, name);
-}
-
-/*******************************************************************
fill in a sess info level 0 structure.
********************************************************************/
@@ -662,11 +851,7 @@ static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
if (snum) {
for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
- init_srv_sess_0_info(&ss0->info_0[num_entries],
- &ss0->info_0_str[num_entries], session_list[(*snum)].remote_machine);
-
- /* move on to creating next session */
- /* move on to creating next sess */
+ init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
num_entries++;
}
@@ -687,17 +872,35 @@ static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
}
/*******************************************************************
- fill in a sess info level 1 structure.
- ********************************************************************/
+********************************************************************/
-static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
- char *name, char *user,
- uint32 num_opens,
- uint32 open_time, uint32 idle_time,
- uint32 usr_flgs)
+/* 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 )
{
- init_srv_sess_info1(se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
- init_srv_sess_info1_str(str1, name, user);
+ struct sess_file_count *sess = &s_file_cnt;
+
+ if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
+ sess->count++;
+ }
+
+ return;
+}
+
+/*******************************************************************
+********************************************************************/
+
+static int net_count_files( uid_t uid, pid_t pid )
+{
+ s_file_cnt.count = 0;
+ s_file_cnt.uid = uid;
+ s_file_cnt.pid = pid;
+
+ share_mode_forall( sess_file_fn );
+
+ return s_file_cnt.count;
}
/*******************************************************************
@@ -708,43 +911,58 @@ static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto
{
struct sessionid *session_list;
uint32 num_entries = 0;
- (*stot) = list_sessions(&session_list);
+ time_t now = time(NULL);
+ if ( !snum ) {
+ ss1->num_entries_read = 0;
+ ss1->ptr_sess_info = 0;
+ ss1->num_entries_read2 = 0;
+
+ (*stot) = 0;
+
+ return;
+ }
+
if (ss1 == NULL) {
(*snum) = 0;
- SAFE_FREE(session_list);
return;
}
- DEBUG(5,("init_srv_sess_1_ss1\n"));
-
- if (snum) {
- for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
- init_srv_sess_1_info(&ss1->info_1[num_entries],
- &ss1->info_1_str[num_entries],
- session_list[*snum].remote_machine,
- session_list[*snum].username,
- 1, 10, 5, 0);
-
- /* move on to creating next session */
- /* move on to creating next sess */
- num_entries++;
- }
+ (*stot) = list_sessions(&session_list);
+
- 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;
+ for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
+ uint32 num_files;
+ uint32 connect_time;
+ struct passwd *pw = sys_getpwnam(session_list[*snum].username);
+ BOOL guest;
+
+ if ( !pw ) {
+ DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
+ session_list[*snum].username));
+ continue;
}
-
- } else {
- ss1->num_entries_read = 0;
- ss1->ptr_sess_info = 0;
- ss1->num_entries_read2 = 0;
-
- (*stot) = 0;
+
+ connect_time = (uint32)(now - session_list[*snum].connect_start);
+ num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
+ guest = strequal( session_list[*snum].username, lp_guestaccount() );
+
+ init_srv_sess_info1( &ss1->info_1[num_entries],
+ session_list[*snum].remote_machine,
+ session_list[*snum].username,
+ num_files,
+ connect_time,
+ 0,
+ guest);
+ 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;
}
SAFE_FREE(session_list);
@@ -964,66 +1182,53 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd,
- uint32 *total_entries)
+static WERROR net_file_enum_3( SRV_R_NET_FILE_ENUM *r, uint32 resume_hnd )
{
- WERROR status = WERR_OK;
- TALLOC_CTX *ctx = p->mem_ctx;
- DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
- *total_entries = 1; /* dummy entries only, for */
+ TALLOC_CTX *ctx = get_talloc_ctx();
+ SRV_FILE_INFO_CTR *ctr = &r->ctr;
- ctr->switch_value = switch_value;
- ctr->num_entries = *total_entries - *resume_hnd;
+ /* TODO -- Windows enumerates
+ (b) active pipes
+ (c) open directories and files */
+
+ r->status = net_enum_files( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
+ if ( !W_ERROR_IS_OK(r->status))
+ goto done;
+
+ r->status = net_enum_pipes( ctx, &ctr->file.info3, &ctr->num_entries, resume_hnd );
+ if ( !W_ERROR_IS_OK(r->status))
+ goto done;
+
+ r->level = ctr->level = 3;
+ r->total_entries = ctr->num_entries;
+ /* ctr->num_entries = r->total_entries - resume_hnd; */
ctr->num_entries2 = ctr->num_entries;
+ ctr->ptr_file_info = 1;
- switch (switch_value) {
- case 3: {
- int i;
- if (*total_entries > 0) {
- ctr->ptr_entries = 1;
- ctr->file.info3 = TALLOC_ARRAY(ctx, SRV_FILE_INFO_3, ctr->num_entries);
- }
- for (i=0 ;i<ctr->num_entries;i++) {
- init_srv_file_info3(&ctr->file.info3[i].info_3, i+*resume_hnd, 0x35, 0, "\\PIPE\\samr", "dummy user");
- init_srv_file_info3_str(&ctr->file.info3[i].info_3_str, "\\PIPE\\samr", "dummy user");
-
- }
- ctr->ptr_file_info = 1;
- *resume_hnd = 0;
- break;
- }
- default:
- DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n", switch_value));
- (*resume_hnd = 0);
- (*total_entries) = 0;
- ctr->ptr_entries = 0;
- status = WERR_UNKNOWN_LEVEL;
- break;
- }
+ r->status = WERR_OK;
- return status;
+done:
+ if ( ctr->num_entries > 0 )
+ ctr->ptr_entries = 1;
+
+ init_enum_hnd(&r->enum_hnd, 0);
+
+ return r->status;
}
/*******************************************************************
- makes a SRV_R_NET_FILE_ENUM structure.
-********************************************************************/
+*******************************************************************/
-static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n,
- uint32 resume_hnd, int file_level, int switch_value)
+WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
{
- DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
-
- r_n->file_level = file_level;
- if (file_level == 0)
- r_n->status = WERR_UNKNOWN_LEVEL;
- else
- r_n->status = init_srv_file_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);
+ switch ( q_u->level ) {
+ case 3:
+ return net_file_enum_3( r_u, get_enum_hnd(&q_u->enum_hnd) );
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ return WERR_OK;
}
/*******************************************************************
@@ -1110,25 +1315,6 @@ WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R
}
/*******************************************************************
-net file enum
-********************************************************************/
-
-WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
-{
- DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
-
- /* set up the */
- init_srv_r_net_file_enum(p, r_u,
- get_enum_hnd(&q_u->enum_hnd),
- q_u->file_level,
- q_u->ctr.switch_value);
-
- DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
-
- return r_u->status;
-}
-
-/*******************************************************************
net conn enum
********************************************************************/
@@ -1185,7 +1371,6 @@ net sess del
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;
fstring username;
fstring machine;
@@ -1205,11 +1390,9 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES
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 ((user.ut.uid != sec_initial_uid()) &&
+ if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
goto done;
@@ -1220,7 +1403,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES
if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
strequal(session_list[snum].remote_machine, machine)) {
- if (user.ut.uid != sec_initial_uid()) {
+ if (p->pipe_user.ut.uid != sec_initial_uid()) {
not_root = True;
become_root();
}
@@ -1337,7 +1520,6 @@ char *valid_share_pathname(char *dos_pathname)
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)
{
- struct current_user user;
pstring command;
fstring share_name;
fstring comment;
@@ -1374,13 +1556,11 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
if (lp_print_ok(snum))
return WERR_ACCESS_DENIED;
- 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 ( user.ut.uid != sec_initial_uid() && !is_disk_op )
+ if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
switch (q_u->info_level) {
@@ -1525,7 +1705,6 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
{
- struct current_user user;
pstring command;
fstring share_name;
fstring comment;
@@ -1543,11 +1722,9 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
r_u->parm_error = 0;
- get_current_user(&user,p);
-
is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
- if (user.ut.uid != sec_initial_uid() && !is_disk_op )
+ if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
@@ -1682,7 +1859,6 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
{
- struct current_user user;
pstring command;
fstring share_name;
int ret;
@@ -1710,11 +1886,9 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
if (lp_print_ok(snum))
return WERR_ACCESS_DENIED;
- get_current_user(&user,p);
-
is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
- if (user.ut.uid != sec_initial_uid() && !is_disk_op )
+ if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
@@ -1826,7 +2000,6 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
SMB_STRUCT_STAT st;
BOOL bad_path;
NTSTATUS nt_status;
- struct current_user user;
connection_struct *conn = NULL;
BOOL became_user = False;
@@ -1839,10 +2012,8 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
/* Null password is ok - we are already an authenticated user... */
null_pw = data_blob(NULL, 0);
- get_current_user(&user, p);
-
become_root();
- conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
+ conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
unbecome_root();
if (conn == NULL) {
@@ -1872,18 +2043,18 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
goto error_exit;
}
- fsp = open_file_stat(conn, filename, &st);
- if (!fsp) {
+ nt_status = open_file_stat(conn, filename, &st, &fsp);
+ if (!NT_STATUS_IS_OK(nt_status)) {
/* Perhaps it is a directory */
- if (errno == EISDIR)
- fsp = open_directory(conn, filename, &st,
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
+ nt_status = open_directory(conn, filename, &st,
READ_CONTROL_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
r_u->status = WERR_ACCESS_DENIED;
goto error_exit;
@@ -1908,7 +2079,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
close_file(fsp, NORMAL_CLOSE);
unbecome_user();
- close_cnum(conn, user.vuid);
+ close_cnum(conn, p->pipe_user.vuid);
return r_u->status;
error_exit:
@@ -1921,7 +2092,7 @@ error_exit:
unbecome_user();
if (conn)
- close_cnum(conn, user.vuid);
+ close_cnum(conn, p->pipe_user.vuid);
return r_u->status;
}
@@ -1941,7 +2112,6 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
SMB_STRUCT_STAT st;
BOOL bad_path;
NTSTATUS nt_status;
- struct current_user user;
connection_struct *conn = NULL;
BOOL became_user = False;
@@ -1954,10 +2124,8 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
/* Null password is ok - we are already an authenticated user... */
null_pw = data_blob(NULL, 0);
- get_current_user(&user, p);
-
become_root();
- conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
+ conn = make_connection(qualname, null_pw, "A:", p->pipe_user.vuid, &nt_status);
unbecome_root();
if (conn == NULL) {
@@ -1988,19 +2156,19 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
}
- fsp = open_file_stat(conn, filename, &st);
+ nt_status = open_file_stat(conn, filename, &st, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(nt_status)) {
/* Perhaps it is a directory */
- if (errno == EISDIR)
- fsp = open_directory(conn, filename, &st,
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
+ nt_status = open_directory(conn, filename, &st,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
r_u->status = WERR_ACCESS_DENIED;
goto error_exit;
@@ -2017,7 +2185,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
close_file(fsp, NORMAL_CLOSE);
unbecome_user();
- close_cnum(conn, user.vuid);
+ close_cnum(conn, p->pipe_user.vuid);
return r_u->status;
error_exit:
@@ -2031,7 +2199,7 @@ error_exit:
}
if (conn) {
- close_cnum(conn, user.vuid);
+ close_cnum(conn, p->pipe_user.vuid);
}
return r_u->status;
@@ -2133,7 +2301,7 @@ WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV
switch ( q_u->type ) {
case 0x9:
- rpcstr_pull(sharename, q_u->uni_name.buffer, sizeof(sharename), q_u->uni_name.uni_str_len*2, 0);
+ 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;
@@ -2146,3 +2314,13 @@ WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV
return WERR_OK;
}
+
+
+/********************************************************************
+********************************************************************/
+
+WERROR _srv_net_file_close(pipes_struct *p, SRV_Q_NET_FILE_CLOSE *q_u, SRV_R_NET_FILE_CLOSE *r_u)
+{
+ return WERR_ACCESS_DENIED;
+}
+
diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index 6062dcee5c..dd790691d3 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -624,7 +624,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" ) && ( lp_servicenumber(name) == -1 ) )
+ if ( strequal( name, "NETLOGON" ) && ( !share_defined(name) ) )
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.c b/source3/rpc_server/srv_unixinfo.c
new file mode 100644
index 0000000000..f21416dfab
--- /dev/null
+++ b/source3/rpc_server/srv_unixinfo.c
@@ -0,0 +1,163 @@
+/*
+ * 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This is the interface to the rpcunixinfo pipe. */
+
+#include "includes.h"
+#include "nterr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+static BOOL api_sid_to_uid(pipes_struct *p)
+{
+ UNIXINFO_Q_SID_TO_UID q_u;
+ UNIXINFO_R_SID_TO_UID r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!unixinfo_io_q_unixinfo_sid_to_uid("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _unixinfo_sid_to_uid(p, &q_u, &r_u);
+
+ if (!unixinfo_io_r_unixinfo_sid_to_uid("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_uid_to_sid(pipes_struct *p)
+{
+ UNIXINFO_Q_UID_TO_SID q_u;
+ UNIXINFO_R_UID_TO_SID r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!unixinfo_io_q_unixinfo_uid_to_sid("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _unixinfo_uid_to_sid(p, &q_u, &r_u);
+
+ if (!unixinfo_io_r_unixinfo_uid_to_sid("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_sid_to_gid(pipes_struct *p)
+{
+ UNIXINFO_Q_SID_TO_GID q_u;
+ UNIXINFO_R_SID_TO_GID r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!unixinfo_io_q_unixinfo_sid_to_gid("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _unixinfo_sid_to_gid(p, &q_u, &r_u);
+
+ if (!unixinfo_io_r_unixinfo_sid_to_gid("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_gid_to_sid(pipes_struct *p)
+{
+ UNIXINFO_Q_GID_TO_SID q_u;
+ UNIXINFO_R_GID_TO_SID r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!unixinfo_io_q_unixinfo_gid_to_sid("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _unixinfo_gid_to_sid(p, &q_u, &r_u);
+
+ if (!unixinfo_io_r_unixinfo_gid_to_sid("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_getpwuid(pipes_struct *p)
+{
+ UNIXINFO_Q_GETPWUID q_u;
+ UNIXINFO_R_GETPWUID r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!unixinfo_io_q_unixinfo_getpwuid("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _unixinfo_getpwuid(p, &q_u, &r_u);
+
+ if (!unixinfo_io_r_unixinfo_getpwuid("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+\pipe\unixinfo commands
+********************************************************************/
+
+struct api_struct api_unixinfo_cmds[] = {
+ {"SID_TO_UID", UNIXINFO_SID_TO_UID, api_sid_to_uid },
+ {"UID_TO_SID", UNIXINFO_UID_TO_SID, api_uid_to_sid },
+ {"SID_TO_GID", UNIXINFO_SID_TO_GID, api_sid_to_gid },
+ {"GID_TO_SID", UNIXINFO_GID_TO_SID, api_gid_to_sid },
+ {"GETPWUID", UNIXINFO_GETPWUID, api_getpwuid },
+};
+
+
+void unixinfo_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_unixinfo_cmds;
+ *n_fns = sizeof(api_unixinfo_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_unixinfo_init(void)
+{
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
+ "unixinfo", "unixinfo", api_unixinfo_cmds,
+ sizeof(api_unixinfo_cmds) / sizeof(struct api_struct));
+}
diff --git a/source3/rpc_server/srv_unixinfo_nt.c b/source3/rpc_server/srv_unixinfo_nt.c
new file mode 100644
index 0000000000..79756f20a7
--- /dev/null
+++ b/source3/rpc_server/srv_unixinfo_nt.c
@@ -0,0 +1,166 @@
+/*
+ * 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This is the interface 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_sid_to_uid(pipes_struct *p,
+ UNIXINFO_Q_SID_TO_UID *q_u,
+ UNIXINFO_R_SID_TO_UID *r_u)
+{
+ uid_t uid;
+
+ r_u->uid.low = 0;
+ r_u->uid.high = 0;
+
+ r_u->status = sid_to_uid(&q_u->sid, &uid) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED;
+ if (NT_STATUS_IS_OK(r_u->status))
+ r_u->uid.low = uid;
+
+ return r_u->status;
+}
+
+/* Map a uid to a sid */
+
+NTSTATUS _unixinfo_uid_to_sid(pipes_struct *p,
+ UNIXINFO_Q_UID_TO_SID *q_u,
+ UNIXINFO_R_UID_TO_SID *r_u)
+{
+ DOM_SID sid;
+
+ r_u->status = NT_STATUS_NO_SUCH_USER;
+
+ if (q_u->uid.high == 0) {
+ uid_to_sid(&sid, q_u->uid.low);
+ r_u->status = NT_STATUS_OK;
+ }
+
+ init_r_unixinfo_uid_to_sid(r_u,
+ NT_STATUS_IS_OK(r_u->status) ? &sid : NULL);
+
+ return r_u->status;
+}
+
+/* Map a sid to a gid */
+
+NTSTATUS _unixinfo_sid_to_gid(pipes_struct *p,
+ UNIXINFO_Q_SID_TO_GID *q_u,
+ UNIXINFO_R_SID_TO_GID *r_u)
+{
+ gid_t gid;
+
+ r_u->gid.low = 0;
+ r_u->gid.high = 0;
+
+ r_u->status = sid_to_gid(&q_u->sid, &gid) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED;
+ if (NT_STATUS_IS_OK(r_u->status))
+ r_u->gid.low = gid;
+
+ return r_u->status;
+}
+
+/* Map a gid to a sid */
+
+NTSTATUS _unixinfo_gid_to_sid(pipes_struct *p,
+ UNIXINFO_Q_GID_TO_SID *q_u,
+ UNIXINFO_R_GID_TO_SID *r_u)
+{
+ DOM_SID sid;
+
+ r_u->status = NT_STATUS_NO_SUCH_USER;
+
+ if (q_u->gid.high == 0) {
+ gid_to_sid(&sid, q_u->gid.low);
+ r_u->status = NT_STATUS_OK;
+ }
+
+ init_r_unixinfo_gid_to_sid(r_u,
+ NT_STATUS_IS_OK(r_u->status) ? &sid : NULL);
+
+ return r_u->status;
+}
+
+/* Get unix struct passwd information */
+
+NTSTATUS _unixinfo_getpwuid(pipes_struct *p,
+ UNIXINFO_Q_GETPWUID *q_u,
+ UNIXINFO_R_GETPWUID *r_u)
+{
+ int i;
+
+ if (r_u->count > 1023) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ r_u->info = TALLOC_ARRAY(p->mem_ctx, struct unixinfo_getpwuid,
+ q_u->count);
+
+ if ((r_u->count > 0) && (r_u->info == NULL)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ r_u->status = NT_STATUS_OK;
+ r_u->count = q_u->count;
+
+ for (i=0; i<r_u->count; i++) {
+ struct passwd *pw;
+ char *homedir, *shell;
+ ssize_t len1, len2;
+
+ r_u->info[i].status = NT_STATUS_NO_SUCH_USER;
+ r_u->info[i].homedir = "";
+ r_u->info[i].shell = "";
+
+ if (q_u->uid[i].high != 0) {
+ DEBUG(10, ("64-bit uids not yet supported...\n"));
+ continue;
+ }
+
+ pw = getpwuid(q_u->uid[i].low);
+
+ if (pw == NULL) {
+ DEBUG(10, ("Did not find uid %d\n", q_u->uid[i].low));
+ 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_u->info[i].status = NT_STATUS_NO_MEMORY;
+ continue;
+ }
+
+ r_u->info[i].status = NT_STATUS_OK;
+ r_u->info[i].homedir = homedir;
+ r_u->info[i].shell = shell;
+ }
+
+ return r_u->status;
+}