return status;
}
+ if (sid_check_is_builtin(&dinfo->sid)) {
+ DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
+ return NT_STATUS_OK;
+ }
+
/*
* calculate how many entries we will return.
* based on
alias_info->all.num_members = 1; /* ??? */
alias_info->all.description.string = alias_description;
break;
+ case ALIASINFONAME:
+ alias_info->name.string = alias_name;
+ break;
case ALIASINFODESCRIPTION:
alias_info->description.string = alias_description;
break;
return status;
}
+/****************************************************************
+ _samr_ChangePasswordUser
+****************************************************************/
+
+NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
+ struct samr_ChangePasswordUser *r)
+{
+ NTSTATUS status;
+ bool ret = false;
+ struct samr_user_info *uinfo;
+ struct samu *pwd;
+ struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
+ struct samr_Password lm_pwd, nt_pwd;
+
+ uinfo = policy_handle_find(p, r->in.user_handle,
+ SAMR_USER_ACCESS_SET_PASSWORD, NULL,
+ struct samr_user_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
+ sid_string_dbg(&uinfo->sid)));
+
+ if (!(pwd = samu_new(NULL))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ become_root();
+ ret = pdb_getsampwsid(pwd, &uinfo->sid);
+ unbecome_root();
+
+ if (!ret) {
+ TALLOC_FREE(pwd);
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ {
+ const uint8_t *lm_pass, *nt_pass;
+
+ lm_pass = pdb_get_lanman_passwd(pwd);
+ nt_pass = pdb_get_nt_passwd(pwd);
+
+ if (!lm_pass || !nt_pass) {
+ status = NT_STATUS_WRONG_PASSWORD;
+ goto out;
+ }
+
+ memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
+ memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
+ }
+
+ /* basic sanity checking on parameters. Do this before any database ops */
+ if (!r->in.lm_present || !r->in.nt_present ||
+ !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
+ !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
+ /* we should really handle a change with lm not
+ present */
+ status = NT_STATUS_INVALID_PARAMETER_MIX;
+ goto out;
+ }
+
+ /* decrypt and check the new lm hash */
+ D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
+ D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
+ if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
+ status = NT_STATUS_WRONG_PASSWORD;
+ goto out;
+ }
+
+ /* decrypt and check the new nt hash */
+ D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
+ D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
+ if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
+ status = NT_STATUS_WRONG_PASSWORD;
+ goto out;
+ }
+
+ /* The NT Cross is not required by Win2k3 R2, but if present
+ check the nt cross hash */
+ if (r->in.cross1_present && r->in.nt_cross) {
+ D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
+ if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
+ status = NT_STATUS_WRONG_PASSWORD;
+ goto out;
+ }
+ }
+
+ /* The LM Cross is not required by Win2k3 R2, but if present
+ check the lm cross hash */
+ if (r->in.cross2_present && r->in.lm_cross) {
+ D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
+ if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
+ status = NT_STATUS_WRONG_PASSWORD;
+ goto out;
+ }
+ }
+
+ if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
+ !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
+ status = NT_STATUS_ACCESS_DENIED;
+ goto out;
+ }
+
+ status = pdb_update_sam_account(pwd);
+ out:
+ TALLOC_FREE(pwd);
+
+ return status;
+}
+
/*******************************************************************
_samr_ChangePasswordUser2
********************************************************************/
DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ return status;
+}
+
+/****************************************************************
+ _samr_OemChangePasswordUser2
+****************************************************************/
+
+NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
+ struct samr_OemChangePasswordUser2 *r)
+{
+ NTSTATUS status;
+ fstring user_name;
+ const char *wks = NULL;
+
+ DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
+
+ fstrcpy(user_name, r->in.account->string);
+ if (r->in.server && r->in.server->string) {
+ wks = r->in.server->string;
+ }
+
+ DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user_name);
+
+ /*
+ * UNIX username case mangling not required, pass_oem_change
+ * is case insensitive.
+ */
+
+ if (!r->in.hash || !r->in.password) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = pass_oem_change(user_name,
+ r->in.password->data,
+ r->in.hash->hash,
+ 0,
+ 0,
+ NULL);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
+
return status;
}
r->in.nt_password->data,
r->in.nt_verifier->hash,
&reject_reason);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
dom_info->info8.sequence_num = seq_num;
dom_info->info8.domain_create_time = 0;
+ break;
+ case 0x09:
+
+ dom_info->info9.domain_server_state = DOMAIN_SERVER_ENABLED;
+
+ break;
+ case 0x0b:
+
+ /* AS ROOT !!! */
+
+ become_root();
+
+ dom_info->general2.general.num_users = count_sam_users(
+ dinfo->disp_info, ACB_NORMAL);
+ dom_info->general2.general.num_groups = count_sam_groups(
+ dinfo->disp_info);
+ dom_info->general2.general.num_aliases = count_sam_aliases(
+ dinfo->disp_info);
+
+ pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
+
+ unix_to_nt_time_abs(&dom_info->general2.general.force_logoff_time, u_logout);
+
+ if (!pdb_get_seq_num(&seq_num))
+ seq_num = time(NULL);
+
+ pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ u_lock_duration = account_policy_temp;
+ if (u_lock_duration != -1) {
+ u_lock_duration *= 60;
+ }
+
+ pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+ u_reset_time = account_policy_temp * 60;
+
+ pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+ &account_policy_temp);
+ dom_info->general2.lockout_threshold = account_policy_temp;
+
+ /* !AS ROOT */
+
+ unbecome_root();
+
+ server_role = ROLE_DOMAIN_PDC;
+ if (lp_server_role() == ROLE_DOMAIN_BDC)
+ server_role = ROLE_DOMAIN_BDC;
+
+ dom_info->general2.general.oem_information.string = lp_serverstring();
+ dom_info->general2.general.domain_name.string = lp_workgroup();
+ dom_info->general2.general.primary.string = global_myname();
+ dom_info->general2.general.sequence_num = seq_num;
+ dom_info->general2.general.domain_server_state = DOMAIN_SERVER_ENABLED;
+ dom_info->general2.general.role = server_role;
+ dom_info->general2.general.unknown3 = 1;
+
+ unix_to_nt_time_abs(&dom_info->general2.lockout_duration,
+ u_lock_duration);
+ unix_to_nt_time_abs(&dom_info->general2.lockout_window,
+ u_reset_time);
+
break;
case 0x0c:
unix_to_nt_time_abs(&dom_info->info12.lockout_window,
u_reset_time);
+ break;
+ case 0x0d:
+
+ become_root();
+
+ /* AS ROOT !!! */
+
+ if (!pdb_get_seq_num(&seq_num)) {
+ seq_num = time(NULL);
+ }
+
+ /* !AS ROOT */
+
+ unbecome_root();
+
+ dom_info->info13.sequence_num = seq_num;
+ dom_info->info13.domain_create_time = 0;
+ dom_info->info13.modified_count_at_last_promotion = 0;
+
break;
default:
return NT_STATUS_INVALID_INFO_CLASS;
code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
rc = can_create(mem_ctx, id7->account_name.string);
+
+ /* when there is nothing to change, we're done here */
+ if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
+ strequal(id7->account_name.string, pdb_get_username(pwd))) {
+ return NT_STATUS_OK;
+ }
if (!NT_STATUS_IS_OK(rc)) {
return rc;
}
set_user_info_16
********************************************************************/
-static bool set_user_info_16(struct samr_UserInfo16 *id16,
- struct samu *pwd)
+static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
+ struct samr_UserInfo16 *id16,
+ struct samu *pwd)
{
if (id16 == NULL) {
- DEBUG(5, ("set_user_info_16: NULL id16\n"));
- return False;
- }
-
- /* FIX ME: check if the value is really changed --metze */
- if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
- return False;
+ DEBUG(5,("set_user_info_16: NULL id16\n"));
+ return NT_STATUS_ACCESS_DENIED;
}
- if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
- return False;
- }
+ copy_id16_to_sam_passwd(pwd, id16);
- return True;
+ return pdb_update_sam_account(pwd);
}
/*******************************************************************
set_user_info_20
********************************************************************/
-static bool set_user_info_20(struct samr_UserInfo20 *id20,
- struct samu *pwd)
+static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
+ struct samr_UserInfo20 *id20,
+ struct samu *pwd)
{
if (id20 == NULL) {
- DEBUG(5, ("set_user_info_20: NULL id20\n"));
- return False;
+ DEBUG(5,("set_user_info_20: NULL id20\n"));
+ return NT_STATUS_ACCESS_DENIED;
}
copy_id20_to_sam_passwd(pwd, id20);
- /* write the change out */
- if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
- return False;
- }
-
- return True;
+ return pdb_update_sam_account(pwd);
}
/*******************************************************************
we'll use the set from the WinXP join as the basis. */
switch (switch_value) {
+ case 7:
+ acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
+ break;
case 18:
case 24:
case 25:
break;
case 16:
- if (!set_user_info_16(&info->info16, pwd)) {
- status = NT_STATUS_ACCESS_DENIED;
- }
+ status = set_user_info_16(p->mem_ctx,
+ &info->info16, pwd);
break;
case 17:
break;
case 20:
- if (!set_user_info_20(&info->info20, pwd)) {
- status = NT_STATUS_ACCESS_DENIED;
- }
+ status = set_user_info_20(p->mem_ctx,
+ &info->info20, pwd);
break;
case 21:
pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
break;
- case 0x02:
- break;
case 0x03:
u_logout=nt_time_to_unix_abs((NTTIME *)&r->in.info->info3.force_logoff_time);
pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
break;
- case 0x05:
+ case 0x04:
break;
case 0x06:
break;
case 0x07:
break;
+ case 0x09:
+ break;
case 0x0c:
u_lock_duration=nt_time_to_unix_abs((NTTIME *)&r->in.info->info12.lockout_duration);
if (u_lock_duration != -1)
/****************************************************************
****************************************************************/
-NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
- struct samr_ChangePasswordUser *r)
-{
- p->rng_fault_state = true;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
struct samr_TestPrivateFunctionsDomain *r)
{
NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
struct samr_TestPrivateFunctionsUser *r)
{
- p->rng_fault_state = true;
return NT_STATUS_NOT_IMPLEMENTED;
}
/****************************************************************
****************************************************************/
-NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
- struct samr_OemChangePasswordUser2 *r)
-{
- p->rng_fault_state = true;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
struct samr_SetBootKeyInformation *r)
{