}
}
- init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
+ init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, type, r_u->status);
DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
{
const char **names;
- uint32 *attrs = NULL;
+ enum SID_NAME_USE *attrs = NULL;
+ uint32 *wire_attrs = NULL;
UNIHDR *hdr_name = NULL;
UNISTR2 *uni_name = NULL;
DOM_SID pol_sid;
int num_rids = q_u->num_rids1;
uint32 acc_granted;
-
+ int i;
+
r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
}
names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
- attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
+ attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum SID_NAME_USE, num_rids);
+ wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
- if ((num_rids != 0) && ((names == NULL) || (attrs == NULL)))
+ if ((num_rids != 0) && ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL)))
return NT_STATUS_NO_MEMORY;
become_root(); /* lookup_sid can require root privs */
&hdr_name, &uni_name))
return NT_STATUS_NO_MEMORY;
- init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, attrs);
+ /* Convert from enum SID_NAME_USE to uint32 for wire format. */
+ for (i = 0; i < num_rids; i++) {
+ wire_attrs[i] = (uint32)attrs[i];
+ }
+
+ init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, wire_attrs);
DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
TALLOC_FREE(sampass);
- return NT_STATUS_OK;
+ return nt_status;
}
/*******************************************************************
}
/*******************************************************************
- _samr_query_dom_info
+ _samr_query_domain_info
********************************************************************/
-NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
+NTSTATUS _samr_query_domain_info(pipes_struct *p,
+ SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+ SAMR_R_QUERY_DOMAIN_INFO *r_u)
{
struct samr_info *info = NULL;
SAM_UNK_CTR *ctr;
r_u->status = NT_STATUS_OK;
- DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
+ DEBUG(5,("_samr_query_domain_info: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info)) {
init_unk_info3(&ctr->info.inf3, nt_logout);
break;
+ case 0x04:
+ init_unk_info4(&ctr->info.inf4, lp_serverstring());
+ break;
case 0x05:
init_unk_info5(&ctr->info.inf5, get_global_sam_name());
break;
case 0x06:
- init_unk_info6(&ctr->info.inf6);
+ /* NT returns its own name when a PDC. win2k and later
+ * only the name of the PDC if itself is a BDC (samba4
+ * idl) */
+ init_unk_info6(&ctr->info.inf6, global_myname());
break;
case 0x07:
server_role = ROLE_DOMAIN_PDC;
}
- init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
+ init_samr_r_query_domain_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
- DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
+ DEBUG(5,("_samr_query_domain_info: %d\n", __LINE__));
return r_u->status;
}
}
DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
- p->pipe_user_name, can_add_account ? "True":"False" ));
+ uidtoname(p->pipe_user.ut.uid),
+ can_add_account ? "True":"False" ));
/********** BEGIN Admin BLOCK **********/
}
/* we need to separately check for an account rename first */
+
if (rpcstr_pull(new_name, id21->uni_user_name.buffer,
- sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0) &&
- (!strequal(new_name, pdb_get_username(pwd)))) {
+ sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0)
+ && (!strequal(new_name, pdb_get_username(pwd))))
+ {
/* check to see if the new username already exists. Note: we can't
reliably lock all backends, so there is potentially the
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
- DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
+ DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
} else {
/* update the UNIX password */
if (lp_unix_password_sync() ) {
- struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
- if (!passwd) {
+ struct passwd *passwd;
+ if (pdb_get_username(pwd) == NULL) {
+ DEBUG(1, ("chgpasswd: User without name???\n"));
+ TALLOC_FREE(pwd);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
}
} else {
/* update the UNIX password */
if (lp_unix_password_sync()) {
- struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
- if (!passwd) {
+ struct passwd *passwd;
+
+ if (pdb_get_username(pwd) == NULL) {
+ DEBUG(1, ("chgpasswd: User without name???\n"));
+ TALLOC_FREE(pwd);
+ return False;
+ }
+
+ if ((passwd = Get_Pwnam(pdb_get_username(pwd))) == NULL) {
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
}
return True;
}
+/*******************************************************************
+ set_user_info_25
+ ********************************************************************/
+
+static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, SAM_USER_INFO_25 *id25,
+ struct samu *pwd)
+{
+ NTSTATUS status;
+
+ if (id25 == NULL) {
+ DEBUG(5, ("set_user_info_25: NULL id25\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ copy_id25_to_sam_passwd(pwd, id25);
+
+ /* write the change out */
+ if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
+ TALLOC_FREE(pwd);
+ return status;
+ }
+
+ /*
+ * We need to "pdb_update_sam_account" before the unix primary group
+ * is set, because the idealx scripts would also change the
+ * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
+ * the delete explicit / add explicit, which would then fail to find
+ * the previous primaryGroupSid value.
+ */
+
+ if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
+ status = pdb_set_unix_primary_group(mem_ctx, pwd);
+ if ( !NT_STATUS_IS_OK(status) ) {
+ return status;
+ }
+ }
+
+ /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
+ * hereafter! */
+
+ return NT_STATUS_OK;
+}
+
/*******************************************************************
samr_reply_set_userinfo
********************************************************************/
if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
return NT_STATUS_INVALID_HANDLE;
- /* observed when joining an XP client to a Samba domain */
+ /* This is tricky. A WinXP domain join sets
+ (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
+ The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the
+ standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().
+ This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so
+ we'll use the set from the WinXP join as the basis. */
+
+ switch (switch_value) {
+ case 18:
+ case 24:
+ case 25:
+ case 26:
+ acc_required = SA_RIGHT_USER_SET_PASSWORD;
+ break;
+ default:
+ acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
+ break;
+ }
- acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
-
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: %s does%s possess sufficient rights\n",
- p->pipe_user_name, has_enough_rights ? "" : " not"));
+ uidtoname(p->pipe_user.ut.uid),
+ has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
dump_data(100, (char *)ctr->info.id25->pass, 532);
+ r_u->status = set_user_info_25(p->mem_ctx,
+ ctr->info.id25, pwd);
+ if (!NT_STATUS_IS_OK(r_u->status)) {
+ goto done;
+ }
if (!set_user_info_pw(ctr->info.id25->pass, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
r_u->status = NT_STATUS_INVALID_INFO_CLASS;
}
+ done:
if ( has_enough_rights )
unbecome_root();
}
DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
- p->pipe_user_name, has_enough_rights ? "" : " not"));
+ uidtoname(p->pipe_user.ut.uid),
+ has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
+ become_root();
status = pdb_enum_aliasmem(&alias_sid, &sids, &num_sids);
+ unbecome_root();
if (!NT_STATUS_IS_OK(status)) {
return status;
attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
- if ((num_members!=0) && (rid==NULL))
+ if ((num_members!=0) && (attr==NULL))
return NT_STATUS_NO_MEMORY;
for (i=0; i<num_members; i++)
BOOL can_add_accounts;
uint32 acb_info;
DISP_INFO *disp_info = NULL;
+ BOOL ret;
DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
return NT_STATUS_NO_MEMORY;
}
- if(!pdb_getsampwsid(sam_pass, &user_sid)) {
+ become_root();
+ ret = pdb_getsampwsid(sam_pass, &user_sid);
+ unbecome_root();
+
+ if( !ret ) {
DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
sid_string_static(&user_sid)));
TALLOC_FREE(sam_pass);
/* get the current group information */
- if ( !pdb_get_aliasinfo( &group_sid, &info ) ) {
+ become_root();
+ ret = pdb_get_aliasinfo( &group_sid, &info );
+ unbecome_root();
+
+ if ( !ret ) {
return NT_STATUS_NO_SUCH_ALIAS;
}
switch (ctr->level) {
case 2:
+ {
+ fstring group_name;
+ NTSTATUS status;
+
/* We currently do not support renaming groups in the
the BUILTIN domain. Refer to util_builtin.c to understand
why. The eventually needs to be fixed to be like Windows
return NT_STATUS_SPECIAL_ACCOUNT;
}
- if ( ctr->alias.info2.name.string ) {
- unistr2_to_ascii( info.acct_name, ctr->alias.info2.name.string,
- sizeof(info.acct_name)-1 );
- }
- else
- fstrcpy( info.acct_name, "" );
+ /* There has to be a valid name */
+ if ( !ctr->alias.info2.name.string )
+ return NT_STATUS_INVALID_PARAMETER;
+
+ unistr2_to_ascii( info.acct_name, ctr->alias.info2.name.string,
+ sizeof(info.acct_name)-1 );
+
+ /* make sure the name doesn't already exist as a user
+ or local group */
+
+ fstr_sprintf( group_name, "%s\\%s", global_myname(), info.acct_name );
+ status = can_create( p->mem_ctx, group_name );
+ if ( !NT_STATUS_IS_OK( status ) )
+ return status;
break;
+ }
case 3:
if ( ctr->alias.info3.description.string ) {
unistr2_to_ascii( info.acct_desc,
********************************************************************/
NTSTATUS _samr_query_domain_info2(pipes_struct *p,
- SAMR_Q_QUERY_DOMAIN_INFO2 *q_u,
- SAMR_R_QUERY_DOMAIN_INFO2 *r_u)
+ SAMR_Q_QUERY_DOMAIN_INFO2 *q_u,
+ SAMR_R_QUERY_DOMAIN_INFO2 *r_u)
{
- struct samr_info *info = NULL;
- SAM_UNK_CTR *ctr;
- uint32 min_pass_len,pass_hist,password_properties;
- time_t u_expire, u_min_age;
- NTTIME nt_expire, nt_min_age;
-
- time_t u_lock_duration, u_reset_time;
- NTTIME nt_lock_duration, nt_reset_time;
- uint32 lockout;
-
- time_t u_logout;
- NTTIME nt_logout;
-
- uint32 num_users=0, num_groups=0, num_aliases=0;
-
- uint32 account_policy_temp;
-
- time_t seq_num;
- uint32 server_role;
+ SAMR_Q_QUERY_DOMAIN_INFO q;
+ SAMR_R_QUERY_DOMAIN_INFO r;
- if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(ctr);
-
- r_u->status = NT_STATUS_OK;
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- switch (q_u->switch_value) {
- case 0x01:
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
- min_pass_len = account_policy_temp;
-
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
- pass_hist = account_policy_temp;
-
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
- password_properties = account_policy_temp;
-
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
- u_expire = account_policy_temp;
-
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
- u_min_age = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_expire, u_expire);
- unix_to_nt_time_abs(&nt_min_age, u_min_age);
-
- init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
- password_properties, nt_expire, nt_min_age);
- break;
- case 0x02:
- become_root();
- num_users = count_sam_users(info->disp_info, ACB_NORMAL);
- num_groups = count_sam_groups(info->disp_info);
- num_aliases = count_sam_aliases(info->disp_info);
- unbecome_root();
-
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
- u_logout = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_logout, u_logout);
-
- if (!pdb_get_seq_num(&seq_num))
- seq_num = time(NULL);
-
- server_role = ROLE_DOMAIN_PDC;
- if (lp_server_role() == ROLE_DOMAIN_BDC)
- server_role = ROLE_DOMAIN_BDC;
-
- init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), seq_num,
- num_users, num_groups, num_aliases, nt_logout, server_role);
- break;
- case 0x03:
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
- u_logout = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_logout, u_logout);
-
- init_unk_info3(&ctr->info.inf3, nt_logout);
- break;
- case 0x05:
- init_unk_info5(&ctr->info.inf5, get_global_sam_name());
- break;
- case 0x06:
- init_unk_info6(&ctr->info.inf6);
- break;
- case 0x07:
- server_role = ROLE_DOMAIN_PDC;
- if (lp_server_role() == ROLE_DOMAIN_BDC)
- server_role = ROLE_DOMAIN_BDC;
+ q.domain_pol = q_u->domain_pol;
+ q.switch_value = q_u->switch_value;
- init_unk_info7(&ctr->info.inf7, server_role);
- break;
- case 0x08:
- if (!pdb_get_seq_num(&seq_num))
- seq_num = time(NULL);
+ r_u->status = _samr_query_domain_info(p, &q, &r);
- init_unk_info8(&ctr->info.inf8, (uint32) seq_num);
- break;
- case 0x0c:
- 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);
- lockout = account_policy_temp;
-
- unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
- unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
-
- init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
-
- init_samr_r_samr_query_domain_info2(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
-
- DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__));
+ r_u->ptr_0 = r.ptr_0;
+ r_u->switch_value = r.switch_value;
+ r_u->ctr = r.ctr;
return r_u->status;
}
/*******************************************************************
- _samr_
+ _samr_set_dom_info
********************************************************************/
NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)