📄 srv_lsa_nt.c
字号:
/*************************************************************************** ***************************************************************************/NTSTATUS _lsa_set_secret(pipes_struct *p, LSA_Q_SET_SECRET *q_u, LSA_R_SET_SECRET *r_u){ return NT_STATUS_ACCESS_DENIED;}/*************************************************************************** ***************************************************************************/NTSTATUS _lsa_delete_object(pipes_struct *p, LSA_Q_DELETE_OBJECT *q_u, LSA_R_DELETE_OBJECT *r_u){ return NT_STATUS_ACCESS_DENIED;}/***************************************************************************_lsa_enum_privs. ***************************************************************************/NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u){ struct lsa_info *handle; uint32 i; uint32 enum_context = q_u->enum_context; int num_privs = count_all_privileges(); LSA_PRIV_ENTRY *entries = NULL; LUID_ATTR luid; /* remember that the enum_context starts at 0 and not 1 */ if ( enum_context >= num_privs ) return NT_STATUS_NO_MORE_ENTRIES; DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context, num_privs)); if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights I don't know if it's the right one. not documented. */ if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) ) return NT_STATUS_NO_MEMORY; for (i = 0; i < num_privs; i++) { if( i < enum_context) { init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE); init_uni_hdr(&entries[i].hdr_name, &entries[i].name); entries[i].luid_low = 0; entries[i].luid_high = 0; } else { init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE); init_uni_hdr(&entries[i].hdr_name, &entries[i].name); luid = get_privilege_luid( &privs[i].se_priv ); entries[i].luid_low = luid.luid.low; entries[i].luid_high = luid.luid.high; } } enum_context = num_privs; init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries); return NT_STATUS_OK;}/***************************************************************************_lsa_priv_get_dispname. ***************************************************************************/NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u){ struct lsa_info *handle; fstring name_asc; const char *description; if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ /* * I don't know if it's the right one. not documented. */ if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc)); DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc)); description = get_privilege_dispname( name_asc ); if ( description ) { DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description)); init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE); init_uni_hdr(&r_u->hdr_desc, &r_u->desc); r_u->ptr_info = 0xdeadbeef; r_u->lang_id = q_u->lang_id; return NT_STATUS_OK; } else { DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n")); r_u->ptr_info = 0; return NT_STATUS_NO_SUCH_PRIVILEGE; }}/***************************************************************************_lsa_enum_accounts. ***************************************************************************/NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u){ struct lsa_info *handle; DOM_SID *sid_list; int i, j, num_entries; LSA_SID_ENUM *sids=&r_u->sids; NTSTATUS ret; if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; sid_list = NULL; num_entries = 0; /* The only way we can currently find out all the SIDs that have been privileged is to scan all privileges */ if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) { return ret; } if (q_u->enum_context >= num_entries) return NT_STATUS_NO_MORE_ENTRIES; sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context); sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context); if (sids->ptr_sid==NULL || sids->sid==NULL) { SAFE_FREE(sid_list); return NT_STATUS_NO_MEMORY; } for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) { init_dom_sid2(&(*sids).sid[j], &sid_list[i]); (*sids).ptr_sid[j] = 1; } SAFE_FREE(sid_list); init_lsa_r_enum_accounts(r_u, num_entries); return NT_STATUS_OK;}NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u){ fstring username, domname; user_struct *vuser = get_valid_user_struct(p->vuid); if (vuser == NULL) return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; fstrcpy(username, vuser->user.smb_name); fstrcpy(domname, vuser->user.domain); r_u->ptr_user_name = 1; init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE); init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name); r_u->unk1 = 1; r_u->ptr_dom_name = 1; init_unistr2(&r_u->uni2_dom_name, domname, UNI_STR_TERMINATE); init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name); r_u->status = NT_STATUS_OK; return r_u->status;}/*************************************************************************** Lsa Create Account ***************************************************************************/NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u){ struct lsa_info *handle; struct lsa_info *info; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ /* * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) return NT_STATUS_ACCESS_DENIED; if ( is_privileged_sid( &q_u->sid.sid ) ) return NT_STATUS_OBJECT_NAME_COLLISION; /* associate the user/group SID with the (unique) handle. */ if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) return NT_STATUS_NO_MEMORY; ZERO_STRUCTP(info); info->sid = q_u->sid.sid; info->access = q_u->access; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return privilege_create_account( &info->sid );}/*************************************************************************** Lsa Open Account ***************************************************************************/NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u){ struct lsa_info *handle; struct lsa_info *info; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ /* * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* TODO: Fis the parsing routine before reenabling this check! */ #if 0 if (!lookup_sid(&handle->sid, dom_name, name, &type)) return NT_STATUS_ACCESS_DENIED; #endif /* associate the user/group SID with the (unique) handle. */ if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) return NT_STATUS_NO_MEMORY; ZERO_STRUCTP(info); info->sid = q_u->sid.sid; info->access = q_u->access; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; return NT_STATUS_OK;}/*************************************************************************** For a given SID, enumerate all the privilege this account has. ***************************************************************************/NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u){ struct lsa_info *info=NULL; SE_PRIV mask; PRIVILEGE_SET privileges; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) return NT_STATUS_OBJECT_NAME_NOT_FOUND; privilege_set_init( &privileges ); if ( se_priv_to_privilege_set( &privileges, &mask ) ) { DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", sid_string_static(&info->sid), privileges.count)); r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0); } else r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; privilege_set_free( &privileges ); return r_u->status;}/*************************************************************************** ***************************************************************************/NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u){ struct lsa_info *info=NULL; fstring name, dom_name; enum SID_NAME_USE type; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; if (!lookup_sid(&info->sid, dom_name, name, &type)) return NT_STATUS_ACCESS_DENIED; /* 0x01 -> Log on locally 0x02 -> Access this computer from network 0x04 -> Log on as a batch job 0x10 -> Log on as a service they can be ORed together */ r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK; return NT_STATUS_OK;}/*************************************************************************** update the systemaccount information ***************************************************************************/NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u){ struct lsa_info *info=NULL; GROUP_MAP map; r_u->status = NT_STATUS_OK; /* find the connection policy handle. */ if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; /* 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 ) ) return NT_STATUS_ACCESS_DENIED; if (!pdb_getgrsid(&map, info->sid)) return NT_STATUS_NO_SUCH_GROUP; if(!pdb_update_group_mapping_entry(&map)) return NT_STATUS_NO_SUCH_GROUP; return r_u->status;}/*************************************************************************** For a given SID, add some privileges. ***************************************************************************/NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u){ struct lsa_info *info = NULL; SE_PRIV mask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -