#include "smbd/globals.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/srv_samr.h"
+#include "rpc_server/srv_samr_util.h"
+#include "../lib/crypto/arcfour.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
};
typedef struct disp_info {
- DOM_SID sid; /* identify which domain this is. */
+ struct dom_sid sid; /* identify which domain this is. */
struct pdb_search *users; /* querydispinfo 1 and 4 */
struct pdb_search *machines; /* querydispinfo 2 */
struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
/*******************************************************************
*******************************************************************/
-static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
+static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
const struct generic_mapping *map,
- DOM_SID *sid, uint32 sid_access )
+ struct dom_sid *sid, uint32 sid_access )
{
- DOM_SID domadmin_sid;
- SEC_ACE ace[5]; /* at most 5 entries */
+ struct dom_sid domadmin_sid;
+ struct security_ace ace[5]; /* at most 5 entries */
size_t i = 0;
- SEC_ACL *psa = NULL;
+ struct security_acl *psa = NULL;
/* basic access for Everyone */
/* Add Full Access for Domain Admins if we are a DC */
if ( IS_DC ) {
- sid_copy( &domadmin_sid, get_global_sam_sid() );
- sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+ sid_compose(&domadmin_sid, get_global_sam_sid(),
+ DOMAIN_RID_ADMINS);
init_sec_ace(&ace[i++], &domadmin_sid,
SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
}
level of access for further checks.
********************************************************************/
-NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
+NTSTATUS access_check_object( struct security_descriptor *psd, NT_USER_TOKEN *token,
SE_PRIV *rights, uint32 rights_mask,
uint32 des_access, uint32 *acc_granted,
const char *debug )
/* Full access for DOMAIN\Domain Admins. */
if ( IS_DC ) {
- DOM_SID domadmin_sid;
- sid_copy( &domadmin_sid, get_global_sam_sid() );
- sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+ struct dom_sid domadmin_sid;
+ sid_compose(&domadmin_sid, get_global_sam_sid(),
+ DOMAIN_RID_ADMINS);
if (is_sid_in_token(nt_token, &domadmin_sid)) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
{
struct samr_connect_info *cinfo;
struct samr_domain_info *dinfo;
- SEC_DESC *psd = NULL;
+ struct security_descriptor *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
NTSTATUS status;
{
struct samr_user_info *uinfo;
uint32 i;
- SEC_ACL *dacl;
+ struct security_acl *dacl;
bool ret;
struct samu *sampass=NULL;
NTSTATUS status;
/*******************************************************************
build correct perms based on policies and password times for _samr_query_sec_obj
*******************************************************************/
-static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
+static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
{
struct samu *sampass=NULL;
bool ret;
struct samr_group_info *ginfo;
struct samr_alias_info *ainfo;
NTSTATUS status;
- SEC_DESC * psd = NULL;
+ struct security_descriptor * psd = NULL;
size_t sd_size = 0;
cinfo = policy_handle_find(p, r->in.handle,
struct samr_OpenUser *r)
{
struct samu *sampass=NULL;
- DOM_SID sid;
+ struct dom_sid sid;
struct samr_domain_info *dinfo;
struct samr_user_info *uinfo;
- SEC_DESC *psd = NULL;
+ struct security_descriptor *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
uint32_t extra_access = 0;
}
/*
* Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
- * in DOMAIN_GROUP_RID_ADMINS. This is almost certainly not
+ * in DOMAIN_RID_ADMINS. This is almost certainly not
* what Windows does but is a hack for people who haven't
* set up privileges on groups in Samba.
*/
if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
- DOMAIN_GROUP_RID_ADMINS)) {
+ DOMAIN_RID_ADMINS)) {
des_access &= ~GENERIC_RIGHTS_USER_WRITE;
extra_access = GENERIC_RIGHTS_USER_WRITE;
DEBUG(4,("_samr_OpenUser: Allowing "
return NT_STATUS_OK;
}
+/*************************************************************************
+ *************************************************************************/
+
+static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
+ struct samu *pw)
+{
+ struct samr_LogonHours hours;
+ const int units_per_week = 168;
+
+ ZERO_STRUCT(hours);
+ hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
+ if (!hours.bits) {
+ return hours;
+ }
+
+ hours.units_per_week = units_per_week;
+ memset(hours.bits, 0xFF, units_per_week);
+
+ if (pdb_get_hours(pw)) {
+ memcpy(hours.bits, pdb_get_hours(pw),
+ MIN(pdb_get_hours_len(pw), units_per_week));
+ }
+
+ return hours;
+}
+
/*************************************************************************
get_user_info_1.
*************************************************************************/
static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
struct samr_UserInfo1 *r,
struct samu *pw,
- DOM_SID *domain_sid)
+ struct dom_sid *domain_sid)
{
- const DOM_SID *sid_group;
+ const struct dom_sid *sid_group;
uint32_t primary_gid;
become_root();
static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
struct samr_UserInfo3 *r,
struct samu *pw,
- DOM_SID *domain_sid)
+ struct dom_sid *domain_sid)
{
- const DOM_SID *sid_user, *sid_group;
+ const struct dom_sid *sid_user, *sid_group;
uint32_t rid, primary_gid;
sid_user = pdb_get_user_sid(pw);
static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
struct samr_UserInfo5 *r,
struct samu *pw,
- DOM_SID *domain_sid)
+ struct dom_sid *domain_sid)
{
- const DOM_SID *sid_user, *sid_group;
+ const struct dom_sid *sid_user, *sid_group;
uint32_t rid, primary_gid;
sid_user = pdb_get_user_sid(pw);
static NTSTATUS get_user_info_18(pipes_struct *p,
TALLOC_CTX *mem_ctx,
struct samr_UserInfo18 *r,
- DOM_SID *user_sid)
+ struct dom_sid *user_sid)
{
struct samu *smbpass=NULL;
bool ret;
static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
struct samr_UserInfo21 *r,
struct samu *pw,
- DOM_SID *domain_sid,
+ struct dom_sid *domain_sid,
uint32_t acc_granted)
{
NTSTATUS status;
- const DOM_SID *sid_user, *sid_group;
+ const struct dom_sid *sid_user, *sid_group;
uint32_t rid, primary_gid;
NTTIME force_password_change;
time_t must_change_time;
NTSTATUS status;
union samr_UserInfo *user_info = NULL;
struct samr_user_info *uinfo;
- DOM_SID domain_sid;
+ struct dom_sid domain_sid;
uint32 rid;
bool ret = false;
struct samu *pwd = NULL;
{
struct samr_user_info *uinfo;
struct samu *sam_pass=NULL;
- DOM_SID *sids;
+ struct dom_sid *sids;
struct samr_RidWithAttribute dom_gid;
struct samr_RidWithAttribute *gids = NULL;
uint32 primary_group_rid;
struct samr_CreateUser2 *r)
{
const char *account = NULL;
- DOM_SID sid;
+ struct dom_sid sid;
uint32_t acb_info = r->in.acct_flags;
struct samr_domain_info *dinfo;
struct samr_user_info *uinfo;
NTSTATUS nt_status;
uint32 acc_granted;
- SEC_DESC *psd;
+ struct security_descriptor *psd;
size_t sd_size;
/* check this, when giving away 'add computer to domain' privs */
uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
se_priv_copy(&se_rights, &se_priv_none);
can_add_account = nt_token_check_domain_rid(
p->server_info->ptok,
- DOMAIN_GROUP_RID_ADMINS );
+ DOMAIN_RID_ADMINS );
}
DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
{
struct samr_connect_info *info = NULL;
struct policy_handle hnd;
- SEC_DESC *psd = NULL;
+ struct security_descriptor *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
NTSTATUS nt_status;
NTSTATUS status;
struct samr_connect_info *info;
const char *domain_name;
- DOM_SID *sid = NULL;
+ struct dom_sid *sid = NULL;
/* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
Reverted that change so we will work with RAS servers again */
NTSTATUS _samr_OpenAlias(pipes_struct *p,
struct samr_OpenAlias *r)
{
- DOM_SID sid;
+ struct dom_sid sid;
uint32 alias_rid = r->in.rid;
struct samr_alias_info *ainfo;
struct samr_domain_info *dinfo;
- SEC_DESC *psd = NULL;
+ struct security_descriptor *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
size_t sd_size;
NTSTATUS status;
- DOM_SID *members;
+ struct dom_sid *members;
DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
if (r->in.sids->num_sids) {
- members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
+ members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
if (members == NULL)
return NT_STATUS_NO_MEMORY;
r->out.rids->count = num_alias_rids;
r->out.rids->ids = alias_rids;
+ if (r->out.rids->ids == NULL) {
+ /* Windows domain clients don't accept a NULL ptr here */
+ r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
+ }
+ if (r->out.rids->ids == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
return NT_STATUS_OK;
}
size_t i;
size_t num_sids = 0;
struct lsa_SidPtr *sids = NULL;
- DOM_SID *pdb_sids = NULL;
+ struct dom_sid *pdb_sids = NULL;
ainfo = policy_handle_find(p, r->in.alias_handle,
SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
return status;
}
- if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
+ if (!sid_check_is_domain(&dinfo->sid)) {
return NT_STATUS_ACCESS_DENIED;
+ }
name = r->in.name->string;
if (name == NULL) {
NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
struct samr_CreateDomAlias *r)
{
- DOM_SID info_sid;
+ struct dom_sid info_sid;
const char *name = NULL;
struct samr_domain_info *dinfo;
struct samr_alias_info *ainfo;
return result;
}
- if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
+ if (!sid_check_is_domain(&dinfo->sid)) {
return NT_STATUS_ACCESS_DENIED;
+ }
name = r->in.alias_name->string;
struct samr_OpenGroup *r)
{
- DOM_SID info_sid;
+ struct dom_sid info_sid;
GROUP_MAP map;
struct samr_domain_info *dinfo;
struct samr_group_info *ginfo;
- SEC_DESC *psd = NULL;
+ struct security_descriptor *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
size_t sd_size;
/* this should not be hard-coded like this */
- if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
+ if (!sid_check_is_domain(&dinfo->sid)) {
return NT_STATUS_ACCESS_DENIED;
+ }
sid_compose(&info_sid, &dinfo->sid, r->in.rid);
{
NTSTATUS status;
- if (req->password.string) {
- if (strlen(req->password.string) < dom_pw_info->min_password_length) {
+ if (req->password.string == NULL) {
+ return SAMR_VALIDATION_STATUS_SUCCESS;
+ }
+ if (strlen(req->password.string) < dom_pw_info->min_password_length) {
+ ZERO_STRUCT(rep->info);
+ return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
+ }
+ if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+ status = check_password_complexity(req->account.string,
+ req->password.string,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
ZERO_STRUCT(rep->info);
- return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
- }
- if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
- status = check_password_complexity(req->account.string,
- req->password.string,
- NULL);
- if (!NT_STATUS_IS_OK(status)) {
- ZERO_STRUCT(rep->info);
- return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
- }
+ return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
}
}
{
NTSTATUS status;
- if (req->password.string) {
- if (strlen(req->password.string) < dom_pw_info->min_password_length) {
+ if (req->password.string == NULL) {
+ return SAMR_VALIDATION_STATUS_SUCCESS;
+ }
+ if (strlen(req->password.string) < dom_pw_info->min_password_length) {
+ ZERO_STRUCT(rep->info);
+ return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
+ }
+ if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+ status = check_password_complexity(req->account.string,
+ req->password.string,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
ZERO_STRUCT(rep->info);
- return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
- }
- if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
- status = check_password_complexity(req->account.string,
- req->password.string,
- NULL);
- if (!NT_STATUS_IS_OK(status)) {
- ZERO_STRUCT(rep->info);
- return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
- }
+ return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
}
}