#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+#define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
+
extern PRIVS privs[];
struct lsa_info {
num = ref->count;
}
- if (num >= MAX_REF_DOMAINS) {
+ if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
/* index not found, already at maximum domain limit */
return -1;
}
ref->count = num + 1;
- ref->max_size = MAX_REF_DOMAINS;
+ ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains,
struct lsa_DomainInfo, ref->count);
}
-/*******************************************************************
- Function to free the per handle data.
- ********************************************************************/
-
-static void free_lsa_info(void *ptr)
-{
- struct lsa_info *lsa = (struct lsa_info *)ptr;
-
- SAFE_FREE(lsa);
-}
-
/***************************************************************************
initialize a lsa_DomainInfo structure.
***************************************************************************/
mapped_count++;
}
- init_lsa_translated_sid(&prid[i], type, rid, dom_idx);
+ prid[i].sid_type = type;
+ prid[i].rid = rid;
+ prid[i].sid_index = dom_idx;
}
*pmapped_count = mapped_count;
DOM_SID adm_sid;
SEC_ACE ace[3];
- SEC_ACCESS mask;
SEC_ACL *psa = NULL;
- init_sec_access(&mask, LSA_POLICY_EXECUTE);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, LSA_POLICY_EXECUTE, 0);
sid_copy(&adm_sid, get_global_sam_sid());
sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
- init_sec_access(&mask, LSA_POLICY_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, LSA_POLICY_ALL_ACCESS, 0);
sid_copy(&local_adm_sid, &global_sid_Builtin);
sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
- init_sec_access(&mask, LSA_POLICY_ALL_ACCESS);
- init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, LSA_POLICY_ALL_ACCESS, 0);
if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
return NT_STATUS_NO_MEMORY;
/* get the generic lsa policy SD until we store it */
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
- if (p->pipe_user.ut.uid != sec_initial_uid()) {
+ status = se_access_check(psd, p->server_info->ptok, des_access,
+ &acc_granted);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
return status;
}
DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
/* This is needed for lsa_open_account and rpcclient .... :-) */
- if (p->pipe_user.ut.uid == sec_initial_uid())
+ if (p->server_info->utok.uid == sec_initial_uid())
acc_granted = LSA_POLICY_ALL_ACCESS;
/* associate the domain SID with the (unique) handle. */
- if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
+ info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
+ }
- ZERO_STRUCTP(info);
sid_copy(&info->sid,get_global_sam_sid());
info->access = acc_granted;
/* set up the LSA QUERY INFO response */
- if (!create_policy_hnd(p, r->out.handle, free_lsa_info, (void *)info))
+ if (!create_policy_hnd(p, r->out.handle, info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
return NT_STATUS_OK;
/* get the generic lsa policy SD until we store it */
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
- if (geteuid() != 0) {
+ status = se_access_check(psd, p->server_info->ptok, des_access,
+ &acc_granted);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
return status;
}
DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
}
/* associate the domain SID with the (unique) handle. */
- if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
+ info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
+ }
- ZERO_STRUCTP(info);
sid_copy(&info->sid,get_global_sam_sid());
info->access = acc_granted;
/* set up the LSA QUERY INFO response */
- if (!create_policy_hnd(p, r->out.handle, free_lsa_info, (void *)info))
+ if (!create_policy_hnd(p, r->out.handle, info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
return NT_STATUS_OK;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
+ become_root();
nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
+ unbecome_root();
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
uint32 policy_def = LSA_AUDIT_POLICY_ALL;
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
return NT_STATUS_ACCESS_DENIED;
break;
}
case 0x03:
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
init_dom_query_3(&info->domain, name, sid);
break;
case 0x05:
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
init_dom_query_5(&info->account_domain, name, sid);
break;
case 0x06:
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
* only a BDC is a backup controller
* of the domain, it controls.
*/
- info->role.role = 2;
+ info->role.role = LSA_ROLE_BACKUP;
break;
default:
/*
* any other role is a primary
* of the domain, it controls.
*/
- info->role.role = 3;
+ info->role.role = LSA_ROLE_PRIMARY;
break;
}
break;
return NT_STATUS_NO_MEMORY;
}
- for (i=0; i<MAX_REF_DOMAINS; i++) {
+ for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
if (!dom_infos[i].valid) {
break;
mapped_count += 1;
}
- init_lsa_translated_name2(&names[i], name->type,
- name->name, name->dom_idx, 0);
+ names[i].sid_type = name->type;
+ names[i].name.string = name->name;
+ names[i].sid_index = name->dom_idx;
+ names[i].unknown = 0;
}
status = NT_STATUS_NONE_MAPPED;
&names,
&mapped_count);
+ /* Only return here when there is a real error.
+ NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
+ the requested sids could be resolved. Older versions of XP (pre SP3)
+ rely that we return with the string representations of those SIDs in
+ that case. If we don't, XP crashes - Guenther
+ */
+
+ if (NT_STATUS_IS_ERR(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+ return status;
+ }
+
/* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
num_sids);
return NT_STATUS_INVALID_HANDLE;
}
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
return NT_STATUS_ACCESS_DENIED;
}
goto done;
}
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
status = NT_STATUS_ACCESS_DENIED;
goto done;
status = _lsa_LookupNames(p, &q);
+ sid_array2->count = sid_array->count;
sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
if (!sid_array2->sids) {
return NT_STATUS_NO_MEMORY;
goto done;
}
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
status = NT_STATUS_ACCESS_DENIED;
goto done;
}
}
- *r->out.count = num_entries;
+ *r->out.count = mapped_count;
*r->out.domains = domains;
r->out.sids->sids = trans_sids;
- r->out.sids->count = mapped_count;
+ r->out.sids->count = num_entries;
return status;
}
q.in.num_names = r->in.num_names;
q.in.names = r->in.names;
q.in.level = r->in.level;
- q.in.unknown1 = r->in.unknown1;
- q.in.unknown2 = r->in.unknown2;
+ q.in.lookup_options = r->in.lookup_options;
+ q.in.client_revision = r->in.client_revision;
q.in.sids = r->in.sids;
q.in.count = r->in.count;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights
+ /* check if the user has enough rights
I don't know if it's the right one. not documented. */
if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
/*
* I don't know if it's the right one. not documented.
sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
num_entries - *r->in.resume_handle);
if (!sids) {
- SAFE_FREE(sid_list);
+ talloc_free(sid_list);
return NT_STATUS_NO_MEMORY;
}
for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
if (!sids[j].sid) {
- SAFE_FREE(sid_list);
+ talloc_free(sid_list);
return NT_STATUS_NO_MEMORY;
}
}
struct lsa_GetUserName *r)
{
const char *username, *domname;
- user_struct *vuser = get_valid_user_struct(p->vuid);
struct lsa_String *account_name = NULL;
struct lsa_String *authority_name = NULL;
- if (vuser == NULL)
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ if (r->in.account_name &&
+ *r->in.account_name) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if (vuser->guest) {
+ if (r->in.authority_name &&
+ *r->in.authority_name) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (p->server_info->guest) {
/*
* I'm 99% sure this is not the right place to do this,
* global_sid_Anonymous should probably be put into the token
return NT_STATUS_NO_MEMORY;
}
} else {
- username = vuser->user.smb_name;
- domname = vuser->user.domain;
+ username = p->server_info->sanitized_username;
+ domname = pdb_get_domain(p->server_info->sam_account);
}
- account_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_String);
+ account_name = TALLOC_P(p->mem_ctx, struct lsa_String);
if (!account_name) {
return NT_STATUS_NO_MEMORY;
}
+ init_lsa_String(account_name, username);
- authority_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_String);
- if (!authority_name) {
- return NT_STATUS_NO_MEMORY;
+ if (r->out.authority_name) {
+ authority_name = TALLOC_P(p->mem_ctx, struct lsa_String);
+ if (!authority_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ init_lsa_String(authority_name, domname);
}
- init_lsa_String(account_name, username);
- init_lsa_String(authority_name, domname);
-
*r->out.account_name = account_name;
- *r->out.authority_name = authority_name;
+ if (r->out.authority_name) {
+ *r->out.authority_name = authority_name;
+ }
return NT_STATUS_OK;
}
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
/*
* I don't know if it's the right one. not documented.
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
return NT_STATUS_ACCESS_DENIED;
if ( is_privileged_sid( r->in.sid ) )
/* associate the user/group SID with the (unique) handle. */
- if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
+ info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
+ }
- ZERO_STRUCTP(info);
info->sid = *r->in.sid;
info->access = r->in.access_mask;
/* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.acct_handle, free_lsa_info, (void *)info))
+ if (!create_policy_hnd(p, r->out.acct_handle, info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
return privilege_create_account( &info->sid );
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
/*
* I don't know if it's the right one. not documented.
return NT_STATUS_ACCESS_DENIED;
#endif
/* associate the user/group SID with the (unique) handle. */
- if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
+ info = TALLOC_ZERO_P(p->mem_ctx, struct lsa_info);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
+ }
- ZERO_STRUCTP(info);
info->sid = *r->in.sid;
info->access = r->in.access_mask;
/* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.acct_handle, free_lsa_info, (void *)info))
+ if (!create_policy_hnd(p, r->out.acct_handle, info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
return NT_STATUS_OK;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
+ return NT_STATUS_ACCESS_DENIED;
+
if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
+ return NT_STATUS_ACCESS_DENIED;
+
if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
return NT_STATUS_ACCESS_DENIED;
they can be ORed together
*/
- *r->out.access_mask = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
+ *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
+ LSA_POLICY_MODE_NETWORK;
return NT_STATUS_OK;
}
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
return NT_STATUS_ACCESS_DENIED;
if (!pdb_getgrsid(&map, info->sid))
/* check to see if the pipe_user is root or a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
/* check to see if the pipe_user is root or a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
-
switch (r->in.sec_info) {
case 1:
/* SD contains only the owner */
switch (q_u->info_class) {
case 0x0c:
- /* check if the user have enough rights */
+ /* check if the user has enough rights */
if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
+ return NT_STATUS_ACCESS_DENIED;
+
/* according to an NT4 PDC, you can add privileges to SIDs even without
call_lsa_create_account() first. And you can use any arbitrary SID. */
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
+ return NT_STATUS_ACCESS_DENIED;
+
name = r->in.name->string;
DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));