diff options
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_dfs.c | 3 | ||||
-rw-r--r-- | source3/rpc_server/srv_dfs_nt.c | 33 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa.c | 5 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_hnd.c | 48 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 58 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog.c | 3 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog_nt.c | 53 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 5 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 50 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg.c | 138 | ||||
-rw-r--r-- | source3/rpc_server/srv_reg_nt.c | 661 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 35 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 1339 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 125 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 1330 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc.c | 39 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 143 | ||||
-rw-r--r-- | source3/rpc_server/srv_util.c | 18 | ||||
-rw-r--r-- | source3/rpc_server/srv_wkssvc.c | 5 | ||||
-rw-r--r-- | source3/rpc_server/srv_wkssvc_nt.c | 3 |
20 files changed, 1037 insertions, 3057 deletions
diff --git a/source3/rpc_server/srv_dfs.c b/source3/rpc_server/srv_dfs.c index 5edc1222a8..4351fd088e 100644 --- a/source3/rpc_server/srv_dfs.c +++ b/source3/rpc_server/srv_dfs.c @@ -28,9 +28,6 @@ #define MAX_MSDFS_JUNCTIONS 256 -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - extern pstring global_myname; /********************************************************************** diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index 65e387176d..4db6c61a3c 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -26,9 +26,6 @@ #include "includes.h" #include "nterr.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - extern pstring global_myname; #define MAX_MSDFS_JUNCTIONS 256 @@ -72,7 +69,10 @@ WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u) pstrcat(altpath, "\\"); pstrcat(altpath, sharename); - if(get_referred_path(dfspath, &jn, NULL, NULL)) + if(!create_junction(dfspath, &jn)) + return WERR_DFS_NO_SUCH_SERVER; + + if(get_referred_path(&jn)) { exists = True; jn.referral_count += 1; @@ -137,14 +137,16 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, pstrcpy(altpath, servername); pstrcat(altpath, "\\"); pstrcat(altpath, sharename); - strlower(altpath); } DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", dfspath, servername, sharename)); - if(!get_referred_path(dfspath, &jn, NULL, NULL)) - return WERR_DFS_NO_SUCH_VOL; + if(!create_junction(dfspath, &jn)) + return WERR_DFS_NO_SUCH_SERVER; + + if(!get_referred_path(&jn)) + return WERR_DFS_NO_SUCH_VOL; /* if no server-share pair given, remove the msdfs link completely */ if(!q_u->ptr_ServerName && !q_u->ptr_ShareName) @@ -156,18 +158,14 @@ WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, { int i=0; /* compare each referral in the list with the one to remove */ - DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count)); for(i=0;i<jn.referral_count;i++) { pstring refpath; pstrcpy(refpath,jn.referral_list[i].alternate_path); trim_string(refpath, "\\", "\\"); - DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath)); if(strequal(refpath, altpath)) { *(jn.referral_list[i].alternate_path)='\0'; - DEBUG(10,("_dfs_remove: Removal request matches referral %s\n", - refpath)); found = True; } } @@ -229,13 +227,8 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, DFS_I { pstring str; dfs3[i].ptr_entrypath = 1; - if (j[i].volume_name[0] == '\0') - slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s", - global_myname, j[i].service_name); - else - slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname, - j[i].service_name, j[i].volume_name); - + slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname, + j[i].service_name, j[i].volume_name); init_unistr2(&dfs3[i].entrypath, str, strlen(str)+1); dfs3[i].ptr_comment = 1; init_unistr2(&dfs3[i].comment, "", 1); @@ -362,8 +355,8 @@ WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, if(!create_junction(path, &jn)) return WERR_DFS_NO_SUCH_SERVER; - if(!get_referred_path(path, &jn, NULL, NULL)) - return WERR_DFS_NO_SUCH_VOL; + if(!get_referred_path(&jn)) + return WERR_DFS_NO_SUCH_VOL; r_u->level = level; r_u->ptr_ctr = 1; diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index e5a4d3b46d..fcd4be0212 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -25,9 +25,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /*************************************************************************** api_lsa_open_policy2 ***************************************************************************/ @@ -108,10 +105,8 @@ static BOOL api_lsa_enum_trust_dom(pipes_struct *p) if(!lsa_io_q_enum_trust_dom("", &q_u, data, 0)) return False; - /* get required trusted domains information */ r_u.status = _lsa_enum_trust_dom(p, &q_u, &r_u); - /* prepare the response */ if(!lsa_io_r_enum_trust_dom("", &r_u, rdata, 0)) return False; diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index 2d04d72323..84c3c5a959 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -22,9 +22,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /* This is the max handles across all instances of a pipe name. */ #ifndef MAX_OPEN_POLS #define MAX_OPEN_POLS 1024 @@ -137,14 +134,6 @@ BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *) DLIST_ADD(p->pipe_handles->Policy, pol); p->pipe_handles->count++; - /* - * Ensure we don't idle this connection if a handle is open. - * Increment the number of files open on the first handle create. - */ - - if (p->pipe_handles->count == 1) - p->conn->num_files_open++; - *hnd = pol->pol_hnd; DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count)); @@ -212,15 +201,6 @@ BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd) p->pipe_handles->count--; - /* - * Ensure we can idle this connection if this is the last handle. - * Decrement the number of files open on the last handle delete. - */ - - if (p->pipe_handles->count == 0) - p->conn->num_files_open--; - - DLIST_REMOVE(p->pipe_handles->Policy, pol); ZERO_STRUCTP(pol); @@ -252,31 +232,3 @@ void close_policy_by_pipe(pipes_struct *p) DEBUG(10,("close_policy_by_pipe: deleted handle list for pipe %s\n", p->name )); } } - -/******************************************************************* -Shall we allow access to this rpc? Currently this function -implements the 'restrict anonymous' setting by denying access to -anonymous users if the restrict anonymous level is > 0. Further work -will be checking a security descriptor to determine whether a user -token has enough access to access the pipe. -********************************************************************/ - -BOOL pipe_access_check(pipes_struct *p) -{ - /* Don't let anonymous users access this RPC if restrict - anonymous > 0 */ - - if (lp_restrict_anonymous() > 0) { - user_struct *user = get_valid_user_struct(p->vuid); - - if (!user) { - DEBUG(3, ("invalid vuid %d\n", p->vuid)); - return False; - } - - if (user->guest) - return False; - } - - return True; -} diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index d072061a5f..84ab44bc30 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -3,9 +3,8 @@ * 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) Rafal Szczesniak 2002. + * Copyright (C) Paul Ashton 1997. + * Copyright (C) Jeremy Allison 2001. * * 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 @@ -26,9 +25,7 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - +extern DOM_SID global_sam_sid; extern fstring global_myworkgroup; extern pstring global_myname; extern PRIVS privs[]; @@ -167,7 +164,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : "not found")); - if (status && name_type != SID_NAME_UNKNOWN) { + if (status) { sid_split_rid(&sid, &rid); dom_idx = init_dom_ref(ref, dom_name, &sid); (*mapped_count)++; @@ -261,8 +258,6 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME if (!status) { sid_name_use = SID_NAME_UNKNOWN; - } else { - (*mapped_count)++; } /* Store domain sid in ref array */ @@ -276,6 +271,8 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to " "referenced list.\n", dom_name, name )); + (*mapped_count)++; + init_lsa_trans_name(&trn->name[total], &trn->uni_name[total], sid_name_use, name, dom_idx); total++; @@ -322,7 +319,7 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s init_sec_access(&mask, POLICY_EXECUTE); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - sid_copy(&adm_sid, get_global_sam_sid()); + sid_copy(&adm_sid, &global_sam_sid); sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS); init_sec_access(&mask, POLICY_ALL_ACCESS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); @@ -369,7 +366,7 @@ NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL return NT_STATUS_NO_MEMORY; ZERO_STRUCTP(info); - sid_copy(&info->sid,get_global_sam_sid()); + info->sid = global_sam_sid; info->access = acc_granted; /* set up the LSA QUERY INFO response */ @@ -407,7 +404,7 @@ NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL * return NT_STATUS_NO_MEMORY; ZERO_STRUCTP(info); - sid_copy(&info->sid,get_global_sam_sid()); + info->sid = global_sam_sid; info->access = acc_granted; /* set up the LSA QUERY INFO response */ @@ -419,22 +416,14 @@ NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL * /*************************************************************************** _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA. - ufff, done :) mimir ***************************************************************************/ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u) { struct lsa_info *info; - uint32 enum_context = q_u->enum_context; - - /* - * preferred length is set to 5 as a "our" preferred length - * nt sets this parameter to 2 - */ - uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10; - TRUSTDOM **trust_doms; - uint32 num_domains; - NTSTATUS nt_status; + uint32 enum_context = 0; + char *dom_name = NULL; + DOM_SID *dom_sid = NULL; if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; @@ -443,18 +432,9 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - nt_status = secrets_get_trusted_domains(p->mem_ctx, &enum_context, max_num_domains, &num_domains, &trust_doms); - - if (!NT_STATUS_IS_OK(nt_status) && - !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) && - !NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) { - return nt_status; - } else { - r_u->status = nt_status; - } - - /* set up the lsa_enum_trust_dom response */ - init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms); + /* set up the LSA QUERY INFO response */ + init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, dom_name, dom_sid, + dom_name != NULL ? NT_STATUS_OK : NT_STATUS_NO_MORE_ENTRIES); return r_u->status; } @@ -504,7 +484,7 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = global_myworkgroup; - sid = get_global_sam_sid(); + sid = &global_sam_sid; break; case ROLE_DOMAIN_MEMBER: name = global_myworkgroup; @@ -534,15 +514,15 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = global_myworkgroup; - sid = get_global_sam_sid(); + sid = &global_sam_sid; break; case ROLE_DOMAIN_MEMBER: name = global_myname; - sid = get_global_sam_sid(); + sid = &global_sam_sid; break; case ROLE_STANDALONE: name = global_myname; - sid = get_global_sam_sid(); + sid = &global_sam_sid; break; default: return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index f96a0e2f2d..dfd270ff7d 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -25,9 +25,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /************************************************************************* api_net_req_chal: *************************************************************************/ diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 4ab9c470d0..bdb064c81d 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -26,10 +26,8 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - extern pstring global_myname; +extern DOM_SID global_sam_sid; /************************************************************************* init_net_r_req_chal: @@ -152,7 +150,7 @@ NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_T ***********************************************************************************/ static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s, - DOM_CRED *srv_cred, NTSTATUS status) + DOM_CRED *srv_cred, NTSTATUS status) { DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__)); @@ -380,7 +378,7 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u) { - NTSTATUS status = NT_STATUS_ACCESS_DENIED; + NTSTATUS status = NT_STATUS_WRONG_PASSWORD; DOM_CRED srv_cred; pstring workstation; SAM_ACCOUNT *sampass=NULL; @@ -397,8 +395,8 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * DEBUG(5,("_net_srv_pwset: %d\n", __LINE__)); - rpcstr_pull(workstation,q_u->clnt_id.login.uni_comp_name.buffer, - sizeof(workstation),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0); + rpcstr_pull(workstation,q_u->clnt_id.login.uni_acct_name.buffer, + sizeof(workstation),q_u->clnt_id.login.uni_acct_name.uni_str_len*2,0); DEBUG(3,("Server Password Set by Wksta:[%s] on account [%s]\n", workstation, p->dc.mach_acct)); @@ -658,35 +656,14 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * { DOM_GID *gids = NULL; - const DOM_SID *user_sid = NULL; - const DOM_SID *group_sid = NULL; - DOM_SID domain_sid; - uint32 user_rid, group_rid; - int num_gids = 0; pstring my_name; - fstring user_sid_string; - fstring group_sid_string; - - sampw = server_info->sam_account; - + pstring my_workgroup; + /* set up pointer indicating user/password failed to be found */ usr_info->ptr_user_info = 0; - - user_sid = pdb_get_user_sid(sampw); - group_sid = pdb_get_group_sid(sampw); - - sid_copy(&domain_sid, user_sid); - sid_split_rid(&domain_sid, &user_rid); - - if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) { - DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid %s\n but group sid %s.\nThe conflicting domain portions are not supported for NETLOGON calls\n", - pdb_get_domain(sampw), pdb_get_username(sampw), - sid_to_string(user_sid_string, user_sid), - sid_to_string(group_sid_string, group_sid))); - return NT_STATUS_UNSUCCESSFUL; - } - + + pstrcpy(my_workgroup, lp_workgroup()); pstrcpy(my_name, global_myname); strupper(my_name); @@ -700,10 +677,12 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * gids = NULL; get_domain_user_groups(p->mem_ctx, &num_gids, &gids, server_info->sam_account); + + sampw = server_info->sam_account; init_net_user_info3(p->mem_ctx, usr_info, - user_rid, - group_rid, + pdb_get_user_rid(sampw), + pdb_get_group_rid(sampw), pdb_get_username(sampw), pdb_get_fullname(sampw), @@ -725,10 +704,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * 0x20 , /* uint32 user_flgs (?) */ NULL, /* uchar sess_key[16] */ my_name , /* char *logon_srv */ - pdb_get_domain(sampw), - &domain_sid, /* DOM_SID *dom_sid */ - /* Should be users domain sid, not servers - for trusted domains */ - + my_workgroup, /* char *logon_dom */ + &global_sam_sid, /* DOM_SID *dom_sid */ NULL); /* char *other_sids */ } free_server_info(&server_info); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1d2c0c2713..70574b4cdd 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -39,9 +39,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { unsigned char *hash = p->ntlmssp_hash; @@ -1151,7 +1148,7 @@ BOOL api_pipe_request(pipes_struct *p) ********************************************************************/ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, - const struct api_struct *api_rpc_cmds) + struct api_struct *api_rpc_cmds) { int fn_num; fstring name; diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index cc6e4b95f9..44dd5fac65 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -22,9 +22,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) @@ -35,23 +32,6 @@ static int pipes_open; #define MAX_OPEN_PIPES 2048 #endif -/* - * Sometimes I can't decide if I hate Windows printer driver - * writers more than I hate the Windows spooler service driver - * writers. This gets around a combination of bugs in the spooler - * and the HP 8500 PCL driver that causes a spooler spin. JRA. - * - * bumped up from 20 -> 64 after viewing traffic from WordPerfect - * 2002 running on NT 4.- SP6 - * bumped up from 64 -> 256 after viewing traffic from con2prt - * for lots of printers on a WinNT 4.x SP6 box. - */ - -#ifndef MAX_OPEN_SPOOLSS_PIPES -#define MAX_OPEN_SPOOLSS_PIPES 256 -#endif -static int current_spoolss_pipes_open; - static smb_np_struct *Pipes; static pipes_struct *InternalPipes; static struct bitmap *bmap; @@ -119,7 +99,6 @@ void set_pipe_handle_offset(int max_open_files) /**************************************************************************** Reset pipe chain handle number. ****************************************************************************/ - void reset_chain_p(void) { chain_p = NULL; @@ -176,20 +155,11 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name, int i; smb_np_struct *p, *p_it; static int next_pipe; - BOOL is_spoolss_pipe = False; DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n", pipe_name, pipes_open)); - if (strstr(pipe_name, "spoolss")) - is_spoolss_pipe = True; - - if (is_spoolss_pipe && current_spoolss_pipes_open >= MAX_OPEN_SPOOLSS_PIPES) { - DEBUG(10,("open_rpc_pipe_p: spooler bug workaround. Denying open on pipe %s\n", - pipe_name )); - return NULL; - } - + /* not repeating pipe numbers makes it easier to track things in log files and prevents client bugs where pipe numbers are reused over connection restarts */ @@ -210,7 +180,8 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name, p = (smb_np_struct *)malloc(sizeof(*p)); - if (!p) { + if (!p) + { DEBUG(0,("ERROR! no memory for pipes_struct!\n")); return NULL; } @@ -227,11 +198,13 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name, p->np_state = p->namedpipe_create(pipe_name, conn, vuid); if (p->np_state == NULL) { + DEBUG(0,("open_rpc_pipe_p: make_internal_rpc_pipe_p failed.\n")); SAFE_FREE(p); return NULL; } + DLIST_ADD(Pipes, p); /* @@ -271,7 +244,7 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name, } /**************************************************************************** - Make an internal namedpipes structure + * make an internal namedpipes structure ****************************************************************************/ static void *make_internal_rpc_pipe_p(char *pipe_name, @@ -325,10 +298,6 @@ static void *make_internal_rpc_pipe_p(char *pipe_name, DLIST_ADD(InternalPipes, p); p->conn = conn; - - /* Ensure the connection isn't idled whilst this pipe is open. */ - p->conn->num_files_open++; - p->vuid = vuid; p->ntlmssp_chal_flags = 0; @@ -344,10 +313,9 @@ static void *make_internal_rpc_pipe_p(char *pipe_name, p->pipe_user.uid = (uid_t)-1; p->pipe_user.gid = (gid_t)-1; - /* Store the session key and NT_TOKEN */ + /* Store the session key */ if (vuser) { memcpy(p->session_key, vuser->session_key, sizeof(p->session_key)); - p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token); } /* @@ -1087,7 +1055,7 @@ BOOL close_rpc_pipe_hnd(smb_np_struct *p) ZERO_STRUCTP(p); SAFE_FREE(p); - + return True; } @@ -1117,8 +1085,6 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn) DLIST_REMOVE(InternalPipes, p); - p->conn->num_files_open--; - ZERO_STRUCTP(p); SAFE_FREE(p); diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c index a096325860..569f3fb8b1 100644 --- a/source3/rpc_server/srv_reg.c +++ b/source3/rpc_server/srv_reg.c @@ -1,12 +1,11 @@ -/* +/* * 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) Marc Jacobsen 2000. - * Copyright (C) Jeremy Allison 2001. - * Copyright (C) Gerald Carter 2002. + * Copyright (C) Marc Jacobsen 2000. + * Copyright (C) Jeremy Allison 2001. * * 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 @@ -27,9 +26,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /******************************************************************* api_reg_close ********************************************************************/ @@ -57,10 +53,10 @@ static BOOL api_reg_close(pipes_struct *p) } /******************************************************************* - api_reg_open_khlm + api_reg_open ********************************************************************/ -static BOOL api_reg_open_hklm(pipes_struct *p) +static BOOL api_reg_open(pipes_struct *p) { REG_Q_OPEN_HKLM q_u; REG_R_OPEN_HKLM r_u; @@ -74,7 +70,7 @@ static BOOL api_reg_open_hklm(pipes_struct *p) if(!reg_io_q_open_hklm("", &q_u, data, 0)) return False; - r_u.status = _reg_open_hklm(p, &q_u, &r_u); + r_u.status = _reg_open(p, &q_u, &r_u); if(!reg_io_r_open_hklm("", &r_u, rdata, 0)) return False; @@ -83,33 +79,6 @@ static BOOL api_reg_open_hklm(pipes_struct *p) } /******************************************************************* - api_reg_open_khlm - ********************************************************************/ - -static BOOL api_reg_open_hku(pipes_struct *p) -{ - REG_Q_OPEN_HKU q_u; - REG_R_OPEN_HKU 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 reg open */ - if(!reg_io_q_open_hku("", &q_u, data, 0)) - return False; - - r_u.status = _reg_open_hku(p, &q_u, &r_u); - - if(!reg_io_r_open_hku("", &r_u, rdata, 0)) - return False; - - return True; -} - - -/******************************************************************* api_reg_open_entry ********************************************************************/ @@ -216,98 +185,17 @@ static BOOL api_reg_abort_shutdown(pipes_struct *p) /******************************************************************* - api_reg_query_key - ********************************************************************/ - -static BOOL api_reg_query_key(pipes_struct *p) -{ - REG_Q_QUERY_KEY q_u; - REG_R_QUERY_KEY 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(!reg_io_q_query_key("", &q_u, data, 0)) - return False; - - r_u.status = _reg_query_key(p, &q_u, &r_u); - - if(!reg_io_r_query_key("", &r_u, rdata, 0)) - return False; - - return True; -} - -/******************************************************************* - api_reg_unknown_1a - ********************************************************************/ - -static BOOL api_reg_unknown_1a(pipes_struct *p) -{ - REG_Q_UNKNOWN_1A q_u; - REG_R_UNKNOWN_1A 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(!reg_io_q_unknown_1a("", &q_u, data, 0)) - return False; - - r_u.status = _reg_unknown_1a(p, &q_u, &r_u); - - if(!reg_io_r_unknown_1a("", &r_u, rdata, 0)) - return False; - - return True; -} - -/******************************************************************* - api_reg_enum_key - ********************************************************************/ - -static BOOL api_reg_enum_key(pipes_struct *p) -{ - REG_Q_ENUM_KEY q_u; - REG_R_ENUM_KEY 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(!reg_io_q_enum_key("", &q_u, data, 0)) - return False; - - r_u.status = _reg_enum_key(p, &q_u, &r_u); - - if(!reg_io_r_enum_key("", &r_u, rdata, 0)) - return False; - - return True; -} - - - -/******************************************************************* array of \PIPE\reg operations ********************************************************************/ static struct api_struct api_reg_cmds[] = { - { "REG_CLOSE" , REG_CLOSE , api_reg_close }, - { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry }, - { "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm }, - { "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku }, - { "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key }, - { "REG_QUERY_KEY" , REG_QUERY_KEY , api_reg_query_key }, - { "REG_INFO" , REG_INFO , api_reg_info }, - { "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown }, - { "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown }, - { "REG_UNKNOWN_1A" , REG_UNKNOWN_1A , api_reg_unknown_1a }, - { NULL , 0 , NULL } + { "REG_CLOSE" , REG_CLOSE , api_reg_close }, + { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry }, + { "REG_OPEN" , REG_OPEN_HKLM , api_reg_open }, + { "REG_INFO" , REG_INFO , api_reg_info }, + { "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown }, + { "REG_ABORT_SHUTDOWN", REG_ABORT_SHUTDOWN, api_reg_abort_shutdown }, + { NULL, 0 , NULL } }; /******************************************************************* diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 3f07e4aaea..adedd4a8fa 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -5,8 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. * Copyright (C) Hewlett-Packard Company 1999. - * Copyright (C) Jeremy Allison 2001. - * Copyright (C) Gerald Carter 2002. + * Copyright (C) Jeremy Allison 2001. * * 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 @@ -27,479 +26,20 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define KEY_HKLM "HKLM" -#define KEY_HKU "HKU" - -#define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \ -((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid()) - -/* structure to store the registry handles */ - -typedef struct _RegistryKey { - struct _RegistryKey *prev, *next; - +struct reg_info { + /* for use by \PIPE\winreg */ fstring name; /* name of registry key */ - POLICY_HND hnd; - -} Registry_Key; - -static Registry_Key *regkeys_list; -static TDB_CONTEXT *tdb_reg; - -/*********************************************************************** - Add subkey strings to the registry tdb under a defined key - fmt is the same format as tdb_pack except this function only supports - fstrings - ***********************************************************************/ - -static BOOL store_reg_keys( TDB_CONTEXT *tdb, char *keyname, char **subkeys, uint32 num_subkeys ) -{ - TDB_DATA kbuf, dbuf; - char *buffer, *tmpbuf; - int i = 0; - uint32 len, buflen; - BOOL ret = True; - - if ( !keyname ) - return False; - - /* allocate some initial memory */ - - buffer = malloc(sizeof(pstring)); - buflen = sizeof(pstring); - len = 0; - - /* store the number of subkeys */ - - len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys); - - /* pack all the strings */ - - for (i=0; i<num_subkeys; i++) { - len += tdb_pack(buffer+len, buflen-len, "f", subkeys[i]); - if ( len > buflen ) { - /* allocate some extra space */ - if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) { - DEBUG(0,("store_reg_keys: Failed to realloc memory of size [%d]\n", len*2)); - ret = False; - goto done; - } - buffer = tmpbuf; - buflen = len*2; - - len = tdb_pack(buffer+len, buflen-len, "f", subkeys[i]); - } - } - - /* finally write out the data */ - - kbuf.dptr = keyname; - kbuf.dsize = strlen(keyname)+1; - dbuf.dptr = buffer; - dbuf.dsize = len; - if ( tdb_store( tdb, kbuf, dbuf, TDB_REPLACE ) == -1) { - ret = False; - goto done; - } - -done: - SAFE_FREE( buffer ); - return ret; -} - -/*********************************************************************** - Retrieve an array of strings containing subkeys. Memory should be - released by the caller. The subkeys are stored in a catenated string - of null terminated character strings - ***********************************************************************/ - -static int fetch_reg_keys( TDB_CONTEXT *tdb, char* key, char **subkeys ) -{ - pstring path; - uint32 num_items; - TDB_DATA dbuf; - char *buf; - uint32 buflen, len; - int i; - char *s; - - - pstrcpy( path, key ); - - /* convert to key format */ - pstring_sub( path, "\\", "/" ); - - dbuf = tdb_fetch_by_string( tdb, path ); - - buf = dbuf.dptr; - buflen = dbuf.dsize; - - if ( !buf ) { - DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key)); - return 0; - } - - len = tdb_unpack( buf, buflen, "d", &num_items); - if (num_items) { - if ( (*subkeys = (char*)malloc(sizeof(fstring)*num_items)) == NULL ) { - DEBUG(0,("fetch_reg_keys: Failed to malloc memory for subkey array containing [%d] items!\n", - num_items)); - num_items = -1; - goto done; - } - } - - s = *subkeys; - for (i=0; i<num_items; i++) { - len += tdb_unpack( buf+len, buflen-len, "f", s ); - s += strlen(s) + 1; - } - -done: - SAFE_FREE(dbuf.dptr); - return num_items; -} - -/*********************************************************************** - count the number of subkeys dtored in the registry - ***********************************************************************/ - -static int fetch_reg_keys_count( TDB_CONTEXT *tdb, char* key ) -{ - pstring path; - uint32 num_items; - TDB_DATA dbuf; - char *buf; - uint32 buflen, len; - - - pstrcpy( path, key ); - - /* convert to key format */ - pstring_sub( path, "\\", "/" ); - - dbuf = tdb_fetch_by_string( tdb, path ); - - buf = dbuf.dptr; - buflen = dbuf.dsize; - - if ( !buf ) { - DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key)); - return 0; - } - - len = tdb_unpack( buf, buflen, "d", &num_items); - - SAFE_FREE( buf ); - - return num_items; -} - -/*********************************************************************** - retreive a specific subkey specified by index. The subkey parameter - is assumed to be an fstring. - ***********************************************************************/ - -static BOOL fetch_reg_keys_specific( TDB_CONTEXT *tdb, char* key, char* subkey, - uint32 key_index ) -{ - int num_subkeys, i; - char *subkeys = NULL; - char *s; - - num_subkeys = fetch_reg_keys( tdb_reg, key, &subkeys ); - if ( num_subkeys == -1 ) - return False; - - s = subkeys; - for ( i=0; i<num_subkeys; i++ ) { - /* copy the key if the index matches */ - if ( i == key_index ) { - fstrcpy( subkey, s ); - break; - } - - /* go onto the next string */ - s += strlen(s) + 1; - } - - SAFE_FREE(subkeys); - - return True; -} - - -/*********************************************************************** - Open the registry database - ***********************************************************************/ - -static BOOL init_registry_data( TDB_CONTEXT* registry_tdb ) -{ - pstring keyname; - char *subkeys[3]; - - /* HKEY_LOCAL_MACHINE */ - - pstrcpy( keyname, KEY_HKLM ); - subkeys[0] = "SYSTEM"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM" ); - subkeys[0] = "CurrentControlSet"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet" ); - subkeys[0] = "Control"; - subkeys[1] = "services"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 2 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" ); - subkeys[0] = "Print"; - subkeys[1] = "ProduceOptions"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 2 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/Print" ); - subkeys[0] = "Environments"; - subkeys[1] = "Forms"; - subkeys[2] = "Printers"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 3 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" ); - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 0 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet/services" ); - subkeys[0] = "Netlogon"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon" ); - subkeys[0] = "parameters"; - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 1 )) - return False; - - pstrcpy( keyname, KEY_HKLM ); - pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon/parameters" ); - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 0 )) - return False; - - - /* HKEY_USER */ - - pstrcpy( keyname, KEY_HKU ); - if ( !store_reg_keys( registry_tdb, keyname, subkeys, 0 ) ) - return False; - - return True; -} - -/*********************************************************************** - Open the registry database - ***********************************************************************/ - -BOOL init_registry( void ) -{ - static pid_t local_pid; - - - if (tdb_reg && local_pid == sys_getpid()) - return True; - - /* - * try to open first without creating so we can determine - * if we need to init the data in the registry - */ - - tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); - if ( !tdb_reg ) - { - tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - if ( !tdb_reg ) { - DEBUG(0,("init_registry: Failed to open registry %s (%s)\n", - lock_path("registry.tdb"), strerror(errno) )); - return False; - } - - DEBUG(10,("init_registry: Successfully created registry tdb\n")); - - /* create the registry here */ - if ( !init_registry_data( tdb_reg ) ) { - DEBUG(0,("init_registry: Failed to initiailize data in registry!\n")); - return False; - } - } - - local_pid = sys_getpid(); - - return True; -} - -/****************************************************************** - Find a registry key handle and return a Registry_Key - *****************************************************************/ - -static Registry_Key *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) -{ - Registry_Key *regkey = NULL; - - if(!find_policy_by_hnd(p,hnd,(void **)®key)) { - DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: ")); - return NULL; - } +}; - return regkey; -} - - -/****************************************************************** - free() function for Registry_Key - *****************************************************************/ - static void free_reg_info(void *ptr) { - Registry_Key *info = (Registry_Key*)ptr; - - DLIST_REMOVE(regkeys_list, info); + struct reg_info *info = (struct reg_info *)ptr; SAFE_FREE(info); } /******************************************************************* - Function for open a new registry handle and creating a handle - Note that P should be valid & hnd should already have space - *******************************************************************/ - -static BOOL open_registry_key(pipes_struct *p, POLICY_HND *hnd, char *name, - uint32 access_granted) -{ - Registry_Key *regkey = NULL; - - DEBUG(7,("open_registry_key: name = [%s]\n", name)); - - /* All registry keys **must** have a name of non-zero length */ - - if (!name || !*name ) - return False; - - if ((regkey=(Registry_Key*)malloc(sizeof(Registry_Key))) == NULL) - return False; - - ZERO_STRUCTP( regkey ); - - DLIST_ADD( regkeys_list, regkey ); - - /* copy the name and obtain a handle */ - - fstrcpy( regkey->name, name ); - - DEBUG(7,("open_registry_key: exit\n")); - - return create_policy_hnd( p, hnd, free_reg_info, regkey ); -} - -/******************************************************************* - Function for open a new registry handle and creating a handle - Note that P should be valid & hnd should already have space - *******************************************************************/ - -static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd) -{ - Registry_Key *regkey = find_regkey_index_by_hnd(p, hnd); - - if ( !regkey ) { - DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); - return False; - } - - close_policy_hnd(p, hnd); - - return True; -} - -/******************************************************************** - retrieve information about the subkeys - *******************************************************************/ - -static BOOL get_subkey_information( Registry_Key *key, uint32 *maxnum, uint32 *maxlen ) -{ - int num_subkeys, i; - uint32 max_len; - char *subkeys = NULL; - uint32 len; - char *s; - - if ( !key ) - return False; - - num_subkeys = fetch_reg_keys( tdb_reg, key->name, &subkeys ); - if ( num_subkeys == -1 ) - return False; - - /* find the longest string */ - - max_len = 0; - s = subkeys; - for ( i=0; i<num_subkeys; i++ ) { - len = strlen(s); - max_len = MAX(max_len, len); - s += len + 1; - } - - *maxnum = num_subkeys; - *maxlen = max_len*2; - - SAFE_FREE(subkeys); - - return True; -} - -/******************************************************************** - retrieve information about the values. We don't store values - here. The registry tdb is intended to be a frontend to oether - Samba tdb's (such as ntdrivers.tdb). - *******************************************************************/ - -static BOOL get_value_information( Registry_Key *key, uint32 *maxnum, - uint32 *maxlen, uint32 *maxsize ) -{ - if ( !key ) - return False; - - /* Hard coded key names first */ - /* nothing has valuies right now */ - - *maxnum = 0; - *maxlen = 0; - *maxsize = 0; - return True; - -#if 0 /* JERRY */ - /* - * FIXME!!! Need to add routines to look up values in other - * databases --jerry - */ - - return False; -#endif -} - -/******************************************************************** - reg_close + reg_reply_unknown_1 ********************************************************************/ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) @@ -508,7 +48,7 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) ZERO_STRUCT(r_u->pol); /* close the policy handle */ - if (!close_registry_key(p, &q_u->pol)) + if (!close_policy_hnd(p, &q_u->pol)) return NT_STATUS_OBJECT_NAME_INVALID; return NT_STATUS_OK; @@ -518,21 +58,9 @@ NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u) reg_reply_open ********************************************************************/ -NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u) -{ - if (!open_registry_key(p, &r_u->pol, KEY_HKLM, 0x0)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - - return NT_STATUS_OK; -} - -/******************************************************************* - reg_reply_open - ********************************************************************/ - -NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u) +NTSTATUS _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u) { - if (!open_registry_key(p, &r_u->pol, KEY_HKU, 0x0)) + if (!create_policy_hnd(p, &r_u->pol, free_reg_info, NULL)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return NT_STATUS_OK; @@ -546,36 +74,34 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR { POLICY_HND pol; fstring name; - pstring path; - int num_subkeys; - Registry_Key *key = find_regkey_index_by_hnd(p, &q_u->pol); + struct reg_info *info = NULL; - DEBUG(5,("reg_open_entry: Enter\n")); + DEBUG(5,("reg_open_entry: %d\n", __LINE__)); - if ( !key ) + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) return NT_STATUS_INVALID_HANDLE; rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0); - /* store the full path in the regkey_list */ - - pstrcpy( path, key->name ); - pstrcat( path, "\\" ); - pstrcat( path, name ); + DEBUG(5,("reg_open_entry: %s\n", name)); - DEBUG(5,("reg_open_entry: %s\n", path)); + /* lkcl XXXX do a check on the name, here */ + if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions") && + !strequal(name, "System\\CurrentControlSet\\services\\Netlogon\\parameters\\")) + return NT_STATUS_ACCESS_DENIED; - /* do a check on the name, here */ - - if ( (num_subkeys=fetch_reg_keys_count( tdb_reg, path )) == -1 ) - return NT_STATUS_ACCESS_DENIED; + if ((info = (struct reg_info *)malloc(sizeof(struct reg_info))) == NULL) + return NT_STATUS_NO_MEMORY; - if (!open_registry_key(p, &pol, path, 0x0)) - return NT_STATUS_TOO_MANY_SECRETS; + ZERO_STRUCTP(info); + fstrcpy(info->name, name); + + if (!create_policy_hnd(p, &pol, free_reg_info, (void *)info)) + return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */ init_reg_r_open_entry(r_u, &pol, NT_STATUS_OK); - DEBUG(5,("reg_open_entry: Exitn")); + DEBUG(5,("reg_open_entry: %d\n", __LINE__)); return r_u->status; } @@ -587,23 +113,21 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) { NTSTATUS status = NT_STATUS_OK; - char *value = NULL; - uint32 type = 0x1; /* key type: REG_SZ */ + char *key = NULL; + uint32 type=0x1; /* key type: REG_SZ */ + UNISTR2 *uni_key = NULL; BUFFER2 *buf = NULL; fstring name; - Registry_Key *key = find_regkey_index_by_hnd( p, &q_u->pol ); - DEBUG(5,("_reg_info: Enter\n")); + DEBUG(5,("_reg_info: %d\n", __LINE__)); - if ( !key ) + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) return NT_STATUS_INVALID_HANDLE; - - DEBUG(7,("_reg_info: policy key name = [%s]\n", key->name)); rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0); - DEBUG(5,("reg_info: checking subkey: %s\n", name)); + DEBUG(5,("reg_info: checking key: %s\n", name)); uni_key = (UNISTR2 *)talloc_zero(p->mem_ctx, sizeof(UNISTR2)); buf = (BUFFER2 *)talloc_zero(p->mem_ctx, sizeof(BUFFER2)); @@ -623,126 +147,33 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u) } switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - value = "LanmanNT"; - break; - case ROLE_STANDALONE: - value = "ServerNT"; - break; - case ROLE_DOMAIN_MEMBER: - value = "WinNT"; - break; + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + key = "LanmanNT"; + break; + case ROLE_STANDALONE: + key = "ServerNT"; + break; + case ROLE_DOMAIN_MEMBER: + key = "WinNT"; + break; } /* This makes the server look like a member server to clients */ /* which tells clients that we have our own local user and */ /* group databases and helps with ACL support. */ - init_unistr2(uni_key, value, strlen(value)+1); + init_unistr2(uni_key, key, strlen(key)+1); init_buffer2(buf, (uint8*)uni_key->buffer, uni_key->uni_str_len*2); out: init_reg_r_info(q_u->ptr_buf, r_u, buf, type, status); - DEBUG(5,("reg_open_entry: Exit\n")); - - return status; -} - - -/***************************************************************************** - Implementation of REG_QUERY_KEY - ****************************************************************************/ - -NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_u) -{ - NTSTATUS status = NT_STATUS_OK; - Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); - - DEBUG(5,("_reg_query_key: Enter\n")); - - if ( !regkey ) - return NT_STATUS_INVALID_HANDLE; - - if ( !get_subkey_information( regkey, &r_u->num_subkeys, &r_u->max_subkeylen ) ) - return NT_STATUS_ACCESS_DENIED; - - if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) ) - return NT_STATUS_ACCESS_DENIED; - - r_u->sec_desc = 0x00000078; /* size for key's sec_desc */ - - /* Win9x set this to 0x0 since it does not keep timestamps. - Doing the same here for simplicity --jerry */ - - ZERO_STRUCT(r_u->mod_time); - - DEBUG(5,("_reg_query_key: Exit\n")); - - return status; -} - - -/***************************************************************************** - Implementation of REG_UNKNOWN_1A - ****************************************************************************/ - -NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u) -{ - NTSTATUS status = NT_STATUS_OK; - Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); - - DEBUG(5,("_reg_unknown_1a: Enter\n")); - - if ( !regkey ) - return NT_STATUS_INVALID_HANDLE; - - r_u->unknown = 0x00000005; /* seems to be consistent...no idea what it means */ - - DEBUG(5,("_reg_unknown_1a: Exit\n")); - - return status; -} - + DEBUG(5,("reg_open_entry: %d\n", __LINE__)); -/***************************************************************************** - Implementation of REG_ENUM_KEY - ****************************************************************************/ - -NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u) -{ - NTSTATUS status = NT_STATUS_OK; - Registry_Key *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); - fstring subkey; - - - DEBUG(5,("_reg_enum_key: Enter\n")); - - if ( !regkey ) - return NT_STATUS_INVALID_HANDLE; - - DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name)); - - if ( !fetch_reg_keys_specific( tdb_reg, regkey->name, subkey, q_u->key_index ) ) - { - status = werror_to_ntstatus( WERR_NO_MORE_ITEMS ); - goto done; - } - - DEBUG(10,("_reg_enum_key: retrieved subkey named [%s]\n", subkey)); - - /* subkey has the string name now */ - - init_reg_r_enum_key( r_u, subkey, q_u->unknown_1, q_u->unknown_2 ); - - DEBUG(5,("_reg_enum_key: Exit\n")); - -done: return status; } - /******************************************************************* reg_shutdwon ********************************************************************/ @@ -788,10 +219,6 @@ NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u return status; } -/******************************************************************* - reg_abort_shutdwon - ********************************************************************/ - NTSTATUS _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u) { NTSTATUS status = NT_STATUS_OK; @@ -807,5 +234,3 @@ NTSTATUS _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_A return status; } - - diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index f002a7d1c9..c555305bce 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -32,9 +32,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /******************************************************************* api_samr_close_hnd ********************************************************************/ @@ -127,37 +124,6 @@ static BOOL api_samr_get_usrdom_pwinfo(pipes_struct *p) } /******************************************************************* - api_samr_set_sec_obj - ********************************************************************/ - -static BOOL api_samr_set_sec_obj(pipes_struct *p) -{ - SAMR_Q_SET_SEC_OBJ q_u; - SAMR_R_SET_SEC_OBJ 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(!samr_io_q_set_sec_obj("", &q_u, data, 0)) { - DEBUG(0,("api_samr_set_sec_obj: unable to unmarshall SAMR_Q_SET_SEC_OBJ.\n")); - return False; - } - - r_u.status = _samr_set_sec_obj(p, &q_u, &r_u); - - if(!samr_io_r_set_sec_obj("", &r_u, rdata, 0)) { - DEBUG(0,("api_samr_set_sec_obj: unable to marshall SAMR_R_SET_SEC_OBJ.\n")); - return False; - } - - - return True; -} - -/******************************************************************* api_samr_query_sec_obj ********************************************************************/ @@ -1461,7 +1427,6 @@ static struct api_struct api_samr_cmds [] = {"SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain }, {"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj }, - {"SAMR_SET_SEC_OBJECT" , SAMR_SET_SEC_OBJECT , api_samr_set_sec_obj }, {"SAMR_GET_USRDOM_PWINFO" , SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo}, {"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e }, {"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info }, diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 88d728d810..106d7c1923 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -29,11 +29,9 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - extern fstring global_myworkgroup; extern pstring global_myname; +extern DOM_SID global_sam_sid; extern DOM_SID global_sid_Builtin; extern rid_name domain_group_rids[]; @@ -54,69 +52,9 @@ struct samr_info { /* for use by the \PIPE\samr policy */ DOM_SID sid; uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ - uint32 acc_granted; DISP_INFO disp_info; - - TALLOC_CTX *mem_ctx; }; -struct generic_mapping sam_generic_mapping = {SAMR_READ, SAMR_WRITE, SAMR_EXECUTE, SAMR_ALL_ACCESS}; -struct generic_mapping dom_generic_mapping = {DOMAIN_READ, DOMAIN_WRITE, DOMAIN_EXECUTE, DOMAIN_ALL_ACCESS}; -struct generic_mapping usr_generic_mapping = {USER_READ, USER_WRITE, USER_EXECUTE, USER_ALL_ACCESS}; -struct generic_mapping grp_generic_mapping = {GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, GROUP_ALL_ACCESS}; -struct generic_mapping ali_generic_mapping = {ALIAS_READ, ALIAS_WRITE, ALIAS_EXECUTE, ALIAS_ALL_ACCESS}; - -static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *d_size); - - -/******************************************************************* - Checks if access to an object should be granted, and returns that - level of access for further checks. -********************************************************************/ - -NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access, - uint32 *acc_granted, const char *debug) -{ - NTSTATUS status = NT_STATUS_ACCESS_DENIED; - - if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) { - if (geteuid() == sec_initial_uid()) { - DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", - debug, des_access)); - DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n")); - status = NT_STATUS_OK; - } - else { - DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n", - debug, des_access)); - } - } - return status; -} - -/******************************************************************* - Checks if access to a function can be granted -********************************************************************/ - -NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug) -{ - DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n", - debug, acc_granted, acc_required)); - if ((acc_granted & acc_required) != acc_required) { - if (geteuid() == sec_initial_uid()) { - DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n", - debug, acc_granted, acc_required)); - DEBUGADD(4,("but overwritten by euid == 0\n")); - return NT_STATUS_OK; - } - DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n", - debug, acc_granted, acc_required)); - return NT_STATUS_ACCESS_DENIED; - } - return NT_STATUS_OK; -} - - /******************************************************************* Create a samr_info struct. ********************************************************************/ @@ -125,27 +63,17 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid) { struct samr_info *info; fstring sid_str; - TALLOC_CTX *mem_ctx; - - if (psid) { - sid_to_string(sid_str, psid); - } else { - fstrcpy(sid_str,"(NULL)"); - } - - mem_ctx = talloc_init_named("samr_info for domain sid %s", sid_str); - if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL) + if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) return NULL; ZERO_STRUCTP(info); - DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str)); if (psid) { + DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) )); sid_copy( &info->sid, psid); } else { DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n")); } - info->mem_ctx = mem_ctx; return info; } @@ -156,13 +84,18 @@ static void free_samr_db(struct samr_info *info) { int i; - /* Groups are talloced */ + if (info->disp_info.group_dbloaded) { + for (i=0; i<info->disp_info.num_group_account; i++) + SAFE_FREE(info->disp_info.disp_group_info[i].grp); + + SAFE_FREE(info->disp_info.disp_group_info); + } if (info->disp_info.user_dbloaded){ - for (i=0; i<info->disp_info.num_user_account; i++) { - /* Not really a free, actually a 'clear' */ + for (i=0; i<info->disp_info.num_user_account; i++) pdb_free_sam(&info->disp_info.disp_user_info[i].sam); - } + + SAFE_FREE(info->disp_info.disp_user_info); } info->disp_info.user_dbloaded=False; @@ -177,13 +110,26 @@ static void free_samr_info(void *ptr) struct samr_info *info=(struct samr_info *) ptr; free_samr_db(info); - talloc_destroy(info->mem_ctx); + SAFE_FREE(info); } /******************************************************************* Ensure password info is never given out. Paranioa... JRA. ********************************************************************/ +static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries) +{ + int i; + + if (!pass) + return; + + for (i = 0; i < num_entries; i++) { + memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd)); + memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd)); + } +} + static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass) { @@ -201,8 +147,6 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) { SAM_ACCOUNT *pwd = NULL; DISP_USER_INFO *pwd_array = NULL; - NTSTATUS nt_status = NT_STATUS_OK; - TALLOC_CTX *mem_ctx = info->mem_ctx; DEBUG(10,("load_sampwd_entries\n")); @@ -217,8 +161,7 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) return NT_STATUS_ACCESS_DENIED; } - for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) - && pdb_getsampwent(pwd) == True; pwd=NULL) { + for (pdb_init_sam(&pwd); pdb_getsampwent(pwd) == True; pwd=NULL, pdb_init_sam(&pwd) ) { if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) { pdb_free_sam(&pwd); @@ -230,7 +173,7 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) { DEBUG(10,("load_sampwd_entries: allocating more memory\n")); - pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info, + pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info, (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO)); if (pwd_array==NULL) @@ -255,7 +198,7 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask) DEBUG(12,("load_sampwd_entries: done\n")); - return nt_status; + return NT_STATUS_OK; } static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) @@ -264,7 +207,6 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) DISP_GROUP_INFO *grp_array = NULL; uint32 group_entries = 0; uint32 i; - TALLOC_CTX *mem_ctx = info->mem_ctx; DEBUG(10,("load_group_domain_entries\n")); @@ -274,13 +216,11 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) return NT_STATUS_OK; } - if (!enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) { - return NT_STATUS_NO_MEMORY; - } + enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV); info->disp_info.num_group_account=group_entries; - grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO)); + grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO)); if (group_entries!=0 && grp_array==NULL) { SAFE_FREE(map); @@ -291,7 +231,7 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) for (i=0; i<group_entries; i++) { - grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP)); + grp_array[i].grp=(DOMAIN_GRP *)malloc(sizeof(DOMAIN_GRP)); fstrcpy(grp_array[i].grp->name, map[i].nt_name); fstrcpy(grp_array[i].grp->comment, map[i].comment); @@ -312,6 +252,84 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid) /******************************************************************* + This next function should be replaced with something that + dynamically returns the correct user info..... JRA. + ********************************************************************/ + +static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, + int *total_entries, int *num_entries, + int max_num_entries, uint16 acb_mask) +{ + SAM_ACCOUNT *pwd = NULL; + BOOL not_finished = True; + + (*num_entries) = 0; + (*total_entries) = 0; + + if (pw_buf == NULL) + return NT_STATUS_NO_MEMORY; + + pdb_init_sam(&pwd); + + if (!pdb_setsampwent(False)) { + DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n")); + pdb_free_sam(&pwd); + return NT_STATUS_ACCESS_DENIED; + } + + while (((not_finished = pdb_getsampwent(pwd)) != False) + && (*num_entries) < max_num_entries) + { + int user_name_len; + + if (start_idx > 0) { + + pdb_reset_sam(pwd); + + /* skip the requested number of entries. + not very efficient, but hey... */ + start_idx--; + continue; + } + + user_name_len = strlen(pdb_get_username(pwd))+1; + init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len); + init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len); + pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd); + memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16); + + /* Now check if the NT compatible password is available. */ + if (pdb_get_nt_passwd(pwd)) + memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16); + + pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd); + + DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x", + (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) )); + + if (acb_mask == 0 || (pdb_get_acct_ctrl(pwd) & acb_mask)) { + DEBUG(5,(" acb_mask %x accepts\n", acb_mask)); + (*num_entries)++; + } else { + DEBUG(5,(" acb_mask %x rejects\n", acb_mask)); + } + + (*total_entries)++; + + pdb_reset_sam(pwd); + + } + + pdb_endsampwent(); + pdb_free_sam(&pwd); + + if (not_finished) + return STATUS_MORE_ENTRIES; + else + return NT_STATUS_OK; +} + +/******************************************************************* _samr_close_hnd ********************************************************************/ @@ -334,37 +352,17 @@ NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HN NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u) { - struct samr_info *info; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access = q_u->flags; - size_t sd_size; - NTSTATUS status; + struct samr_info *info; r_u->status = NT_STATUS_OK; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info)) + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) return NT_STATUS_INVALID_HANDLE; - if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SAMR_ACCESS_OPEN_DOMAIN,"_samr_open_domain"))) { - return status; - } - - /*check if access can be granted as requested by client. */ - samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size); - se_map_generic(&des_access,&dom_generic_mapping); - - if (!NT_STATUS_IS_OK(status = - access_check_samr_object(psd, p->pipe_user.nt_user_token, - des_access, &acc_granted, "_samr_open_domain"))) { - return status; - } - /* associate the domain SID with the (unique) handle. */ if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL) return NT_STATUS_NO_MEMORY; - info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info)) @@ -404,90 +402,11 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, return r_u->status; } - -/******************************************************************* - samr_make_sam_obj_sd - ********************************************************************/ - -static NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) -{ - extern DOM_SID global_sid_World; - DOM_SID adm_sid; - DOM_SID act_sid; - - SEC_ACE ace[3]; - SEC_ACCESS mask; - - SEC_ACL *psa = NULL; - - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - sid_copy(&act_sid, &global_sid_Builtin); - sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); - - /*basic access for every one*/ - init_sec_access(&mask, SAMR_EXECUTE | SAMR_READ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /*full access for builtin aliases Administrators and Account Operators*/ - init_sec_access(&mask, SAMR_ALL_ACCESS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) - return NT_STATUS_NO_MEMORY; - - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) - return NT_STATUS_NO_MEMORY; - - return NT_STATUS_OK; -} - -/******************************************************************* - samr_make_dom_obj_sd - ********************************************************************/ - -static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) -{ - extern DOM_SID global_sid_World; - DOM_SID adm_sid; - DOM_SID act_sid; - - SEC_ACE ace[3]; - SEC_ACCESS mask; - - SEC_ACL *psa = NULL; - - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - sid_copy(&act_sid, &global_sid_Builtin); - sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); - - /*basic access for every one*/ - init_sec_access(&mask, DOMAIN_EXECUTE | DOMAIN_READ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /*full access for builtin aliases Administrators and Account Operators*/ - init_sec_access(&mask, DOMAIN_ALL_ACCESS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) - return NT_STATUS_NO_MEMORY; - - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) - return NT_STATUS_NO_MEMORY; - - return NT_STATUS_OK; -} - /******************************************************************* samr_make_usr_obj_sd ********************************************************************/ -static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid) +static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid) { extern DOM_SID global_sid_World; DOM_SID adm_sid; @@ -497,6 +416,8 @@ static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd SEC_ACCESS mask; SEC_ACL *psa = NULL; + SEC_DESC *psd = NULL; + size_t sd_size; sid_copy(&adm_sid, &global_sid_Builtin); sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); @@ -504,107 +425,29 @@ static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd sid_copy(&act_sid, &global_sid_Builtin); sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); - /*basic access for every one*/ - init_sec_access(&mask, USER_EXECUTE | USER_READ); + init_sec_access(&mask, 0x2035b); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - /*full access for builtin aliases Administrators and Account Operators*/ - init_sec_access(&mask, USER_ALL_ACCESS); + init_sec_access(&mask, 0xf07ff); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - /*extended access for the user*/ - init_sec_access(&mask,READ_CONTROL_ACCESS | USER_ACCESS_CHANGE_PASSWORD | USER_ACCESS_SET_LOC_COM); + init_sec_access(&mask,0x20044); init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL) - return NT_STATUS_NO_MEMORY; - - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) + if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL) return NT_STATUS_NO_MEMORY; - return NT_STATUS_OK; -} - -/******************************************************************* - samr_make_grp_obj_sd - ********************************************************************/ - -static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) -{ - extern DOM_SID global_sid_World; - DOM_SID adm_sid; - DOM_SID act_sid; - - SEC_ACE ace[3]; - SEC_ACCESS mask; - - SEC_ACL *psa = NULL; - - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - sid_copy(&act_sid, &global_sid_Builtin); - sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); - - /*basic access for every one*/ - init_sec_access(&mask, GROUP_EXECUTE | GROUP_READ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /*full access for builtin aliases Administrators and Account Operators*/ - init_sec_access(&mask, GROUP_ALL_ACCESS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) + if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL) return NT_STATUS_NO_MEMORY; - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) + if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; } -/******************************************************************* - samr_make_ali_obj_sd - ********************************************************************/ - -static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) -{ - extern DOM_SID global_sid_World; - DOM_SID adm_sid; - DOM_SID act_sid; - - SEC_ACE ace[3]; - SEC_ACCESS mask; - - SEC_ACL *psa = NULL; - - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - - sid_copy(&act_sid, &global_sid_Builtin); - sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS); - - /*basic access for every one*/ - init_sec_access(&mask, ALIAS_EXECUTE | ALIAS_READ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /*full access for builtin aliases Administrators and Account Operators*/ - init_sec_access(&mask, ALIAS_ALL_ACCESS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) - return NT_STATUS_NO_MEMORY; - - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL) - return NT_STATUS_NO_MEMORY; - - return NT_STATUS_OK; -} - -static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted) +static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid) { struct samr_info *info = NULL; @@ -616,22 +459,10 @@ static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *s return False; *sid = info->sid; - *acc_granted = info->acc_granted; return True; } /******************************************************************* - _samr_set_sec_obj - ********************************************************************/ - -NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u) -{ - DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - - -/******************************************************************* _samr_query_sec_obj ********************************************************************/ @@ -639,52 +470,17 @@ NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_ { DOM_SID pol_sid; fstring str_sid; - SEC_DESC * psd = NULL; - size_t sd_size; - uint32 acc_granted; r_u->status = NT_STATUS_OK; /* Get the SID. */ - if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted)) - return NT_STATUS_INVALID_HANDLE; - + if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid)) + return NT_STATUS_INVALID_HANDLE; DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid))); - /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */ - - /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */ - if (pol_sid.sid_rev_num == 0) - { - DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n")); - r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size); - } - else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */ - - { - DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); - r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size); - } - else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */ - { - /* TODO: Builtin probably needs a different SD with restricted write access*/ - DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); - r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size); - } - else if (sid_check_is_in_our_domain(&pol_sid) || - sid_check_is_in_builtin(&pol_sid)) - { - /* TODO: different SDs have to be generated for aliases groups and users. - Currently all three get a default user SD */ - DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid))); - r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid); - } - else return NT_STATUS_OBJECT_TYPE_MISMATCH; - - if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) - return NT_STATUS_NO_MEMORY; + r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid); if (NT_STATUS_IS_OK(r_u->status)) r_u->ptr = 1; @@ -696,123 +492,69 @@ NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_ makes a SAM_ENTRY / UNISTR2* structure from a user list. ********************************************************************/ -static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp, - uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info, - DOM_SID *domain_sid) +static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp, + uint32 num_sam_entries, SAM_USER_INFO_21 *pass) { uint32 i; SAM_ENTRY *sam; UNISTR2 *uni_name; - SAM_ACCOUNT *pwd = NULL; - UNISTR2 uni_temp_name; - const char *temp_name; - const DOM_SID *user_sid; - uint32 user_rid; - fstring user_sid_string; - fstring domain_sid_string; - + *sam_pp = NULL; *uni_name_pp = NULL; - if (num_entries == 0) - return NT_STATUS_OK; + if (num_sam_entries == 0) + return; - sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries); + sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries); - uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries); + uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries); if (sam == NULL || uni_name == NULL) { - DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n")); - return NT_STATUS_NO_MEMORY; + DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n")); + return; } - for (i = 0; i < num_entries; i++) { - int len = uni_temp_name.uni_str_len; - - pwd = disp_user_info[i+start_idx].sam; - temp_name = pdb_get_username(pwd); - init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1); - user_sid = pdb_get_user_sid(pwd); - - if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { - DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with " - "the domain sid %s. Failing operation.\n", - temp_name, - sid_to_string(user_sid_string, user_sid), - sid_to_string(domain_sid_string, domain_sid))); - return NT_STATUS_UNSUCCESSFUL; - } + ZERO_STRUCTP(sam); + ZERO_STRUCTP(uni_name); + + for (i = 0; i < num_sam_entries; i++) { + int len = pass[i].uni_user_name.uni_str_len; - init_sam_entry(&sam[i], len, user_rid); - copy_unistr2(&uni_name[i], &uni_temp_name); + init_sam_entry(&sam[i], len, pass[i].user_rid); + copy_unistr2(&uni_name[i], &pass[i].uni_user_name); } *sam_pp = sam; *uni_name_pp = uni_name; - return NT_STATUS_OK; } /******************************************************************* samr_reply_enum_dom_users ********************************************************************/ -NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, - SAMR_R_ENUM_DOM_USERS *r_u) +NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u) { - struct samr_info *info = NULL; - uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */ - int num_account; - uint32 enum_context=q_u->start_idx; - uint32 max_size=q_u->max_size; - uint32 temp_size; - enum remote_arch_types ra_type = get_remote_arch(); - int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K; - uint32 max_entries = max_sam_entries; - DOM_SID domain_sid; + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]; + int num_entries = 0; + int total_entries = 0; r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) + if (!find_policy_by_hnd(p, &q_u->pol, NULL)) return NT_STATUS_INVALID_HANDLE; - domain_sid = info->sid; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, - DOMAIN_ACCESS_ENUM_ACCOUNTS, - "_samr_enum_dom_users"))) { - return r_u->status; - } - DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); become_root(); - r_u->status=load_sampwd_entries(info, q_u->acb_mask); + r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + MAX_SAM_ENTRIES, q_u->acb_mask); unbecome_root(); - - if (!NT_STATUS_IS_OK(r_u->status)) - return r_u->status; - - num_account = info->disp_info.num_user_account; - if (enum_context > num_account) { - DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n")); - return NT_STATUS_OK; - } + if (NT_STATUS_IS_ERR(r_u->status)) + return r_u->status; - /* verify we won't overflow */ - if (max_entries > num_account-enum_context) { - max_entries = num_account-enum_context; - DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries)); - } - - /* calculate the size and limit on the number of entries we will return */ - temp_size=max_entries*struct_size; - - if (temp_size>max_size) { - max_entries=MIN((max_size/struct_size),max_entries);; - DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries)); - } + samr_clear_passwd_fields(pass, num_entries); /* * Note from JRA. total_entries is not being used here. Currently if there is a @@ -827,20 +569,9 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, * value (again I think this is wrong). */ - r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, - max_entries, enum_context, - info->disp_info.disp_user_info, - &domain_sid); + make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass); - if (!NT_STATUS_IS_OK(r_u->status)) - return r_u->status; - - if (enum_context+max_entries < num_account) - r_u->status = STATUS_MORE_ENTRIES; - - DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__)); - - init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries); + init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries); DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); @@ -923,12 +654,13 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM } SAFE_FREE(map); - } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) { + } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) { struct sys_grent *glist; struct sys_grent *grp; struct passwd *pw; gid_t winbind_gid_low, winbind_gid_high; - BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high); + + lp_winbind_gid(&winbind_gid_low, &winbind_gid_high); /* local aliases */ /* we return the UNIX groups here. This seems to be the right */ @@ -958,15 +690,24 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM continue; /* Don't return winbind groups as they are not local! */ - if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) { + if ((grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) { DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name )); continue; } /* Don't return user private groups... */ + + /* + * We used to do a Get_Pwnam() here, but this has been + * trimmed back to the common case for private groups + * to save lookups and to use the _alloc interface. + * + * This also matches the group mapping code + */ - if ((pw = Get_Pwnam(smap.nt_name)) != 0) { + if ((pw = getpwnam_alloc(smap.nt_name)) != 0) { DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name )); + passwd_free(&pw); continue; } @@ -1067,16 +808,11 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM DOMAIN_GRP *grp=NULL; uint32 num_entries; DOM_SID sid; - uint32 acc_granted; r_u->status = NT_STATUS_OK; - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) { - return r_u->status; - } DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__)); @@ -1104,17 +840,12 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S fstring sid_str; DOM_SID sid; NTSTATUS status; - uint32 acc_granted; r_u->status = NT_STATUS_OK; - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid)) return NT_STATUS_INVALID_HANDLE; - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) { - return r_u->status; - } - sid_to_string(sid_str, &sid); DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str)); @@ -1136,8 +867,7 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S /******************************************************************* samr_reply_query_dispinfo ********************************************************************/ -NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, - SAMR_R_QUERY_DISPINFO *r_u) +NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u) { struct samr_info *info = NULL; uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */ @@ -1152,8 +882,9 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, NTSTATUS disp_ret; uint32 num_account = 0; enum remote_arch_types ra_type = get_remote_arch(); - int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K; - DOM_SID domain_sid; + int max_sam_entries; + + max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K; DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__)); r_u->status = NT_STATUS_OK; @@ -1162,8 +893,6 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - domain_sid = info->sid; - /* * calculate how many entries we will return. * based on @@ -1207,7 +936,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, become_root(); r_u->status=load_sampwd_entries(info, acb_mask); unbecome_root(); - if (!NT_STATUS_IS_OK(r_u->status)) { + if (NT_STATUS_IS_ERR(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n")); return r_u->status; } @@ -1216,7 +945,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, case 0x3: case 0x5: r_u->status = load_group_domain_entries(info, &info->sid); - if (!NT_STATUS_IS_OK(r_u->status)) + if (NT_STATUS_IS_ERR(r_u->status)) return r_u->status; num_account = info->disp_info.num_group_account; break; @@ -1233,7 +962,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, if (enum_context > num_account) { DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n")); - return NT_STATUS_NO_MORE_ENTRIES; + return NT_STATUS_OK; } /* verify we won't overflow */ @@ -1262,9 +991,8 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1)))) return NT_STATUS_NO_MEMORY; } - disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, - info->disp_info.disp_user_info, &domain_sid); - if (!NT_STATUS_IS_OK(disp_ret)) + disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info); + if (NT_STATUS_IS_ERR(disp_ret)) return disp_ret; break; case 0x2: @@ -1272,9 +1000,8 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2)))) return NT_STATUS_NO_MEMORY; } - disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, - info->disp_info.disp_user_info, &domain_sid); - if (!NT_STATUS_IS_OK(disp_ret)) + disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info); + if (NT_STATUS_IS_ERR(disp_ret)) return disp_ret; break; case 0x3: @@ -1283,7 +1010,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, return NT_STATUS_NO_MEMORY; } disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info); - if (!NT_STATUS_IS_OK(disp_ret)) + if (NT_STATUS_IS_ERR(disp_ret)) return disp_ret; break; case 0x4: @@ -1292,7 +1019,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, return NT_STATUS_NO_MEMORY; } disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info); - if (!NT_STATUS_IS_OK(disp_ret)) + if (NT_STATUS_IS_ERR(disp_ret)) return disp_ret; break; case 0x5: @@ -1301,7 +1028,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, return NT_STATUS_NO_MEMORY; } disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info); - if (!NT_STATUS_IS_OK(disp_ret)) + if (NT_STATUS_IS_ERR(disp_ret)) return disp_ret; break; @@ -1330,26 +1057,22 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u) { - DOM_SID sid; + struct samr_info *info = NULL; GROUP_MAP map; - uint32 acc_granted; r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_LOOKUP_INFO, "_samr_query_aliasinfo"))) { - return r_u->status; - } - if (!sid_check_is_in_our_domain(&sid) && - !sid_check_is_in_builtin(&sid)) + if (!sid_check_is_in_our_domain(&info->sid) && + !sid_check_is_in_builtin(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; - if (!get_local_group_from_sid(sid, &map, MAPPING_WITHOUT_PRIV)) + if(!get_local_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; switch (q_u->switch_level) { @@ -1446,7 +1169,6 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO int num_rids = q_u->num_names2; DOM_SID pol_sid; fstring sid_str; - uint32 acc_granted; r_u->status = NT_STATUS_OK; @@ -1455,14 +1177,10 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO ZERO_ARRAY(rid); ZERO_ARRAY(type); - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) { + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) { init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH); return r_u->status; } - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */ - return r_u->status; - } if (num_rids > MAX_SAM_ENTRIES) { num_rids = MAX_SAM_ENTRIES; @@ -1606,14 +1324,13 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK DOM_SID pol_sid; int num_rids = q_u->num_rids1; int i; - uint32 acc_granted; r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) return NT_STATUS_INVALID_HANDLE; if (num_rids > MAX_SAM_ENTRIES) { @@ -1639,7 +1356,7 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK group_attrs[i] = SID_NAME_UNKNOWN; *group_names[i] = '\0'; - if (sid_equal(&pol_sid, get_global_sam_sid())) { + if (sid_equal(&pol_sid, &global_sam_sid)) { sid_copy(&sid, &pol_sid); sid_append_rid(&sid, q_u->rid[i]); @@ -1673,58 +1390,42 @@ NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN SAM_ACCOUNT *sampass=NULL; DOM_SID sid; POLICY_HND domain_pol = q_u->domain_pol; + uint32 user_rid = q_u->user_rid; POLICY_HND *user_pol = &r_u->user_pol; struct samr_info *info = NULL; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access = q_u->access_mask; - size_t sd_size; BOOL ret; - NTSTATUS nt_status; r_u->status = NT_STATUS_OK; - /* find the domain policy handle and get domain SID / access bits in the domain policy. */ - if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted)) + /* find the domain policy handle. */ + if (!find_policy_by_hnd(p, &domain_pol, NULL)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_user"))) { - return nt_status; - } - nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - /* append the user's RID to it */ - if (!sid_append_rid(&sid, q_u->user_rid)) - return NT_STATUS_NO_SUCH_USER; - - /* check if access can be granted as requested by client. */ - samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid); - se_map_generic(&des_access, &usr_generic_mapping); - if (!NT_STATUS_IS_OK(nt_status = - access_check_samr_object(psd, p->pipe_user.nt_user_token, - des_access, &acc_granted, "_samr_open_user"))) { - return nt_status; - } + pdb_init_sam(&sampass); become_root(); - ret=pdb_getsampwsid(sampass, &sid); + ret=pdb_getsampwrid(sampass, user_rid); unbecome_root(); - /* check that the SID exists in our domain. */ + /* check that the RID exists in our domain. */ if (ret == False) { + pdb_free_sam(&sampass); return NT_STATUS_NO_SUCH_USER; } pdb_free_sam(&sampass); - /* associate the user's SID and access bits with the new handle. */ + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid)) + return NT_STATUS_INVALID_HANDLE; + + /* append the user's RID to it */ + if(!sid_append_rid(&sid, user_rid)) + return NT_STATUS_NO_SUCH_USER; + + /* associate the user's SID with the new handle. */ if ((info = get_samr_info_by_sid(&sid)) == NULL) return NT_STATUS_NO_MEMORY; - info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) @@ -1737,25 +1438,21 @@ NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN get_user_info_10. Safe. Only gives out acb bits. *************************************************************************/ -static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid) +static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid) { SAM_ACCOUNT *smbpass=NULL; BOOL ret; - NTSTATUS nt_status; - nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + pdb_init_sam(&smbpass); become_root(); - ret = pdb_getsampwsid(smbpass, user_sid); + ret = pdb_getsampwrid(smbpass, user_rid); unbecome_root(); if (ret==False) { - DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); - return NT_STATUS_NO_SUCH_USER; + DEBUG(4,("User 0x%x not found\n", user_rid)); + pdb_free_sam(&smbpass); + return False; } DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) )); @@ -1765,7 +1462,7 @@ static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DO pdb_free_sam(&smbpass); - return NT_STATUS_OK; + return True; } /************************************************************************* @@ -1774,11 +1471,10 @@ static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DO user. JRA. *************************************************************************/ -static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid) +static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid) { SAM_ACCOUNT *smbpass=NULL; BOOL ret; - NTSTATUS nt_status; if (!p->ntlmssp_auth_validated) return NT_STATUS_ACCESS_DENIED; @@ -1789,17 +1485,12 @@ static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_ /* * Do *NOT* do become_root()/unbecome_root() here ! JRA. */ + pdb_init_sam(&smbpass); - nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - ret = pdb_getsampwsid(smbpass, user_sid); + ret = pdb_getsampwrid(smbpass, user_rid); if (ret == False) { - DEBUG(4, ("User %s not found\n", sid_string_static(user_sid))); + DEBUG(4, ("User 0x%x not found\n", user_rid)); pdb_free_sam(&smbpass); return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED; } @@ -1823,20 +1514,21 @@ static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_ get_user_info_20 *************************************************************************/ -static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid) +static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid) { SAM_ACCOUNT *sampass=NULL; BOOL ret; - pdb_init_sam_talloc(mem_ctx, &sampass); + pdb_init_sam(&sampass); become_root(); - ret = pdb_getsampwsid(sampass, user_sid); + ret = pdb_getsampwrid(sampass, user_rid); unbecome_root(); if (ret == False) { - DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); - return NT_STATUS_NO_SUCH_USER; + DEBUG(4,("User 0x%x not found\n", user_rid)); + pdb_free_sam(&sampass); + return False; } samr_clear_sam_passwd(sampass); @@ -1848,32 +1540,28 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DO pdb_free_sam(&sampass); - return NT_STATUS_OK; + return True; } /************************************************************************* get_user_info_21 *************************************************************************/ -static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, - DOM_SID *user_sid, DOM_SID *domain_sid) +static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid) { SAM_ACCOUNT *sampass=NULL; BOOL ret; - NTSTATUS nt_status; - nt_status = pdb_init_sam_talloc(mem_ctx, &sampass); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } + pdb_init_sam(&sampass); become_root(); - ret = pdb_getsampwsid(sampass, user_sid); + ret = pdb_getsampwrid(sampass, user_rid); unbecome_root(); if (ret == False) { - DEBUG(4,("User %s not found\n", sid_string_static(user_sid))); - return NT_STATUS_NO_SUCH_USER; + DEBUG(4,("User 0x%x not found\n", user_rid)); + pdb_free_sam(&sampass); + return False; } samr_clear_sam_passwd(sampass); @@ -1881,11 +1569,11 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) )); ZERO_STRUCTP(id21); - nt_status = init_sam_user_info21A(id21, sampass, domain_sid); + init_sam_user_info21A(id21, sampass); pdb_free_sam(&sampass); - return NT_STATUS_OK; + return True; } /******************************************************************* @@ -1895,24 +1583,21 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u) { SAM_USERINFO_CTR *ctr; + uint32 rid = 0; struct samr_info *info = NULL; - DOM_SID domain_sid; - uint32 rid; - + r_u->status=NT_STATUS_OK; /* search for the handle */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - domain_sid = info->sid; - - sid_split_rid(&domain_sid, &rid); - if (!sid_check_is_in_our_domain(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; - DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid))); + sid_peek_rid(&info->sid, &rid); + + DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid)); ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR)); if (!ctr) @@ -1929,8 +1614,8 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_ if (ctr->info.id10 == NULL) return NT_STATUS_NO_MEMORY; - if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid))) - return r_u->status; + if (!get_user_info_10(ctr->info.id10, rid)) + return NT_STATUS_NO_SUCH_USER; break; #if 0 @@ -1964,25 +1649,24 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_ if (ctr->info.id12 == NULL) return NT_STATUS_NO_MEMORY; - if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid))) + if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid))) return r_u->status; break; - + case 20: ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20)); if (ctr->info.id20 == NULL) return NT_STATUS_NO_MEMORY; - if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid))) - return r_u->status; + if (!get_user_info_20(ctr->info.id20, rid)) + return NT_STATUS_NO_SUCH_USER; break; case 21: ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21)); if (ctr->info.id21 == NULL) return NT_STATUS_NO_MEMORY; - if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, - &info->sid, &domain_sid))) - return r_u->status; + if (!get_user_info_21(ctr->info.id21, rid)) + return NT_STATUS_NO_SUCH_USER; break; default: @@ -1992,7 +1676,7 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_ init_samr_r_query_userinfo(r_u, ctr, r_u->status); DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__)); - + return r_u->status; } @@ -2003,10 +1687,10 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u) { SAM_ACCOUNT *sam_pass=NULL; - DOM_SID sid; DOM_GID *gids = NULL; int num_groups = 0; - uint32 acc_granted; + uint32 rid; + struct samr_info *info = NULL; BOOL ret; /* @@ -2026,39 +1710,37 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted)) + if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, USER_ACCESS_GET_GROUPS, "_samr_query_usergroups"))) { - return r_u->status; - } - if (!sid_check_is_in_our_domain(&sid)) + if (!sid_check_is_in_our_domain(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; + sid_peek_rid(&info->sid, &rid); + pdb_init_sam(&sam_pass); - + become_root(); - ret = pdb_getsampwsid(sam_pass, &sid); + ret = pdb_getsampwrid(sam_pass, rid); unbecome_root(); if (ret == False) { pdb_free_sam(&sam_pass); return NT_STATUS_NO_SUCH_USER; } - + if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) { pdb_free_sam(&sam_pass); return NT_STATUS_NO_SUCH_GROUP; } - + /* construct the response. lkclXXXX: gids are not copied! */ init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status); - + DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__)); pdb_free_sam(&sam_pass); - + return r_u->status; } @@ -2089,13 +1771,13 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA ZERO_STRUCTP(ctr); r_u->status = NT_STATUS_OK; - + DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__)); - + /* find the policy handle. open a policy on it. */ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - + switch (q_u->switch_value) { case 0x01: account_policy_get(AP_MIN_PASSWORD_LEN, &min_pass_len); @@ -2114,15 +1796,15 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA become_root(); r_u->status=load_sampwd_entries(info, ACB_NORMAL); unbecome_root(); - if (!NT_STATUS_IS_OK(r_u->status)) { + if (NT_STATUS_IS_ERR(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n")); return r_u->status; } num_users=info->disp_info.num_user_account; free_samr_db(info); - r_u->status=load_group_domain_entries(info, get_global_sam_sid()); - if (!NT_STATUS_IS_OK(r_u->status)) { + r_u->status=load_group_domain_entries(info, &global_sam_sid); + if (NT_STATUS_IS_ERR(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n")); return r_u->status; } @@ -2160,12 +1842,12 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA break; default: return NT_STATUS_INVALID_INFO_CLASS; - } - + } + init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK); - + DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__)); - + return r_u->status; } @@ -2189,19 +1871,11 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ BOOL ret; NTSTATUS nt_status; struct passwd *pw; - uint32 acc_granted; - SEC_DESC *psd; - size_t sd_size; - uint32 des_access; - /* Get the domain SID stored in the domain policy */ - if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted)) + /* find the policy handle. open a policy on it. */ + if (!find_policy_by_hnd(p, &dom_pol, NULL)) return NT_STATUS_INVALID_HANDLE; - if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_USER, "_samr_create_user"))) { - return nt_status; - } - /* find the account: tell the caller if it exists. lkclXXXX i have *no* idea if this is a problem or not or even if you are supposed to construct a different @@ -2270,7 +1944,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ else pstrcpy(add_script, lp_adduser_script()); - if (*add_script) { + if(*add_script) { int add_ret; all_string_sub(add_script, "%u", account, sizeof(account)); add_ret = smbrun(add_script,NULL); @@ -2316,15 +1990,16 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ return NT_STATUS_ACCESS_DENIED; } - /* Get the user's SID */ - sid_copy(&sid, pdb_get_user_sid(sam_pass)); - - samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid); - se_map_generic(&des_access, &usr_generic_mapping); - if (!NT_STATUS_IS_OK(nt_status = - access_check_samr_object(psd, p->pipe_user.nt_user_token, - des_access, &acc_granted, "_samr_create_user"))) { - return nt_status; + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) { + pdb_free_sam(&sam_pass); + return NT_STATUS_INVALID_HANDLE; + } + + /* append the user's RID to it */ + if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) { + pdb_free_sam(&sam_pass); + return NT_STATUS_NO_SUCH_USER; } /* associate the user's SID with the new handle. */ @@ -2335,7 +2010,6 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_ ZERO_STRUCTP(info); info->sid = sid; - info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) { @@ -2359,29 +2033,21 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO { struct samr_info *info = NULL; - /* Access check */ + /* set up the SAMR connect_anon response */ - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to samr_connect_anon\n")); - r_u->status = NT_STATUS_ACCESS_DENIED; - return r_u->status; - } - - /* set up the SAMR connect_anon response */ - - r_u->status = NT_STATUS_OK; + r_u->status = NT_STATUS_OK; - /* associate the user's SID with the new handle. */ - if ((info = get_samr_info_by_sid(NULL)) == NULL) - return NT_STATUS_NO_MEMORY; + /* associate the user's SID with the new handle. */ + if ((info = get_samr_info_by_sid(NULL)) == NULL) + return NT_STATUS_NO_MEMORY; - info->status = q_u->unknown_0; + info->status = q_u->unknown_0; - /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + /* get a (unique) handle. open a policy on it. */ + if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; - return r_u->status; + return r_u->status; } /******************************************************************* @@ -2391,47 +2057,24 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u) { struct samr_info *info = NULL; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access = q_u->access_mask; - size_t sd_size; - NTSTATUS nt_status; + DEBUG(5,("_samr_connect: %d\n", __LINE__)); - DEBUG(5,("_samr_connect: %d\n", __LINE__)); - - /* Access check */ - - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to samr_connect\n")); - r_u->status = NT_STATUS_ACCESS_DENIED; - return r_u->status; - } - - samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size); - se_map_generic(&des_access, &sam_generic_mapping); - if (!NT_STATUS_IS_OK(nt_status = - access_check_samr_object(psd, p->pipe_user.nt_user_token, - des_access, &acc_granted, "_samr_connect"))) { - return nt_status; - } - - r_u->status = NT_STATUS_OK; + r_u->status = NT_STATUS_OK; - /* associate the user's SID and access granted with the new handle. */ + /* associate the user's SID with the new handle. */ if ((info = get_samr_info_by_sid(NULL)) == NULL) - return NT_STATUS_NO_MEMORY; + return NT_STATUS_NO_MEMORY; - info->acc_granted = acc_granted; - info->status = q_u->access_mask; + info->status = q_u->access_mask; - /* get a (unique) handle. open a policy on it. */ - if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info)) - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + /* get a (unique) handle. open a policy on it. */ + if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; - DEBUG(5,("_samr_connect: %d\n", __LINE__)); + DEBUG(5,("_samr_connect: %d\n", __LINE__)); - return r_u->status; + return r_u->status; } /********************************************************************** @@ -2440,19 +2083,14 @@ NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u) { - struct samr_info *info; fstring domain_name; DOM_SID sid; r_u->status = NT_STATUS_OK; - if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info)) + if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL)) return NT_STATUS_INVALID_HANDLE; - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SAMR_ACCESS_OPEN_DOMAIN, "_samr_lookup_domain"))) { - return r_u->status; - } - rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0); ZERO_STRUCT(sid); @@ -2512,19 +2150,11 @@ static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam, NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u) { - struct samr_info *info; uint32 num_entries = 2; fstring dom[2]; char *name; r_u->status = NT_STATUS_OK; - - if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info)) - return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SAMR_ACCESS_ENUM_DOMAINS, "_samr_enum_domains"))) { - return r_u->status; - } switch (lp_server_role()) { case ROLE_DOMAIN_PDC: @@ -2557,35 +2187,21 @@ NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OP POLICY_HND domain_pol = q_u->dom_pol; uint32 alias_rid = q_u->rid_alias; POLICY_HND *alias_pol = &r_u->pol; - struct samr_info *info = NULL; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access = q_u->access_mask; - size_t sd_size; - NTSTATUS status; + struct samr_info *info = NULL; r_u->status = NT_STATUS_OK; - /* find the domain policy and get the SID / access bits stored in the domain policy */ - if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted)) + /* get the domain policy. */ + if (!find_policy_by_hnd(p, &domain_pol, NULL)) + return NT_STATUS_INVALID_HANDLE; + + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_alias"))) { - return status; - } /* append the alias' RID to it */ - if (!sid_append_rid(&sid, alias_rid)) + if(!sid_append_rid(&sid, alias_rid)) return NT_STATUS_NO_SUCH_USER; - - /*check if access can be granted as requested by client. */ - samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size); - se_map_generic(&des_access,&ali_generic_mapping); - if (!NT_STATUS_IS_OK(status = - access_check_samr_object(psd, p->pipe_user.nt_user_token, - des_access, &acc_granted, "_samr_open_alias"))) { - return status; - } /* * we should check if the rid really exist !!! @@ -2595,8 +2211,6 @@ NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OP /* associate the user's SID with the new handle. */ if ((info = get_samr_info_by_sid(&sid)) == NULL) return NT_STATUS_NO_MEMORY; - - info->acc_granted = acc_granted; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info)) @@ -2609,14 +2223,14 @@ NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OP set_user_info_10 ********************************************************************/ -static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid) +static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid) { SAM_ACCOUNT *pwd =NULL; BOOL ret; pdb_init_sam(&pwd); - ret = pdb_getsampwsid(pwd, sid); + ret = pdb_getsampwrid(pwd, rid); if(ret==False) { pdb_free_sam(&pwd); @@ -2648,13 +2262,13 @@ static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid) set_user_info_12 ********************************************************************/ -static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid) +static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid) { SAM_ACCOUNT *pwd = NULL; pdb_init_sam(&pwd); - if(!pdb_getsampwsid(pwd, sid)) { + if(!pdb_getsampwrid(pwd, rid)) { pdb_free_sam(&pwd); return False; } @@ -2691,7 +2305,7 @@ static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid) set_user_info_21 ********************************************************************/ -static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid) +static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid) { SAM_ACCOUNT *pwd = NULL; @@ -2702,7 +2316,7 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid) pdb_init_sam(&pwd); - if (!pdb_getsampwsid(pwd, sid)) { + if (!pdb_getsampwrid(pwd, rid)) { pdb_free_sam(&pwd); return False; } @@ -2731,7 +2345,7 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid) set_user_info_23 ********************************************************************/ -static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid) +static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid) { SAM_ACCOUNT *pwd = NULL; pstring plaintext_buf; @@ -2745,7 +2359,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid) pdb_init_sam(&pwd); - if (!pdb_getsampwsid(pwd, sid)) { + if (!pdb_getsampwrid(pwd, rid)) { pdb_free_sam(&pwd); return False; } @@ -2798,7 +2412,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid) set_user_info_pw ********************************************************************/ -static BOOL set_user_info_pw(char *pass, DOM_SID *sid) +static BOOL set_user_info_pw(char *pass, uint32 rid) { SAM_ACCOUNT *pwd = NULL; uint32 len; @@ -2807,7 +2421,7 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid) pdb_init_sam(&pwd); - if (!pdb_getsampwsid(pwd, sid)) { + if (!pdb_getsampwrid(pwd, rid)) { pdb_free_sam(&pwd); return False; } @@ -2866,27 +2480,23 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid) NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u) { + uint32 rid = 0x0; DOM_SID sid; POLICY_HND *pol = &q_u->pol; uint16 switch_value = q_u->switch_value; SAM_USERINFO_CTR *ctr = q_u->ctr; - uint32 acc_granted; - uint32 acc_required; DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__)); r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, pol, &sid)) return NT_STATUS_INVALID_HANDLE; - - acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; /* This is probably wrong */ - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) { - return r_u->status; - } - - DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value)); + + sid_split_rid(&sid, &rid); + + DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value)); if (ctr == NULL) { DEBUG(5, ("_samr_set_userinfo: NULL info level\n")); @@ -2896,7 +2506,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE /* ok! user info levels (lots: see MSDEV help), off we go... */ switch (switch_value) { case 0x12: - if (!set_user_info_12(ctr->info.id12, &sid)) + if (!set_user_info_12(ctr->info.id12, rid)) return NT_STATUS_ACCESS_DENIED; break; @@ -2905,7 +2515,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE dump_data(100, (char *)ctr->info.id24->pass, 516); - if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid)) + if (!set_user_info_pw((char *)ctr->info.id24->pass, rid)) return NT_STATUS_ACCESS_DENIED; break; @@ -2923,7 +2533,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE dump_data(100, (char *)ctr->info.id25->pass, 532); - if (!set_user_info_pw(ctr->info.id25->pass, &sid)) + if (!set_user_info_pw(ctr->info.id25->pass, rid)) return NT_STATUS_ACCESS_DENIED; break; #endif @@ -2934,7 +2544,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE dump_data(100, (char *)ctr->info.id23->pass, 516); - if (!set_user_info_23(ctr->info.id23, &sid)) + if (!set_user_info_23(ctr->info.id23, rid)) return NT_STATUS_ACCESS_DENIED; break; @@ -2952,26 +2562,22 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u) { DOM_SID sid; + uint32 rid = 0x0; SAM_USERINFO_CTR *ctr = q_u->ctr; POLICY_HND *pol = &q_u->pol; uint16 switch_value = q_u->switch_value; - uint32 acc_granted; - uint32 acc_required; DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__)); r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, pol, &sid)) return NT_STATUS_INVALID_HANDLE; - - acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; /* This is probably wrong */ - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) { - return r_u->status; - } - DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid))); + sid_split_rid(&sid, &rid); + + DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid)); if (ctr == NULL) { DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n")); @@ -2983,16 +2589,16 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ /* ok! user info levels (lots: see MSDEV help), off we go... */ switch (switch_value) { case 21: - if (!set_user_info_21(ctr->info.id21, &sid)) + if (!set_user_info_21(ctr->info.id21, rid)) return NT_STATUS_ACCESS_DENIED; break; case 16: - if (!set_user_info_10(ctr->info.id10, &sid)) + if (!set_user_info_10(ctr->info.id10, rid)) return NT_STATUS_ACCESS_DENIED; break; case 18: /* Used by AS/U JRA. */ - if (!set_user_info_12(ctr->info.id12, &sid)) + if (!set_user_info_12(ctr->info.id12, rid)) return NT_STATUS_ACCESS_DENIED; break; default: @@ -3036,10 +2642,6 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, /* find the policy handle. open a policy on it. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, USER_ACCESS_GET_GROUPS, "_samr_query_useraliases"))) { - return r_u->status; - } if (!sid_check_is_domain(&info->sid) && !sid_check_is_builtin(&info->sid)) @@ -3054,7 +2656,7 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, * if there is an error, we just continue as * it can be an unfound user or group */ - if (!NT_STATUS_IS_OK(r_u->status)) { + if (NT_STATUS_IS_ERR(r_u->status)) { DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n")); continue; } @@ -3104,16 +2706,11 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ SAM_ACCOUNT *sam_user = NULL; BOOL check; - uint32 acc_granted; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_GET_MEMBERS, "_samr_query_aliasmem"))) { - return r_u->status; - } - + sid_copy(&als_sid, &alias_sid); sid_to_string(alias_sid_str, &alias_sid); sid_split_rid(&alias_sid, &alias_rid); @@ -3125,7 +2722,7 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; } else { - if (sid_equal(&alias_sid, get_global_sam_sid())) { + if (sid_equal(&alias_sid, &global_sam_sid)) { DEBUG(10, ("lookup on Server SID\n")); if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; @@ -3144,12 +2741,12 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ struct passwd *pass; uint32 rid; - sid_copy(&temp_sid, get_global_sam_sid()); + sid_copy(&temp_sid, &global_sam_sid); pass = getpwuid_alloc(uid[i]); if (!pass) continue; - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) { + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) { passwd_free(&pass); continue; } @@ -3205,16 +2802,12 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ SAM_ACCOUNT *sam_user = NULL; BOOL check; - uint32 acc_granted; + /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_GET_MEMBERS, "_samr_query_groupmem"))) { - return r_u->status; - } - + /* todo: change to use sid_compare_front */ sid_split_rid(&group_sid, &group_rid); @@ -3222,7 +2815,7 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ DEBUG(10, ("sid is %s\n", group_sid_str)); /* can we get a query for an SID outside our domain ? */ - if (!sid_equal(&group_sid, get_global_sam_sid())) + if (!sid_equal(&group_sid, &global_sam_sid)) return NT_STATUS_NO_SUCH_GROUP; sid_append_rid(&group_sid, group_rid); @@ -3247,7 +2840,7 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ pass = getpwuid_alloc(uid[i]); if (!pass) continue; - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) { + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) { passwd_free(&pass); continue; } @@ -3293,24 +2886,20 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD struct passwd *pwd; struct group *grp; fstring grp_name; + uint32 rid; GROUP_MAP map; NTSTATUS ret; SAM_ACCOUNT *sam_user = NULL; BOOL check; - uint32 acc_granted; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_ADD_MEMBER, "_samr_add_aliasmem"))) { - return r_u->status; - } - + sid_to_string(alias_sid_str, &alias_sid); DEBUG(10, ("sid is %s\n", alias_sid_str)); - if (sid_compare(&alias_sid, get_global_sam_sid())>0) { + if (sid_compare(&alias_sid, &global_sam_sid)>0) { DEBUG(10, ("adding member on Server SID\n")); if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; @@ -3325,11 +2914,13 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD return NT_STATUS_NO_SUCH_ALIAS; } + sid_split_rid(&q_u->sid.sid, &rid); + ret = pdb_init_sam(&sam_user); - if (!NT_STATUS_IS_OK(ret)) + if (NT_STATUS_IS_ERR(ret)) return ret; - check = pdb_getsampwsid(sam_user, &q_u->sid.sid); + check = pdb_getsampwrid(sam_user, rid); if (check != True) { pdb_free_sam(&sam_user); @@ -3344,11 +2935,8 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD pdb_free_sam(&sam_user); - if ((pwd=getpwuid_alloc(uid)) == NULL) { + if ((pwd=getpwuid(uid)) == NULL) return NT_STATUS_NO_SUCH_USER; - } else { - passwd_free(&pwd); - } if ((grp=getgrgid(map.gid)) == NULL) return NT_STATUS_NO_SUCH_ALIAS; @@ -3383,18 +2971,14 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE fstring alias_sid_str; struct group *grp; fstring grp_name; + uint32 rid; GROUP_MAP map; SAM_ACCOUNT *sam_pass=NULL; - uint32 acc_granted; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_REMOVE_MEMBER, "_samr_del_aliasmem"))) { - return r_u->status; - } - + sid_to_string(alias_sid_str, &alias_sid); DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str)); @@ -3413,9 +2997,11 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE /* we need to copy the name otherwise it's overloaded in user_in_group_list */ fstrcpy(grp_name, grp->gr_name); + sid_peek_rid(&q_u->sid.sid, &rid); + /* check if the user exists before trying to remove it from the group */ pdb_init_sam(&sam_pass); - if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) { + if(!pdb_getsampwrid(sam_pass, rid)) { DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass))); pdb_free_sam(&sam_pass); return NT_STATUS_NO_SUCH_USER; @@ -3446,7 +3032,6 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u) { DOM_SID group_sid; - DOM_SID user_sid; fstring group_sid_str; struct passwd *pwd; struct group *grp; @@ -3456,20 +3041,15 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD NTSTATUS ret; SAM_ACCOUNT *sam_user; BOOL check; - uint32 acc_granted; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_ADD_MEMBER, "_samr_add_groupmem"))) { - return r_u->status; - } sid_to_string(group_sid_str, &group_sid); DEBUG(10, ("sid is %s\n", group_sid_str)); - if (sid_compare(&group_sid, get_global_sam_sid())<=0) + if (sid_compare(&group_sid, &global_sam_sid)<=0) return NT_STATUS_NO_SUCH_GROUP; DEBUG(10, ("lookup on Domain SID\n")); @@ -3477,14 +3057,11 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_GROUP; - sid_copy(&user_sid, get_global_sam_sid()); - sid_append_rid(&user_sid, q_u->rid); - ret = pdb_init_sam(&sam_user); - if (!NT_STATUS_IS_OK(ret)) + if (NT_STATUS_IS_ERR(ret)) return ret; - check = pdb_getsampwsid(sam_user, &user_sid); + check = pdb_getsampwrid(sam_user, q_u->rid); if (check != True) { pdb_free_sam(&sam_user); @@ -3499,11 +3076,8 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD pdb_free_sam(&sam_user); - if ((pwd=getpwuid_alloc(uid)) == NULL) { + if ((pwd=getpwuid(uid)) == NULL) return NT_STATUS_NO_SUCH_USER; - } else { - passwd_free(&pwd); - } if ((grp=getgrgid(map.gid)) == NULL) return NT_STATUS_NO_SUCH_GROUP; @@ -3537,12 +3111,11 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u) { DOM_SID group_sid; - DOM_SID user_sid; SAM_ACCOUNT *sam_pass=NULL; + uint32 rid; GROUP_MAP map; fstring grp_name; struct group *grp; - uint32 acc_granted; /* * delete the group member named q_u->rid @@ -3551,20 +3124,15 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE */ /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_REMOVE_MEMBER, "_samr_del_groupmem"))) { - return r_u->status; - } - - if (!sid_check_is_in_our_domain(&group_sid)) + + if(!sid_check_is_in_our_domain(&group_sid)) return NT_STATUS_NO_SUCH_GROUP; - sid_copy(&user_sid, get_global_sam_sid()); - sid_append_rid(&user_sid, q_u->rid); + rid=q_u->rid; - if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) + if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_GROUP; if ((grp=getgrgid(map.gid)) == NULL) @@ -3575,14 +3143,14 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE /* check if the user exists before trying to remove it from the group */ pdb_init_sam(&sam_pass); - if (!pdb_getsampwsid(sam_pass, &user_sid)) { + if(!pdb_getsampwrid(sam_pass, rid)) { DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass))); pdb_free_sam(&sam_pass); return NT_STATUS_NO_SUCH_USER; } /* if the user is not in the group */ - if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) { + if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) { pdb_free_sam(&sam_pass); return NT_STATUS_MEMBER_NOT_IN_GROUP; } @@ -3590,7 +3158,7 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE smb_delete_user_group(grp_name, pdb_get_username(sam_pass)); /* check if the user has been removed then ... */ - if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) { + if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) { pdb_free_sam(&sam_pass); return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */ } @@ -3600,24 +3168,6 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE } -/**************************************************************************** - Delete a UNIX user on demand. -****************************************************************************/ - -static int smb_delete_user(const char *unix_user) -{ - pstring del_script; - int ret; - - pstrcpy(del_script, lp_deluser_script()); - if (! *del_script) - return -1; - all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); - ret = smbrun(del_script,NULL); - DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); - return ret; -} - /********************************************************************* _samr_delete_dom_user *********************************************************************/ @@ -3626,24 +3176,22 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM { DOM_SID user_sid; SAM_ACCOUNT *sam_pass=NULL; - uint32 acc_granted; + uint32 rid; DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__)); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_user"))) { - return r_u->status; - } - + if (!sid_check_is_in_our_domain(&user_sid)) return NT_STATUS_CANNOT_DELETE; + sid_peek_rid(&user_sid, &rid); + /* check if the user exists before trying to delete */ pdb_init_sam(&sam_pass); - if(!pdb_getsampwsid(sam_pass, &user_sid)) { + if(!pdb_getsampwrid(sam_pass, rid)) { DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass))); pdb_free_sam(&sam_pass); return NT_STATUS_NO_SUCH_USER; @@ -3685,18 +3233,13 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S gid_t gid; struct group *grp; GROUP_MAP map; - uint32 acc_granted; DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__)); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_group"))) { - return r_u->status; - } - + sid_copy(&dom_sid, &group_sid); sid_to_string(group_sid_str, &dom_sid); sid_split_rid(&dom_sid, &group_rid); @@ -3704,7 +3247,7 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S DEBUG(10, ("sid is %s\n", group_sid_str)); /* we check if it's our SID before deleting */ - if (!sid_equal(&dom_sid, get_global_sam_sid())) + if (!sid_equal(&dom_sid, &global_sam_sid)) return NT_STATUS_NO_SUCH_GROUP; DEBUG(10, ("lookup on Domain SID\n")); @@ -3747,18 +3290,13 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S gid_t gid; struct group *grp; GROUP_MAP map; - uint32 acc_granted; DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__)); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_alias"))) { - return r_u->status; - } - + sid_copy(&dom_sid, &alias_sid); sid_to_string(alias_sid_str, &dom_sid); sid_split_rid(&dom_sid, &alias_rid); @@ -3766,7 +3304,7 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S DEBUG(10, ("sid is %s\n", alias_sid_str)); /* we check if it's our SID before deleting */ - if (!sid_equal(&dom_sid, get_global_sam_sid())) + if (!sid_equal(&dom_sid, &global_sam_sid)) return NT_STATUS_NO_SUCH_ALIAS; DEBUG(10, ("lookup on Local SID\n")); @@ -3809,19 +3347,14 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S struct group *grp; struct samr_info *info; PRIVILEGE_SET priv_set; - uint32 acc_granted; init_privilege(&priv_set); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_GROUP, "_samr_create_dom_group"))) { - return r_u->status; - } - - if (!sid_equal(&dom_sid, get_global_sam_sid())) + + if (!sid_equal(&dom_sid, &global_sam_sid)) return NT_STATUS_ACCESS_DENIED; /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/ @@ -3842,7 +3375,7 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S r_u->rid=pdb_gid_to_group_rid(grp->gr_gid); /* add the group to the mapping table */ - sid_copy(&info_sid, get_global_sam_sid()); + sid_copy(&info_sid, &global_sam_sid); sid_append_rid(&info_sid, r_u->rid); sid_to_string(sid_string, &info_sid); @@ -3872,19 +3405,14 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S struct group *grp; struct samr_info *info; PRIVILEGE_SET priv_set; - uint32 acc_granted; init_privilege(&priv_set); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_ALIAS, "_samr_create_alias"))) { - return r_u->status; - } - - if (!sid_equal(&dom_sid, get_global_sam_sid())) + + if (!sid_equal(&dom_sid, &global_sam_sid)) return NT_STATUS_ACCESS_DENIED; /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/ @@ -3904,7 +3432,7 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S r_u->rid=pdb_gid_to_group_rid(grp->gr_gid); - sid_copy(&info_sid, get_global_sam_sid()); + sid_copy(&info_sid, &global_sam_sid); sid_append_rid(&info_sid, r_u->rid); sid_to_string(sid_string, &info_sid); @@ -3936,15 +3464,10 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM uid_t *uid=NULL; int num_uids=0; GROUP_INFO_CTR *ctr; - uint32 acc_granted; - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_LOOKUP_INFO, "_samr_query_groupinfo"))) { - return r_u->status; - } - + if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_INVALID_HANDLE; @@ -3988,15 +3511,10 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_ DOM_SID group_sid; GROUP_MAP map; GROUP_INFO_CTR *ctr; - uint32 acc_granted; - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_SET_INFO, "_samr_set_groupinfo"))) { - return r_u->status; - } - + if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; @@ -4035,15 +3553,10 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ DOM_SID group_sid; GROUP_MAP map; ALIAS_INFO_CTR *ctr; - uint32 acc_granted; - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_SET_INFO, "_samr_set_aliasinfo"))) { - return r_u->status; - } - + if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; @@ -4074,18 +3587,7 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u) { - /* Perform access check. Since this rpc does not require a - policy handle it will not be caught by the access checks on - SAMR_CONNECT or SAMR_CONNECT_ANON. */ - - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to samr_get_dom_pwinfo\n")); - r_u->status = NT_STATUS_ACCESS_DENIED; - return r_u->status; - } - /* Actually, returning zeros here works quite well :-). */ - return NT_STATUS_OK; } @@ -4099,42 +3601,21 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G DOM_SID info_sid; GROUP_MAP map; struct samr_info *info; - SEC_DESC *psd = NULL; - uint32 acc_granted; - uint32 des_access; - size_t sd_size; - NTSTATUS status; fstring sid_string; - if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid)) return NT_STATUS_INVALID_HANDLE; - - if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_group"))) { - return status; - } - - /*check if access can be granted as requested by client. */ - samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size); - se_map_generic(&des_access,&grp_generic_mapping); - if (!NT_STATUS_IS_OK(status = - access_check_samr_object(psd, p->pipe_user.nt_user_token, - des_access, &acc_granted, "_samr_open_group"))) { - return status; - } - /* this should not be hard-coded like this */ - if (!sid_equal(&sid, get_global_sam_sid())) + if (!sid_equal(&sid, &global_sam_sid)) return NT_STATUS_ACCESS_DENIED; - sid_copy(&info_sid, get_global_sam_sid()); + sid_copy(&info_sid, &global_sam_sid); sid_append_rid(&info_sid, q_u->rid_group); sid_to_string(sid_string, &info_sid); if ((info = get_samr_info_by_sid(&info_sid)) == NULL) return NT_STATUS_NO_MEMORY; - - info->acc_granted = acc_granted; DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string)); @@ -4211,14 +3692,14 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW become_root(); r_u->status=load_sampwd_entries(info, ACB_NORMAL); unbecome_root(); - if (!NT_STATUS_IS_OK(r_u->status)) { + if (NT_STATUS_IS_ERR(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n")); return r_u->status; } num_users=info->disp_info.num_user_account; free_samr_db(info); - r_u->status=load_group_domain_entries(info, get_global_sam_sid()); + r_u->status=load_group_domain_entries(info, &global_sam_sid); if (NT_STATUS_IS_ERR(r_u->status)) { DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n")); return r_u->status; diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 6e3463e79b..c7dc5d27ff 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -4,8 +4,7 @@ * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, * Copyright (C) Jean François Micouleau 1998-2000. - * Copyright (C) Jeremy Allison 2001. - * Copyright (C) Gerald Carter 2001-2002. + * Copyright (C) Jeremy Allison 2001. * * 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 @@ -24,9 +23,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /******************************************************************** * api_spoolss_open_printer_ex (rarely seen - older call) ********************************************************************/ @@ -1403,119 +1399,6 @@ static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p) return True; } -/**************************************************************************** -****************************************************************************/ - -static BOOL api_spoolss_deleteprinterdataex(pipes_struct *p) -{ - SPOOL_Q_DELETEPRINTERDATAEX q_u; - SPOOL_R_DELETEPRINTERDATAEX 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(!spoolss_io_q_deleteprinterdataex("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_deleteprinterdataex: unable to unmarshall SPOOL_Q_DELETEPRINTERDATAEX.\n")); - return False; - } - - r_u.status = _spoolss_deleteprinterdataex(p, &q_u, &r_u); - - if(!spoolss_io_r_deleteprinterdataex("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_deleteprinterdataex: unable to marshall SPOOL_R_DELETEPRINTERDATAEX.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static BOOL api_spoolss_deleteprinterkey(pipes_struct *p) -{ - SPOOL_Q_DELETEPRINTERKEY q_u; - SPOOL_R_DELETEPRINTERKEY 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(!spoolss_io_q_deleteprinterkey("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_deleteprinterkey: unable to unmarshall SPOOL_Q_DELETEPRINTERKEY.\n")); - return False; - } - - r_u.status = _spoolss_deleteprinterkey(p, &q_u, &r_u); - - if(!spoolss_io_r_deleteprinterkey("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_deleteprinterkey: unable to marshall SPOOL_R_DELETEPRINTERKEY.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static BOOL api_spoolss_addprinterdriverex(pipes_struct *p) -{ - SPOOL_Q_ADDPRINTERDRIVEREX q_u; - SPOOL_R_ADDPRINTERDRIVEREX 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(!spoolss_io_q_addprinterdriverex("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_addprinterdriverex: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVEREX.\n")); - return False; - } - - r_u.status = _spoolss_addprinterdriverex(p, &q_u, &r_u); - - if(!spoolss_io_r_addprinterdriverex("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_addprinterdriverex: unable to marshall SPOOL_R_ADDPRINTERDRIVEREX.\n")); - return False; - } - - return True; -} - -/**************************************************************************** -****************************************************************************/ - -static BOOL api_spoolss_deleteprinterdriverex(pipes_struct *p) -{ - SPOOL_Q_DELETEPRINTERDRIVEREX q_u; - SPOOL_R_DELETEPRINTERDRIVEREX 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(!spoolss_io_q_deleteprinterdriverex("", &q_u, data, 0)) { - DEBUG(0,("spoolss_io_q_deleteprinterdriverex: unable to unmarshall SPOOL_Q_DELETEPRINTERDRIVEREX.\n")); - return False; - } - - r_u.status = _spoolss_deleteprinterdriverex(p, &q_u, &r_u); - - if(!spoolss_io_r_deleteprinterdriverex("", &r_u, rdata, 0)) { - DEBUG(0,("spoolss_io_r_deleteprinterdriverex: unable to marshall SPOOL_R_DELETEPRINTERDRIVEREX.\n")); - return False; - } - - return True; -} - - /******************************************************************* \pipe\spoolss commands ********************************************************************/ @@ -1566,13 +1449,9 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes }, {"SPOOLSS_GETPRINTERDATAEX", SPOOLSS_GETPRINTERDATAEX, api_spoolss_getprinterdataex }, {"SPOOLSS_SETPRINTERDATAEX", SPOOLSS_SETPRINTERDATAEX, api_spoolss_setprinterdataex }, - {"SPOOLSS_DELETEPRINTERDATAEX", SPOOLSS_DELETEPRINTERDATAEX, api_spoolss_deleteprinterdataex }, - {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex }, {"SPOOLSS_ENUMPRINTERKEY", SPOOLSS_ENUMPRINTERKEY, api_spoolss_enumprinterkey }, - {"SPOOLSS_DELETEPRINTERKEY", SPOOLSS_DELETEPRINTERKEY, api_spoolss_deleteprinterkey }, + {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex }, {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory}, - {"SPOOLSS_ADDPRINTERDRIVEREX", SPOOLSS_ADDPRINTERDRIVEREX, api_spoolss_addprinterdriverex }, - {"SPOOLSS_DELETEPRINTERDRIVEREX", SPOOLSS_DELETEPRINTERDRIVEREX, api_spoolss_deleteprinterdriverex }, { NULL, 0, NULL } }; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 68c792f8b0..322efa22b5 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, * Copyright (C) Jean François Micouleau 1998-2000, * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Gerald Carter 2000-2002, + * Copyright (C) Gerald Carter 2000-2001, * Copyright (C) Tim Potter 2001-2002. * * This program is free software; you can redistribute it and/or modify @@ -28,10 +28,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV -/* #define EMULATE_WIN2K_HACK 1 */ - #ifndef MAX_OPEN_PRINTER_EXS #define MAX_OPEN_PRINTER_EXS 50 #endif @@ -41,15 +37,6 @@ #define PRINTER_HANDLE_IS_PRINTER 0 #define PRINTER_HANDLE_IS_PRINTSERVER 1 -/* Table to map the driver version */ -/* to OS */ -char * drv_ver_to_os[] = { - "WIN9X", /* driver version/cversion 0 */ - "", /* unused ? */ - "WINNT", /* driver version/cversion 2 */ - "WIN2K", /* driver version/cversion 3 */ -}; - struct table_node { char *long_archi; char *short_archi; @@ -81,7 +68,6 @@ typedef struct _Printer{ SPOOL_NOTIFY_OPTION *option; POLICY_HND client_hnd; uint32 client_connected; - uint32 change; } notify; struct { fstring machine; @@ -192,10 +178,10 @@ static void srv_spoolss_replycloseprinter(POLICY_HND *handle) /* if it's the last connection, deconnect the IPC$ share */ if (smb_connections==1) { - cli_nt_session_close(&cli); - cli_ulogoff(&cli); - cli_shutdown(&cli); - message_deregister(MSG_PRINTER_NOTIFY2); + if(!spoolss_disconnect_from_client(&cli)) + return; + + message_deregister(MSG_PRINTER_NOTIFY); } smb_connections--; @@ -440,7 +426,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) * anymore, so I've simplified this loop greatly. Here * we are just verifying that the printer name is a valid * printer service defined in smb.conf - * --jerry [Fri Feb 15 11:17:46 CST 2002] + * --jerry [Fri Feb 15 11:17:46 CST 2002] */ for (snum=0; snum<n_services; snum++) { @@ -549,417 +535,229 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) return True; } - /*************************************************************************** - check to see if the client motify handle is monitoring the notification - given by (notify_type, notify_field). + Always give preference Printer_entry.notify.option over + Printer_entry.notify.flags. Return True if we should send notification + events using SPOOLSS_RRPCN. False means that we should use + SPOOLSS_ROUTERREPLYPRINTER. **************************************************************************/ - -static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type, - uint16 notify_field) +static BOOL valid_notify_options(Printer_entry *printer) { + if (printer->notify.option == NULL) + return False; + return True; } -static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type, - uint16 notify_field) +/*************************************************************************** + Simple check to see if the client motify handle is set to watch for events + represented by 'flags' + + FIXME!!!! only a stub right now --jerry + **************************************************************************/ + +static BOOL is_client_monitoring_event(Printer_entry *p, uint32 flags) { - SPOOL_NOTIFY_OPTION *option = p->notify.option; - uint32 i, j; - - if (p->notify.flags) - return is_monitoring_event_flags( - p->notify.flags, notify_type, notify_field); - for (i = 0; i < option->count; i++) { - - /* Check match for notify_type */ - - if (option->ctr.type[i].type != notify_type) - continue; - - /* Check match for field */ - - for (j = 0; j < option->ctr.type[i].count; j++) { - if (option->ctr.type[i].fields[j] == notify_field) { - return True; - } - } - } - - DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n", - (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ? - p->dev.handlename : p->dev.printerservername, - notify_type, notify_field)); - - return False; -} - -/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */ - -static void notify_one_value(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, - TALLOC_CTX *mem_ctx) -{ - data->notify_data.value[0] = msg->notify.value[0]; - data->notify_data.value[1] = 0; + return True; } -static void notify_string(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, - TALLOC_CTX *mem_ctx) +/*************************************************************************** + Server wrapper for cli_spoolss_routerreplyprinter() since the client + function can only send a single change notification at a time. + + FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER) + --jerry + **************************************************************************/ + +static WERROR srv_spoolss_routerreplyprinter (struct cli_state *reply_cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, PRINTER_MESSAGE_INFO *info, + NT_PRINTER_INFO_LEVEL *printer) { - UNISTR2 unistr; + WERROR result; + uint32 condition = 0x0; - /* The length of the message includes the trailing \0 */ - - init_unistr2(&unistr, msg->notify.data, msg->len); - - data->notify_data.data.length = msg->len * 2; - data->notify_data.data.string = (uint16 *)talloc(mem_ctx, msg->len * 2); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } + if (info->flags & PRINTER_MESSAGE_DRIVER) + condition = PRINTER_CHANGE_SET_PRINTER_DRIVER; - memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2); + result = cli_spoolss_routerreplyprinter(reply_cli, mem_ctx, pol, condition, + printer->info_2->changeid); + + return result; } -static void notify_system_time(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, - TALLOC_CTX *mem_ctx) +/*********************************************************************** + Wrapper around the decision of which RPC use to in the change + notification + **********************************************************************/ + +static WERROR srv_spoolss_send_event_to_client(Printer_entry* Printer, + struct cli_state *send_cli, PRINTER_MESSAGE_INFO *msg, + NT_PRINTER_INFO_LEVEL *info) { - SYSTEMTIME systime; - prs_struct ps; - - if (msg->len != sizeof(time_t)) { - DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n", - msg->len)); - return; - } + WERROR result; + + if (valid_notify_options(Printer)) { + /* This is a single call that can send information about multiple changes */ + if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) + msg->flags |= PRINTER_MESSAGE_ATTRIBUTES; - if (!prs_init(&ps, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) { - DEBUG(5, ("notify_system_time: prs_init() failed\n")); - return; + result = cli_spoolss_reply_rrpcn(send_cli, send_cli->mem_ctx, &Printer->notify.client_hnd, + msg, info); } - - if (!make_systemtime(&systime, localtime((time_t *)msg->notify.data))) { - DEBUG(5, ("notify_system_time: unable to make systemtime\n")); - return; + else { + /* This requires that the server send an individual event notification for each change */ + result = srv_spoolss_routerreplyprinter(send_cli, send_cli->mem_ctx, &Printer->notify.client_hnd, + msg, info); } - - if (!spoolss_io_system_time("", &ps, 0, &systime)) - return; - - data->notify_data.data.length = prs_offset(&ps); - data->notify_data.data.string = - talloc(mem_ctx, prs_offset(&ps)); - - memcpy(data->notify_data.data.string, prs_data_p(&ps), prs_offset(&ps)); - - prs_mem_free(&ps); + + return result; } -struct notify2_message_table { - char *name; - void (*fn)(struct spoolss_notify_msg *msg, - SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx); -}; - -static struct notify2_message_table printer_notify_table[] = { - /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", NULL }, - /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", NULL }, - /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", NULL }, - /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", NULL }, - /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", NULL }, - /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", NULL }, - /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", NULL }, - /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL }, - /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", NULL }, - /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", NULL }, - /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL }, - /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", NULL }, - /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL }, - /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", NULL }, - /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", NULL }, - /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL }, - /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL }, - /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL }, - /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value }, -}; - -static struct notify2_message_table job_notify_table[] = { - /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL }, - /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL }, - /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL }, - /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string }, - /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL }, - /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL }, - /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL }, - /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL }, - /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL }, - /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL }, - /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value }, - /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL }, - /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL }, - /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string }, - /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL }, - /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL }, - /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time }, - /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL }, - /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL }, - /* 0x13 */ { "JOB_NOTIFY_TIME", NULL }, - /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value }, - /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL }, - /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value }, - /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL }, -}; /*********************************************************************** Send a change notication message on all handles which have a call back registered **********************************************************************/ -static void process_notify2_message(struct spoolss_notify_msg *msg, - TALLOC_CTX *mem_ctx) +static void send_spoolss_event_notification(PRINTER_MESSAGE_INFO *msg) { - Printer_entry *p; - - for (p = printers_list; p; p = p->next) { - SPOOL_NOTIFY_INFO_DATA *data; - uint32 data_len = 1; - uint32 id; - - /* Is there notification on this handle? */ - - if (!p->notify.client_connected) - continue; - - /* For this printer? Print servers always receive - notifications. */ - - if (p->printer_type == PRINTER_HANDLE_IS_PRINTER && - !strequal(msg->printer, p->dev.handlename)) - continue; - - /* Are we monitoring this event? */ - - if (!is_monitoring_event(p, msg->type, msg->field)) - continue; - - /* OK - send the event to the client */ - - data = talloc(mem_ctx, sizeof(SPOOL_NOTIFY_INFO_DATA)); - - ZERO_STRUCTP(data); + Printer_entry *find_printer; + WERROR result; + NT_PRINTER_INFO_LEVEL *printer = NULL; - /* Convert unix jobid to smb jobid */ + if (!msg) { + DEBUG(0,("send_spoolss_event_notification: NULL msg pointer!\n")); + return; + } - id = msg->id; + for(find_printer = printers_list; find_printer; find_printer = find_printer->next) { - if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) { + /* + * If the entry has a connected client we send the message. There should + * only be one of these normally when dealing with the NT/2k spooler. + * However, iterate over all to make sure we deal with user applications + * in addition to spooler service. + * + * While we are only maintaining a single connection to the client, + * the FindFirstPrinterChangeNotification() call is made on a printer + * handle, so "client_connected" represents the whether or not the + * client asked for change notication on this handle. + * + * --jerry + */ - id = sysjob_to_jobid(msg->id); + if (find_printer->notify.client_connected==True) { + + /* does the client care about what changed? */ - if (id == -1) { - DEBUG(3, ("no such unix jobid %d\n", msg->id)); - goto done; + if (msg->flags && !is_client_monitoring_event(find_printer, msg->flags)) { + DEBUG(10,("send_spoolss_event_notification: Client [%s] not monitoring these events\n", + find_printer->client.machine)); + continue; } - } - construct_info_data(data, msg->type, msg->field, id); - - switch(msg->type) { - case PRINTER_NOTIFY_TYPE: - if (printer_notify_table[msg->field].fn) - printer_notify_table[msg->field].fn( - msg, data, mem_ctx); - else - goto done; - break; - case JOB_NOTIFY_TYPE: - if (job_notify_table[msg->field].fn) - job_notify_table[msg->field].fn( - msg, data, mem_ctx); + if (find_printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) + DEBUG(10,("send_spoolss_event_notification: printserver [%s]\n", find_printer->dev.printerservername )); else - goto done; - break; - default: - DEBUG(5, ("Unknown notification type %d\n", - msg->type)); - goto done; - } - - if (!p->notify.flags) - cli_spoolss_rrpcn( - &cli, mem_ctx, &p->notify.client_hnd, - data_len, data, p->notify.change, 0); - else { - NT_PRINTER_INFO_LEVEL *printer = NULL; + DEBUG(10,("send_spoolss_event_notification: printer [%s]\n", find_printer->dev.handlename)); - get_a_printer(&printer, 2, msg->printer); + /* + * if handle is a printer, only send if the printer_name matches. + * ...else if handle is a printerserver, send to all + */ - if (!printer) { - DEBUG(5, ("unable to load info2 for %s\n", - msg->printer)); - goto done; + if (*msg->printer_name && (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER) + && !strequal(msg->printer_name, find_printer->dev.handlename)) + { + DEBUG(10,("send_spoolss_event_notification: ignoring message sent to %s [%s]\n", + msg->printer_name, find_printer->dev.handlename )); + continue; } - /* XXX: This needs to be updated for - PRINTER_CHANGE_SET_PRINTER_DRIVER. */ - cli_spoolss_routerreplyprinter( - &cli, mem_ctx, &p->notify.client_hnd, - 0, printer->info_2->changeid); + /* lookup the printer if we have a name if we don't already have a + valid NT_PRINTER_INFO_LEVEL structure. And yes I'm assuming we + will always have a non-empty msg.printer_name */ + + if (!printer || !printer->info_2 || strcmp(msg->printer_name, printer->info_2->printername)) + { + + if (printer) { + free_a_printer(&printer, 2); + printer = NULL; + } + + result = get_a_printer(&printer, 2, msg->printer_name); + if (!W_ERROR_IS_OK(result)) + continue; + } - free_a_printer(&printer, 2); + /* issue the client call */ + + result = srv_spoolss_send_event_to_client(find_printer, &cli, msg, printer); + + if (!W_ERROR_IS_OK(result)) { + DEBUG(5,("send_spoolss_event_notification: Event notification failed [%s]\n", + dos_errstr(result))); } } -done: - return; } -/* Receive a notify2 message */ + return; +} +/*************************************************************************** + Receive the notify message and decode the message. Do not send + notification if we sent this originally as that would result in + duplicates. +****************************************************************************/ -static void receive_notify2_message(int msg_type, pid_t src, void *buf, - size_t len) +static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len) { - struct spoolss_notify_msg msg; - int offset = 0; - TALLOC_CTX *mem_ctx = talloc_init(); - - /* Unpack message */ - - ZERO_STRUCT(msg); - - offset += tdb_unpack((char *)buf + offset, len - offset, "f", - msg.printer); + PRINTER_MESSAGE_INFO msg; - offset += tdb_unpack((char *)buf + offset, len - offset, "ddddd", - &msg.type, &msg.field, &msg.id, &msg.len, &msg.flags); - - if (msg.len == 0) - tdb_unpack((char *)buf + offset, len - offset, "dd", - &msg.notify.value[0], &msg.notify.value[1]); - else - tdb_unpack((char *)buf + offset, len - offset, "B", - &msg.len, &msg.notify.data); - - DEBUG(3, ("got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x\n", - msg.type, msg.field, msg.flags)); - - if (msg.len == 0) - DEBUG(3, ("value1 = %d, value2 = %d\n", msg.notify.value[0], - msg.notify.value[1])); - else - dump_data(3, msg.notify.data, msg.len); - - /* Process message */ - - process_notify2_message(&msg, mem_ctx); - - /* Free message */ + if (len < sizeof(msg)) { + DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len)); + return; + } - if (msg.len > 0) - free(msg.notify.data); + memcpy(&msg, buf, sizeof(PRINTER_MESSAGE_INFO)); + + DEBUG(10,("srv_spoolss_receive_message: Got message printer change [queue = %s] low=0x%x high=0x%x flags=0x%x\n", + msg.printer_name, (unsigned int)msg.low, (unsigned int)msg.high, msg.flags )); - talloc_destroy(mem_ctx); + /* Iterate the printer list */ + + send_spoolss_event_notification(&msg); + } /*************************************************************************** - Server wrapper for cli_spoolss_routerreplyprinter() since the client - function can only send a single change notification at a time. - - FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER) - --jerry - **************************************************************************/ - -static WERROR srv_spoolss_routerreplyprinter (struct cli_state *reply_cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, PRINTER_MESSAGE_INFO *info, - NT_PRINTER_INFO_LEVEL *printer) + Send a notify event. +****************************************************************************/ + +static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low, uint32 flags) { - WERROR result; - uint32 condition = 0x0; + char msg[sizeof(PRINTER_MESSAGE_INFO)]; + PRINTER_MESSAGE_INFO info; - if (info->flags & PRINTER_MESSAGE_DRIVER) - condition = PRINTER_CHANGE_SET_PRINTER_DRIVER; - - result = cli_spoolss_routerreplyprinter(reply_cli, mem_ctx, pol, condition, - printer->info_2->changeid); - - return result; -} + ZERO_STRUCT(info); -/******************************************************************** - Send a message to ourself about new driver being installed - so we can upgrade the information for each printer bound to this - driver - ********************************************************************/ - -static BOOL srv_spoolss_drv_upgrade_printer(char* drivername) -{ - int len = strlen(drivername); + info.low = low; + info.high = high; + info.flags = flags; + fstrcpy(info.printer_name, printer_name); - if (!len) - return False; + memcpy(msg, &info, sizeof(PRINTER_MESSAGE_INFO)); - DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n", - drivername)); + DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x [%s], flags=0x%x\n", + low, high, printer_name, flags)); - message_send_pid(sys_getpid(), MSG_PRINTER_DRVUPGRADE, drivername, len+1, False); + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO), + False, NULL); return True; -} - -/********************************************************************** - callback to receive a MSG_PRINTER_DRVUPGRADE message and interate - over all printers, upgrading ones as neessary - **********************************************************************/ - -void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len) -{ - fstring drivername; - int snum; - int n_services = lp_numservices(); - - len = MIN(len,sizeof(drivername)-1); - strncpy(drivername, buf, len); - - DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername )); - - /* Iterate the printer list */ - - for (snum=0; snum<n_services; snum++) - { - if (lp_snum_ok(snum) && lp_print_ok(snum) ) - { - WERROR result; - NT_PRINTER_INFO_LEVEL *printer = NULL; - - result = get_a_printer(&printer, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(result)) - continue; - - if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername)) - { - DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername)); - - /* all we care about currently is the change_id */ - - result = mod_a_printer(*printer, 2); - if (!W_ERROR_IS_OK(result)) { - DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n", - dos_errstr(result))); - } - } - - free_a_printer(&printer, 2); - } - } - - /* all done */ -} +} /******************************************************************** Copy routines used by convert_to_openprinterex() @@ -1126,6 +924,16 @@ Can't find printer handle we created for printer %s\n", name )); return WERR_INVALID_PRINTER_NAME; } +/* + if (printer_default->datatype_ptr != NULL) + { + unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1); + set_printer_hnd_datatype(handle, datatype); + } + else + set_printer_hnd_datatype(handle, ""); +*/ + /* First case: the user is opening the print server: @@ -1189,7 +997,7 @@ Can't find printer handle we created for printer %s\n", name )); user_in_list(uidtoname(user.uid), lp_printer_admin(snum))) return WERR_OK; - + close_printer_handle(p, handle); return WERR_ACCESS_DENIED; } @@ -1223,9 +1031,7 @@ Can't find printer handle we created for printer %s\n", name )); printer_default->access_required = PRINTER_ACCESS_USE; } - /* check smb.conf parameters and the the sec_desc */ - - if (!user_ok(uidtoname(user.uid), snum) || !print_access_check(&user, snum, printer_default->access_required)) { + if (!print_access_check(&user, snum, printer_default->access_required)) { DEBUG(3, ("access DENIED for printer open\n")); close_printer_handle(p, handle); return WERR_ACCESS_DENIED; @@ -1502,6 +1308,10 @@ WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL update_c_setprinter(False); + if (W_ERROR_IS_OK(result)) { + srv_spoolss_sendnotify(Printer->dev.handlename, 0, PRINTER_CHANGE_DELETE_PRINTER, 0x0); + } + return result; } @@ -1534,17 +1344,26 @@ static int get_version_id (char * arch) /******************************************************************** * _spoolss_deleteprinterdriver + * + * We currently delete the driver for the architecture only. + * This can leave the driver for other archtectures. However, + * since every printer associates a "Windows NT x86" driver name + * and we cannot delete that one while it is in use, **and** since + * it is impossible to assign a driver to a Samba printer without + * having the "Windows NT x86" driver installed,... + * + * ....we should not get into trouble here. + * + * --jerry ********************************************************************/ -WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u) +WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, + SPOOL_R_DELETEPRINTERDRIVER *r_u) { fstring driver; fstring arch; NT_PRINTER_DRIVER_INFO_LEVEL info; int version; - struct current_user user; - - get_current_user(&user, p); unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); @@ -1554,89 +1373,21 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER /* this is what NT returns */ return WERR_INVALID_ENVIRONMENT; } - - /* if they said "Windows NT x86", then try for version 2 & 3 */ - - if ( version == 2 ) - version = DRIVER_ANY_VERSION; ZERO_STRUCT(info); - - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { return WERR_UNKNOWN_PRINTER_DRIVER; - - if (printer_driver_in_use(info.info_3)) - return WERR_PRINTER_DRIVER_IN_USE; - - return delete_printer_driver(info.info_3, &user, DRIVER_ANY_VERSION, False); -} - -/******************************************************************** - * spoolss_deleteprinterdriverex - ********************************************************************/ - -WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u) -{ - fstring driver; - fstring arch; - NT_PRINTER_DRIVER_INFO_LEVEL info; - int version; - uint32 flags = q_u->delete_flags; - BOOL delete_files; - struct current_user user; - - get_current_user(&user, p); - - unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); - unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); - - /* check that we have a valid driver name first */ - if ((version=get_version_id(arch)) == -1) { - /* this is what NT returns */ - return WERR_INVALID_ENVIRONMENT; } - if ( flags & DPD_DELETE_SPECIFIC_VERSION ) - version = q_u->version; - else if ( version == 2 ) - /* if they said "Windows NT x86", then try for version 2 & 3 */ - version = DRIVER_ANY_VERSION; - - ZERO_STRUCT(info); - - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) - return WERR_UNKNOWN_PRINTER_DRIVER; - - if ( printer_driver_in_use(info.info_3) ) - return WERR_PRINTER_DRIVER_IN_USE; - - /* - * we have a couple of cases to consider. - * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set, - * then the delete should fail if **any** files overlap with - * other drivers - * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all - * non-overlapping files - * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES - * is set, the do not delete any files - * Refer to MSDN docs on DeletePrinterDriverEx() for details. - */ - - delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); - - if ( delete_files ) + + if (printer_driver_in_use(arch, driver)) { - /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ - - if ( printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) - /* no idea of the correct error here */ - return WERR_ACCESS_DENIED; + return WERR_PRINTER_DRIVER_IN_USE; } - return delete_printer_driver(info.info_3, &user, version, delete_files); + return delete_printer_driver(info.info_3); } - /******************************************************************** GetPrinterData on a printer server Handle. ********************************************************************/ @@ -1687,11 +1438,7 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type = 0x4; if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL) return False; -#ifndef EMULATE_WIN2K_HACK /* JERRY */ SIVAL(*data, 0, 2); -#else - SIVAL(*data, 0, 3); -#endif *needed = 0x4; return True; } @@ -1859,96 +1606,6 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO return WERR_OK; } -/********************************************************* - Connect to the client machine. -**********************************************************/ - -static BOOL spoolss_connect_to_client(struct cli_state *the_cli, char *remote_machine) -{ - extern pstring global_myname; - - ZERO_STRUCTP(the_cli); - if(cli_initialise(the_cli) == NULL) { - DEBUG(0,("connect_to_client: unable to initialize client connection.\n")); - return False; - } - - if(!resolve_name( remote_machine, &the_cli->dest_ip, 0x20)) { - DEBUG(0,("connect_to_client: Can't resolve address for %s\n", remote_machine)); - cli_shutdown(the_cli); - return False; - } - - if (ismyip(the_cli->dest_ip)) { - DEBUG(0,("connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); - cli_shutdown(the_cli); - return False; - } - - if (!cli_connect(the_cli, remote_machine, &the_cli->dest_ip)) { - DEBUG(0,("connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); - cli_shutdown(the_cli); - return False; - } - - if (!attempt_netbios_session_request(the_cli, global_myname, remote_machine, &the_cli->dest_ip)) { - DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n", - remote_machine)); - return False; - } - - the_cli->protocol = PROTOCOL_NT1; - - if (!cli_negprot(the_cli)) { - DEBUG(0,("connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); - cli_shutdown(the_cli); - return False; - } - - if (the_cli->protocol != PROTOCOL_NT1) { - DEBUG(0,("connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine)); - cli_shutdown(the_cli); - return False; - } - - /* - * Do an anonymous session setup. - */ - - if (!cli_session_setup(the_cli, "", "", 0, "", 0, "")) { - DEBUG(0,("connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); - cli_shutdown(the_cli); - return False; - } - - if (!(the_cli->sec_mode & 1)) { - DEBUG(0,("connect_to_client: machine %s isn't in user level security mode\n", remote_machine)); - cli_shutdown(the_cli); - return False; - } - - if (!cli_send_tconX(the_cli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(the_cli) )); - cli_shutdown(the_cli); - return False; - } - - /* - * Ok - we have an anonymous connection to the IPC$ share. - * Now start the NT Domain stuff :-). - */ - - if(cli_nt_session_open(the_cli, PIPE_SPOOLSS) == False) { - DEBUG(0,("connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli))); - cli_nt_session_close(the_cli); - cli_ulogoff(the_cli); - cli_shutdown(the_cli); - return False; - } - - return True; -} - /*************************************************************************** Connect to the client. ****************************************************************************/ @@ -1969,14 +1626,15 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin if(!spoolss_connect_to_client(&cli, unix_printer)) return False; - message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message); + message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message); + } smb_connections++; result = cli_spoolss_reply_open_printer(&cli, cli.mem_ctx, printer, localprinter, type, handle); - + if (!W_ERROR_IS_OK(result)) DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n", dos_errstr(result))); @@ -1988,8 +1646,9 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin * _spoolss_rffpcnex * ReplyFindFirstPrinterChangeNotifyEx * - * before replying OK: status=0 a rpc call is made to the workstation - * asking ReplyOpenPrinter + * jfmxxxx: before replying OK: status=0 + * should do a rpc call to the workstation asking ReplyOpenPrinter + * have to code it, later. * * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe * called from api_spoolss_rffpcnex @@ -2022,17 +1681,15 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE Printer->notify.option=dup_spool_notify_option(option); - unistr2_to_ascii(Printer->notify.localmachine, localmachine, - sizeof(Printer->notify.localmachine)-1); - - /* Connect to the client machine and send a ReplyOpenPrinter */ + unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1); - if(!srv_spoolss_replyopenprinter(Printer->notify.localmachine, + /* connect to the client machine and send a ReplyOpenPrinter */ + if(srv_spoolss_replyopenprinter(Printer->notify.localmachine, Printer->notify.printerlocal, 1, &Printer->notify.client_hnd)) - return WERR_SERVER_UNAVAILABLE; - - Printer->notify.client_connected=True; + { + Printer->notify.client_connected=True; + } return WERR_OK; } @@ -2054,7 +1711,7 @@ void spoolss_notify_server_name(int snum, len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2089,7 +1746,7 @@ void spoolss_notify_printer_name(int snum, len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2115,7 +1772,7 @@ void spoolss_notify_share_name(int snum, len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2143,7 +1800,7 @@ void spoolss_notify_port_name(int snum, len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2169,8 +1826,7 @@ void spoolss_notify_driver_name(int snum, uint32 len; len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE); - - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2199,7 +1855,7 @@ void spoolss_notify_comment(int snum, else len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2226,7 +1882,7 @@ void spoolss_notify_location(int snum, len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2265,7 +1921,7 @@ void spoolss_notify_sepfile(int snum, len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2292,7 +1948,7 @@ void spoolss_notify_print_processor(int snum, len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2319,7 +1975,7 @@ void spoolss_notify_parameters(int snum, len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2346,7 +2002,7 @@ void spoolss_notify_datatype(int snum, len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2506,7 +2162,7 @@ static void spoolss_notify_username(int snum, len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2546,7 +2202,7 @@ static void spoolss_notify_job_name(int snum, len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2596,7 +2252,7 @@ static void spoolss_notify_job_status_string(int snum, len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE); - data->notify_data.data.length = len; + data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); if (!data->notify_data.data.string) { @@ -2720,6 +2376,8 @@ static void spoolss_notify_submitted_time(int snum, SSVAL(p, 14, st.milliseconds); } +#define END 65535 + struct s_notify_info_data_table { uint16 type; @@ -2731,61 +2389,59 @@ struct s_notify_info_data_table NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); }; -/* A table describing the various print notification constants and - whether the notification data is a pointer to a variable sized - buffer, a one value uint32 or a two value uint32. */ - struct s_notify_info_data_table notify_info_data_table[] = { -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, spoolss_notify_security_desc }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL }, -{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed }, -{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, spoolss_notify_submitted_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, spoolss_notify_total_pages }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, spoolss_notify_pages_printed }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL }, +{ END, END, "", END, NULL } }; /******************************************************************* @@ -2796,46 +2452,43 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field) { int i=0; - for (i = 0; i < sizeof(notify_info_data_table); i++) { - if (notify_info_data_table[i].type == type && - notify_info_data_table[i].field == field) { - switch(notify_info_data_table[i].size) { - case NOTIFY_ONE_VALUE: - case NOTIFY_TWO_VALUE: - return 1; - case NOTIFY_STRING: - return 2; - - /* The only pointer notify data I have seen on - the wire is the submitted time and this has - the notify size set to 4. -tpot */ - - case NOTIFY_POINTER: - return 4; - } + while (notify_info_data_table[i].type != END) + { + if ( (notify_info_data_table[i].type == type ) && + (notify_info_data_table[i].field == field ) ) + { + return (notify_info_data_table[i].size); } + i++; } - - DEBUG(5, ("invalid notify data type %d/%d\n", type, field)); - - return 0; + return (65535); } /******************************************************************* Return the type of notify_info_data. ********************************************************************/ -static int type_of_notify_info_data(uint16 type, uint16 field) +static BOOL type_of_notify_info_data(uint16 type, uint16 field) { int i=0; - for (i = 0; i < sizeof(notify_info_data_table); i++) { - if (notify_info_data_table[i].type == type && - notify_info_data_table[i].field == field) - return notify_info_data_table[i].size; + while (notify_info_data_table[i].type != END) + { + if ( (notify_info_data_table[i].type == type ) && + (notify_info_data_table[i].field == field ) ) + { + if (notify_info_data_table[i].size == POINTER) + { + return (False); + } + else + { + return (True); + } + } + i++; } - - return False; + return (False); } /**************************************************************************** @@ -2843,18 +2496,21 @@ static int type_of_notify_info_data(uint16 type, uint16 field) static int search_notify(uint16 type, uint16 field, int *value) { - int i; + int j; + BOOL found; - for (i = 0; i < sizeof(notify_info_data_table); i++) { - if (notify_info_data_table[i].type == type && - notify_info_data_table[i].field == field && - notify_info_data_table[i].fn != NULL) { - *value = i; - return True; - } + for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++) + { + if ( (notify_info_data_table[j].type == type ) && + (notify_info_data_table[j].field == field ) ) + found=True; } - - return False; + *value=--j; + + if ( found && (notify_info_data_table[j].fn != NULL) ) + return True; + else + return False; } /**************************************************************************** @@ -2865,12 +2521,7 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 info_data->type = type; info_data->field = field; info_data->reserved = 0; - - if (type == JOB_NOTIFY_TYPE) - info_data->id = id; - else - info_data->id = 0; - + info_data->id = id; info_data->size = size_of_notify_info_data(type, field); info_data->enc_type = type_of_notify_info_data(type, field); } @@ -2919,7 +2570,7 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int current_data=&info->data[info->count]; - construct_info_data(current_data, type, field, id); + construct_info_data(current_data, type, field, id); DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n", notify_info_data_table[j].name, snum, printer->info_2->printername )); @@ -3161,6 +2812,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u) { POLICY_HND *handle = &q_u->handle; +/* uint32 change = q_u->change; - notused. */ /* SPOOL_NOTIFY_OPTION *option = q_u->option; - notused. */ SPOOL_NOTIFY_INFO *info = &r_u->info; @@ -3178,19 +2830,17 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN DEBUG(4,("Printer type %x\n",Printer->printer_type)); - /* - * We are now using the change value, and + /* jfm: the change value isn't used right now. + * we will honour it when + * a) we'll be able to send notification to the client + * b) we'll have a way to communicate between the spoolss process. + * + * same thing for option->flags * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as * I don't have a global notification system, I'm sending back all the * informations even when _NOTHING_ has changed. */ - /* We need to keep track of the change value to send back in - RRPCN replies otherwise our updates are ignored. */ - - if (Printer->notify.client_connected) - Printer->notify.change = q_u->change; - /* just ignore the SPOOL_NOTIFY_OPTION */ switch (Printer->printer_type) { @@ -3282,7 +2932,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum) printer->global_counter = global_counter; printer->total_pages = 0; -#ifndef EMULATE_WIN2K_HACK /* JERRY */ +#if 0 /* JERRY */ printer->major_version = 0x0004; /* NT 4 */ printer->build_version = 0x0565; /* build 1381 */ #else @@ -3321,6 +2971,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum) * construct_printer_info_1 * fill a printer_info_1 struct ********************************************************************/ + static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int snum) { pstring chaine; @@ -3395,10 +3046,8 @@ static DEVICEMODE *construct_dev_mode(int snum) if (printer->info_2->devmode) ntdevmode = dup_nt_devicemode(printer->info_2->devmode); - if (ntdevmode == NULL) { - DEBUG(5, ("BONG! There was no device mode!\n")); + if (ntdevmode == NULL) goto fail; - } DEBUGADD(8,("loading DEVICEMODE\n")); @@ -3759,26 +3408,10 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, enum_all_printers_info_1_network. *********************************************************************/ -static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - char *s = name; - DEBUG(4,("enum_all_printers_info_1_network\n")); - /* If we respond to a enum_printers level 1 on our name with flags - set to PRINTER_ENUM_REMOTE with a list of printers then these - printers incorrectly appear in the APW browse list. - Specifically the printers for the server appear at the workgroup - level where all the other servers in the domain are - listed. Windows responds to this call with a - WERR_CAN_NOT_COMPLETE so we should do the same. */ - - if (name[0] == '\\' && name[1] == '\\') - s = name + 2; - - if (is_myname_or_ipaddr(s)) - return WERR_CAN_NOT_COMPLETE; - return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned); } @@ -3816,9 +3449,9 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3 } /* check the required size. */ - for (i=0; i<*returned; i++) + for (i=0; i<*returned; i++) (*needed) += spoolss_size_printer_info_2(&printers[i]); - + if (!alloc_buffer_size(buffer, *needed)) { for (i=0; i<*returned; i++) { free_devmode(printers[i].devmode); @@ -3865,7 +3498,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name, return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned); if (flags & PRINTER_ENUM_NETWORK) - return enum_all_printers_info_1_network(name, buffer, offered, needed, returned); + return enum_all_printers_info_1_network(buffer, offered, needed, returned); return WERR_OK; /* NT4sp5 does that */ } @@ -4048,7 +3681,7 @@ static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, u /* check the required size. */ *needed += spoolss_size_printer_info_2(printer); - + if (!alloc_buffer_size(buffer, *needed)) { free_printer_info_2(printer); return WERR_INSUFFICIENT_BUFFER; @@ -5095,7 +4728,6 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer) { - extern userdom_struct current_user_info; char *cmd = lp_addprinter_cmd(); char **qlines; pstring command; @@ -5110,13 +4742,13 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer) get_called_name()); /* change \ to \\ for the shell */ all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring)); - standard_sub_basic(current_user_info.smb_name, 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, printer->info_2->portname, printer->info_2->drivername, printer->info_2->location, driverlocation, remote_machine); + /* Convert script args to unix-codepage */ DEBUG(10,("Running [%s]\n", command)); ret = smbrun(command, &fd); DEBUGADD(10,("returned [%d]\n", ret)); @@ -5407,10 +5039,13 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, int snum; NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + PRINTER_MESSAGE_INFO msg; WERROR result; DEBUG(8,("update_printer\n")); - + + ZERO_STRUCT(msg); + result = WERR_OK; if (level!=2) { @@ -5524,11 +5159,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, * bound to the printer, simulating what happens in the Windows arch. */ if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){ - if (!set_driver_init(printer, 2)) { - DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n", - printer->info_2->drivername)); - } - notify_printer_driver(snum, printer->info_2->drivername); + set_driver_init(printer, 2); + msg.flags |= PRINTER_MESSAGE_DRIVER; } } @@ -5539,18 +5171,28 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, all the possible changes */ if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) - notify_printer_comment(snum, printer->info_2->comment); + msg.flags |= PRINTER_MESSAGE_COMMENT; if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) - notify_printer_sharename(snum, printer->info_2->sharename); + msg.flags |= PRINTER_MESSAGE_SHARENAME; if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) - notify_printer_port(snum, printer->info_2->portname); + msg.flags |= PRINTER_MESSAGE_PORT; if (!strequal(printer->info_2->location, old_printer->info_2->location)) - notify_printer_location(snum, printer->info_2->location); + msg.flags |= PRINTER_MESSAGE_LOCATION; -done: + ZERO_STRUCT(msg); + + msg.low = PRINTER_CHANGE_ADD_PRINTER; + fstrcpy(msg.printer_name, printer->info_2->printername); + + /* only send a notify if something changed */ + if (msg.flags) { + srv_spoolss_sendnotify(msg.printer_name, 0, PRINTER_CHANGE_ADD_PRINTER, msg.flags); + } + + done: free_a_printer(&printer, 2); free_a_printer(&old_printer, 2); @@ -5668,7 +5310,7 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue, static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, int position, int snum, - NT_PRINTER_INFO_LEVEL *ntprinter, + NT_PRINTER_INFO_LEVEL *ntprinter, DEVICEMODE *devmode) { pstring temp_name; @@ -5785,7 +5427,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, *returned = 0; goto done; } - + if (!(devmode = construct_dev_mode(snum))) { *returned = 0; result = WERR_NOMEM; @@ -5828,7 +5470,6 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, SAFE_FREE(info); return result; - } /**************************************************************************** @@ -5897,6 +5538,8 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u { POLICY_HND *handle = &q_u->handle; uint32 jobid = q_u->jobid; +/* uint32 level = q_u->level; - notused. */ +/* JOB_INFO *ctr = &q_u->ctr; - notused. */ uint32 command = q_u->command; struct current_user user; @@ -5954,7 +5597,9 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture *returned=0; - for (version=0; version<DRIVER_MAX_VERSION; version++) { +#define MAX_VERSION 4 + + for (version=0; version<MAX_VERSION; version++) { list=NULL; ndrivers=get_ntdrivers(&list, architecture, version); DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); @@ -6033,7 +5678,9 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture *returned=0; - for (version=0; version<DRIVER_MAX_VERSION; version++) { +#define MAX_VERSION 4 + + for (version=0; version<MAX_VERSION; version++) { list=NULL; ndrivers=get_ntdrivers(&list, architecture, version); DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); @@ -6113,7 +5760,9 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture *returned=0; - for (version=0; version<DRIVER_MAX_VERSION; version++) { +#define MAX_VERSION 4 + + for (version=0; version<MAX_VERSION; version++) { list=NULL; ndrivers=get_ntdrivers(&list, architecture, version); DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); @@ -6766,6 +6415,9 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_ } update_c_setprinter(False); + + srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0); + free_a_printer(&printer,2); return WERR_OK; @@ -6810,12 +6462,10 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, 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); + get_current_user(&user, p); if (!convert_printer_driver_info(info, &driver, level)) { err = WERR_NOMEM; @@ -6839,131 +6489,11 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, goto done; } - /* BEGIN_ADMIN_LOG */ - switch(level) { - case 3: - sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.", - driver.info_3->name,drv_ver_to_os[driver.info_3->cversion],uidtoname(user.uid)); - fstrcpy(driver_name, driver.info_3->name); - break; - case 6: - sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.", - driver.info_6->name,drv_ver_to_os[driver.info_6->version],uidtoname(user.uid)); - fstrcpy(driver_name, driver.info_6->name); - break; - } - /* END_ADMIN_LOG */ - - /* - * I think this is where he DrvUpgradePrinter() hook would be - * be called in a driver's interface DLL on a Windows NT 4.0/2k - * server. Right now, we just need to send ourselves a message - * to update each printer bound to this driver. --jerry - */ - - if (!srv_spoolss_drv_upgrade_printer(driver_name)) { - DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n", - driver_name)); - } - - /* - * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp), - * decide if the driver init data should be deleted. The rules are: - * 1) never delete init data if it is a 9x driver, they don't use it anyway - * 2) delete init data only if there is no 2k/Xp driver - * 3) always delete init data - * The generalized rule is always use init data from the highest order driver. - * It is necessary to follow the driver install by an initialization step to - * finish off this process. - */ - if (level == 3) - version = driver.info_3->cversion; - else if (level == 6) - version = driver.info_6->version; - else - version = -1; - switch (version) { - /* - * 9x printer driver - never delete init data - */ - case 0: - DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n", - driver_name)); - break; - - /* - * Nt or 2k (compatiblity mode) printer driver - only delete init data if - * there is no 2k/Xp driver init data for this driver name. - */ - case 2: - { - NT_PRINTER_DRIVER_INFO_LEVEL driver1; - - if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) { - /* - * No 2k/Xp driver found, delete init data (if any) for the new Nt driver. - */ - if (!del_driver_init(driver_name)) - DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name)); - } else { - /* - * a 2k/Xp driver was found, don't delete init data because Nt driver will use it. - */ - free_a_printer_driver(driver1,3); - DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n", - driver_name)); - } - } - break; - - /* - * 2k or Xp printer driver - always delete init data - */ - case 3: - if (!del_driver_init(driver_name)) - DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name)); - break; - - default: - DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level)); - break; - } - - -done: + done: free_a_printer_driver(driver, level); return err; } -/******************************************************************** - * spoolss_addprinterdriverex - ********************************************************************/ - -WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u) -{ - SPOOL_Q_ADDPRINTERDRIVER q_u_local; - SPOOL_R_ADDPRINTERDRIVER r_u_local; - - /* - * we only support the semantics of AddPrinterDriver() - * i.e. only copy files that are newer than existing ones - */ - - if ( q_u->copy_flags != APD_COPY_NEW_FILES ) - return WERR_ACCESS_DENIED; - - /* just pass the information off to _spoolss_addprinterdriver() */ - ZERO_STRUCT(q_u_local); - ZERO_STRUCT(r_u_local); - - q_u_local.server_name_ptr = q_u->server_name_ptr; - copy_unistr2(&q_u_local.server_name, &q_u->server_name); - q_u_local.level = q_u->level; - memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) ); - - return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local ); -} - /**************************************************************************** ****************************************************************************/ @@ -7102,6 +6632,23 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S if ( (in_value_len==0) && (in_data_len==0) ) { DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); +#if 0 + /* + * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS + * if this parameter size doesn't exist. + * Ok - my opinion here is that the client is not asking for the greatest + * possible size of all the parameters, but is asking specifically for the size needed + * for this specific parameter. In that case we can remove the loop below and + * simplify this lookup code considerably. JF - comments welcome. JRA. + */ + + if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) { + SAFE_FREE(data); + free_a_printer(&printer, 2); + return WERR_NO_MORE_ITEMS; + } +#endif + SAFE_FREE(data); param_index=0; @@ -7145,7 +6692,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL) return WERR_NOMEM; - *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0); + *out_value_len = rpcstr_push((char *)*out_value, "", in_value_len, 0); /* the data is counted in bytes */ *out_max_data_len = in_data_len; @@ -7173,7 +6720,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S return WERR_NOMEM; } - *out_value_len = (uint32)rpcstr_push((char *)*out_value,value, in_value_len, 0); + *out_value_len = rpcstr_push((char *)*out_value,value, in_value_len, 0); *out_type=type; @@ -7200,8 +6747,10 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP POLICY_HND *handle = &q_u->handle; UNISTR2 *value = &q_u->value; uint32 type = q_u->type; +/* uint32 max_len = q_u->max_len; - notused. */ uint8 *data = q_u->data; uint32 real_len = q_u->real_len; +/* uint32 numeric_data = q_u->numeric_data; - notused. */ NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_PARAM *param = NULL, old_param; @@ -7473,6 +7022,8 @@ done: WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u) { POLICY_HND *handle = &q_u->handle; +/* UNISTR2 *uni_name = &q_u->name; - notused. */ +/* uint32 level = q_u->level; - notused. */ FORM *form = &q_u->form; nt_forms_struct tmpForm; int snum; @@ -7563,10 +7114,12 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u) { +/* UNISTR2 *name = &q_u->name; - notused. */ +/* UNISTR2 *environment = &q_u->environment; - notused. */ uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + NEW_BUFFER *buffer = NULL; uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; + uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; /* that's an [in out] buffer */ @@ -7630,6 +7183,8 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u) { +/* UNISTR2 *name = &q_u->name; - notused. */ +/* UNISTR2 *processor = &q_u->processor; - notused. */ uint32 level = q_u->level; NEW_BUFFER *buffer = NULL; uint32 offered = q_u->offered; @@ -7724,10 +7279,11 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u) { +/* UNISTR2 *name = &q_u->name; - notused. */ uint32 level = q_u->level; - NEW_BUFFER *buffer = NULL; + NEW_BUFFER *buffer = NULL; uint32 offered = q_u->offered; - uint32 *needed = &r_u->needed; + uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; /* that's an [in out] buffer */ @@ -7871,7 +7427,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin free_job_info_2(info_2); /* Also frees devmode */ SAFE_FREE(info_2); free_a_printer(&ntprinter, 2); - + return ret; } @@ -8038,34 +7594,6 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, return _spoolss_setprinterdata(p, &q_u_local, &r_u_local); } - -/******************************************************************** - * spoolss_deleteprinterdataex - ********************************************************************/ - -WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX *q_u, SPOOL_R_DELETEPRINTERDATAEX *r_u) -{ - SPOOL_Q_DELETEPRINTERDATA q_u_local; - SPOOL_R_DELETEPRINTERDATA r_u_local; - fstring key; - - /* From MSDN documentation of SetPrinterDataEx: pass request to - SetPrinterData if key is "PrinterDriverData" */ - - unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); - - if (strcmp(key, "PrinterDriverData") != 0) - return WERR_INVALID_PARAM; - - memcpy(&q_u_local.handle, &q_u->handle, sizeof(POLICY_HND)); - copy_unistr2(&q_u_local.valuename, &q_u->valuename); - - return _spoolss_deleteprinterdata( p, &q_u_local, &r_u_local ); -} - - - - /******************************************************************** * spoolss_enumprinterkey ********************************************************************/ @@ -8133,34 +7661,6 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO } /******************************************************************** - * spoolss_deleteprinterkey - ********************************************************************/ - -WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, SPOOL_R_DELETEPRINTERKEY *r_u) -{ - Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle); - fstring key; - - if (!Printer) { - DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle))); - return WERR_BADFID; - } - - unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); - - if (strcmp(key, "PrinterDriverData") != 0) - return WERR_INVALID_PARAM; - - /* - * this is what 2k returns when you try to delete the "PrinterDriverData" - * key - */ - - return WERR_ACCESS_DENIED; -} - - -/******************************************************************** * spoolss_enumprinterdataex ********************************************************************/ @@ -8301,7 +7801,7 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1); - if (get_short_archi(short_archi, long_archi)==False) + if (get_short_archi(short_archi, long_archi)==FALSE) return WERR_INVALID_ENVIRONMENT; if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL) @@ -8334,7 +7834,6 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC NEW_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; - WERROR result; /* that's an [in out] buffer */ spoolss_move_buffer(q_u->buffer, &r_u->buffer); @@ -8346,13 +7845,12 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC switch(level) { case 1: - result = getprintprocessordirectory_level_1 + return getprintprocessordirectory_level_1 (&q_u->name, &q_u->environment, buffer, offered, needed); default: - result = WERR_UNKNOWN_LEVEL; + return WERR_UNKNOWN_LEVEL; } - return result; + return WERR_ACCESS_DENIED; } - diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c index 5e1c005d54..ee4ec8aa0a 100644 --- a/source3/rpc_server/srv_srvsvc.c +++ b/source3/rpc_server/srv_srvsvc.c @@ -25,9 +25,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /******************************************************************* api_srv_net_srv_get_info ********************************************************************/ @@ -495,25 +492,25 @@ static BOOL api_srv_net_file_set_secdesc(pipes_struct *p) \PIPE\srvsvc commands ********************************************************************/ -static const struct api_struct api_srv_cmds[] = +struct api_struct api_srv_cmds[] = { - { "SRV_NET_CONN_ENUM" , SRV_NET_CONN_ENUM , api_srv_net_conn_enum }, - { "SRV_NET_SESS_ENUM" , SRV_NET_SESS_ENUM , api_srv_net_sess_enum }, - { "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all }, - { "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_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}, - { NULL , 0 , NULL } + { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum }, + { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum }, + { "SRV_NETSHAREENUM_ALL" , SRV_NETSHAREENUM_ALL , api_srv_net_share_enum_all }, + { "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , 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_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_NETFILEENUM" , SRV_NETFILEENUM , 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_NETFILEQUERYSECDESC",SRV_NETFILEQUERYSECDESC,api_srv_net_file_query_secdesc}, + { "SRV_NETFILESETSECDESC" , SRV_NETFILESETSECDESC , api_srv_net_file_set_secdesc}, + { NULL , 0 , NULL } }; /******************************************************************* diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index b5f6bd2f07..1f3b1945e3 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -23,9 +23,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - extern pstring global_myname; /******************************************************************* @@ -41,7 +38,7 @@ static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int sn pstrcpy(net_name, lp_servicename(snum)); pstrcpy(remark, lp_comment(snum)); - standard_sub_conn(p->conn, remark,sizeof(remark)); + standard_sub_conn(p->conn, remark); len_net_name = strlen(net_name); /* work out the share type */ @@ -73,7 +70,7 @@ static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int sn pstrcpy(net_name, lp_servicename(snum)); pstrcpy(remark, lp_comment(snum)); - standard_sub_conn(p->conn, remark,sizeof(remark)); + standard_sub_conn(p->conn, remark); pstrcpy(path, "C:"); pstrcat(path, lp_pathname(snum)); @@ -311,7 +308,7 @@ void map_generic_share_sd_bits(SEC_DESC *psd) Can this user access with share with the required permissions ? ********************************************************************/ -BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access) +BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access) { uint32 granted; NTSTATUS status; @@ -319,6 +316,7 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u SEC_DESC *psd = NULL; size_t sd_size; NT_USER_TOKEN *token = NULL; + user_struct *vuser = get_valid_user_struct(vuid); BOOL ret = True; mem_ctx = talloc_init(); @@ -357,7 +355,7 @@ static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, pstrcpy(net_name, lp_servicename(snum)); pstrcpy(remark, lp_comment(snum)); - standard_sub_conn(p->conn, remark, sizeof(remark)); + standard_sub_conn(p->conn, remark); len_net_name = strlen(net_name); @@ -396,7 +394,7 @@ 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_conn(p->conn, remark); pstrcpy(path, "C:"); pstrcat(path, lp_pathname(snum)); @@ -640,13 +638,11 @@ static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0, char * static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot) { - struct sessionid *session_list; uint32 num_entries = 0; - (*stot) = list_sessions(&session_list); + (*stot) = 1; if (ss0 == NULL) { (*snum) = 0; - SAFE_FREE(session_list); return; } @@ -655,7 +651,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); + &ss0->info_0_str[num_entries], "MACHINE"); /* move on to creating next session */ /* move on to creating next sess */ @@ -675,7 +671,6 @@ static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto ss0->ptr_sess_info = 0; ss0->num_entries_read2 = 0; } - SAFE_FREE(session_list); } /******************************************************************* @@ -698,13 +693,11 @@ static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1, static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot) { - struct sessionid *session_list; uint32 num_entries = 0; - (*stot) = list_sessions(&session_list); + (*stot) = 1; if (ss1 == NULL) { (*snum) = 0; - SAFE_FREE(session_list); return; } @@ -713,10 +706,8 @@ static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto 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); + &ss1->info_1_str[num_entries], + "MACHINE", "dummy_user", 1, 10, 5, 0); /* move on to creating next session */ /* move on to creating next sess */ @@ -951,45 +942,73 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n, } /******************************************************************* + fill in a file info level 3 structure. + ********************************************************************/ + +static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3, + uint32 fnum, uint32 perms, uint32 num_locks, + char *path_name, char *user_name) +{ + init_srv_file_info3(fl3 , fnum, perms, num_locks, path_name, user_name); + init_srv_file_info3_str(str3, path_name, user_name); +} + +/******************************************************************* + fill in a file info level 3 structure. + ********************************************************************/ + +static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot) +{ + uint32 num_entries = 0; + (*ftot) = 1; + + if (fl3 == NULL) { + (*fnum) = 0; + return; + } + + DEBUG(5,("init_srv_file_3_fl3\n")); + + for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++) { + init_srv_file_3_info(&fl3->info_3[num_entries], + &fl3->info_3_str[num_entries], + (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user"); + + /* move on to creating next file */ + num_entries++; + } + + fl3->num_entries_read = num_entries; + fl3->ptr_file_info = num_entries > 0 ? 1 : 0; + fl3->num_entries_read2 = num_entries; + + if ((*fnum) >= (*ftot)) { + (*fnum) = 0; + } +} + +/******************************************************************* makes a SRV_R_NET_FILE_ENUM structure. ********************************************************************/ -static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr, +static WERROR init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr, int switch_value, uint32 *resume_hnd, uint32 *total_entries) { 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 */ ctr->switch_value = switch_value; - ctr->num_entries = *total_entries - *resume_hnd; - if (ctr->num_entries < 0) - ctr->num_entries = 0; - ctr->num_entries2 = ctr->num_entries; switch (switch_value) { - case 3: { - int i; - if (*total_entries > 0) { - ctr->ptr_entries = 1; - ctr->file.info3 = talloc(ctx, ctr->num_entries * - sizeof(SRV_FILE_INFO_3)); - } - 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; + case 3: + init_srv_file_info_3(&ctr->file.info3, resume_hnd, total_entries); + ctr->ptr_file_ctr = 1; 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; + ctr->ptr_file_ctr = 0; status = WERR_UNKNOWN_LEVEL; break; } @@ -1001,7 +1020,7 @@ static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr, 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, +static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n, uint32 resume_hnd, int file_level, int switch_value) { DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__)); @@ -1010,7 +1029,7 @@ static void init_srv_r_net_file_enum(pipes_struct *p, SRV_R_NET_FILE_ENUM *r_n, 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)); + r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries)); if (!W_ERROR_IS_OK(r_n->status)) resume_hnd = 0; @@ -1034,21 +1053,11 @@ WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to srv_net_srv_get_info\n")); - return WERR_ACCESS_DENIED; - } - 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: init_srv_info_102(&ctr->srv.sv102, 500, global_myname, - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), lp_major_announce_version(), lp_minor_announce_version(), lp_default_server_announce(), 0xffffffff, /* users */ @@ -1107,13 +1116,19 @@ 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) { + r_u->ctr = (SRV_FILE_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_FILE_INFO_CTR)); + if (!r_u->ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(r_u->ctr); + DEBUG(5,("srv_net_file_enum: %d\n", __LINE__)); /* set up the */ - init_srv_r_net_file_enum(p, r_u, + init_srv_r_net_file_enum(r_u, get_enum_hnd(&q_u->enum_hnd), q_u->file_level, - q_u->ctr.switch_value); + q_u->ctr->switch_value); DEBUG(5,("srv_net_file_enum: %d\n", __LINE__)); @@ -1178,11 +1193,6 @@ WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R { DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to srv_net_share_enum_all\n")); - return WERR_ACCESS_DENIED; - } - /* Create the list of shares for the response. */ init_srv_r_net_share_enum(p, r_u, q_u->ctr.info_level, @@ -1201,11 +1211,6 @@ WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET { DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); - if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to srv_net_share_enum\n")); - return WERR_ACCESS_DENIED; - } - /* Create the list of shares for the response. */ init_srv_r_net_share_enum(p, r_u, q_u->ctr.info_level, @@ -1824,7 +1829,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ "Nigel Williams" <nigel@veritas.com>. ***********************************************************************************/ -static const char *server_disks[] = {"C:"}; +const char *server_disks[] = {"C:"}; static uint32 get_server_disk_count(void) { diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index f896d1d9d8..53bbebb95e 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -38,9 +38,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /* * A list of the rids of well known BUILTIN and Domain users * and groups. @@ -96,7 +93,6 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui uint32 *rids=NULL, *new_rids=NULL; gid_t winbind_gid_low, winbind_gid_high; BOOL ret; - BOOL winbind_groups_exist; /* * this code is far from perfect. @@ -112,15 +108,17 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui *prids=NULL; *numgroups=0; - winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high); + lp_winbind_gid(&winbind_gid_low, &winbind_gid_high); DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n", sid_to_string(str_qsid, q_sid), sid_to_string(str_domsid, sid))); + sid_peek_rid(q_sid, &rid); + pdb_init_sam(&sam_pass); become_root(); - ret = pdb_getsampwsid(sam_pass, q_sid); + ret = pdb_getsampwrid(sam_pass, rid); unbecome_root(); if (ret == False) { pdb_free_sam(&sam_pass); @@ -159,7 +157,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui } /* Don't return winbind groups as they are not local! */ - if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low) && (grp->gr_gid <= winbind_gid_high)) { + if ((grp->gr_gid >= winbind_gid_low) && (grp->gr_gid <= winbind_gid_high)) { DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name)); continue; } @@ -228,7 +226,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui } /* Don't return winbind groups as they are not local! */ - if (winbind_groups_exist && (gid >= winbind_gid_low) && (gid <= winbind_gid_high)) { + if ((gid >= winbind_gid_low) && (gid <= winbind_gid_high)) { DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name )); goto done; } @@ -406,8 +404,6 @@ NTSTATUS local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type) return NT_STATUS_NONE_MAPPED; } - -#if 0 /*Nobody uses this function just now*/ /******************************************************************* Look up a local user rid and return a name and type. ********************************************************************/ @@ -452,8 +448,6 @@ NTSTATUS local_lookup_user_name(uint32 rid, char *user_name, uint32 *type) return NT_STATUS_NONE_MAPPED; } -#endif - /******************************************************************* Look up a local (domain) group name and return a rid ********************************************************************/ diff --git a/source3/rpc_server/srv_wkssvc.c b/source3/rpc_server/srv_wkssvc.c index c783becbbe..8eb5b3002e 100644 --- a/source3/rpc_server/srv_wkssvc.c +++ b/source3/rpc_server/srv_wkssvc.c @@ -24,9 +24,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - /******************************************************************* api_wks_query_info ********************************************************************/ @@ -58,7 +55,7 @@ static BOOL api_wks_query_info(pipes_struct *p) /******************************************************************* \PIPE\wkssvc commands ********************************************************************/ -static struct api_struct api_wks_cmds[] = +struct api_struct api_wks_cmds[] = { { "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info }, { NULL , 0 , NULL } diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index 7687e7b00a..637c95af69 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -25,9 +25,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - extern pstring global_myname; /******************************************************************* |